提交 29c52a95 authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 89430342
import { useDataQuery } from '@/hooks/useQuery'
import { Column, Line, Pie, Radar, Scatter, WordCloud } from '@ant-design/plots'
export default function Chart({ type = '1', ...props }) {
const { data } = useDataQuery()
switch (type) {
case '1':
return <Column data={data.list} {...props} />
case '2': {
const defaultConfig = {
data: data.list,
point: { shapeField: 'point', sizeField: 4 },
style: { lineWidth: 2 },
}
return <Line {...defaultConfig} {...props} />
}
case '3': {
const defaultConfig = {
data: data.list,
angleField: props.yField,
colorField: props.xField,
}
return <Pie {...defaultConfig} />
}
case '4':
return <Radar data={data.list} {...props} />
case '5':
return <Scatter data={data.list} {...props} />
case '7':
return <WordCloud data={data.list} {...props} />
default:
return <Column data={data.list} {...props} />
}
}
import { useState } from 'react' 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 { useDataQuery, useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
import { useCreateChart } from '@/hooks/useChartQuery' import { useCreateChart, useUpdateChart, useViewChartQuery } from '@/hooks/useChartQuery'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/hooks/useAI'
import { Column } from '@ant-design/plots' import Chart from './Chart'
interface Props { interface Props {
id?: string
type: string type: string
setOpen: (open: boolean) => void setOpen: (open: boolean) => void
} }
const ModalContent = ({ setOpen, type }: Props) => { const ModalContent = ({ setOpen, type, id = '' }: Props) => {
const { data } = useDataQuery()
const { fieldOptions } = useDataFieldQuery() const { fieldOptions } = useDataFieldQuery()
const { data: chartData } = useViewChartQuery(id)
const [form] = Form.useForm() const [form] = Form.useForm()
useEffect(() => {
if (id && chartData) {
try {
const parsedContent = JSON.parse(chartData.content)
form.setFieldsValue({ ...parsedContent.form })
} catch (e) {
console.error('解析图表数据失败:', e)
}
}
}, [id, chartData, form])
const [results, setResults] = useState({}) const [results, setResults] = useState({})
const xField = Form.useWatch('x', form) const xField = Form.useWatch('x', form)
const yField = Form.useWatch('y', form) const yField = Form.useWatch('y', form)
const colorField = Form.useWatch('colorField', form)
const title = Form.useWatch('title', form) const title = Form.useWatch('title', form)
const config = { data: data.list, xField, yField, colorField: xField, title, ...results } const config = { xField, yField, colorField, title, ...results }
const { post } = useAI({ const { post } = useAI({
onComplete: (message) => { onComplete: (message) => {
...@@ -59,17 +72,28 @@ const ModalContent = ({ setOpen, type }: Props) => { ...@@ -59,17 +72,28 @@ const ModalContent = ({ setOpen, type }: Props) => {
}) })
} }
const { mutate } = useCreateChart() const { mutate: mutateCreate } = useCreateChart()
const { mutate: mutateUpdate } = useUpdateChart()
// 保存 // 保存
const handleSubmit = () => { const handleSubmit = () => {
form.validateFields().then((values) => { form.validateFields().then((values) => {
const params = { ...values, type, content: JSON.stringify({ config }) } const params = { ...values, type, content: JSON.stringify({ form: values, config }) }
mutate(params, {
if (id) {
mutateUpdate(
{ id, ...params },
{
onSuccess: () => setOpen(false),
}
)
} else {
mutateCreate(params, {
onSuccess: () => setOpen(false), onSuccess: () => setOpen(false),
}) })
}
}) })
} }
return ( return (
<> <>
<Form <Form
...@@ -84,11 +108,11 @@ const ModalContent = ({ setOpen, type }: Props) => { ...@@ -84,11 +108,11 @@ const ModalContent = ({ setOpen, type }: Props) => {
has_title: '无', has_title: '无',
fill_image: '纯色', fill_image: '纯色',
}}> }}>
<Form.Item label="组件名称" name="name"> <Form.Item label="组件名称" name="name" rules={[{ required: true, message: '请输入组件名称' }]}>
<Input placeholder="请输入" /> <Input placeholder="请输入" />
</Form.Item> </Form.Item>
<Divider orientation="left" orientationMargin="0"> <Divider orientation="left" orientationMargin="0">
步骤1:数字字段设置 数字字段设置
</Divider> </Divider>
<Row gutter={20}> <Row gutter={20}>
<Col span={8}> <Col span={8}>
...@@ -127,17 +151,17 @@ const ModalContent = ({ setOpen, type }: Props) => { ...@@ -127,17 +151,17 @@ const ModalContent = ({ setOpen, type }: Props) => {
</Col> </Col>
</Row> </Row>
<Divider orientation="left" orientationMargin="0"> <Divider orientation="left" orientationMargin="0">
步骤2:辅助可视化设置 辅助可视化设置
</Divider> </Divider>
<Row gutter={20}> <Row gutter={20}>
<Col span={12}> <Col span={12}>
<Form.Item label="请选择“标签”字段" name="label"> <Form.Item label="请选择“标签”字段" name="colorField">
<Select options={fieldOptions} placeholder="请选择"></Select> <Select options={fieldOptions} placeholder="请选择"></Select>
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item label="请选择颜色规则" name="fill_color"> <Form.Item label="请选择颜色规则" name="fill_color">
<Radio.Group options={['自动颜色', '不同柱子颜色不同']}></Radio.Group> <Radio.Group options={['自动颜色']}></Radio.Group>
</Form.Item> </Form.Item>
</Col> </Col>
</Row> </Row>
...@@ -171,9 +195,9 @@ const ModalContent = ({ setOpen, type }: Props) => { ...@@ -171,9 +195,9 @@ const ModalContent = ({ setOpen, type }: Props) => {
</Col> </Col>
</Row> </Row>
<Divider orientation="left" orientationMargin="0"> <Divider orientation="left" orientationMargin="0">
步骤3:预览组件效果 预览组件效果
</Divider> </Divider>
{xField && yField && <Column {...config} />} <Chart type={type} {...config} />
</Form> </Form>
<Flex justify="center" gap={20}> <Flex justify="center" gap={20}>
...@@ -189,15 +213,16 @@ const ModalContent = ({ setOpen, type }: Props) => { ...@@ -189,15 +213,16 @@ const ModalContent = ({ setOpen, type }: Props) => {
) )
} }
export default function ButtonModal({ title = '新建柱状图', type = '1' }) { export default function ButtonModal({ type = '1', id = '' }) {
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const title = id ? '编辑' : '新建'
return ( return (
<> <>
<Button type="primary" onClick={() => setOpen(true)}> <Button color="primary" variant={id ? 'text' : 'solid'} onClick={() => setOpen(true)}>
{title} {title}
</Button> </Button>
<Modal title={title} open={open} footer={null} destroyOnClose width={1000} onCancel={() => setOpen(false)}> <Modal title={title} open={open} footer={null} destroyOnClose width={1000} onCancel={() => setOpen(false)}>
<ModalContent type={type} setOpen={(open) => setOpen(open)} /> <ModalContent type={type} setOpen={(open) => setOpen(open)} id={id} />
</Modal> </Modal>
</> </>
) )
......
import { Button, Card, Flex } from 'antd' import { Button, Card, Flex } from 'antd'
import { ReactNode } from 'react' import { lazy, ReactNode } from 'react'
import AppList, { AppListProps } from '@/components/AppList' import AppList, { AppListProps } from '@/components/AppList'
import ViewDataButtonModal from '../data/ViewMyDataButtonModal' import ViewDataButtonModal from '../data/ViewMyDataButtonModal'
import ViewChartButtonModal from './ViewChartButtonModal' import ViewChartButtonModal from './ViewChartButtonModal'
import { getChartComponentList } from '@/api/data' import { getChartComponentList } from '@/api/data'
import { useDeleteChart } from '@/hooks/useChartQuery' import { useDeleteChart } from '@/hooks/useChartQuery'
import { CHART_TYPE } from '@/utils/constants'
const chartType: any = { const ButtonModal = lazy(() => import('@/components/chart/ChartButtonModal'))
1: '柱状图',
2: '折线图',
3: '饼状图',
4: '雷达图',
5: '散点图',
6: '气泡图',
7: '词云',
8: '地图',
9: '指标卡',
10: '漏斗图',
11: '直方图',
12: '表格',
13: '帕累托图',
14: '矩形树图',
}
export default function DataWrap({ export default function DataWrap({
title, title,
buttons,
type, type,
}: { }: {
type: string type: string
title: string title: string
buttons: ReactNode buttons?: ReactNode
children?: ReactNode children?: ReactNode
}) { }) {
const { mutate } = useDeleteChart() const { mutate } = useDeleteChart()
...@@ -58,8 +42,8 @@ export default function DataWrap({ ...@@ -58,8 +42,8 @@ export default function DataWrap({
title: '组件类型', title: '组件类型',
dataIndex: 'type', dataIndex: 'type',
align: 'center', align: 'center',
render(value) { render(value: keyof typeof CHART_TYPE) {
return chartType[value] || value return CHART_TYPE[value] || value
}, },
}, },
{ title: '组件名称', dataIndex: 'name', align: 'center' }, { title: '组件名称', dataIndex: 'name', align: 'center' },
...@@ -75,9 +59,7 @@ export default function DataWrap({ ...@@ -75,9 +59,7 @@ export default function DataWrap({
return ( return (
<> <>
<ViewChartButtonModal id={record.id}></ViewChartButtonModal> <ViewChartButtonModal id={record.id}></ViewChartButtonModal>
<Button color="primary" variant="text"> <ButtonModal type={type} id={record.id}></ButtonModal>
编辑
</Button>
<Button color="danger" variant="text" onClick={() => handleRemove(record)}> <Button color="danger" variant="text" onClick={() => handleRemove(record)}>
删除 删除
</Button> </Button>
...@@ -92,7 +74,7 @@ export default function DataWrap({ ...@@ -92,7 +74,7 @@ export default function DataWrap({
<Card className="app-card" title={title} style={{ flex: 1, overflowX: 'hidden' }}> <Card className="app-card" title={title} style={{ flex: 1, overflowX: 'hidden' }}>
<Flex justify="space-between" style={{ marginBottom: '20px' }}> <Flex justify="space-between" style={{ marginBottom: '20px' }}>
<Flex wrap gap={10}> <Flex wrap gap={10}>
{buttons} <ButtonModal type={type}></ButtonModal>
</Flex> </Flex>
<ViewDataButtonModal></ViewDataButtonModal> <ViewDataButtonModal></ViewDataButtonModal>
</Flex> </Flex>
......
import { Button, Modal } from 'antd'
import AppList, { AppListProps } from '@/components/AppList'
import { getChartComponentList } from '@/api/data'
import { CHART_TYPE } from '@/utils/constants'
import { useState, useEffect } from 'react'
import ViewChartButtonModal from './ViewChartButtonModal'
interface SelectChartProps {
type?: string
value?: any[]
onChange?: (value: any[]) => void
}
export default function SelectChart({ type, value = [], onChange }: SelectChartProps) {
const [open, setOpen] = useState(false)
const [selectedRows, setSelectedRows] = useState<any[]>([])
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([])
const [dataSource, setDataSource] = useState<any[]>(value)
useEffect(() => {
setDataSource(value)
}, [value])
const listOptions: AppListProps = {
queryKey: ['chartComponentList', { type }],
fetchApi: async (params) => {
const { data } = await getChartComponentList({ ...params, type })
return { ...data }
},
columns: [
{
title: '序号',
key: 'index',
render(_value, _record, index) {
return index + 1
},
width: 62,
align: 'center',
},
{
title: '组件类型',
dataIndex: 'type',
align: 'center',
render(value: keyof typeof CHART_TYPE) {
return CHART_TYPE[value] || value
},
},
{ title: '组件名称', dataIndex: 'name', align: 'center' },
{ title: '创建人', dataIndex: 'created_operator_name', align: 'center' },
{ title: '创建时间', dataIndex: 'created_time', align: 'center' },
{ title: '更新时间', dataIndex: 'updated_time', align: 'center' },
],
rowSelection: {
type: 'checkbox',
selectedRowKeys,
onChange: (keys: React.Key[], rows: any[]) => {
setSelectedRowKeys(keys)
setSelectedRows(rows)
},
getCheckboxProps: (record: any) => ({
disabled: dataSource.some((item) => item.id === record.id),
}),
},
}
const removeDuplicates = (originalArray: any[], newArray: any[]) => {
const uniqueArray = [...originalArray]
newArray.forEach((newItem) => {
const isDuplicate = uniqueArray.some((item) => item.id === newItem.id)
if (!isDuplicate) {
uniqueArray.push(newItem)
}
})
return uniqueArray
}
const handleRemove = (record: any) => {
const newDataSource = dataSource.filter((item) => item.id !== record.id)
setDataSource(newDataSource)
onChange?.(newDataSource)
}
const handleOk = () => {
const newDataSource = removeDuplicates(dataSource, selectedRows)
setDataSource(newDataSource)
onChange?.(newDataSource)
setSelectedRows([])
setSelectedRowKeys([])
setOpen(false)
}
const selectListOptions: AppListProps = {
dataSource,
columns: [
{
title: '序号',
key: 'index',
render(_value, _record, index) {
return index + 1
},
width: 62,
align: 'center',
},
{
title: '组件类型',
dataIndex: 'type',
align: 'center',
render(value: keyof typeof CHART_TYPE) {
return CHART_TYPE[value] || value
},
},
{ title: '组件名称', dataIndex: 'name', align: 'center' },
{
title: '操作',
key: 'x',
width: 220,
align: 'center',
render(_value, record) {
return (
<>
<ViewChartButtonModal id={record.id}></ViewChartButtonModal>
<Button color="danger" variant="text" onClick={() => handleRemove(record)}>
删除
</Button>
</>
)
},
},
],
}
return (
<>
<Button type="primary" onClick={() => setOpen(true)} style={{ marginBottom: 20 }}>
添加可视化组件
</Button>
<AppList {...selectListOptions} style={{ marginBottom: 20 }} />
<Modal title="添加可视化组件" width="1000px" open={open} onCancel={() => setOpen(false)} onOk={handleOk}>
<AppList {...listOptions} />
</Modal>
</>
)
}
import { useState } from 'react' import { useState } from 'react'
import { Button, Modal } from 'antd' import { Button, Modal } from 'antd'
import { Column } from '@ant-design/plots'
import { useViewChartQuery } from '@/hooks/useChartQuery' import { useViewChartQuery } from '@/hooks/useChartQuery'
import Chart from './Chart'
export default function ViewDataButtonModal({ id }: { id: string }) { export default function ViewDataButtonModal({ id }: { id: string }) {
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
...@@ -34,7 +34,7 @@ function ModalContent({ id }: { id: string }) { ...@@ -34,7 +34,7 @@ function ModalContent({ id }: { id: string }) {
return ( return (
<div> <div>
<Column {...config} /> <Chart type={data.type} {...config} />
</div> </div>
) )
} }
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { createChartComponent, deleteChartComponent, getChartComponent } from '@/api/data' import { createChartComponent, updateChartComponent, deleteChartComponent, getChartComponent } from '@/api/data'
import { message } from 'antd' import { message } from 'antd'
// 创建 // 创建
...@@ -15,6 +15,19 @@ export function useCreateChart() { ...@@ -15,6 +15,19 @@ export function useCreateChart() {
}) })
} }
// 编辑
export function useUpdateChart() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: (data: { id: string; name: string; type: string; content: string }) => updateChartComponent(data),
onSuccess: () => {
message.success('编辑成功')
queryClient.invalidateQueries({ queryKey: ['chartComponentList'] })
},
})
}
// 删除 // 删除
export function useDeleteChart() { export function useDeleteChart() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
...@@ -36,5 +49,7 @@ export function useViewChartQuery(id: string) { ...@@ -36,5 +49,7 @@ export function useViewChartQuery(id: string) {
return getChartComponent({ id }) return getChartComponent({ id })
}, },
select: (res) => res.data, select: (res) => res.data,
enabled: !!id,
staleTime: 0,
}) })
} }
import { lazy } from 'react'
import ChartWrap from '@/components/chart/ChartWrap' import ChartWrap from '@/components/chart/ChartWrap'
const ButtonModal = lazy(() => import('@/components/chart/ChartButtonModal'))
export default function DataProcess() { export default function DataProcess() {
return <ChartWrap title="可视化:柱状图" type="1" buttons={<ButtonModal title="新建柱状图" type="1" />}></ChartWrap> return <ChartWrap title="可视化:柱状图" type="1"></ChartWrap>
} }
import { lazy } from 'react'
import ChartWrap from '@/components/chart/ChartWrap' import ChartWrap from '@/components/chart/ChartWrap'
const ButtonModal = lazy(() => import('@/components/chart/ChartButtonModal'))
export default function DataProcess() { export default function DataProcess() {
return <ChartWrap title="可视化:气泡图" type="6" buttons={<ButtonModal title="新建气泡图" type="6" />}></ChartWrap> return <ChartWrap title="可视化:气泡图" type="6"></ChartWrap>
} }
import { lazy } from 'react'
import ChartWrap from '@/components/chart/ChartWrap' import ChartWrap from '@/components/chart/ChartWrap'
const ButtonModal = lazy(() => import('@/components/chart/ChartButtonModal'))
export default function DataProcess() { export default function DataProcess() {
return <ChartWrap title="可视化:漏斗图" type="10" buttons={<ButtonModal title="新建漏斗图" type="10" />}></ChartWrap> return <ChartWrap title="可视化:漏斗图" type="10"></ChartWrap>
} }
import { lazy } from 'react'
import ChartWrap from '@/components/chart/ChartWrap' import ChartWrap from '@/components/chart/ChartWrap'
const ButtonModal = lazy(() => import('@/components/chart/ChartButtonModal'))
export default function DataProcess() { export default function DataProcess() {
return <ChartWrap title="可视化:直方图" type="11" buttons={<ButtonModal title="新建直方图" type="11" />}></ChartWrap> return <ChartWrap title="可视化:直方图" type="11"></ChartWrap>
} }
import { lazy } from 'react'
import ChartWrap from '@/components/chart/ChartWrap' import ChartWrap from '@/components/chart/ChartWrap'
const ButtonModal = lazy(() => import('@/components/chart/ChartButtonModal'))
export default function DataProcess() { export default function DataProcess() {
return <ChartWrap title="可视化:指标卡" type="9" buttons={<ButtonModal title="新建指标卡" type="9" />}></ChartWrap> return <ChartWrap title="可视化:指标卡" type="9"></ChartWrap>
} }
import { lazy } from 'react'
import ChartWrap from '@/components/chart/ChartWrap' import ChartWrap from '@/components/chart/ChartWrap'
const ButtonModal = lazy(() => import('@/components/chart/ChartButtonModal'))
export default function DataProcess() { export default function DataProcess() {
return <ChartWrap title="可视化:折线图" type="2" buttons={<ButtonModal title="新建折线图" type="2" />}></ChartWrap> return <ChartWrap title="可视化:折线图" type="2"></ChartWrap>
} }
import { lazy } from 'react'
import ChartWrap from '@/components/chart/ChartWrap' import ChartWrap from '@/components/chart/ChartWrap'
const ButtonModal = lazy(() => import('@/components/chart/ChartButtonModal'))
export default function DataProcess() { export default function DataProcess() {
return <ChartWrap title="可视化:地图" type="8" buttons={<ButtonModal title="新建地图" type="8" />}></ChartWrap> return <ChartWrap title="可视化:地图" type="8"></ChartWrap>
} }
import { lazy } from 'react'
import ChartWrap from '@/components/chart/ChartWrap' import ChartWrap from '@/components/chart/ChartWrap'
const ButtonModal = lazy(() => import('@/components/chart/ChartButtonModal'))
export default function DataProcess() { export default function DataProcess() {
return ( return <ChartWrap title="可视化:帕累托图" type="13"></ChartWrap>
<ChartWrap title="可视化:帕累托图" type="13" buttons={<ButtonModal title="新建帕累托图" type="13" />}></ChartWrap>
)
} }
import { lazy } from 'react'
import ChartWrap from '@/components/chart/ChartWrap' import ChartWrap from '@/components/chart/ChartWrap'
const ButtonModal = lazy(() => import('@/components/chart/ChartButtonModal'))
export default function DataProcess() { export default function DataProcess() {
return <ChartWrap title="可视化:饼状图" type="3" buttons={<ButtonModal title="新建饼状图" type="3" />}></ChartWrap> return <ChartWrap title="可视化:饼状图" type="3"></ChartWrap>
} }
import { lazy } from 'react'
import ChartWrap from '@/components/chart/ChartWrap' import ChartWrap from '@/components/chart/ChartWrap'
const ButtonModal = lazy(() => import('@/components/chart/ChartButtonModal'))
export default function DataProcess() { export default function DataProcess() {
return <ChartWrap title="可视化:散点图" type="5" buttons={<ButtonModal title="新建散点图" type="5" />}></ChartWrap> return <ChartWrap title="可视化:散点图" type="5"></ChartWrap>
} }
import { lazy } from 'react'
import ChartWrap from '@/components/chart/ChartWrap' import ChartWrap from '@/components/chart/ChartWrap'
const ButtonModal = lazy(() => import('@/components/chart/ChartButtonModal'))
export default function DataProcess() { export default function DataProcess() {
return <ChartWrap title="可视化:雷达图" type="4" buttons={<ButtonModal title="新建雷达图" type="4" />}></ChartWrap> return <ChartWrap title="可视化:雷达图" type="4"></ChartWrap>
} }
import { lazy } from 'react'
import ChartWrap from '@/components/chart/ChartWrap' import ChartWrap from '@/components/chart/ChartWrap'
const ButtonModal = lazy(() => import('@/components/chart/ChartButtonModal'))
export default function DataProcess() { export default function DataProcess() {
return <ChartWrap title="可视化:表格" type="12" buttons={<ButtonModal title="新建表格" type="12" />}></ChartWrap> return <ChartWrap title="可视化:表格" type="12"></ChartWrap>
} }
import { lazy } from 'react'
import ChartWrap from '@/components/chart/ChartWrap' import ChartWrap from '@/components/chart/ChartWrap'
const ButtonModal = lazy(() => import('@/components/chart/ChartButtonModal'))
export default function DataProcess() { export default function DataProcess() {
return ( return <ChartWrap title="可视化:矩形树图" type="14"></ChartWrap>
<ChartWrap title="可视化:矩形树图" type="14" buttons={<ButtonModal title="新建矩形树图" type="14" />}></ChartWrap>
)
} }
import { lazy } from 'react'
import ChartWrap from '@/components/chart/ChartWrap' import ChartWrap from '@/components/chart/ChartWrap'
const ButtonModal = lazy(() => import('@/components/chart/ChartButtonModal'))
export default function DataProcess() { export default function DataProcess() {
return <ChartWrap title="可视化:词云" type="7" buttons={<ButtonModal title="新建词云" type="7" />}></ChartWrap> return <ChartWrap title="可视化:词云" type="7"></ChartWrap>
} }
import { useMutation, useQueryClient } from '@tanstack/react-query' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { createLargeScreen, deleteLargeScreen } from './api' import { createLargeScreen, deleteLargeScreen, getLargeScreen, updateLargeScreen } from './api'
import { message } from 'antd' import { message } from 'antd'
// 创建 // 创建
...@@ -15,6 +15,18 @@ export function useCreateLargeScreen() { ...@@ -15,6 +15,18 @@ export function useCreateLargeScreen() {
}) })
} }
// 更新
export function useUpdateLargeScreen() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: (data: { id: string; name: string; type: string; content: string }) => updateLargeScreen(data),
onSuccess: () => {
message.success('更新成功')
queryClient.invalidateQueries({ queryKey: ['largeScreenList'] })
},
})
}
// 删除 // 删除
export function useDeleteLargeScreen() { export function useDeleteLargeScreen() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
...@@ -27,3 +39,13 @@ export function useDeleteLargeScreen() { ...@@ -27,3 +39,13 @@ export function useDeleteLargeScreen() {
}, },
}) })
} }
export function useViewLargeScreen(id: string) {
return useQuery({
queryKey: ['largeScreen', id],
queryFn: () => getLargeScreen({ id }),
select: (res) => res.data,
enabled: !!id,
staleTime: 0,
})
}
import { lazy } from 'react'
import type { RouteObject } from 'react-router'
export const routes: RouteObject[] = [
{
path: '/data/screen/view/:id',
Component: lazy(() => import('./views/View')),
},
]
...@@ -4,6 +4,7 @@ import ViewDataButtonModal from '@/components/data/ViewMyDataButtonModal' ...@@ -4,6 +4,7 @@ import ViewDataButtonModal from '@/components/data/ViewMyDataButtonModal'
import ButtonModal from '../components/ButtonModal' import ButtonModal from '../components/ButtonModal'
import { getLargeScreenList } from '../api' import { getLargeScreenList } from '../api'
import { useDeleteLargeScreen } from '../query' import { useDeleteLargeScreen } from '../query'
import { Link } from 'react-router'
export default function DataWrap() { export default function DataWrap() {
const { mutate } = useDeleteLargeScreen() const { mutate } = useDeleteLargeScreen()
...@@ -39,12 +40,12 @@ export default function DataWrap() { ...@@ -39,12 +40,12 @@ export default function DataWrap() {
render(_value, record) { render(_value, record) {
return ( return (
<> <>
<Link to={`/data/screen/view/${record.id}`} target="_blank">
<Button color="primary" variant="text"> <Button color="primary" variant="text">
查看 查看
</Button> </Button>
<Button color="primary" variant="text"> </Link>
编辑 <ButtonModal id={record.id}></ButtonModal>
</Button>
<Button color="danger" variant="text" onClick={() => handleRemove(record)}> <Button color="danger" variant="text" onClick={() => handleRemove(record)}>
删除 删除
</Button> </Button>
...@@ -56,7 +57,7 @@ export default function DataWrap() { ...@@ -56,7 +57,7 @@ export default function DataWrap() {
} }
return ( return (
<Flex gap={20} style={{ height: '100%' }}> <Flex gap={20} style={{ height: '100%' }}>
<Card className="app-card" style={{ flex: 1, overflowX: 'hidden' }}> <Card className="app-card" title="数据可视化大屏" style={{ flex: 1, overflowX: 'hidden' }}>
<Flex justify="space-between" style={{ marginBottom: '20px' }}> <Flex justify="space-between" style={{ marginBottom: '20px' }}>
<Flex wrap gap={10}> <Flex wrap gap={10}>
<ButtonModal></ButtonModal> <ButtonModal></ButtonModal>
......
import { useParams } from 'react-router'
import { useViewLargeScreen } from '../query'
import Chart from '@/components/chart/Chart'
import { Card } from 'antd'
export default function LargeScreenView() {
const { id } = useParams()
const { data } = useViewLargeScreen(id || '')
if (!data) return null
const components = data.component.map((item: any) => {
try {
const { config } = JSON.parse(item.content)
return { ...item, config }
} catch (error) {
console.log(error)
}
return item
})
try {
const { form } = JSON.parse(data.content)
const getBackground = () => {
switch (form.bg) {
case 'default':
return '#f0f2f5'
case 'color':
return form.bgColor || '#ffffff'
case 'image':
return form.bgImage ? `url(${form.bgImage?.url})` : '#ffffff'
default:
return '#ffffff'
}
}
return (
<div
style={{
width: '100vw',
minHeight: '100%',
background: getBackground(),
backgroundSize: form.bg === 'image' ? 'cover' : 'auto',
backgroundPosition: form.bg === 'image' ? 'center' : 'auto',
}}>
<div style={{ padding: 20 }}>
<h2
style={{
fontSize: `${form.titleStyle.fontSize}px`,
color: form.titleStyle.color,
fontWeight: form.titleStyle.bold ? 'bold' : 'normal',
fontStyle: form.titleStyle.italic ? 'italic' : 'normal',
textAlign: form.titleStyle.align,
marginBottom: '20px',
}}>
{form.title}
</h2>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(400px, 1fr))', gap: '20px' }}>
{components.map((item: any) => (
<Card title={item.name} key={item.id}>
<Chart type={item.type} {...item.config} />
</Card>
))}
</div>
</div>
</div>
)
} catch (e) {
console.error('解析数据失败:', e)
return null
}
}
export const CHART_TYPE = {
1: '柱状图',
2: '折线图',
3: '饼状图',
4: '雷达图',
5: '散点图',
6: '气泡图',
7: '词云',
8: '地图',
9: '指标卡',
10: '漏斗图',
11: '直方图',
12: '表格',
13: '帕累托图',
14: '矩形树图',
}
export const CHART_TYPE_OPTIONS = Object.entries(CHART_TYPE).map(([key, value]) => ({
label: value,
value: key,
}))
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论