提交 8daae360 authored 作者: 王鹏飞's avatar 王鹏飞

feat: implement AI chat functionality with new components and API integration

上级 191a6af6
...@@ -2,8 +2,8 @@ import { useState, KeyboardEvent, useEffect, useRef } from 'react' ...@@ -2,8 +2,8 @@ import { useState, KeyboardEvent, useEffect, useRef } from 'react'
import { Button, Card, FloatButton, Input, Select } from 'antd' import { Button, Card, FloatButton, Input, Select } from 'antd'
import { CircleArrowLeft, CircleArrowRight } from 'lucide-react' import { CircleArrowLeft, CircleArrowRight } from 'lucide-react'
import { OpenAIOutlined, ArrowUpOutlined } from '@ant-design/icons' import { OpenAIOutlined, ArrowUpOutlined } from '@ant-design/icons'
import { useAIStore, AIMessage } from '@/stores/ai' import { useAIStore, AIMessage } from './useAIStore'
import MarkdownRender from '../MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
import './AIChat.scss' import './AIChat.scss'
export const MessageItem = ({ message }: { message: AIMessage }) => { export const MessageItem = ({ message }: { message: AIMessage }) => {
...@@ -74,7 +74,7 @@ export default function AIChat() { ...@@ -74,7 +74,7 @@ export default function AIChat() {
onChange={setAI} onChange={setAI}
variant="filled" variant="filled"
suffixIcon={null} suffixIcon={null}
popupMatchSelectWidth={110}></Select> popupMatchSelectWidth={210}></Select>
<Button type="primary" shape="circle" icon={<ArrowUpOutlined />} onClick={handleAI} loading={isLoading} /> <Button type="primary" shape="circle" icon={<ArrowUpOutlined />} onClick={handleAI} loading={isLoading} />
</div> </div>
<div className="upload-list"></div> <div className="upload-list"></div>
......
import md5 from 'blueimp-md5'
import axios from 'axios' import axios from 'axios'
import md5 from 'blueimp-md5'
import { fetchEventSource, FetchEventSourceInit } from '@fortaine/fetch-event-source' import { fetchEventSource, FetchEventSourceInit } from '@fortaine/fetch-event-source'
import { AIData, AIMessage, InitOptions } from './types'
export interface AIOption { import { extractJSON } from '@/utils/helper'
label: string
value: string
}
export interface AIMessage {
id?: string
role: 'user' | 'assistant' | 'system'
content: string
}
export interface AIData {
response_format?: { type: 'text' | 'json_object' }
model?: string
messages: AIMessage[]
}
export interface AIResponse {
id?: string
content: string
}
export interface InitOptions extends FetchEventSourceInit {
onMessage?: (message: AIResponse) => void
onComplete?: (message: AIMessage) => void
}
// Available AI options for different implementations
export const AI_OPTIONS: AIOption[] = [
// { label: '文心一言', value: 'yiyan' },
{ label: 'DeepSeek', value: 'siliconflow' },
{ label: '通义千问', value: 'qwen' },
// { label: '天工', value: 'tiangong' },
]
export async function getYiyanAccessToken() {
const AK = 'wY7bvMpkWeZbDVq9w3EDvpjU'
const SK = 'XJwpiJWxs5HXkOtbo6tQrvYPZFJAWdAy'
const resp = await axios.post(
`/api/qianfan/oauth/2.0/token?grant_type=client_credentials&client_id=${AK}&client_secret=${SK}`
)
return resp.data.access_token
}
export async function fetchAIEventSource(url: string, options: FetchEventSourceInit) { export async function fetchAIEventSource(url: string, options: FetchEventSourceInit) {
await fetchEventSource(url, { await fetchEventSource(url, {
...@@ -58,8 +16,29 @@ export async function fetchAIEventSource(url: string, options: FetchEventSourceI ...@@ -58,8 +16,29 @@ export async function fetchAIEventSource(url: string, options: FetchEventSourceI
}) })
} }
function getCommonResponseMessage(res: any) {
if (res.data === '[DONE]') return
try {
const message = JSON.parse(res.data)
if (message.choices && message.choices.length > 0) {
const content = message.choices[0].delta?.content || ''
return { id: message.id, content, json: extractJSON(content) }
}
} catch (error) {
console.error(error)
}
}
// https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Fm2vrveyu // https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Fm2vrveyu
export async function yiyan(data: AIData, options: InitOptions): Promise<void> { export async function yiyan(data: AIData, options: InitOptions): Promise<void> {
const getYiyanAccessToken = async () => {
const AK = 'wY7bvMpkWeZbDVq9w3EDvpjU'
const SK = 'XJwpiJWxs5HXkOtbo6tQrvYPZFJAWdAy'
const resp = await axios.post(
`/api/qianfan/oauth/2.0/token?grant_type=client_credentials&client_id=${AK}&client_secret=${SK}`
)
return resp.data.access_token
}
const accessToken = await getYiyanAccessToken() const accessToken = await getYiyanAccessToken()
const params = { stream: true, ...data } const params = { stream: true, ...data }
await fetchAIEventSource( await fetchAIEventSource(
...@@ -88,15 +67,8 @@ export async function deepseek(data: AIData, options: InitOptions): Promise<void ...@@ -88,15 +67,8 @@ export async function deepseek(data: AIData, options: InitOptions): Promise<void
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` }, headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` },
body: JSON.stringify(params), body: JSON.stringify(params),
onmessage(res) { onmessage(res) {
if (res.data === '[DONE]') return const message = getCommonResponseMessage(res)
try { if (message) options.onMessage?.(message)
const message = JSON.parse(res.data)
if (message.choices && message.choices.length > 0 && options.onMessage) {
options.onMessage({ id: message.id, content: message.choices[0].delta?.content || '' } as any)
}
} catch (error) {
console.error(error)
}
}, },
}) })
} }
...@@ -110,15 +82,8 @@ export async function siliconflow(data: AIData, options: InitOptions): Promise<v ...@@ -110,15 +82,8 @@ export async function siliconflow(data: AIData, options: InitOptions): Promise<v
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` }, headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` },
body: JSON.stringify(params), body: JSON.stringify(params),
onmessage(res) { onmessage(res) {
if (res.data === '[DONE]') return const message = getCommonResponseMessage(res)
try { if (message) options.onMessage?.(message)
const message = JSON.parse(res.data)
if (message.choices && message.choices.length > 0 && options.onMessage) {
options.onMessage({ id: message.id, content: message.choices[0].delta?.content || '' } as any)
}
} catch (error) {
console.error(error)
}
}, },
}) })
} }
...@@ -132,15 +97,8 @@ export async function qwen(data: AIData, options: InitOptions): Promise<void> { ...@@ -132,15 +97,8 @@ export async function qwen(data: AIData, options: InitOptions): Promise<void> {
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` }, headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` },
body: JSON.stringify(params), body: JSON.stringify(params),
onmessage(res) { onmessage(res) {
if (res.data === '[DONE]') return const message = getCommonResponseMessage(res)
try { if (message) options.onMessage?.(message)
const message = JSON.parse(res.data)
if (message.choices && message.choices.length > 0 && options.onMessage) {
options.onMessage({ id: message.id, content: message.choices[0].delta?.content || '' } as any)
}
} catch (error) {
console.error(error)
}
}, },
}) })
} }
...@@ -176,41 +134,59 @@ export async function tiangong(data: AIData, options: InitOptions): Promise<void ...@@ -176,41 +134,59 @@ export async function tiangong(data: AIData, options: InitOptions): Promise<void
}) })
} }
// Core AI API implementation export async function openAIStream(data: AIData, options: InitOptions): Promise<void> {
const aiService = { const params = { model: 'qwen-max-latest', stream: true, ...data }
yiyan, await fetchEventSource('/api/openai/chat/create', {
deepseek, ...options,
siliconflow, method: 'POST',
qwen, headers: { 'Content-Type': 'application/json', Authorization: 'ezijing@20250331' },
tiangong, body: JSON.stringify(params),
async onopen(response) {
if (response.ok) return
else throw response
},
onmessage(res) {
const message = getCommonResponseMessage(res)
if (message) options.onMessage?.(message)
},
})
}
async post(type: string, data: AIData, options: InitOptions): Promise<void> { export async function openAI(data: AIData, options: InitOptions): Promise<void> {
try {
const response = await axios.post(
'/api/openai/chat/create',
{ stream: true, ...data },
{ headers: { 'Content-Type': 'application/json', Authorization: 'ezijing@20250331' } }
)
const content = response.data.choices[0]?.message?.content || ''
const message: AIMessage = {
id: response.data.id,
role: 'assistant',
content,
json: extractJSON(content),
}
options.onMessage?.(message)
options.onclose?.()
} catch (error) {
console.error(error)
options.onerror?.(error)
}
}
const aiService = {
async post(data: AIData, options: InitOptions): Promise<void> {
const messages: AIMessage[] = [] const messages: AIMessage[] = []
const dataset = localStorage.getItem('dataset') const dataset = localStorage.getItem('dataset')
if (dataset) { if (dataset) {
const datasetInfo = JSON.parse(dataset) const datasetInfo = JSON.parse(dataset)
messages.push({ role: 'system', content: `这是一个数据集:${JSON.stringify(datasetInfo)}` }) messages.push({
role: 'system',
content: `这是一个数据集:${JSON.stringify(datasetInfo)}`,
})
} }
data.messages = [...messages, ...data.messages] data.messages = [...messages, ...data.messages]
switch (type) { openAI(data, options)
case 'yiyan':
return yiyan(data, options)
case 'deepseek':
return deepseek(data, options)
case 'siliconflow':
return siliconflow(data, options)
case 'qwen':
return qwen(data, options)
case 'tiangong':
return tiangong(data, options)
default:
throw new Error(`未找到对应的 AI 配置: ${type}`)
}
}, },
} }
......
import { AIOption } from './types'
export const AI_OPTIONS: AIOption[] = [
{ label: 'DeepSeek-R1', value: 'Pro/deepseek-ai/DeepSeek-R1' },
{ label: 'DeepSeek-V3', value: 'Pro/deepseek-ai/DeepSeek-V3' },
{ label: 'QwQ-32B', value: 'Qwen/QwQ-32B' },
{ label: 'deepseek-r1-250120', value: 'deepseek-r1-250120' },
{ label: 'doubao-pro-32k-241215', value: 'doubao-pro-32k-241215' },
{ label: 'qwen-max-latest', value: 'qwen-max-latest' },
{ label: 'qwen-long', value: 'qwen-long' },
{ label: 'hunyuan-t1-latest', value: 'hunyuan-t1-latest' },
{ label: 'hunyuan-standard-256K', value: 'hunyuan-standard-256K' },
]
import { FetchEventSourceInit } from '@fortaine/fetch-event-source'
export interface AIOption {
label: string
value: string
}
export interface AIMessage {
id?: string
role: 'user' | 'assistant' | 'system'
content: string
json?: any
}
export interface AIData {
response_format?: { type: 'text' | 'json_object' }
model?: string
messages: AIMessage[]
}
export interface AIResponse {
id: string
content: string
json?: any
}
export interface InitOptions extends FetchEventSourceInit {
onMessage?: (message: AIResponse) => void
}
import { useState, useEffect, useCallback, useRef } from 'react' import { useState, useEffect, useCallback, useRef } from 'react'
import aiService, { AIMessage, AIData, AI_OPTIONS, InitOptions } from '@/utils/ai' import { AI_OPTIONS } from './config'
import aiService from './api'
import type { AIMessage, AIData, InitOptions } from './types'
export function useAI(globalOptions?: InitOptions) { export function useAI(globalOptions?: InitOptions) {
const [ai, setAI] = useState<string>(localStorage.getItem('ai') || 'qwen') const [ai, setAI] = useState<string>(localStorage.getItem('ai') || 'qwen')
...@@ -24,6 +26,7 @@ export function useAI(globalOptions?: InitOptions) { ...@@ -24,6 +26,7 @@ export function useAI(globalOptions?: InitOptions) {
id: response.id, id: response.id,
role: 'assistant', role: 'assistant',
content: response.content, content: response.content,
json: response.json,
} }
latestMessageRef.current = newMessage latestMessageRef.current = newMessage
...@@ -39,6 +42,7 @@ export function useAI(globalOptions?: InitOptions) { ...@@ -39,6 +42,7 @@ export function useAI(globalOptions?: InitOptions) {
const updatedMessage = { const updatedMessage = {
...msg, ...msg,
content: msg.content + response.content, content: msg.content + response.content,
json: msg.json || response.json,
} }
latestMessageRef.current = updatedMessage latestMessageRef.current = updatedMessage
setMessage(updatedMessage) setMessage(updatedMessage)
...@@ -53,6 +57,7 @@ export function useAI(globalOptions?: InitOptions) { ...@@ -53,6 +57,7 @@ export function useAI(globalOptions?: InitOptions) {
const post = useCallback( const post = useCallback(
async (data: AIData, options?: InitOptions) => { async (data: AIData, options?: InitOptions) => {
return new Promise<AIMessage>((resolve, reject) => {
try { try {
setIsLoading(true) setIsLoading(true)
...@@ -61,9 +66,9 @@ export function useAI(globalOptions?: InitOptions) { ...@@ -61,9 +66,9 @@ export function useAI(globalOptions?: InitOptions) {
messagesRef.current = [...messagesRef.current, ...userMessages] messagesRef.current = [...messagesRef.current, ...userMessages]
setMessages((prev) => [...prev, ...userMessages]) setMessages((prev) => [...prev, ...userMessages])
const onComplete = options?.onComplete || globalOptions?.onComplete aiService.post(
{ ...data, model: ai },
await aiService.post(ai, data, { {
onMessage: (response) => { onMessage: (response) => {
const messageIndex = messagesRef.current.findIndex((msg) => msg.id === response.id) const messageIndex = messagesRef.current.findIndex((msg) => msg.id === response.id)
updateMessage(response, messageIndex === -1) updateMessage(response, messageIndex === -1)
...@@ -71,20 +76,26 @@ export function useAI(globalOptions?: InitOptions) { ...@@ -71,20 +76,26 @@ export function useAI(globalOptions?: InitOptions) {
onerror: (error) => { onerror: (error) => {
console.error('AI service error:', error) console.error('AI service error:', error)
setIsLoading(false) setIsLoading(false)
reject(error)
}, },
onclose: () => { onclose: () => {
setIsLoading(false) setIsLoading(false)
if (latestMessageRef.current && onComplete) { if (latestMessageRef.current) {
onComplete(latestMessageRef.current) resolve(latestMessageRef.current)
} else {
reject(new Error('No message received'))
} }
}, },
...globalOptions, ...globalOptions,
...options, ...options,
}) }
)
} catch (error) { } catch (error) {
console.error('Post error:', error) console.error('Post error:', error)
setIsLoading(false) setIsLoading(false)
reject(error)
} }
})
}, },
[ai, updateMessage, globalOptions] [ai, updateMessage, globalOptions]
) )
......
import { create } from 'zustand'
import { AI_OPTIONS } from './config'
import aiService from './api'
import type { AIOption, AIMessage, AIData, InitOptions } from './types'
interface AIState {
ai: string
options: AIOption[]
message: AIMessage | null
messages: AIMessage[]
isLoading: boolean
collapsed: boolean
setAI: (ai: string) => void
toggleCollapsed: () => void
post: (data: AIData, options?: InitOptions) => Promise<AIMessage>
}
export const useAIStore = create<AIState>((set, get) => ({
ai: localStorage.getItem('ai') || 'qwen',
options: AI_OPTIONS,
message: null,
messages: [],
isLoading: false,
collapsed: false,
setAI: (ai) => {
localStorage.setItem('ai', ai)
set({ ai })
},
toggleCollapsed: () => {
set((state) => ({ collapsed: !state.collapsed }))
},
post: async (data, options) => {
const { ai, messages } = get()
// 处理用户消息(去掉 system 角色的消息)
const userMessages = data.messages.filter((item) => item.role !== 'system')
set({
collapsed: true,
isLoading: true,
messages: [...messages, ...userMessages],
})
return new Promise<AIMessage>((resolve, reject) => {
try {
aiService.post(
{ ...data, model: ai },
{
onMessage: (response) => {
set((state) => {
const messageIndex = state.messages.findIndex((msg) => msg.id === response.id)
if (messageIndex === -1) {
// 新的 AI 回复
const newMessage: AIMessage = {
id: response.id,
role: 'assistant',
content: response.content,
json: response.json,
}
return {
message: newMessage, // 存储最新的 AI 消息
messages: [...state.messages, newMessage], // 追加到历史消息
}
} else {
// 追加内容到已有的消息
const updatedMessages = state.messages.map((msg) =>
msg.id === response.id
? { ...msg, content: msg.content + response.content, json: msg.json || response.json }
: msg
)
return {
message: updatedMessages[messageIndex], // 更新最新的 AI 消息
messages: updatedMessages,
}
}
})
},
onerror: (err) => {
console.error('AI 请求失败:', err)
set({ isLoading: false })
reject(err)
},
onclose: () => {
set({ isLoading: false })
const { message } = get()
if (message) {
resolve(message)
} else {
reject(new Error('No message received'))
}
},
...options,
}
)
} catch (err) {
console.error('AI 请求失败:', err)
set({ isLoading: false })
reject(err)
}
})
},
}))
export type { AIMessage }
...@@ -2,7 +2,7 @@ import { useEffect, useState } from 'react' ...@@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'
import { Button, Flex, Modal, Form, Divider, Select, Radio, Row, Col, Input } from 'antd' import { Button, Flex, Modal, Form, Divider, Select, Radio, Row, Col, Input } from 'antd'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
import { useCreateChart, useUpdateChart, useViewChartQuery } from '@/hooks/useChartQuery' import { useCreateChart, useUpdateChart, useViewChartQuery } from '@/hooks/useChartQuery'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import Chart from './Chart' import Chart from './Chart'
interface Props { interface Props {
...@@ -143,7 +143,6 @@ const Step2 = ({ fieldOptions, type, showTitle }: any) => { ...@@ -143,7 +143,6 @@ const Step2 = ({ fieldOptions, type, showTitle }: any) => {
<Radio.Group <Radio.Group
options={[ options={[
{ label: '不做圆滑处理', value: 0 }, { label: '不做圆滑处理', value: 0 },
{ label: '四个角圆滑处理', value: 10 },
{ label: '两个角圆滑处理', value: [10, 10, 0, 0] }, { label: '两个角圆滑处理', value: [10, 10, 0, 0] },
]}></Radio.Group> ]}></Radio.Group>
</Form.Item> </Form.Item>
...@@ -333,22 +332,11 @@ const ModalContent = ({ setOpen, type, id = '' }: Props) => { ...@@ -333,22 +332,11 @@ const ModalContent = ({ setOpen, type, id = '' }: Props) => {
...results, ...results,
} }
const { post } = useAI({ const { post } = useAI()
onComplete: (message) => {
console.log(message)
try {
const { results } = JSON.parse(message.content)
setResults(results)
console.log(results)
} catch (e) {
console.log(e)
}
},
})
const handlePreview = () => { const handlePreview = async () => {
const values = form.getFieldsValue() const values = form.getFieldsValue()
post({ const message = await post({
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -390,6 +378,9 @@ const ModalContent = ({ setOpen, type, id = '' }: Props) => { ...@@ -390,6 +378,9 @@ const ModalContent = ({ setOpen, type, id = '' }: Props) => {
}, },
], ],
}) })
if (message.json && message.json.results) {
setResults(message.json.results)
}
} }
const { mutate: mutateCreate } = useCreateChart() const { mutate: mutateCreate } = useCreateChart()
......
import { Button, Flex, Modal, Spin } from 'antd' import { Button, Flex, Modal, Spin } from 'antd'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function AIModal({ prompt }: { prompt: string }) { export default function AIModal({ prompt }: { prompt: string }) {
......
...@@ -13,7 +13,7 @@ import { ...@@ -13,7 +13,7 @@ import {
} from 'lucide-react' } from 'lucide-react'
import { Menu, MenuProps } from 'antd' import { Menu, MenuProps } from 'antd'
import './DataLayout.scss' import './DataLayout.scss'
import AIChat from '../ai/AIChat' import AIChat from '@/ai/AIChat'
type MyMenuItem = { type MyMenuItem = {
name: string name: string
......
...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd' ...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons' import { QuestionCircleOutlined } from '@ant-design/icons'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function ButtonModal() { export default function ButtonModal() {
...@@ -20,8 +20,7 @@ export default function ButtonModal() { ...@@ -20,8 +20,7 @@ export default function ButtonModal() {
await form.validateFields(['independent_variables', 'dependent_variable']) await form.validateFields(['independent_variables', 'dependent_variable'])
const values = form.getFieldsValue() const values = form.getFieldsValue()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -36,19 +35,11 @@ json ...@@ -36,19 +35,11 @@ json
`, `,
}, },
], ],
}, })
{ console.log(message.json)
onComplete: (message) => { if (message.json && message.json.results) {
console.log(message) form.setFieldsValue(message.json.results)
try {
const parse = JSON.parse(message.content)
form.setFieldsValue(parse.results)
} catch (error) {
console.error(error)
} }
},
}
)
} }
// AI计算 // AI计算
...@@ -57,8 +48,7 @@ json ...@@ -57,8 +48,7 @@ json
const [openResults, setOpenResults] = useState(false) const [openResults, setOpenResults] = useState(false)
const handleAICompute = async () => { const handleAICompute = async () => {
const values = await form.validateFields() const values = await form.validateFields()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -80,22 +70,14 @@ json ...@@ -80,22 +70,14 @@ json
`, `,
}, },
], ],
}, })
{ console.log(message.json)
onComplete: (message) => { if (message.json && message.json.results) {
console.log(message) setResults(message.json.results)
try {
const parse = JSON.parse(message.content)
setResults(parse.results)
} catch (error) {
console.error(error)
} }
if (current === 1) { if (current === 1) {
setStep(3) setStep(3)
} }
},
}
)
} }
const [step, setStep] = useState<number>(-1) const [step, setStep] = useState<number>(-1)
...@@ -133,7 +115,7 @@ json ...@@ -133,7 +115,7 @@ json
<div style={{ flex: 1 }}> <div style={{ flex: 1 }}>
<Form.Item label="请输入最小支持度(min_support)"> <Form.Item label="请输入最小支持度(min_support)">
<Flex gap={10}> <Flex gap={10}>
<Form.Item name="fit_intercept" noStyle rules={[{ required: true, message: '请选择' }]}> <Form.Item name="min_support" noStyle rules={[{ required: true, message: '请选择' }]}>
<Input placeholder="请输入" /> <Input placeholder="请输入" />
</Form.Item> </Form.Item>
<Popover <Popover
...@@ -155,7 +137,7 @@ json ...@@ -155,7 +137,7 @@ json
</Form.Item> </Form.Item>
<Form.Item label="请输入最小置信度(min_confidence)"> <Form.Item label="请输入最小置信度(min_confidence)">
<Flex gap={10}> <Flex gap={10}>
<Form.Item name="copy_x" noStyle rules={[{ required: true, message: '请选择' }]}> <Form.Item name="min_confidence" noStyle rules={[{ required: true, message: '请选择' }]}>
<Input placeholder="请输入" /> <Input placeholder="请输入" />
</Form.Item> </Form.Item>
<Popover <Popover
...@@ -177,7 +159,7 @@ json ...@@ -177,7 +159,7 @@ json
</Form.Item> </Form.Item>
<Form.Item label="请输入最小提升度(min_lift)"> <Form.Item label="请输入最小提升度(min_lift)">
<Flex gap={10}> <Flex gap={10}>
<Form.Item name="n_jobs" noStyle rules={[{ required: true, message: '请输入' }]}> <Form.Item name="min_lift" noStyle rules={[{ required: true, message: '请输入' }]}>
<Input placeholder="请输入" /> <Input placeholder="请输入" />
</Form.Item> </Form.Item>
<Popover <Popover
...@@ -197,7 +179,7 @@ json ...@@ -197,7 +179,7 @@ json
</Form.Item> </Form.Item>
<Form.Item label="请输入规则最小长度(min_length)"> <Form.Item label="请输入规则最小长度(min_length)">
<Flex gap={10}> <Flex gap={10}>
<Form.Item name="positive" noStyle rules={[{ required: true, message: '请选择' }]}> <Form.Item name="min_length" noStyle rules={[{ required: true, message: '请选择' }]}>
<Input placeholder="请输入" /> <Input placeholder="请输入" />
</Form.Item> </Form.Item>
<Popover <Popover
...@@ -219,7 +201,7 @@ json ...@@ -219,7 +201,7 @@ json
</Form.Item> </Form.Item>
<Form.Item label="请输入规则最大长度(max_length)"> <Form.Item label="请输入规则最大长度(max_length)">
<Flex gap={10}> <Flex gap={10}>
<Form.Item name="positive" noStyle rules={[{ required: true, message: '请选择' }]}> <Form.Item name="max_length" noStyle rules={[{ required: true, message: '请选择' }]}>
<Input placeholder="请输入" /> <Input placeholder="请输入" />
</Form.Item> </Form.Item>
<Popover <Popover
...@@ -241,7 +223,7 @@ json ...@@ -241,7 +223,7 @@ json
</Form.Item> </Form.Item>
<Form.Item label="请输入评估指标(metric)"> <Form.Item label="请输入评估指标(metric)">
<Flex gap={10}> <Flex gap={10}>
<Form.Item name="positive" noStyle rules={[{ required: true, message: '请选择' }]}> <Form.Item name="metric" noStyle rules={[{ required: true, message: '请选择' }]}>
<Input placeholder="请输入" /> <Input placeholder="请输入" />
</Form.Item> </Form.Item>
<Popover <Popover
......
...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd' ...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons' import { QuestionCircleOutlined } from '@ant-design/icons'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function ButtonModal() { export default function ButtonModal() {
...@@ -20,8 +20,7 @@ export default function ButtonModal() { ...@@ -20,8 +20,7 @@ export default function ButtonModal() {
await form.validateFields(['independent_variables', 'dependent_variable']) await form.validateFields(['independent_variables', 'dependent_variable'])
const values = form.getFieldsValue() const values = form.getFieldsValue()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -37,19 +36,10 @@ json ...@@ -37,19 +36,10 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { form.setFieldsValue(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
form.setFieldsValue(parse.results)
} catch (error) {
console.error(error)
} }
},
}
)
} }
// AI计算 // AI计算
...@@ -58,8 +48,7 @@ json ...@@ -58,8 +48,7 @@ json
const [openResults, setOpenResults] = useState(false) const [openResults, setOpenResults] = useState(false)
const handleAICompute = async () => { const handleAICompute = async () => {
const values = await form.validateFields() const values = await form.validateFields()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -80,22 +69,13 @@ json ...@@ -80,22 +69,13 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { setResults(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
setResults(parse.results)
} catch (error) {
console.error(error)
} }
if (current === 1) { if (current === 1) {
setStep(3) setStep(3)
} }
},
}
)
} }
const [step, setStep] = useState<number>(-1) const [step, setStep] = useState<number>(-1)
......
...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd' ...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons' import { QuestionCircleOutlined } from '@ant-design/icons'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function ButtonModal() { export default function ButtonModal() {
...@@ -20,8 +20,7 @@ export default function ButtonModal() { ...@@ -20,8 +20,7 @@ export default function ButtonModal() {
await form.validateFields(['independent_variables', 'dependent_variable']) await form.validateFields(['independent_variables', 'dependent_variable'])
const values = form.getFieldsValue() const values = form.getFieldsValue()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -36,19 +35,10 @@ json ...@@ -36,19 +35,10 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { form.setFieldsValue(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
form.setFieldsValue(parse.results)
} catch (error) {
console.error(error)
} }
},
}
)
} }
// AI计算 // AI计算
...@@ -57,8 +47,7 @@ json ...@@ -57,8 +47,7 @@ json
const [openResults, setOpenResults] = useState(false) const [openResults, setOpenResults] = useState(false)
const handleAICompute = async () => { const handleAICompute = async () => {
const values = await form.validateFields() const values = await form.validateFields()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -77,31 +66,17 @@ json ...@@ -77,31 +66,17 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { setResults(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
setResults(parse.results)
} catch (error) {
console.error(error)
} }
if (current === 1) { if (current === 1) {
setStep(3) setStep(3)
} }
},
}
)
} }
const [step, setStep] = useState<number>(-1) const [step, setStep] = useState<number>(-1)
const options = [
{ label: 'True', value: true },
{ label: 'False', value: false },
]
// 处理下一步按钮逻辑 // 处理下一步按钮逻辑
const handleNext = async () => { const handleNext = async () => {
await form.validateFields() await form.validateFields()
......
...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd' ...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons' import { QuestionCircleOutlined } from '@ant-design/icons'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function ButtonModal() { export default function ButtonModal() {
...@@ -20,8 +20,7 @@ export default function ButtonModal() { ...@@ -20,8 +20,7 @@ export default function ButtonModal() {
await form.validateFields(['independent_variables', 'dependent_variable']) await form.validateFields(['independent_variables', 'dependent_variable'])
const values = form.getFieldsValue() const values = form.getFieldsValue()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -36,19 +35,10 @@ json ...@@ -36,19 +35,10 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { form.setFieldsValue(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
form.setFieldsValue(parse.results)
} catch (error) {
console.error(error)
} }
},
}
)
} }
// AI计算 // AI计算
...@@ -57,8 +47,7 @@ json ...@@ -57,8 +47,7 @@ json
const [openResults, setOpenResults] = useState(false) const [openResults, setOpenResults] = useState(false)
const handleAICompute = async () => { const handleAICompute = async () => {
const values = await form.validateFields() const values = await form.validateFields()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -78,22 +67,13 @@ json ...@@ -78,22 +67,13 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { setResults(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
setResults(parse.results)
} catch (error) {
console.error(error)
} }
if (current === 1) { if (current === 1) {
setStep(3) setStep(3)
} }
},
}
)
} }
const [step, setStep] = useState<number>(-1) const [step, setStep] = useState<number>(-1)
......
...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd' ...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons' import { QuestionCircleOutlined } from '@ant-design/icons'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function ButtonModal() { export default function ButtonModal() {
...@@ -20,8 +20,7 @@ export default function ButtonModal() { ...@@ -20,8 +20,7 @@ export default function ButtonModal() {
await form.validateFields(['independent_variables', 'dependent_variable']) await form.validateFields(['independent_variables', 'dependent_variable'])
const values = form.getFieldsValue() const values = form.getFieldsValue()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -37,19 +36,10 @@ json ...@@ -37,19 +36,10 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { form.setFieldsValue(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
form.setFieldsValue(parse.results)
} catch (error) {
console.error(error)
} }
},
}
)
} }
// AI计算 // AI计算
...@@ -58,8 +48,7 @@ json ...@@ -58,8 +48,7 @@ json
const [openResults, setOpenResults] = useState(false) const [openResults, setOpenResults] = useState(false)
const handleAICompute = async () => { const handleAICompute = async () => {
const values = await form.validateFields() const values = await form.validateFields()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -79,22 +68,13 @@ json ...@@ -79,22 +68,13 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { setResults(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
setResults(parse.results)
} catch (error) {
console.error(error)
} }
if (current === 1) { if (current === 1) {
setStep(3) setStep(3)
} }
},
}
)
} }
const [step, setStep] = useState<number>(-1) const [step, setStep] = useState<number>(-1)
......
...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd' ...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons' import { QuestionCircleOutlined } from '@ant-design/icons'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function ButtonModal() { export default function ButtonModal() {
...@@ -20,8 +20,7 @@ export default function ButtonModal() { ...@@ -20,8 +20,7 @@ export default function ButtonModal() {
await form.validateFields(['independent_variables']) await form.validateFields(['independent_variables'])
const values = form.getFieldsValue() const values = form.getFieldsValue()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -36,19 +35,10 @@ json ...@@ -36,19 +35,10 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { form.setFieldsValue(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
form.setFieldsValue(parse.results)
} catch (error) {
console.error(error)
} }
},
}
)
} }
// AI计算 // AI计算
...@@ -57,8 +47,7 @@ json ...@@ -57,8 +47,7 @@ json
const [openResults, setOpenResults] = useState(false) const [openResults, setOpenResults] = useState(false)
const handleAICompute = async () => { const handleAICompute = async () => {
const values = await form.validateFields() const values = await form.validateFields()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -80,22 +69,13 @@ json ...@@ -80,22 +69,13 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { setResults(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
setResults(parse.results)
} catch (error) {
console.error(error)
} }
if (current === 1) { if (current === 1) {
setStep(3) setStep(3)
} }
},
}
)
} }
const [step, setStep] = useState<number>(-1) const [step, setStep] = useState<number>(-1)
......
...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd' ...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons' import { QuestionCircleOutlined } from '@ant-design/icons'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function ButtonModal() { export default function ButtonModal() {
...@@ -19,8 +19,7 @@ export default function ButtonModal() { ...@@ -19,8 +19,7 @@ export default function ButtonModal() {
const handleAISet = async () => { const handleAISet = async () => {
await form.validateFields(['independent_variables', 'dependent_variable']) await form.validateFields(['independent_variables', 'dependent_variable'])
const values = form.getFieldsValue() const values = form.getFieldsValue()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -37,19 +36,10 @@ json ...@@ -37,19 +36,10 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { form.setFieldsValue(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
form.setFieldsValue(parse.results)
} catch (error) {
console.error(error)
} }
},
}
)
} }
// AI计算 // AI计算
...@@ -59,8 +49,7 @@ json ...@@ -59,8 +49,7 @@ json
const handleAICompute = async () => { const handleAICompute = async () => {
const values = await form.validateFields() const values = await form.validateFields()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -80,22 +69,14 @@ json ...@@ -80,22 +69,14 @@ json
`, `,
}, },
], ],
}, })
{ console.log(message.json)
onComplete: (message) => { if (message.json && message.json.results) {
console.log(message) setResults(message.json.results)
try {
const parse = JSON.parse(message.content)
setResults(parse.results)
} catch (error) {
console.error(error)
} }
if (current === 1) { if (current === 1) {
setStep(3) setStep(3)
} }
},
}
)
} }
const [step, setStep] = useState<number>(-1) const [step, setStep] = useState<number>(-1)
......
...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd' ...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons' import { QuestionCircleOutlined } from '@ant-design/icons'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function ButtonModal() { export default function ButtonModal() {
...@@ -20,8 +20,7 @@ export default function ButtonModal() { ...@@ -20,8 +20,7 @@ export default function ButtonModal() {
await form.validateFields(['independent_variables', 'dependent_variable']) await form.validateFields(['independent_variables', 'dependent_variable'])
const values = form.getFieldsValue() const values = form.getFieldsValue()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -37,19 +36,10 @@ json ...@@ -37,19 +36,10 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { form.setFieldsValue(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
form.setFieldsValue(parse.results)
} catch (error) {
console.error(error)
} }
},
}
)
} }
// AI计算 // AI计算
...@@ -58,8 +48,7 @@ json ...@@ -58,8 +48,7 @@ json
const [openResults, setOpenResults] = useState(false) const [openResults, setOpenResults] = useState(false)
const handleAICompute = async () => { const handleAICompute = async () => {
const values = await form.validateFields() const values = await form.validateFields()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -81,22 +70,14 @@ json ...@@ -81,22 +70,14 @@ json
`, `,
}, },
], ],
}, })
{ console.log(message.json)
onComplete: (message) => { if (message.json && message.json.results) {
console.log(message) setResults(message.json.results)
try {
const parse = JSON.parse(message.content)
setResults(parse.results)
} catch (error) {
console.error(error)
} }
if (current === 1) { if (current === 1) {
setStep(3) setStep(3)
} }
},
}
)
} }
const [step, setStep] = useState<number>(-1) const [step, setStep] = useState<number>(-1)
......
...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd' ...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons' import { QuestionCircleOutlined } from '@ant-design/icons'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function ButtonModal() { export default function ButtonModal() {
...@@ -20,8 +20,7 @@ export default function ButtonModal() { ...@@ -20,8 +20,7 @@ export default function ButtonModal() {
await form.validateFields(['independent_variables', 'dependent_variable']) await form.validateFields(['independent_variables', 'dependent_variable'])
const values = form.getFieldsValue() const values = form.getFieldsValue()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -37,19 +36,10 @@ json ...@@ -37,19 +36,10 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { form.setFieldsValue(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
form.setFieldsValue(parse.results)
} catch (error) {
console.error(error)
} }
},
}
)
} }
// AI计算 // AI计算
...@@ -58,8 +48,7 @@ json ...@@ -58,8 +48,7 @@ json
const [openResults, setOpenResults] = useState(false) const [openResults, setOpenResults] = useState(false)
const handleAICompute = async () => { const handleAICompute = async () => {
const values = await form.validateFields() const values = await form.validateFields()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -80,22 +69,13 @@ json ...@@ -80,22 +69,13 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { setResults(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
setResults(parse.results)
} catch (error) {
console.error(error)
} }
if (current === 1) { if (current === 1) {
setStep(3) setStep(3)
} }
},
}
)
} }
const [step, setStep] = useState<number>(-1) const [step, setStep] = useState<number>(-1)
......
...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd' ...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Select, Form, Input, Popover, Card } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons' import { QuestionCircleOutlined } from '@ant-design/icons'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function ButtonModal() { export default function ButtonModal() {
...@@ -20,8 +20,7 @@ export default function ButtonModal() { ...@@ -20,8 +20,7 @@ export default function ButtonModal() {
await form.validateFields(['independent_variables', 'dependent_variable']) await form.validateFields(['independent_variables', 'dependent_variable'])
const values = form.getFieldsValue() const values = form.getFieldsValue()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -37,19 +36,10 @@ json ...@@ -37,19 +36,10 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { form.setFieldsValue(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
form.setFieldsValue(parse.results)
} catch (error) {
console.error(error)
} }
},
}
)
} }
// AI计算 // AI计算
...@@ -58,8 +48,7 @@ json ...@@ -58,8 +48,7 @@ json
const [openResults, setOpenResults] = useState(false) const [openResults, setOpenResults] = useState(false)
const handleAICompute = async () => { const handleAICompute = async () => {
const values = await form.validateFields() const values = await form.validateFields()
post( const message = await post({
{
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [ messages: [
{ {
...@@ -80,22 +69,13 @@ json ...@@ -80,22 +69,13 @@ json
`, `,
}, },
], ],
}, })
{ if (message.json && message.json.results) {
onComplete: (message) => { setResults(message.json.results)
console.log(message)
try {
const parse = JSON.parse(message.content)
setResults(parse.results)
} catch (error) {
console.error(error)
} }
if (current === 1) { if (current === 1) {
setStep(3) setStep(3)
} }
},
}
)
} }
const [step, setStep] = useState<number>(-1) const [step, setStep] = useState<number>(-1)
......
...@@ -3,8 +3,9 @@ import { Button, Flex, Modal, Radio, Form, Row, Col } from 'antd' ...@@ -3,8 +3,9 @@ import { Button, Flex, Modal, Radio, Form, Row, Col } 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' import { useAIStore } from '@/ai/useAIStore'
import prompt from '@/ai/prompt'
import { useProcessData } from '../query' import { useProcessData } from '../query'
interface ResultItem { interface ResultItem {
...@@ -21,20 +22,17 @@ export default function ButtonModal() { ...@@ -21,20 +22,17 @@ export default function ButtonModal() {
})) }))
const selectOptions = resultsOptions.length ? resultsOptions : fieldOptions const selectOptions = resultsOptions.length ? resultsOptions : fieldOptions
const { isLoading, post } = useAI({ const { isLoading, post } = useAIStore()
onComplete: (message) => {
if (!message.content) return
const parse = JSON.parse(message.content)
console.log(parse)
setResults(parse.results || [])
},
})
const handleAI = () => { const handleAI = async () => {
post({ const message = await post({
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [{ role: 'user', content: prompt.error }], messages: [{ role: 'user', content: prompt.error }],
}) })
console.log(message.json)
if (message.json && Array.isArray(message.json.results)) {
setResults(message.json.results)
}
} }
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'abnormal' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'abnormal' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
......
...@@ -3,8 +3,9 @@ import { Button, Flex, Modal, Radio, Form, Row, Col } from 'antd' ...@@ -3,8 +3,9 @@ import { Button, Flex, Modal, Radio, Form, Row, Col } 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' import { useAIStore } from '@/ai/useAIStore'
import prompt from '@/ai/prompt'
import { useProcessData } from '../query' import { useProcessData } from '../query'
interface ResultItem { interface ResultItem {
...@@ -21,20 +22,17 @@ export default function ButtonModal() { ...@@ -21,20 +22,17 @@ export default function ButtonModal() {
})) }))
const selectOptions = resultsOptions.length ? resultsOptions : fieldOptions const selectOptions = resultsOptions.length ? resultsOptions : fieldOptions
const { isLoading, post } = useAI({ const { isLoading, post } = useAIStore()
onComplete: (message) => {
if (!message.content) return
const parse = JSON.parse(message.content)
console.log(parse)
setResults(parse.results || [])
},
})
const handleAI = () => { const handleAI = async () => {
post({ const message = await post({
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [{ role: 'user', content: prompt.max }], messages: [{ role: 'user', content: prompt.max }],
}) })
console.log(message.json)
if (message.json && Array.isArray(message.json.results)) {
setResults(message.json.results)
}
} }
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'outOfRange' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'outOfRange' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
......
...@@ -3,8 +3,9 @@ import { Button, Flex, Modal, Radio, Form, Row, Col } from 'antd' ...@@ -3,8 +3,9 @@ import { Button, Flex, Modal, Radio, Form, Row, Col } 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' import { useAIStore } from '@/ai/useAIStore'
import prompt from '@/ai/prompt'
import { useProcessData } from '../query' import { useProcessData } from '../query'
interface ResultItem { interface ResultItem {
...@@ -14,6 +15,7 @@ interface ResultItem { ...@@ -14,6 +15,7 @@ interface ResultItem {
export default function ButtonModal() { export default function ButtonModal() {
const [searchParams] = useSearchParams() const [searchParams] = useSearchParams()
const { fieldOptions, getFieldName } = useDataFieldQuery() const { fieldOptions, getFieldName } = useDataFieldQuery()
const [results, setResults] = useState<ResultItem[]>([]) const [results, setResults] = useState<ResultItem[]>([])
const resultsOptions = results.map((result) => ({ const resultsOptions = results.map((result) => ({
label: result.name, label: result.name,
...@@ -21,20 +23,18 @@ export default function ButtonModal() { ...@@ -21,20 +23,18 @@ export default function ButtonModal() {
})) }))
const selectOptions = resultsOptions.length ? resultsOptions : fieldOptions const selectOptions = resultsOptions.length ? resultsOptions : fieldOptions
const { isLoading, post } = useAI({
onComplete: (message) => {
if (!message.content) return
const parse = JSON.parse(message.content)
console.log(parse)
setResults(parse.results || [])
},
})
const handleAI = () => { const { isLoading, post } = useAIStore()
post({
const handleAI = async () => {
const message = await post({
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [{ role: 'user', content: prompt.min }], messages: [{ role: 'user', content: prompt.min }],
}) })
console.log(message.json)
if (message.json && Array.isArray(message.json.results)) {
setResults(message.json.results)
}
} }
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'underRange' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'underRange' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
......
...@@ -3,8 +3,9 @@ import { Button, Checkbox, Flex, Modal, Radio, Select, Input, Form, Row, Col, Di ...@@ -3,8 +3,9 @@ import { Button, Checkbox, Flex, Modal, Radio, Select, Input, Form, Row, Col, Di
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' import { useAIStore } from '@/ai/useAIStore'
import prompt from '@/ai/prompt'
import { useProcessData } from '../query' import { useProcessData } from '../query'
const actionOptions = [ const actionOptions = [
...@@ -29,26 +30,25 @@ interface ResultItem { ...@@ -29,26 +30,25 @@ interface ResultItem {
export default function ButtonModal() { export default function ButtonModal() {
const [searchParams] = useSearchParams() const [searchParams] = useSearchParams()
const { fieldOptions, getFieldName, getFieldNames } = useDataFieldQuery() const { fieldOptions, getFieldName, getFieldNames } = useDataFieldQuery()
const [results, setResults] = useState<ResultItem[]>([]) const [results, setResults] = useState<ResultItem[]>([])
const resultsOptions = results.map((result) => ({ const resultsOptions = results.map((result) => ({
label: result.name, label: result.name,
value: fieldOptions.find((option) => option.label === result.name)?.value || '', value: fieldOptions.find((option) => option.label === result.name)?.value || '',
})) }))
const selectOptions = resultsOptions.length ? resultsOptions : fieldOptions const selectOptions = resultsOptions.length ? resultsOptions : fieldOptions
const { isLoading, post } = useAI({
onComplete: (message) => { const { isLoading, post } = useAIStore()
if (!message.content) return
const parse = JSON.parse(message.content) const handleAI = async () => {
console.log(parse) const message = await post({
setResults(parse.results || [])
},
})
const handleAI = () => {
post({
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [{ role: 'user', content: prompt.null }], messages: [{ role: 'user', content: prompt.null }],
}) })
console.log(message.json)
if (message.json && Array.isArray(message.json.results)) {
setResults(message.json.results)
}
} }
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'missing' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'missing' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
......
...@@ -2,31 +2,38 @@ import { useEffect, useState } from 'react' ...@@ -2,31 +2,38 @@ import { useEffect, useState } from 'react'
import { Button, Checkbox, Flex, Modal, Radio, Form, Row, Col, Empty } from 'antd' import { Button, Checkbox, Flex, Modal, Radio, Form, Row, Col, Empty } from 'antd'
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' import { useAIStore } from '@/ai/useAIStore'
import prompt from '@/ai/prompt'
import { useProcessData } from '../query' import { useProcessData } from '../query'
interface ResultItem {
line: number
lines: number[]
desc: string
}
export default function ButtonModal() { export default function ButtonModal() {
const [searchParams] = useSearchParams() const [searchParams] = useSearchParams()
const [results, setResults] = useState<Array<{ line: number; lines: number[]; desc: string }>>([]) const [results, setResults] = useState<ResultItem[]>([])
useEffect(() => { useEffect(() => {
if (searchParams.get('results')) { if (searchParams.get('results')) {
setResults(JSON.parse(searchParams.get('results') || '') as any) setResults(JSON.parse(searchParams.get('results') || '') as ResultItem[])
setOpen(true) setOpen(true)
} }
}, [searchParams]) }, [searchParams])
const { isLoading, post } = useAI({ const { isLoading, post } = useAIStore()
onComplete: (message) => {
if (!message.content) return
const parse = JSON.parse(message.content)
console.log(parse)
setResults(parse.results || [])
},
})
const handleAI = () => { const handleAI = async () => {
post({ response_format: { type: 'json_object' }, messages: [{ role: 'user', content: prompt.repeat }] }) const message = await post({
response_format: { type: 'json_object' },
messages: [{ role: 'user', content: prompt.repeat }],
})
console.log(message.json)
if (message.json && Array.isArray(message.json.results)) {
setResults(message.json.results)
}
} }
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'duplicate' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'duplicate' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'sort' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'sort' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
......
...@@ -3,19 +3,15 @@ import { Button, Flex, Modal, Radio, Form, Row, Col } from 'antd' ...@@ -3,19 +3,15 @@ import { Button, Flex, Modal, Radio, Form, Row, Col } from 'antd'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import { useProcessData } from '../query' import { useProcessData } from '../query'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function ButtonModal() { export default function ButtonModal() {
const [result, setResult] = useState('') const [result, setResult] = useState('')
const { isLoading, post } = useAI({ const { isLoading, post } = useAI()
onComplete: (message) => {
setResult(message?.content || '')
},
})
const handleAI = async () => { const handleAI = async () => {
post({ const message = await post({
messages: [ messages: [
{ {
role: 'user', role: 'user',
...@@ -62,6 +58,7 @@ export default function ButtonModal() { ...@@ -62,6 +58,7 @@ export default function ButtonModal() {
}, },
], ],
}) })
if (message.content) setResult(message.content)
} }
const { fieldOptions, getFieldName } = useDataFieldQuery() const { fieldOptions, getFieldName } = useDataFieldQuery()
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'trim' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'trim' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'merge' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'merge' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'split' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'split' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'punctuation' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'punctuation' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'type' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'type' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
......
...@@ -4,7 +4,7 @@ import { useDataFieldQuery } from '@/hooks/useQuery' ...@@ -4,7 +4,7 @@ import { useDataFieldQuery } from '@/hooks/useQuery'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import { useProcessData } from '../query' import { useProcessData } from '../query'
import { MinusCircleOutlined } from '@ant-design/icons' import { MinusCircleOutlined } from '@ant-design/icons'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function ButtonModal() { export default function ButtonModal() {
...@@ -26,14 +26,10 @@ export default function ButtonModal() { ...@@ -26,14 +26,10 @@ export default function ButtonModal() {
const step = Form.useWatch('step', form) const step = Form.useWatch('step', form)
const [result, setResult] = useState('') const [result, setResult] = useState('')
const { isLoading, post } = useAI({ const { isLoading, post } = useAI()
onComplete: (message) => {
setResult(message?.content || '')
},
})
const handleAI = async () => { const handleAI = async () => {
post({ const message = await post({
messages: [ messages: [
{ {
role: 'user', role: 'user',
...@@ -95,6 +91,7 @@ ${action === '固定步长分箱' ? `最小值 ${min}、最大值 ${max}、步 ...@@ -95,6 +91,7 @@ ${action === '固定步长分箱' ? `最小值 ${min}、最大值 ${max}、步
}, },
], ],
}) })
if (message.content) setResult(message.content)
} }
// 处理下一步按钮逻辑 // 处理下一步按钮逻辑
const handleNext = async () => { const handleNext = async () => {
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'mapping' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'mapping' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
return { ...query, progress: data.progress, message: data.message, remove } return { ...query, progress: data.progress, message: data.message, remove }
......
...@@ -4,7 +4,7 @@ import { useDataFieldQuery } from '@/hooks/useQuery' ...@@ -4,7 +4,7 @@ import { useDataFieldQuery } from '@/hooks/useQuery'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import FunctionInput from '@/components/data/FunctionInput' import FunctionInput from '@/components/data/FunctionInput'
import { useProcessData } from '../query' import { useProcessData } from '../query'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
const functionShortcutOptions = [ const functionShortcutOptions = [
...@@ -95,18 +95,14 @@ export default function ButtonModal() { ...@@ -95,18 +95,14 @@ export default function ButtonModal() {
const action = Form.useWatch('action', form) const action = Form.useWatch('action', form)
const [result, setResult] = useState('') const [result, setResult] = useState('')
const { isLoading, post } = useAI({ const { isLoading, post } = useAI()
onComplete: (message) => {
setResult(message?.content || '')
},
})
const handleAI = async () => { const handleAI = async () => {
const values = form.getFieldsValue() const values = form.getFieldsValue()
const selectedFunction = values.function const selectedFunction = values.function
const functionFormula = values.content || '' const functionFormula = values.content || ''
post({ const message = await post({
messages: [ messages: [
{ {
role: 'user', role: 'user',
...@@ -130,6 +126,7 @@ export default function ButtonModal() { ...@@ -130,6 +126,7 @@ export default function ButtonModal() {
}, },
], ],
}) })
if (message.content) setResult(message.content)
} }
// 处理下一步按钮逻辑 // 处理下一步按钮逻辑
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'date' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'date' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
return { ...query, progress: data.progress, message: data.message, remove } return { ...query, progress: data.progress, message: data.message, remove }
......
...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Radio, Input, Form, Row, Col } from 'antd' ...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Radio, Input, Form, Row, Col } from 'antd'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import { useProcessData } from '../query' import { useProcessData } from '../query'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function ButtonModal() { export default function ButtonModal() {
...@@ -19,14 +19,10 @@ export default function ButtonModal() { ...@@ -19,14 +19,10 @@ export default function ButtonModal() {
const formSmFun = Form.useWatch('sm_fun', form) const formSmFun = Form.useWatch('sm_fun', form)
const [result, setResult] = useState('') const [result, setResult] = useState('')
const { isLoading, post } = useAI({ const { isLoading, post } = useAI()
onComplete: (message) => {
setResult(message?.content || '')
},
})
const handleAI = async () => { const handleAI = async () => {
post({ const message = await post({
messages: [ messages: [
{ {
role: 'user', role: 'user',
...@@ -73,6 +69,7 @@ export default function ButtonModal() { ...@@ -73,6 +69,7 @@ export default function ButtonModal() {
}, },
], ],
}) })
if (message.content) setResult(message.content)
} }
// 处理下一步按钮逻辑 // 处理下一步按钮逻辑
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'anonymization' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'anonymization' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
return { ...query, progress: data.progress, message: data.message, remove } return { ...query, progress: data.progress, message: data.message, remove }
......
...@@ -5,7 +5,7 @@ import AppProgressSteps from '@/components/AppProgressSteps' ...@@ -5,7 +5,7 @@ import AppProgressSteps from '@/components/AppProgressSteps'
import { useProcessData } from '../query' import { useProcessData } from '../query'
import { MinusCircleOutlined } from '@ant-design/icons' import { MinusCircleOutlined } from '@ant-design/icons'
import { uniqBy } from 'lodash-es' import { uniqBy } from 'lodash-es'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function ButtonModal() { export default function ButtonModal() {
...@@ -36,14 +36,10 @@ export default function ButtonModal() { ...@@ -36,14 +36,10 @@ export default function ButtonModal() {
}, [field, data.list]) }, [field, data.list])
const [result, setResult] = useState('') const [result, setResult] = useState('')
const { isLoading, post } = useAI({ const { isLoading, post } = useAI()
onComplete: (message) => {
setResult(message?.content || '')
},
})
const handleAI = async () => { const handleAI = async () => {
post({ const message = await post({
messages: [ messages: [
{ {
role: 'user', role: 'user',
...@@ -86,6 +82,7 @@ export default function ButtonModal() { ...@@ -86,6 +82,7 @@ export default function ButtonModal() {
}, },
], ],
}) })
if (message.content) setResult(message.content)
} }
// 处理下一步按钮逻辑 // 处理下一步按钮逻辑
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'grouping' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'grouping' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
return { ...query, progress: data.progress, message: data.message, remove } return { ...query, progress: data.progress, message: data.message, remove }
......
...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Input, Form, Select } from 'antd' ...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Input, Form, Select } from 'antd'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import FunctionInput from '@/components/data/FunctionInput' import FunctionInput from '@/components/data/FunctionInput'
import { useProcessData } from '../query' import { useProcessData } from '../query'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
const functionOptions = [ const functionOptions = [
...@@ -26,18 +26,14 @@ export default function ButtonModal() { ...@@ -26,18 +26,14 @@ export default function ButtonModal() {
const [form] = Form.useForm() const [form] = Form.useForm()
const [result, setResult] = useState('') const [result, setResult] = useState('')
const { isLoading, post } = useAI({ const { isLoading, post } = useAI()
onComplete: (message) => {
setResult(message?.content || '')
},
})
const handleAI = async () => { const handleAI = async () => {
const values = form.getFieldsValue() const values = form.getFieldsValue()
const selectedFunction = values.function const selectedFunction = values.function
const functionFormula = values.content || '' const functionFormula = values.content || ''
post({ const message = await post({
messages: [ messages: [
{ {
role: 'user', role: 'user',
...@@ -61,6 +57,7 @@ export default function ButtonModal() { ...@@ -61,6 +57,7 @@ export default function ButtonModal() {
}, },
], ],
}) })
if (message.content) setResult(message.content)
} }
// 处理下一步按钮逻辑 // 处理下一步按钮逻辑
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'logic' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'logic' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
return { ...query, progress: data.progress, message: data.message, remove } return { ...query, progress: data.progress, message: data.message, remove }
......
...@@ -4,7 +4,7 @@ import { useDataQuery, useDataFieldQuery } from '@/hooks/useQuery' ...@@ -4,7 +4,7 @@ import { useDataQuery, useDataFieldQuery } from '@/hooks/useQuery'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import { uniqBy } from 'lodash-es' import { uniqBy } from 'lodash-es'
import { useProcessData } from '../query' import { useProcessData } from '../query'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function ButtonModal() { export default function ButtonModal() {
...@@ -39,14 +39,10 @@ export default function ButtonModal() { ...@@ -39,14 +39,10 @@ export default function ButtonModal() {
} }
const [result, setResult] = useState('') const [result, setResult] = useState('')
const { isLoading, post } = useAI({ const { isLoading, post } = useAI()
onComplete: (message) => {
setResult(message?.content || '')
},
})
const handleAI = async () => { const handleAI = async () => {
post({ const message = await post({
messages: [ messages: [
{ {
role: 'user', role: 'user',
...@@ -85,6 +81,7 @@ export default function ButtonModal() { ...@@ -85,6 +81,7 @@ export default function ButtonModal() {
}, },
], ],
}) })
if (message.content) setResult(message.content)
} }
// 处理下一步按钮逻辑 // 处理下一步按钮逻辑
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'mapping' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'mapping' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
return { ...query, progress: data.progress, message: data.message, remove } return { ...query, progress: data.progress, message: data.message, remove }
......
...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Input, Form, Select } from 'antd' ...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Input, Form, Select } from 'antd'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import FunctionInput from '@/components/data/FunctionInput' import FunctionInput from '@/components/data/FunctionInput'
import { useProcessData } from '../query' import { useProcessData } from '../query'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
const functionOptions = [ const functionOptions = [
...@@ -35,18 +35,14 @@ export default function ButtonModal() { ...@@ -35,18 +35,14 @@ export default function ButtonModal() {
const [form] = Form.useForm() const [form] = Form.useForm()
const [result, setResult] = useState('') const [result, setResult] = useState('')
const { isLoading, post } = useAI({ const { isLoading, post } = useAI()
onComplete: (message) => {
setResult(message?.content || '')
},
})
const handleAI = async () => { const handleAI = async () => {
const values = form.getFieldsValue() const values = form.getFieldsValue()
const selectedFunction = values.function const selectedFunction = values.function
const functionFormula = values.content || '' const functionFormula = values.content || ''
post({ const message = await post({
messages: [ messages: [
{ {
role: 'user', role: 'user',
...@@ -70,6 +66,7 @@ export default function ButtonModal() { ...@@ -70,6 +66,7 @@ export default function ButtonModal() {
}, },
], ],
}) })
if (message.content) setResult(message.content)
} }
// 处理下一步按钮逻辑 // 处理下一步按钮逻辑
const handleNext = async () => { const handleNext = async () => {
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'numeric' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'numeric' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
return { ...query, progress: data.progress, message: data.message, remove } return { ...query, progress: data.progress, message: data.message, remove }
......
...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Input, Form, Select } from 'antd' ...@@ -3,7 +3,7 @@ import { Button, Flex, Modal, Input, Form, Select } from 'antd'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import FunctionInput from '@/components/data/FunctionInput' import FunctionInput from '@/components/data/FunctionInput'
import { useProcessData } from '../query' import { useProcessData } from '../query'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
const functionOptions = [ const functionOptions = [
...@@ -49,18 +49,14 @@ export default function ButtonModal() { ...@@ -49,18 +49,14 @@ export default function ButtonModal() {
const { mutate, isPending, progress, message, remove } = useProcessData() const { mutate, isPending, progress, message, remove } = useProcessData()
const [result, setResult] = useState('') const [result, setResult] = useState('')
const { isLoading, post } = useAI({ const { isLoading, post } = useAI()
onComplete: (message) => {
setResult(message?.content || '')
},
})
const handleAI = async () => { const handleAI = async () => {
const values = form.getFieldsValue() const values = form.getFieldsValue()
const selectedFunction = values.function const selectedFunction = values.function
const functionFormula = values.content || '' const functionFormula = values.content || ''
post({ const message = await post({
messages: [ messages: [
{ {
role: 'user', role: 'user',
...@@ -84,6 +80,7 @@ export default function ButtonModal() { ...@@ -84,6 +80,7 @@ export default function ButtonModal() {
}, },
], ],
}) })
if (message.content) setResult(message.content)
} }
// 开始处理 // 开始处理
const handleStart = () => { const handleStart = () => {
......
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation } from '@tanstack/react-query'
import { processData } from './api' import { processData } from './api'
import type { ProcessDataParams } from './types' import type { ProcessDataParams } from './types'
import { useProcessProgressQuery } from '@/hooks/useQuery' import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据 // 处理数据
export function useProcessData() { export function useProcessData() {
const queryClient = useQueryClient()
const { data, start, remove } = useProcessProgressQuery({ function_name: 'text' }) const { data, start, remove } = useProcessProgressQuery({ function_name: 'text' })
const query = useMutation({ const query = useMutation({
...@@ -14,7 +13,6 @@ export function useProcessData() { ...@@ -14,7 +13,6 @@ export function useProcessData() {
}, },
onSuccess: () => { onSuccess: () => {
start() start()
queryClient.invalidateQueries({ queryKey: ['data'] })
}, },
}) })
return { ...query, progress: data.progress, message: data.message, remove } return { ...query, progress: data.progress, message: data.message, remove }
......
...@@ -3,8 +3,8 @@ import { Button, Radio, Flex, Modal, Empty } from 'antd' ...@@ -3,8 +3,8 @@ 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 { useAIStore } from '@/ai/useAIStore'
import prompt from '@/utils/prompt' import prompt from '@/ai/prompt'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
interface ResultItem { interface ResultItem {
...@@ -13,26 +13,25 @@ interface ResultItem { ...@@ -13,26 +13,25 @@ interface ResultItem {
} }
export default function ButtonModal() { export default function ButtonModal() {
const [results, setResults] = useState<ResultItem[]>([])
const { fieldOptions } = useDataFieldQuery() const { fieldOptions } = useDataFieldQuery()
const [results, setResults] = useState<ResultItem[]>([])
const resultsOptions = results.map((result) => ({ const resultsOptions = results.map((result) => ({
label: result.name, label: result.name,
value: fieldOptions.find((option) => option.label === result.name)?.value || '', value: fieldOptions.find((option) => option.label === result.name)?.value || '',
})) }))
const { isLoading, post } = useAI({ const { isLoading, post } = useAIStore()
onComplete: (message) => {
if (!message.content) return const handleAI = async () => {
const parse = JSON.parse(message.content) const message = await post({
console.log(parse)
setResults(parse.results || [])
},
})
const handleAI = () => {
post({
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [{ role: 'user', content: prompt.min }], messages: [{ role: 'user', content: prompt.error }],
}) })
console.log(message.json)
if (message.json && Array.isArray(message.json.results)) {
setResults(message.json.results)
}
} }
const navigate = useNavigate() const navigate = useNavigate()
......
...@@ -3,8 +3,9 @@ import { Button, Radio, Flex, Modal, Empty } from 'antd' ...@@ -3,8 +3,9 @@ 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 { useAIStore } from '@/ai/useAIStore'
import prompt from '@/utils/prompt'
import prompt from '@/ai/prompt'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
interface ResultItem { interface ResultItem {
...@@ -20,19 +21,17 @@ export default function ButtonModal() { ...@@ -20,19 +21,17 @@ export default function ButtonModal() {
value: fieldOptions.find((option) => option.label === result.name)?.value || '', value: fieldOptions.find((option) => option.label === result.name)?.value || '',
})) }))
const { isLoading, post } = useAI({ const { isLoading, post } = useAIStore()
onComplete: (message) => {
if (!message.content) return const handleAI = async () => {
const parse = JSON.parse(message.content) const message = await post({
console.log(parse)
setResults(parse.results || [])
},
})
const handleAI = () => {
post({
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [{ role: 'user', content: prompt.max }], messages: [{ role: 'user', content: prompt.max }],
}) })
console.log(message.json)
if (message.json && Array.isArray(message.json.results)) {
setResults(message.json.results)
}
} }
const navigate = useNavigate() const navigate = useNavigate()
......
...@@ -3,8 +3,8 @@ import { Button, Radio, Flex, Modal, Empty } from 'antd' ...@@ -3,8 +3,8 @@ 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 { useAIStore } from '@/ai/useAIStore'
import prompt from '@/utils/prompt' import prompt from '@/ai/prompt'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
interface ResultItem { interface ResultItem {
...@@ -13,26 +13,25 @@ interface ResultItem { ...@@ -13,26 +13,25 @@ interface ResultItem {
} }
export default function ButtonModal() { export default function ButtonModal() {
const [results, setResults] = useState<ResultItem[]>([])
const { fieldOptions } = useDataFieldQuery() const { fieldOptions } = useDataFieldQuery()
const [results, setResults] = useState<ResultItem[]>([])
const resultsOptions = results.map((result) => ({ const resultsOptions = results.map((result) => ({
label: result.name, label: result.name,
value: fieldOptions.find((option) => option.label === result.name)?.value || '', value: fieldOptions.find((option) => option.label === result.name)?.value || '',
})) }))
const { isLoading, post } = useAI({ const { isLoading, post } = useAIStore()
onComplete: (message) => {
if (!message.content) return const handleAI = async () => {
const parse = JSON.parse(message.content) const message = await post({
console.log(parse)
setResults(parse.results || [])
},
})
const handleAI = () => {
post({
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [{ role: 'user', content: prompt.min }], messages: [{ role: 'user', content: prompt.min }],
}) })
console.log(message.json)
if (message.json && Array.isArray(message.json.results)) {
setResults(message.json.results)
}
} }
const navigate = useNavigate() const navigate = useNavigate()
......
...@@ -3,8 +3,9 @@ import { Button, Checkbox, Empty, Flex, Modal } from 'antd' ...@@ -3,8 +3,9 @@ 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 prompt from '@/utils/prompt' import { useAIStore } from '@/ai/useAIStore'
import prompt from '@/ai/prompt'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
const CheckboxGroup = Checkbox.Group const CheckboxGroup = Checkbox.Group
...@@ -15,28 +16,24 @@ interface ResultItem { ...@@ -15,28 +16,24 @@ interface ResultItem {
} }
export default function ButtonModal() { export default function ButtonModal() {
const [results, setResults] = useState<ResultItem[]>([])
const { fieldOptions } = useDataFieldQuery() const { fieldOptions } = useDataFieldQuery()
const [results, setResults] = useState<ResultItem[]>([])
const resultsOptions = results.map((result) => ({ const resultsOptions = results.map((result) => ({
label: result.name, label: result.name,
value: fieldOptions.find((option) => option.label === result.name)?.value || '', value: fieldOptions.find((option) => option.label === result.name)?.value || '',
})) }))
const { isLoading, post } = useAI({ const { isLoading, post } = useAIStore()
onComplete: (message) => {
if (!message.content) return
const parse = JSON.parse(message.content) const handleAI = async () => {
console.log(parse) const message = await post({
setResults(parse.results || [])
},
})
const handleAI = () => {
post({
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [{ role: 'user', content: prompt.null }], messages: [{ role: 'user', content: prompt.null }],
}) })
console.log(message.json)
if (message.json && Array.isArray(message.json.results)) {
setResults(message.json.results)
}
} }
const navigate = useNavigate() const navigate = useNavigate()
......
import { useState, useMemo } from 'react' import { useState, useMemo, useEffect } 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, useDataQuery } from '@/hooks/useQuery'
import { useAI } from '@/hooks/useAI'
import { utils, writeFile } from 'xlsx' import { utils, writeFile } from 'xlsx'
interface ResultItem { interface ResultItem {
name: string name: string
[key: string]: any
} }
const buttons = ['最大值', '最小值', '平均值', '中位数', '众数', '1/4位数', '3/4位数', '方差', '标准差', '极差'] interface DataField {
name: string
english_name: string
type: string
}
interface DataListItem {
[key: string]: string | number
}
interface Stats {
最大值: number
最小值: number
平均值: number
中位数: number
众数: number
'1/4位数': number
'3/4位数': number
方差: number
标准差: number
极差: number
}
const buttons = [
'最大值',
'最小值',
'平均值',
'中位数',
'众数',
'1/4位数',
'3/4位数',
'方差',
'标准差',
'极差',
] as const
export default function ButtonModal() { export default function ButtonModal() {
const { data = [] } = useDataFieldQuery() const { data } = useDataQuery()
const { getFieldOptions } = useDataFieldQuery()
const numberFields = getFieldOptions('number') as DataField[]
const [results, setResults] = useState<ResultItem[]>( const [selectedButtons, setSelectedButtons] = useState<string[]>([])
data.filter((item: any) => {
return item.type.includes('DECIMAL') || item.type.includes('SMALLINT') const calculateStats = (values: number[]): Stats => {
}) const sortedValues = [...values].sort((a, b) => a - b)
) const n = values.length
const { isLoading, post } = useAI({ const sum = values.reduce((a, b) => a + b, 0)
onComplete: (message) => { const mean = sum / n
if (!message.content) return const variance = values.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / n
const parse = JSON.parse(message.content)
console.log(parse) const roundToTwo = (num: number) => Math.round(num * 100) / 100
setResults(parse.results || {})
}, return {
最大值: roundToTwo(Math.max(...values)),
最小值: roundToTwo(Math.min(...values)),
平均值: roundToTwo(mean),
中位数: roundToTwo(
n % 2 === 0 ? (sortedValues[n / 2 - 1] + sortedValues[n / 2]) / 2 : sortedValues[Math.floor(n / 2)]
),
众数: roundToTwo(
(() => {
const frequency: { [key: number]: number } = {}
values.forEach((v) => (frequency[v] = (frequency[v] || 0) + 1))
return Number(Object.entries(frequency).sort((a, b) => b[1] - a[1])[0][0])
})()
),
'1/4位数': roundToTwo(sortedValues[Math.floor(n * 0.25)]),
'3/4位数': roundToTwo(sortedValues[Math.floor(n * 0.75)]),
方差: roundToTwo(variance),
标准差: roundToTwo(Math.sqrt(variance)),
极差: roundToTwo(Math.max(...values) - Math.min(...values)),
}
}
const results = numberFields.map((field) => {
const fieldData = (data.list as DataListItem[])
.map((item) => Number(item[field.english_name]))
.filter((v: number) => !isNaN(v))
if (fieldData.length === 0) return field
const stats = calculateStats(fieldData)
const result: ResultItem = { name: field.name }
selectedButtons.forEach((button) => {
result[button] = stats[button as keyof Stats]
}) })
const handleAI = () => { return result
const names = results.map((item: any) => item.name).join(',')
post({
response_format: { type: 'json_object' },
messages: [
{
role: 'user',
content: `请帮我计算数据集中,字段${names}${selectedButtons.join('、')}
返回格式示例:
json
{
results:[
{ name: "字段1", 计算类型(中文):"计算结果" },
{ name: "字段2", 计算类型(中文):"计算结果" },
]
}`,
},
],
}) })
}
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const [title, setTitle] = useState('') const [title, setTitle] = useState('')
...@@ -57,8 +108,6 @@ json ...@@ -57,8 +108,6 @@ json
setOpen(true) setOpen(true)
} }
const [selectedButtons, setSelectedButtons] = useState<string[]>([])
const dataSource = results.map((item) => { const dataSource = results.map((item) => {
return { ...item, key: item.name } return { ...item, key: item.name }
}) })
...@@ -111,19 +160,7 @@ json ...@@ -111,19 +160,7 @@ json
{button} {button}
</Button> </Button>
))} ))}
<Modal <Modal title={title} open={open} footer={null} destroyOnClose width={1000} onCancel={() => setOpen(false)}>
title={title}
open={open}
footer={
<Flex justify="center" gap={20}>
<Button type="primary" loading={isLoading} onClick={handleAI}>
一键计算
</Button>
</Flex>
}
destroyOnClose
width={1000}
onCancel={() => setOpen(false)}>
<div style={{ minHeight: 300, padding: '20px 0' }}> <div style={{ minHeight: 300, padding: '20px 0' }}>
<Flex justify="space-between" align="center" style={{ marginBottom: '20px' }}> <Flex justify="space-between" align="center" style={{ marginBottom: '20px' }}>
<div> <div>
......
...@@ -3,25 +3,29 @@ import { Button, Empty, Flex, Modal } from 'antd' ...@@ -3,25 +3,29 @@ 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 { useAIStore } from '@/ai/useAIStore'
import prompt from '@/utils/prompt' import prompt from '@/ai/prompt'
interface ResultItem {
line: number
lines: number[]
desc: string
}
export default function ButtonModal() { export default function ButtonModal() {
const [results, setResults] = useState<Array<{ line: number; lines: number[]; desc: string }>>([]) const [results, setResults] = useState<ResultItem[]>([])
const { isLoading, post } = useAI({ const { isLoading, post } = useAIStore()
onComplete: (message) => {
if (!message.content) return const handleAI = async () => {
const parse = JSON.parse(message.content) const message = await post({
console.log(parse)
setResults(parse.results || [])
},
})
const handleAI = () => {
post({
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
messages: [{ role: 'user', content: prompt.repeat }], messages: [{ role: 'user', content: prompt.repeat }],
}) })
console.log(message.json)
if (message.json && Array.isArray(message.json.results)) {
setResults(message.json.results)
}
} }
const navigate = useNavigate() const navigate = useNavigate()
......
import DataWrap from '@/components/data/DataWrap' import DataWrap from '@/components/data/DataWrap'
import { Button } from 'antd' import { Button, message } from 'antd'
import { useAIStore } from '@/stores/ai' import { useAIStore } from '@/ai/useAIStore'
export default function DataWriteUpload() { export default function DataWriteUpload() {
const [messageApi, contextHolder] = message.useMessage()
const post = useAIStore((state) => state.post) const post = useAIStore((state) => state.post)
const isLoading = useAIStore((state) => state.isLoading)
function handleClick(type: number) { async function handleClick(type: number) {
messageApi.open({ type: 'loading', content: '数据正在智能分析中,请您耐心等待', duration: 0 })
if (type == 1) { if (type == 1) {
post({ await post({
messages: [ messages: [
{ {
role: 'user', role: 'user',
...@@ -29,7 +30,7 @@ export default function DataWriteUpload() { ...@@ -29,7 +30,7 @@ export default function DataWriteUpload() {
], ],
}) })
} else { } else {
post({ await post({
messages: [ messages: [
{ {
role: 'user', role: 'user',
...@@ -50,6 +51,8 @@ export default function DataWriteUpload() { ...@@ -50,6 +51,8 @@ export default function DataWriteUpload() {
], ],
}) })
} }
messageApi.destroy()
} }
return ( return (
...@@ -57,10 +60,11 @@ export default function DataWriteUpload() { ...@@ -57,10 +60,11 @@ export default function DataWriteUpload() {
title="数据理解" title="数据理解"
buttons={ buttons={
<> <>
<Button type="primary" onClick={() => handleClick(1)} loading={isLoading}> {contextHolder}
<Button type="primary" onClick={() => handleClick(1)}>
一键理解数据字段 一键理解数据字段
</Button> </Button>
<Button type="primary" onClick={() => handleClick(2)} loading={isLoading}> <Button type="primary" onClick={() => handleClick(2)}>
一键梳理字段关系 一键梳理字段关系
</Button> </Button>
</> </>
......
...@@ -11,6 +11,7 @@ export function useCopyDataset() { ...@@ -11,6 +11,7 @@ export function useCopyDataset() {
onSuccess: () => { onSuccess: () => {
message.success('复制成功') message.success('复制成功')
queryClient.invalidateQueries({ queryKey: ['data'] }) queryClient.invalidateQueries({ queryKey: ['data'] })
queryClient.invalidateQueries({ queryKey: ['dataFiled'] })
}, },
}) })
} }
import { Button, Flex, Modal, Spin } from 'antd' import { Button, Flex, Modal, Spin } from 'antd'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/ai/useAI'
import MarkdownRender from '@/components/MarkdownRender' import MarkdownRender from '@/components/MarkdownRender'
export default function DataReport() { export default function DataReport() {
......
import { create } from 'zustand'
import aiService, { AIOption, AIMessage, AIData, AI_OPTIONS, InitOptions } from '@/utils/ai'
\ No newline at end of file
interface AIState {
ai: string
options: AIOption[]
message: AIMessage | null
messages: AIMessage[]
isLoading: boolean
collapsed: boolean
setAI: (ai: string) => void
toggleCollapsed: () => void
post: (data: AIData, options?: InitOptions) => Promise<void>
}
export const useAIStore = create<AIState>((set, get) => ({
ai: localStorage.getItem('ai') || 'qwen',
options: AI_OPTIONS,
message: null,
messages: [],
isLoading: false,
collapsed: false,
setAI: (ai) => {
localStorage.setItem('ai', ai)
set({ ai })
},
toggleCollapsed: () => {
set((state) => ({ collapsed: !state.collapsed }))
},
post: async (data, options) => {
const { ai, messages } = get()
// 处理用户消息(去掉 system 角色的消息)
const userMessages = data.messages.filter((item) => item.role !== 'system')
set({
collapsed: true,
isLoading: true,
messages: [...messages, ...userMessages],
})
try {
await aiService.post(ai, data, {
onMessage: (response) => {
set((state) => {
const messageIndex = state.messages.findIndex((msg) => msg.id === response.id)
if (messageIndex === -1) {
// 新的 AI 回复
const newMessage: AIMessage = { id: response.id, role: 'assistant', content: response.content }
return {
message: newMessage, // 存储最新的 AI 消息
messages: [...state.messages, newMessage], // 追加到历史消息
}
} else {
// 追加内容到已有的消息
const updatedMessages = state.messages.map((msg) =>
msg.id === response.id ? { ...msg, content: msg.content + response.content } : msg
)
return {
message: updatedMessages[messageIndex], // 更新最新的 AI 消息
messages: updatedMessages,
}
}
})
},
onerror: (err) => {
console.error('AI 请求失败:', err)
set({ isLoading: false })
},
onclose: () => {
set({ isLoading: false })
},
...options,
})
} catch (err) {
console.error('AI 请求失败:', err)
set({ isLoading: false })
}
},
}))
export type { AIMessage }
export function extractJSON(str: string) {
const jsonRegex = /(\{.*\}|\[.*\])/s
const match = str.match(jsonRegex)
if (!match) return null
try {
return JSON.parse(match[0])
} catch (e) {
return null
}
}
...@@ -10,13 +10,7 @@ export default defineConfig({ ...@@ -10,13 +10,7 @@ export default defineConfig({
open: true, open: true,
host: 'dev.ezijing.com', host: 'dev.ezijing.com',
proxy: { proxy: {
// '/api/resource/bi': { '/api': 'https://saas-bi.ezijing.com',
// target: 'https://saas-lab.ezijing.com',
// changeOrigin: true,
// rewrite: (path) => path.replace(/^\/api\/bi/, '/api/resource/bi'),
// },
// '/api/resource/bi': 'https://saas-lab.ezijing.com/api/resource/bi',
'/api': 'https://saas-lab.ezijing.com',
}, },
}, },
resolve: { resolve: {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论