提交 5dfaf713 authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 d0308fdc
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
"antd": "^5.24.3", "antd": "^5.24.3",
"axios": "^1.8.1", "axios": "^1.8.1",
"blueimp-md5": "^2.19.0", "blueimp-md5": "^2.19.0",
"lodash-es": "^4.17.21",
"lucide-react": "^0.477.0", "lucide-react": "^0.477.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
...@@ -25,6 +26,7 @@ ...@@ -25,6 +26,7 @@
}, },
"devDependencies": { "devDependencies": {
"@types/blueimp-md5": "^2.18.2", "@types/blueimp-md5": "^2.18.2",
"@types/lodash-es": "^4.17.12",
"@types/node": "^22.13.9", "@types/node": "^22.13.9",
"@types/react": "^18.2.66", "@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22", "@types/react-dom": "^18.2.22",
...@@ -1468,6 +1470,23 @@ ...@@ -1468,6 +1470,23 @@
"@types/unist": "*" "@types/unist": "*"
} }
}, },
"node_modules/@types/lodash": {
"version": "4.17.16",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.16.tgz",
"integrity": "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/lodash-es": {
"version": "4.17.12",
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
"integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/lodash": "*"
}
},
"node_modules/@types/mdast": { "node_modules/@types/mdast": {
"version": "4.0.4", "version": "4.0.4",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
...@@ -3284,6 +3303,12 @@ ...@@ -3284,6 +3303,12 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
"license": "MIT"
},
"node_modules/lodash.merge": { "node_modules/lodash.merge": {
"version": "4.6.2", "version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
"antd": "^5.24.3", "antd": "^5.24.3",
"axios": "^1.8.1", "axios": "^1.8.1",
"blueimp-md5": "^2.19.0", "blueimp-md5": "^2.19.0",
"lodash-es": "^4.17.21",
"lucide-react": "^0.477.0", "lucide-react": "^0.477.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
...@@ -27,6 +28,7 @@ ...@@ -27,6 +28,7 @@
}, },
"devDependencies": { "devDependencies": {
"@types/blueimp-md5": "^2.18.2", "@types/blueimp-md5": "^2.18.2",
"@types/lodash-es": "^4.17.12",
"@types/node": "^22.13.9", "@types/node": "^22.13.9",
"@types/react": "^18.2.66", "@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22", "@types/react-dom": "^18.2.22",
......
...@@ -33,3 +33,13 @@ export async function uploadFile(data: Record<string, any>) { ...@@ -33,3 +33,13 @@ export async function uploadFile(data: Record<string, any>) {
export function getMapList() { export function getMapList() {
return httpRequest.get('/api/resource/v1/util/get-data-dictionary-list') return httpRequest.get('/api/resource/v1/util/get-data-dictionary-list')
} }
// 我的数据集列表
export function getMyList(params?: Partial<{ page: number; 'per-page': number }>) {
return httpRequest.get('/api/bi/v1/data/my/list', { params })
}
// 查看字段详情
export function getMyField() {
return httpRequest.get('/api/bi/v1/data/my/field-detail')
}
...@@ -20,80 +20,80 @@ export interface AppListRef { ...@@ -20,80 +20,80 @@ export interface AppListRef {
reset: () => void reset: () => void
} }
const AppList = forwardRef<AppListRef, AppListProps>((props, ref) => { const AppList = forwardRef<AppListRef, AppListProps>(
const { fetchApi, filters = [], filterAside, dataSource = [], ...rest } = props ({ fetchApi, filters = [], filterAside, dataSource = [], ...props }, ref) => {
const [form] = Form.useForm()
const [queryParams, setQueryParams] = useState<QueryParams>({ page: 1, 'per-page': 10 })
const [form] = Form.useForm() const { data, refetch, isLoading } = useQuery({
const [queryParams, setQueryParams] = useState<QueryParams>({ page: 1, 'per-page': 10 }) queryKey: ['appList', queryParams],
queryFn: async () => {
return fetchApi ? await fetchApi(queryParams) : { list: dataSource || [], total: dataSource?.length || 0 }
},
})
const { data, refetch, isLoading } = useQuery({ // 暴露方法
queryKey: ['appList', queryParams], useImperativeHandle(ref, () => ({
queryFn: async () => { refresh: refetch,
return fetchApi ? await fetchApi(queryParams) : { list: dataSource || [], total: dataSource?.length || 0 } reset: handleReset,
}, }))
})
// 暴露方法 // 提交筛选
useImperativeHandle(ref, () => ({ const handleSearch = (values: Record<string, any>) => {
refresh: refetch, console.log(values)
reset: handleReset, setQueryParams((prev) => ({ ...prev, ...values, page: 1 }))
})) }
// 提交筛选 const handleReset = () => {
const handleSearch = (values: Record<string, any>) => { form.resetFields()
console.log(values) setQueryParams({ page: 1, 'per-page': 10 })
setQueryParams((prev) => ({ ...prev, ...values, page: 1 })) }
}
const handleReset = () => { // 处理分页
form.resetFields() const handlePageChange = (page: number, pageSize: number) => {
setQueryParams({ page: 1, 'per-page': 10 }) setQueryParams((prev) => ({ ...prev, page, 'per-page': pageSize }))
} }
// 处理分页 const pagination = {
const handlePageChange = (page: number, pageSize: number) => { showSizeChanger: true,
setQueryParams((prev) => ({ ...prev, page, 'per-page': pageSize })) showQuickJumper: true,
} pageSizeOptions: [10, 20, 30, 40, 50],
showTotal: (total: number) => `共${total}条数据`,
onChange: handlePageChange,
}
const pagination = { const filterElement = (
showSizeChanger: true, <div className="app-list-filter" style={{ marginBottom: 20 }}>
showQuickJumper: true, <Flex justify="space-between">
pageSizeOptions: [10, 20, 30, 40, 50], <Form layout="inline" autoComplete="off" form={form} onFinish={handleSearch}>
showTotal: (total: number) => `共${total}条数据`, {filters.map((item, index) => (
onChange: handlePageChange, <Form.Item label={item.label} name={item.name} key={index}>
} {item.element}
</Form.Item>
const filterElement = ( ))}
<div className="app-list-filter" style={{ marginBottom: 20 }}> <Space>
<Flex justify="space-between"> <Button type="primary" htmlType="button" ghost onClick={handleReset}>
<Form layout="inline" autoComplete="off" form={form} onFinish={handleSearch}> 重置
{filters.map((item, index) => ( </Button>
<Form.Item label={item.label} name={item.name} key={index}> <Button type="primary" htmlType="submit">
{item.element} 查询
</Form.Item> </Button>
))} </Space>
<Space> </Form>
<Button type="primary" htmlType="button" ghost onClick={handleReset}> {filterAside}
重置 </Flex>
</Button> </div>
<Button type="primary" htmlType="submit"> )
查询
</Button>
</Space>
</Form>
{filterAside}
</Flex>
</div>
)
return ( return (
<div className="app-list"> <div className="app-list">
{filters.length > 0 && filterElement} {filters.length > 0 && filterElement}
<div className="app-list-table"> <div className="app-list-table">
<Table rowKey="id" dataSource={data?.list} loading={isLoading} pagination={pagination} {...rest} /> <Table bordered rowKey="id" dataSource={data?.list} loading={isLoading} pagination={pagination} {...props} />
</div>
</div> </div>
</div> )
) }
}) )
export default AppList export default AppList
import { Table, TableProps } from 'antd' import { Table, TableProps } from 'antd'
export default function DataRender(props: TableProps) { export default function DataRender({ pagination = {}, ...props }: TableProps) {
const pagination = {
showSizeChanger: true,
pageSize: 100,
pageSizeOptions: [100, 200, 500],
showTotal: (total: number) => `共${total}条数据`,
}
return ( return (
<Table <Table
bordered bordered
scroll={{ x: 'max-content', y: 600 }} scroll={{ x: 'max-content', y: 800 }}
tableLayout="auto" tableLayout="auto"
size="middle" size="middle"
pagination={pagination} pagination={{
hideOnSinglePage: true,
showSizeChanger: true,
defaultPageSize: 100,
pageSizeOptions: [100, 200, 500],
showTotal: (total: number) => `共${total}条数据`,
...pagination,
}}
{...props} {...props}
/> />
) )
......
import { Button, Card, Flex } from 'antd' import { lazy, ReactNode, useState } from 'react'
import { Card, Flex } from 'antd'
import AIChat from '@/components/ai/AIChat' import AIChat from '@/components/ai/AIChat'
import ViewData from './ViewData' import DataRender from './DataRender'
import { ReactNode } from 'react' import { useDataQuery } from '@/hooks/useQuery'
export default function DataWrap({ title, buttons }: { title: string; buttons: ReactNode }) { const ViewDataFiledButtonModal = lazy(() => import('./ViewDataFiledButtonModal'))
export default function DataWrap({
hasAI = true,
title,
headerRender,
buttons,
empty,
}: {
title: string
buttons?: ReactNode
headerRender?: (data: any) => ReactNode
empty?: ReactNode
hasAI: boolean
}) {
const [pagination, setPagination] = useState({ page: 1, 'per-page': 100 })
const { data, isPending } = useDataQuery(pagination)
const columns: any = data.title.map((item: any) => {
return {
title: item.name,
dataIndex: item.english_name,
align: 'center',
minWidth: 120,
}
})
const handleTableChange = (pagination: any) => {
setPagination({ page: pagination.current, 'per-page': pagination.pageSize })
}
const Header = () => {
if (headerRender) return headerRender(data)
return (
<Flex justify="space-between" style={{ marginBottom: '20px' }}>
<Flex wrap gap={10}>
{buttons}
</Flex>
<ViewDataFiledButtonModal></ViewDataFiledButtonModal>
</Flex>
)
}
return ( return (
<Flex gap={20} style={{ height: '100%' }}> <Flex gap={20} style={{ height: '100%' }}>
<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' }}> {empty && !data.info ? (
<Flex wrap gap={10}> empty
{buttons} ) : (
</Flex> <>
<Button>查看字段详细信息</Button> <Header />
</Flex> <DataRender
<ViewData /> rowKey={'pk_id'}
loading={isPending}
dataSource={data.list}
pagination={{ total: data.total, current: pagination.page, pageSize: pagination['per-page'] }}
columns={columns}
onChange={handleTableChange}
/>
</>
)}
</Card> </Card>
<AIChat></AIChat> {hasAI && <AIChat />}
</Flex> </Flex>
) )
} }
差异被折叠。
import { useEffect, useState } from 'react'
import { Button, Flex, Modal } from 'antd'
import axios from 'axios'
import DataRender from './DataRender'
import { read, utils } from 'xlsx'
import { uniqueId } from 'lodash-es'
export default function ViewDataButtonModal({ data }: { data: any }) {
const [open, setOpen] = useState(false)
const [dataset, setDataset] = useState<any[]>([])
const [isLoading, setIsLoading] = useState(false)
useEffect(() => {
const workbook = async () => {
setIsLoading(true)
try {
const file = JSON.parse(data.file)
const res = await axios(file.url, { responseType: 'arraybuffer' })
const workbook = read(res.data)
const sheetName = workbook.SheetNames[0]
const worksheet = workbook.Sheets[sheetName]
const jsonData = utils.sheet_to_json(worksheet)
setDataset(jsonData)
} catch (error) {
console.error(error)
}
setIsLoading(false)
}
if (open) workbook()
}, [open, data])
const columns: any =
dataset.length > 0
? Object.keys(dataset[0]).map((key) => ({
title: key,
dataIndex: key,
align: 'center',
}))
: []
const dataSource = dataset.map((item) => ({ ...item, pk_id: uniqueId() }))
return (
<>
<Button color="primary" variant="text" onClick={() => setOpen(true)}>
查阅
</Button>
<Modal title="查阅数据集" width={'80%'} open={open} footer={null} onCancel={() => setOpen(false)}>
<Flex justify="space-between" style={{ marginBottom: 20 }}>
<div>数据集名称:{data.name}</div>
<div>共计:{data.number}条数据</div>
</Flex>
<DataRender rowKey={'pk_id'} dataSource={dataSource} columns={columns} loading={isLoading}></DataRender>
</Modal>
</>
)
}
import { useState } from 'react'
import { Button, Modal } from 'antd'
import { useDataFieldQuery } from '@/hooks/useQuery'
import AppList, { AppListProps } from '@/components/AppList'
export default function ViewDataFiledButtonModal({ children }: { children?: string }) {
const [open, setOpen] = useState(false)
const { data } = useDataFieldQuery()
const listOptions: AppListProps = {
columns: [
{
title: '序号',
key: 'index',
render(_value, _record, index) {
return index + 1
},
width: 62,
align: 'center',
},
{ title: '字段名称', dataIndex: 'english_name', align: 'center' },
{ title: '字段类型', dataIndex: 'type_name', align: 'center' },
{ title: '长度', dataIndex: 'length', align: 'center' },
{ title: '小数点', dataIndex: 'point', align: 'center' },
{ title: '是否允许为空', dataIndex: 'null', align: 'center' },
{ title: '默认值', dataIndex: 'default', align: 'center' },
{ title: '备注', dataIndex: 'name', align: 'center' },
],
dataSource: data || [],
}
return (
<>
<Button onClick={() => setOpen(true)}>{children ? children : '查看字段详细信息'}</Button>
<Modal title="查看字段详细信息" width={1000} open={open} footer={null} onCancel={() => setOpen(false)}>
<AppList rowKey="english_name" pagination={false} {...listOptions}></AppList>
</Modal>
</>
)
}
差异被折叠。
.app-header { .app-header {
position: sticky; position: sticky;
top: 0; top: 0;
z-index: 2001; z-index: 100;
padding: 0 20px; padding: 0 20px;
display: flex; display: flex;
align-items: center; align-items: center;
......
import { useEffect } from 'react' import { useEffect } from 'react'
import { useQuery } from '@tanstack/react-query' import { useQuery, keepPreviousData } from '@tanstack/react-query'
import { getUser, getMapList } from '@/api/base' import { getUser, getMapList, getMyList, getMyField } from '@/api/base'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { useMapStore } from '@/stores/map' import { useMapStore } from '@/stores/map'
...@@ -31,3 +31,27 @@ export function useMapQuery() { ...@@ -31,3 +31,27 @@ export function useMapQuery() {
return query return query
} }
// 我的数据集
export function useDataQuery(params?: Partial<{ page: number; 'per-page': number }>) {
const query = useQuery({
queryKey: ['data', params],
queryFn: () => {
return getMyList(params)
},
select: (res) => res.data,
initialData: (): any => {
return { data: { total: 0, list: [], title: [] } }
},
placeholderData: keepPreviousData,
})
return query
}
// 查看字段详情
export function useDataFieldQuery() {
const query = useQuery({ queryKey: ['data-filed'], queryFn: getMyField, select: (res) => res.data })
return query
}
...@@ -4,7 +4,7 @@ import AppUpload from '@/components/AppUpload' ...@@ -4,7 +4,7 @@ import AppUpload from '@/components/AppUpload'
import { useCreateDataset } from '../query' import { useCreateDataset } from '../query'
import { useState } from 'react' import { useState } from 'react'
export default function FormButtonModal({ title, children }: { title: string; children?: React.ReactNode }) { export default function FormButtonModal({ title = '添加数据集' }: { title?: string }) {
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const [form] = Form.useForm() const [form] = Form.useForm()
...@@ -27,13 +27,9 @@ export default function FormButtonModal({ title, children }: { title: string; ch ...@@ -27,13 +27,9 @@ export default function FormButtonModal({ title, children }: { title: string; ch
return ( return (
<> <>
{children ? ( <Button type="primary" onClick={() => setOpen(true)}>
children {title}
) : ( </Button>
<Button type="primary" onClick={() => setOpen(true)}>
{title}
</Button>
)}
<Modal <Modal
title={title} title={title}
open={open} open={open}
......
import { lazy, useState } from 'react' import { lazy } from 'react'
import { Button, Card, Input, Select } from 'antd' import { Button, Card, Input, Select } from 'antd'
import AppList, { AppListProps } from '@/components/AppList' import AppList, { AppListProps } from '@/components/AppList'
import { useMapStore } from '@/stores/map' import { useMapStore } from '@/stores/map'
...@@ -6,19 +6,12 @@ import { getDatasetList } from '../api' ...@@ -6,19 +6,12 @@ import { getDatasetList } from '../api'
import { useDeleteDataset } from '../query' import { useDeleteDataset } from '../query'
const FormButtonModal = lazy(() => import('../components/FormButtonModal')) const FormButtonModal = lazy(() => import('../components/FormButtonModal'))
const ViewDataModal = lazy(() => import('@/components/data/ViewDataModal')) const ViewDataButtonModal = lazy(() => import('@/components/data/ViewDataButtonModal'))
export default function DataWriteBuilt() { export default function DataWriteBuilt() {
const getMapValuesByKey = useMapStore((state) => state.getMapValuesByKey) const getMapValuesByKey = useMapStore((state) => state.getMapValuesByKey)
const industryList = getMapValuesByKey('bi_data_industry') const industryList = getMapValuesByKey('bi_data_industry')
const [viewModalIsOpen, setViewModalIsOpen] = useState(false)
const handleView = (record: any) => {
console.log(record)
setViewModalIsOpen(true)
}
const { mutate } = useDeleteDataset() const { mutate } = useDeleteDataset()
const handleRemove = (record: any) => { const handleRemove = (record: any) => {
mutate({ id: record.id }) mutate({ id: record.id })
...@@ -67,9 +60,7 @@ export default function DataWriteBuilt() { ...@@ -67,9 +60,7 @@ export default function DataWriteBuilt() {
render(_value, record) { render(_value, record) {
return ( return (
<> <>
<Button color="primary" variant="text" onClick={() => handleView(record)}> <ViewDataButtonModal data={record}></ViewDataButtonModal>
查阅
</Button>
<Button color="danger" variant="text" onClick={() => handleRemove(record)}> <Button color="danger" variant="text" onClick={() => handleRemove(record)}>
删除 删除
</Button> </Button>
...@@ -82,8 +73,6 @@ export default function DataWriteBuilt() { ...@@ -82,8 +73,6 @@ export default function DataWriteBuilt() {
return ( return (
<Card className="app-card" title="内置数据集管理"> <Card className="app-card" title="内置数据集管理">
<AppList bordered {...listOptions} filterAside={<FormButtonModal title="添加数据集"></FormButtonModal>}></AppList> <AppList bordered {...listOptions} filterAside={<FormButtonModal title="添加数据集"></FormButtonModal>}></AppList>
<ViewDataModal open={viewModalIsOpen} onCancel={() => setViewModalIsOpen(false)}></ViewDataModal>
</Card> </Card>
) )
} }
...@@ -14,3 +14,8 @@ export function getDatasetList( ...@@ -14,3 +14,8 @@ export function getDatasetList(
) { ) {
return httpRequest.get('/api/bi/v1/data/built-in/list', { params }) return httpRequest.get('/api/bi/v1/data/built-in/list', { params })
} }
// 复制数据集
export function copyDataset(data: { id: string; name: string; force: string }) {
return httpRequest.post('/api/bi/v1/data/my/copy-built-in', data)
}
import { Button, Form, Input, Modal } from 'antd'
import { useState } from 'react'
import { useCopyDataset } from '../query'
export default function CopyButtonModal({ children, data }: { children?: string; data: any }) {
const [open, setOpen] = useState(false)
const [form] = Form.useForm()
const { mutate, isPending } = useCopyDataset()
const handleOk = () => {
form.validateFields().then((values) => {
const params = { id: data.id, force: '1', ...values }
mutate(params, {
onSuccess: () => setOpen(false),
})
})
}
return (
<>
<Button color="primary" variant="text" onClick={() => setOpen(true)}>
{children ? children : '复制'}
</Button>
<Modal
title="复制数据集"
open={open}
onOk={handleOk}
onCancel={() => setOpen(false)}
confirmLoading={isPending}
okText="复制"
destroyOnClose>
<Form form={form} labelCol={{ span: 5 }} preserve={false}>
<Form.Item label="数据集名称" name="name">
<Input placeholder="请输入" />
</Form.Item>
<Form.Item label="原始数据集">{data.name}</Form.Item>
<Form.Item label="数据量">{data.number}</Form.Item>
<Form.Item label="所属行业">{data.industry_name}</Form.Item>
<Form.Item label="数据来源">{data.source_name}</Form.Item>
<Form.Item label="敏感等级">{data.sensitivity_level_name}</Form.Item>
<Form.Item label="访问权限">{data.access_permissions_name}</Form.Item>
<Form.Item label="创建人">{data.created_operator_name}</Form.Item>
<Form.Item label="创建时间">{data.created_time}</Form.Item>
<Form.Item label="更新时间">{data.updated_time}</Form.Item>
</Form>
</Modal>
</>
)
}
import { Form, Input, Modal } from 'antd'
export default function FormModal(props) {
return (
<Modal title="复制数据集" destroyOnClose {...props}>
<Form labelCol={{ span: 4 }} preserve={false}>
<Form.Item label="数据集名称" name="name">
<Input placeholder="请输入" />
</Form.Item>
<Form.Item label="原始数据集">电子商务案例数据集</Form.Item>
<Form.Item label="数据量">2000</Form.Item>
<Form.Item label="所属行业">电子商务</Form.Item>
<Form.Item label="数据来源">案例数据</Form.Item>
<Form.Item label="敏感等级">L1一般敏感</Form.Item>
<Form.Item label="访问权限">完全开放</Form.Item>
<Form.Item label="创建人">张三疯</Form.Item>
<Form.Item label="创建时间">2024-12-12 13:13:13</Form.Item>
<Form.Item label="更新时间">2024-12-12 13:13:13</Form.Item>
</Form>
</Modal>
)
}
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { copyDataset } from './api'
import { message } from 'antd'
// 复制
export function useCopyDataset() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: (data: { id: string; name: string; force: string }) => copyDataset(data),
onSuccess: () => {
message.success('复制成功')
queryClient.invalidateQueries({ queryKey: ['data'] })
},
})
}
import { Button, Card, Input, Select } from 'antd' import { lazy } from 'react'
import { Card, Input, Select } from 'antd'
import AppList, { AppListProps } from '@/components/AppList' import AppList, { AppListProps } from '@/components/AppList'
import { useMapStore } from '@/stores/map' import { useMapStore } from '@/stores/map'
import { lazy, useState } from 'react'
import { getDatasetList } from '../api' import { getDatasetList } from '../api'
const CopyModal = lazy(() => import('../components/CopyModal')) const CopyButtonModal = lazy(() => import('../components/CopyButtonModal'))
const ViewDataModal = lazy(() => import('@/components/data/ViewDataModal')) const ViewDataButtonModal = lazy(() => import('@/components/data/ViewDataButtonModal'))
export default function DataWriteCopy() { export default function DataWriteCopy() {
const getMapValuesByKey = useMapStore((state) => state.getMapValuesByKey) const getMapValuesByKey = useMapStore((state) => state.getMapValuesByKey)
const industryList = getMapValuesByKey('bi_data_industry') const industryList = getMapValuesByKey('bi_data_industry')
const [viewModalIsOpen, setViewModalIsOpen] = useState(false)
const handleView = (record: any) => {
console.log(record)
setViewModalIsOpen(true)
}
const [copyModalIsOpen, setCopyModalIsOpen] = useState(false)
const handleCopy = (record: any) => {
console.log(record)
setCopyModalIsOpen(true)
}
const listOptions: AppListProps = { const listOptions: AppListProps = {
fetchApi: async (params) => { fetchApi: async (params) => {
const { data } = await getDatasetList({ ...params, access_permissions: '1' }) const { data } = await getDatasetList({ ...params, access_permissions: '1' })
...@@ -67,12 +54,8 @@ export default function DataWriteCopy() { ...@@ -67,12 +54,8 @@ export default function DataWriteCopy() {
render(_value, record) { render(_value, record) {
return ( return (
<> <>
<Button color="primary" variant="text" onClick={() => handleView(record)}> <ViewDataButtonModal data={record}></ViewDataButtonModal>
查阅 <CopyButtonModal data={record}></CopyButtonModal>
</Button>
<Button color="primary" variant="text" onClick={() => handleCopy(record)}>
复制
</Button>
</> </>
) )
}, },
...@@ -82,8 +65,6 @@ export default function DataWriteCopy() { ...@@ -82,8 +65,6 @@ export default function DataWriteCopy() {
return ( return (
<Card className="app-card" title="数据复制"> <Card className="app-card" title="数据复制">
<AppList bordered {...listOptions}></AppList> <AppList bordered {...listOptions}></AppList>
<CopyModal open={copyModalIsOpen} onCancel={() => setCopyModalIsOpen(false)}></CopyModal>
<ViewDataModal open={viewModalIsOpen} onCancel={() => setViewModalIsOpen(false)}></ViewDataModal>
</Card> </Card>
) )
} }
import { Button, Card, Empty, Flex, Space } from 'antd'
import { Link } from 'react-router' import { Link } from 'react-router'
import { Button, Empty, Flex, Space } from 'antd'
import DataWrap from '@/components/data/DataWrap'
export default function DataWriteMy() { // 无数据渲染
const isEmpty = true const EmptyRender = () => {
// 无数据渲染
const emptyRender = () => {
return (
<>
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="无数据"></Empty>
<Flex justify="center" align="middle">
<Space>
<Link to="/data/write/copy">
<Button type="primary">复制数据</Button>
</Link>
<Link to="/data/write/upload">
<Button type="primary">导入数据</Button>
</Link>
<Button type="primary" disabled>
爬取数据
</Button>
<Button type="primary" disabled>
本地数据库连接
</Button>
<Button type="primary" disabled>
API数据获取
</Button>
</Space>
</Flex>
</>
)
}
return ( return (
<Card className="app-card" title="我的数据集"> <>
<Flex justify="space-between" align="middle"> <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="无数据"></Empty>
<h4>数据集名称:电子商务案例分析数据集</h4> <Flex justify="center" align="middle">
<Button type="primary" disabled={isEmpty}> <Space>
数据质量分析报告 <Link to="/data/write/copy">
</Button> <Button type="primary">复制数据</Button>
</Link>
<Link to="/data/write/upload">
<Button type="primary">导入数据</Button>
</Link>
<Button type="primary" disabled>
爬取数据
</Button>
<Button type="primary" disabled>
本地数据库连接
</Button>
<Button type="primary" disabled>
API数据获取
</Button>
</Space>
</Flex> </Flex>
{!isEmpty && ( </>
<Flex justify="space-between" align="middle"> )
<p>《商务数据分析基础》数据集-电子商务2025.xlsx</p> }
<p>共计:1000条数据</p>
export default function DataWriteMy() {
return (
<DataWrap
title="我的数据集"
hasAI={false}
headerRender={(data) => (
<Flex justify="space-between" align="middle" style={{ marginBottom: '20px' }}>
<h4>数据集名称:{data.info.name}</h4>
<Button type="primary">数据质量分析报告</Button>
</Flex> </Flex>
)} )}
{isEmpty && emptyRender()} empty={<EmptyRender />}></DataWrap>
</Card>
) )
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论