智能分析(异步)
This commit is contained in:
parent
f2d561071b
commit
683cc1ec74
@ -13,6 +13,12 @@ export default [
|
|||||||
icon: 'barChart',
|
icon: 'barChart',
|
||||||
component: './Chart/AddChart'
|
component: './Chart/AddChart'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: '智能分析(异步)',
|
||||||
|
path: '/analyze/async',
|
||||||
|
icon: 'barChart',
|
||||||
|
component: './Chart/AddChartAsync'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: '我的图表',
|
name: '我的图表',
|
||||||
path: '/my_chart',
|
path: '/my_chart',
|
||||||
|
|||||||
@ -56,6 +56,9 @@ const AddChart: React.FC = () => {
|
|||||||
<Card title="智能分析">
|
<Card title="智能分析">
|
||||||
<Form
|
<Form
|
||||||
name="addChart"
|
name="addChart"
|
||||||
|
labelAlign='left'
|
||||||
|
labelCol={{span : 4}}
|
||||||
|
wrapperCol={{span : 16}}
|
||||||
onFinish={onFinish}
|
onFinish={onFinish}
|
||||||
initialValues={{ }}
|
initialValues={{ }}
|
||||||
>
|
>
|
||||||
|
|||||||
93
src/pages/Chart/AddChartAsync/index.tsx
Normal file
93
src/pages/Chart/AddChartAsync/index.tsx
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import { genChartByAiAsyncUsingPOST } from '@/services/answerbi/chartController';
|
||||||
|
import { UploadOutlined } from '@ant-design/icons';
|
||||||
|
import { Button, Card, Form, Input, Select, Space, Upload, message } from 'antd';
|
||||||
|
import { useForm } from 'antd/es/form/Form';
|
||||||
|
import TextArea from 'antd/es/input/TextArea';
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
|
|
||||||
|
const AddChartAsync: React.FC = () => {
|
||||||
|
//定义状态,用来接收后端返回值,让它实时展示再页面上
|
||||||
|
const [form] = useForm();
|
||||||
|
const [submitting, setSubmitting] = useState<boolean>(false);
|
||||||
|
|
||||||
|
|
||||||
|
const onFinish = async (values: any) => {
|
||||||
|
if(submitting) return;
|
||||||
|
setSubmitting(true);
|
||||||
|
//对接后端,上传数据
|
||||||
|
const params = {
|
||||||
|
...values,
|
||||||
|
file: undefined,
|
||||||
|
};
|
||||||
|
try{
|
||||||
|
//需要取到上传的原始数据 file->file->originFileObj
|
||||||
|
const res = await genChartByAiAsyncUsingPOST(params, {}, values.file.file.originFileObj);
|
||||||
|
//正常情况下,如果没有返回值就分析失败,有就分析成功
|
||||||
|
if(!res?.data){
|
||||||
|
message.error('分析失败');
|
||||||
|
}else{
|
||||||
|
message.success('分析任务提交成功,稍后请在我的图表页面查看');
|
||||||
|
form.resetFields();
|
||||||
|
}
|
||||||
|
}catch(e: any){
|
||||||
|
//异常情况下,提示分析失败+具体失败原因
|
||||||
|
message.error('分析失败,' + e.message);
|
||||||
|
}
|
||||||
|
setSubmitting(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='add-chart-async'>
|
||||||
|
<Card title="智能分析">
|
||||||
|
<Form
|
||||||
|
name="addChart"
|
||||||
|
labelAlign='left'
|
||||||
|
labelCol={{span : 4}}
|
||||||
|
wrapperCol={{span : 16}}
|
||||||
|
onFinish={onFinish}
|
||||||
|
initialValues={{ }}
|
||||||
|
>
|
||||||
|
<Form.Item
|
||||||
|
name="goal"
|
||||||
|
label="分析目标"
|
||||||
|
rules={[{ required: true, message: '请输入分析目标!' }]}
|
||||||
|
>
|
||||||
|
<TextArea placeholder='请输入你的分析需求,比如:分析网站用户的增长情况'/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item name="chartName" label="图表名称">
|
||||||
|
<Input placeholder='请输入图表名称'/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item name="chartType" label="图表类型">
|
||||||
|
<Select
|
||||||
|
placeholder="请选择图表类型"
|
||||||
|
options={[
|
||||||
|
{value: '折线图', label: '折线图'},
|
||||||
|
{value: '柱状图', label: '柱状图'},
|
||||||
|
{value: '堆叠图', label: '堆叠图'},
|
||||||
|
{value: '饼图', label: '饼图'},
|
||||||
|
{value: '雷达图', label: '雷达图'},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item name="file" label="上传原始数据">
|
||||||
|
<Upload name="file">
|
||||||
|
<Button icon={<UploadOutlined />}>上传EXCEL文件</Button>
|
||||||
|
</Upload>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item wrapperCol={{ span: 12, offset: 6 }}>
|
||||||
|
<Space>
|
||||||
|
<Button type="primary" htmlType="submit">提交</Button>
|
||||||
|
<Button htmlType="reset">重置</Button>
|
||||||
|
</Space>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default AddChartAsync;
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { listMyChartByPageUsingPOST } from '@/services/answerbi/chartController';
|
import { listMyChartByPageUsingPOST } from '@/services/answerbi/chartController';
|
||||||
import { useModel } from '@umijs/max';
|
import { useModel } from '@umijs/max';
|
||||||
import { Avatar, Card, List, message } from 'antd';
|
import { Avatar, Card, List, Result, message } from 'antd';
|
||||||
import Search from 'antd/es/input/Search';
|
import Search from 'antd/es/input/Search';
|
||||||
import ReactECharts from 'echarts-for-react';
|
import ReactECharts from 'echarts-for-react';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
@ -10,6 +10,8 @@ const MyChartPage: React.FC = () => {
|
|||||||
const initSearchParams = {
|
const initSearchParams = {
|
||||||
current: 1,
|
current: 1,
|
||||||
pageSize: 4,
|
pageSize: 4,
|
||||||
|
sortField: 'created_time',
|
||||||
|
sortOrder: 'desc',
|
||||||
}
|
}
|
||||||
|
|
||||||
const [searchParams, setSearchParams] = useState<API.ChartQueryRequest>({...initSearchParams});
|
const [searchParams, setSearchParams] = useState<API.ChartQueryRequest>({...initSearchParams});
|
||||||
@ -34,9 +36,11 @@ const MyChartPage: React.FC = () => {
|
|||||||
//去除图表标题
|
//去除图表标题
|
||||||
if(res.data.records){
|
if(res.data.records){
|
||||||
res.data.records.forEach(data => {
|
res.data.records.forEach(data => {
|
||||||
|
if(data.status === 'succeed'){
|
||||||
const chartOption = JSON.parse(data.genChart ?? '{}');
|
const chartOption = JSON.parse(data.genChart ?? '{}');
|
||||||
chartOption.title = undefined;
|
chartOption.title = undefined;
|
||||||
data.genChart = JSON.stringify(chartOption);
|
data.genChart = JSON.stringify(chartOption);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@ -51,7 +55,10 @@ const MyChartPage: React.FC = () => {
|
|||||||
//首次加载页面时,触发加载数据
|
//首次加载页面时,触发加载数据
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
//这个页面首次渲染的时候,以及这个数组中的搜索条件发生变化的时候,会执行loadData方法,自动触发重新搜索
|
//这个页面首次渲染的时候,以及这个数组中的搜索条件发生变化的时候,会执行loadData方法,自动触发重新搜索
|
||||||
|
const timer = setInterval(() => {
|
||||||
loadData();
|
loadData();
|
||||||
|
}, 5000);
|
||||||
|
return () => clearInterval(timer);
|
||||||
},[searchParams]);
|
},[searchParams]);
|
||||||
|
|
||||||
|
|
||||||
@ -107,10 +114,45 @@ const MyChartPage: React.FC = () => {
|
|||||||
title={item.chartName}
|
title={item.chartName}
|
||||||
description={item.chartType ? '图表类型:' + item.chartType : undefined}
|
description={item.chartType ? '图表类型:' + item.chartType : undefined}
|
||||||
/>
|
/>
|
||||||
|
<>
|
||||||
|
{
|
||||||
|
item.status === 'wait' && <>
|
||||||
|
<Result
|
||||||
|
status="warning"
|
||||||
|
title="待生成"
|
||||||
|
subTitle={item.execMessage ?? '当前图表生成队列繁忙,请耐心等候'}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
item.status === 'running' && <>
|
||||||
|
<Result
|
||||||
|
status="info"
|
||||||
|
title="图表生成中"
|
||||||
|
subTitle={item.execMessage}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
item.status === 'succeed' && <>
|
||||||
<div style={{ marginBottom: 16 }} />
|
<div style={{ marginBottom: 16 }} />
|
||||||
{'分析目标:' + item.goal}
|
<p>{'分析目标:' + item.goal}</p>
|
||||||
<div style={{ marginBottom: 16 }} />
|
<div style={{ marginBottom: 16 }} />
|
||||||
<ReactECharts option={JSON.parse(item.genChart ?? '{}')}></ReactECharts>
|
<ReactECharts option={item.genChart && JSON.parse(item.genChart)} />
|
||||||
|
<div style={{ marginBottom: 16 }} />
|
||||||
|
<p>{'分析结论:' + item.genResult}</p>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
item.status === 'failed' && <>
|
||||||
|
<Result
|
||||||
|
status="error"
|
||||||
|
title="图表生成失败"
|
||||||
|
subTitle={item.execMessage}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</>
|
||||||
</Card>
|
</Card>
|
||||||
</List.Item>
|
</List.Item>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -83,6 +83,42 @@ export async function genChartByAiUsingPOST(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** genChartByAiAsync POST /api/chart/gen/async */
|
||||||
|
export async function genChartByAiAsyncUsingPOST(
|
||||||
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
params: API.genChartByAiAsyncUsingPOSTParams,
|
||||||
|
body: {},
|
||||||
|
file?: File,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
formData.append('file', file);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(body).forEach((ele) => {
|
||||||
|
const item = (body as any)[ele];
|
||||||
|
|
||||||
|
if (item !== undefined && item !== null) {
|
||||||
|
formData.append(
|
||||||
|
ele,
|
||||||
|
typeof item === 'object' && !(item instanceof File) ? JSON.stringify(item) : item,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return request<API.CommonResponseBiResponse_>('/api/chart/gen/async', {
|
||||||
|
method: 'POST',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
data: formData,
|
||||||
|
requestType: 'form',
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/** getChartById GET /api/chart/get */
|
/** getChartById GET /api/chart/get */
|
||||||
export async function getChartByIdUsingGET(
|
export async function getChartByIdUsingGET(
|
||||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||||
|
|||||||
8
src/services/answerbi/typings.d.ts
vendored
8
src/services/answerbi/typings.d.ts
vendored
@ -11,10 +11,12 @@ declare namespace API {
|
|||||||
chartType?: string;
|
chartType?: string;
|
||||||
createdTime?: string;
|
createdTime?: string;
|
||||||
deletedFlag?: number;
|
deletedFlag?: number;
|
||||||
|
execMessage?: string;
|
||||||
genChart?: string;
|
genChart?: string;
|
||||||
genResult?: string;
|
genResult?: string;
|
||||||
goal?: string;
|
goal?: string;
|
||||||
id?: number;
|
id?: number;
|
||||||
|
status?: string;
|
||||||
updatedTime?: string;
|
updatedTime?: string;
|
||||||
userId?: number;
|
userId?: number;
|
||||||
};
|
};
|
||||||
@ -147,6 +149,12 @@ declare namespace API {
|
|||||||
id?: number;
|
id?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type genChartByAiAsyncUsingPOSTParams = {
|
||||||
|
chartName?: string;
|
||||||
|
chartType?: string;
|
||||||
|
goal?: string;
|
||||||
|
};
|
||||||
|
|
||||||
type genChartByAiUsingPOSTParams = {
|
type genChartByAiUsingPOSTParams = {
|
||||||
chartName?: string;
|
chartName?: string;
|
||||||
chartType?: string;
|
chartType?: string;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user