Browse Source

feat: 数据集管理和模型管理添加版本描述

pull/14/head
cp3hnu 1 year ago
parent
commit
16804b6985
9 changed files with 1236 additions and 1083 deletions
  1. +2
    -2
      react-ui/config/defaultSettings.ts
  2. +284
    -192
      react-ui/src/pages/Dataset/datasetIntro.jsx
  3. +271
    -277
      react-ui/src/pages/Dataset/index.less
  4. +43
    -53
      react-ui/src/pages/Model/index.jsx
  5. +269
    -272
      react-ui/src/pages/Model/index.less
  6. +88
    -39
      react-ui/src/pages/Model/modelIntro.jsx
  7. +269
    -247
      react-ui/src/pages/Pipeline/index.jsx
  8. +2
    -1
      react-ui/src/requestConfig.ts
  9. +8
    -0
      react-ui/src/styles/theme.less

+ 2
- 2
react-ui/config/defaultSettings.ts View File

@@ -9,7 +9,7 @@ const Settings: ProLayoutProps & {
} = { } = {
navTheme: 'light', navTheme: 'light',
// 拂晓蓝 // 拂晓蓝
colorPrimary: '#1890ff',
colorPrimary: '#1664ff',
layout: 'mix', layout: 'mix',
contentWidth: 'Fluid', contentWidth: 'Fluid',
fixedHeader: false, fixedHeader: false,
@@ -19,7 +19,7 @@ const Settings: ProLayoutProps & {
title: '复杂智能软件', title: '复杂智能软件',
pwa: true, pwa: true,
logo: '/assets/images/left-top-logo.png', logo: '/assets/images/left-top-logo.png',
iconfontUrl: '',
iconfontUrl: '',
token: { token: {
// 参见ts声明,demo 见文档,通过token 修改样式 // 参见ts声明,demo 见文档,通过token 修改样式
//https://procomponents.ant.design/components/layout#%E9%80%9A%E8%BF%87-token-%E4%BF%AE%E6%94%B9%E6%A0%B7%E5%BC%8F //https://procomponents.ant.design/components/layout#%E9%80%9A%E8%BF%87-token-%E4%BF%AE%E6%94%B9%E6%A0%B7%E5%BC%8F


+ 284
- 192
react-ui/src/pages/Dataset/datasetIntro.jsx View File

@@ -1,88 +1,95 @@

import React ,{useEffect,useState,useRef}from 'react';
import Styles from './index.less'
import { Input, Space ,Button,Tabs,Pagination,Modal, Form,message, Radio,Select,Table,Upload} from 'antd';
import { PlusOutlined,PlusCircleOutlined, DeleteOutlined,UploadOutlined, ExclamationCircleOutlined, DownOutlined, EditOutlined ,CopyOutlined} from '@ant-design/icons';
import {getDatasetList,getDatasetById,getDatasetVersionsById,getDatasetVersionIdList,deleteDatasetVersion,addDatasetVersionDetail,exportDataset} from '@/services/dataset/index.js'
import { useParams } from 'react-router-dom'
import {downLoadZip} from '@/utils/downloadfile'
const { Search } = Input;
import { getAccessToken } from '@/access';
import {
addDatasetVersionDetail,
deleteDatasetVersion,
getDatasetById,
getDatasetVersionIdList,
getDatasetVersionsById,
} from '@/services/dataset/index.js';
import { downLoadZip } from '@/utils/downloadfile';
import {
DeleteOutlined,
DownloadOutlined,
PlusCircleOutlined,
UploadOutlined,
} from '@ant-design/icons';
import { Button, Form, Input, Modal, Select, Table, Tabs, Upload, message } from 'antd';
import moment from 'moment'; import moment from 'moment';
import { getAccessToken } from '@/access';
import { useEffect, useRef, useState } from 'react';
import { useParams } from 'react-router-dom';
import Styles from './index.less';
const { Search } = Input;
const { TabPane } = Tabs; const { TabPane } = Tabs;


const Dataset= React.FC = () => {
const Dataset = () => {
const props = { const props = {
action: '/api/mmp/dataset/upload', action: '/api/mmp/dataset/upload',
// headers: { // headers: {
// 'X-Requested-With': null // 'X-Requested-With': null
// }, // },
headers: { headers: {
Authorization:getAccessToken(),
'X-Requested-With': null
Authorization: getAccessToken(),
'X-Requested-With': null,
}, },
onChange({ file, fileList }) { onChange({ file, fileList }) {
if (file.status !== 'uploading') { if (file.status !== 'uploading') {
console.log(file, fileList); console.log(file, fileList);
setFormList(fileList.map(item=>{
return {
...form.getFieldsValue(),
dataset_id:locationParams.id,
file_name:item.response.data[0].fileName,
file_size:item.response.data[0].fileSize,
url:item.response.data[0].url,
}
}))
setFormList(
fileList.map((item) => {
return {
...form.getFieldsValue(),
dataset_id: locationParams.id,
file_name: item.response.data[0].fileName,
file_size: item.response.data[0].fileSize,
url: item.response.data[0].url,
};
}),
);
} }
}, },
defaultFileList: [
],
defaultFileList: [],
}; };
const [form] = Form.useForm(); const [form] = Form.useForm();
const [formList,setFormList]=useState([])
const [formList, setFormList] = useState([]);
const [dialogTitle, setDialogTitle] = useState('新建版本'); const [dialogTitle, setDialogTitle] = useState('新建版本');
const [isModalOpen,setIsModalOpen]=useState(false)
const [datasetDetailObj,setDatasetDetailObj]=useState({
});
const [version,setVersion]=useState('')
const [isModalOpen, setIsModalOpen] = useState(false);
const [datasetDetailObj, setDatasetDetailObj] = useState({});
const [version, setVersion] = useState('');
const [versionList, setVersionList] = useState([]); const [versionList, setVersionList] = useState([]);
const locationParams =useParams () //新版本获取路由参数接口
console.log(locationParams);
const locationParams = useParams(); //新版本获取路由参数接口
const [wordList, setWordList] = useState([]); const [wordList, setWordList] = useState([]);
const getDatasetByDetail=()=>{
getDatasetById(locationParams.id).then(ret=>{
const [activeTabKey, setActiveTabKey] = useState('1');
const getDatasetByDetail = () => {
getDatasetById(locationParams.id).then((ret) => {
console.log(ret); console.log(ret);
if(ret.code==200){
setDatasetDetailObj(ret.data)
}
})
}
const getDatasetVersionList=()=>{
getDatasetVersionsById(locationParams.id).then(ret=>{
setDatasetDetailObj(ret.data);
});
};
const getDatasetVersionList = () => {
getDatasetVersionsById(locationParams.id).then((ret) => {
console.log(ret); console.log(ret);
if(ret.code==200&&ret.data&&ret.data.length>0){
setVersionList(ret.data.map(item=>{
return {
'label':item,
'value':item
}
}))
if (ret.data && ret.data.length > 0) {
setVersionList(
ret.data.map((item) => {
return {
label: item,
value: item,
};
}),
);
} }
})
}
useEffect(()=>{
getDatasetByDetail()
getDatasetVersionList()
return ()=>{
}
},[])
});
};
useEffect(() => {
getDatasetByDetail();
getDatasetVersionList();
return () => {};
}, []);
const showModal = () => { const showModal = () => {
form.resetFields()
form.setFieldsValue({name:datasetDetailObj.name})
setDialogTitle('创建新版本')
form.resetFields();
form.setFieldsValue({ name: datasetDetailObj.name });
setDialogTitle('创建新版本');
setIsModalOpen(true); setIsModalOpen(true);
}; };
const handleCancel = () => { const handleCancel = () => {
@@ -91,80 +98,74 @@ const Dataset= React.FC = () => {
const handleExport = async () => { const handleExport = async () => {
const hide = message.loading('正在下载'); const hide = message.loading('正在下载');
hide(); hide();
downLoadZip(`/api/mmp/dataset/downloadAllFiles`,{dataset_id:locationParams.id,version})
downLoadZip(`/api/mmp/dataset/downloadAllFiles`, { dataset_id: locationParams.id, version });
}; };
const deleteDataset=()=>{
const deleteDataset = () => {
Modal.confirm({ Modal.confirm({
title: '删除', title: '删除',
content: '确定删除数据集版本?', content: '确定删除数据集版本?',
okText: '确认', okText: '确认',
cancelText: '取消', cancelText: '取消',


onOk: () => {
deleteDatasetVersion({dataset_id:locationParams.id,version}).then(ret=>{
if(ret.code==200){
message.success('删除成功')
getDatasetVersions({version,dataset_id:locationParams.id})
}
else{
message.error(ret.msg)
}
onOk: () => {
deleteDatasetVersion({ dataset_id: locationParams.id, version }).then((ret) => {
message.success('删除成功');
getDatasetVersions({ version, dataset_id: locationParams.id });
}); });
}, },
}); });
}
const onFinish = (values) => {
addDatasetVersionDetail(formList).then(ret=>{
console.log(ret);
getDatasetVersionList()
setIsModalOpen(false);
})
};
const getDatasetVersions=(params)=>{
getDatasetVersionIdList(params).then(ret=>{
};
const onFinish = (values) => {
addDatasetVersionDetail(formList).then((ret) => {
console.log(ret); console.log(ret);
if(ret.code==200){
setWordList(ret.data)
}
})
}
const handleChange=(value)=>{
getDatasetVersionList();
setIsModalOpen(false);
});
};
const getDatasetVersions = (params) => {
getDatasetVersionIdList(params).then((res) => {
setWordList(
res.data.map((v) => ({
...v,
key: v.id,
})),
);
});
};
const handleChange = (value) => {
console.log(value); console.log(value);
if(value){
getDatasetVersions({version:value,dataset_id:locationParams.id})
setVersion(value)
}
else{
setVersion(null)
if (value) {
getDatasetVersions({ version: value, dataset_id: locationParams.id });
setVersion(value);
} else {
setVersion(null);
} }
}
};
const onFinishFailed = (errorInfo) => { const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo); console.log('Failed:', errorInfo);
}; };
const downloadAlone=(e,record)=>{
const downloadAlone = (e, record) => {
console.log(record); console.log(record);
const hide = message.loading('正在下载'); const hide = message.loading('正在下载');
hide(); hide();
downLoadZip(`/api/mmp//dataset/download/${record.id}`)
}
downLoadZip(`/api/mmp/dataset/download/${record.id}`);
};
const columns = [ const columns = [
// {
// title: '序号',
// dataIndex: 'index',
// key: 'index',
// width: 80,
// render(text, record, index) {
// return (
// <span>{(pageOption.current.page - 1) * 10 + index + 1}</span>
// )
// }
// // render: (text, record, index) => `${((curPage-1)*10)+(index+1)}`,
// },
{
title: '序号',
dataIndex: 'index',
key: 'index',
width: 80,
render(text, record, index) {
return <span>{(pageOption.current.page - 1) * 10 + index + 1}</span>;
},
// render: (text, record, index) => `${((curPage-1)*10)+(index+1)}`,
},
{ {
title: '文件名称', title: '文件名称',
dataIndex: 'file_name', dataIndex: 'file_name',
key: 'file_name', key: 'file_name',
render: (text,record) => <a onClick={(e)=>downloadAlone(e,record)}>{text}</a>,
render: (text, record) => <a onClick={(e) => downloadAlone(e, record)}>{text}</a>,
}, },
{ {
title: '版本号', title: '版本号',
@@ -182,80 +183,128 @@ const Dataset= React.FC = () => {
key: 'update_time', key: 'update_time',
render: (text) => <span>{moment(text).format('YYYY-MM-DD HH:mm:ss')}</span>, render: (text) => <span>{moment(text).format('YYYY-MM-DD HH:mm:ss')}</span>,
}, },
{
title: '操作',
dataIndex: 'option',
width: '100px',
key: 'option',
render: (_, record) => [
<Button
type="link"
size="small"
key="download"
icon={<DownloadOutlined />}
onClick={(e) => downloadAlone(e, record)}
>
下载
</Button>,
],
},
]; ];
const pageOption = useRef({page: 1,size: 10})
const pageOption = useRef({ page: 1, size: 10 });


// 当前页面切换 // 当前页面切换
const paginationChange = async (current, size) => { const paginationChange = async (current, size) => {
console.log('page', current, size)
pageOption.current={
page:current,
size:size
}
console.log('page', current, size);
pageOption.current = {
page: current,
size: size,
};
// getList() // getList()
}
return (<div className={Styles.datasetBox}>
<div className={Styles.datasetIntroTopBox}>
<span style={{color:'#1d1d20',fontSize:'20px'}}>{datasetDetailObj.name}</span>
<div className={Styles.smallTagBox}>
<div className={Styles.tagItem}>{datasetDetailObj.data_tag||'...'}</div>
};
return (
<div className={Styles.datasetBox}>
<div className={Styles.datasetIntroTopBox}>
<span style={{ color: '#1d1d20', fontSize: '20px' }}>{datasetDetailObj.name}</span>
<div className={Styles.smallTagBox}>
<div className={Styles.tagItem}>{datasetDetailObj.data_tag || '...'}</div>
<div className={Styles.tagItem}>{datasetDetailObj.data_type}</div> <div className={Styles.tagItem}>{datasetDetailObj.data_type}</div>
{/* <div className={Styles.tagItem}>English</div> */} {/* <div className={Styles.tagItem}>English</div> */}
</div>
</div>
<div className={Styles.datasetIntroCneterBox}>
<Tabs
defaultActiveKey="1"
>
<TabPane tab="数据集简介" key="1">
<div className={Styles.datasetIntroTitle}>简介</div>
<div className={Styles.datasetIntroText}>{datasetDetailObj.description}</div>
</TabPane>
<TabPane tab="数据集文件/版本" key="2">
<div className={Styles.dataListBox}>
<div>数据集文件列表</div>
<div className={Styles.dataButtonList}>
<div style={{display: 'flex',
justifyContent: 'space-between',
alignItems: 'center'}}>
<span style={{marginRight:'10px'}}>版本号:</span>
<Select
placeholder="请选择版本号"
style={{
width: 160,
}}
allowClear
onChange={handleChange}
options={versionList}
/>
<Button type="primary" className={Styles.plusButton} onClick={showModal} icon = {<PlusCircleOutlined style={{color:'#1664ff'}} />}>
创建新版本
</Button>
</div>
<div style={{display: 'flex',
justifyContent: 'space-between',
alignItems: 'center'}}>
<Button type="primary" className={Styles.plusButton} style={{margin:'0 20px 0 0' }} onClick={deleteDataset} icon = {<DeleteOutlined style={{color:'#1664ff', }} />}>
删除
</Button>
<Button type="primary" disabled={!version} className={Styles.plusButton} style={{margin:'0 20px 0 0' }} onClick={handleExport} icon = {<UploadOutlined style={{color:'#1664ff'}} />}>
下载
</Button>
</div>
</div> </div>
<Table columns={columns} dataSource={wordList} pagination={false} />
</div>
</TabPane>
</Tabs>
</div>
<Modal title={<div style={{display:'flex',alignItems:'center',fontWeight:500}}>
<img style={{width:'20px',marginRight:'10px'}} src={`/assets/images/pipeline-edit-icon.png`} alt="" />{dialogTitle}
</div>} open={isModalOpen} className={Styles.modal} okButtonProps={{
htmlType: 'submit',
form: 'form',
}} onCancel={handleCancel}>
</div>
<div className={Styles.datasetIntroCneterBox}>
<Tabs activeKey={activeTabKey} onChange={(key) => setActiveTabKey(key)}>
<TabPane tab="数据集简介" key="1">
<div className={Styles.datasetIntroTitle}>简介</div>
<div className={Styles.datasetIntroText}>{datasetDetailObj.description}</div>
</TabPane>
<TabPane tab="数据集文件/版本" key="2">
<div className={Styles.dataListBox}>
<div>数据集文件列表</div>
<div className={Styles.dataButtonList}>
<div
style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}
>
<span style={{ marginRight: '10px' }}>版本号:</span>
<Select
placeholder="请选择版本号"
style={{
width: 160,
}}
allowClear
onChange={handleChange}
options={versionList}
/>
<Button
type="primary"
className={Styles.plusButton}
onClick={showModal}
icon={<PlusCircleOutlined style={{ color: '#1664ff' }} />}
>
创建新版本
</Button>
</div>
<div
style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}
>
<Button
type="primary"
className={Styles.plusButton}
style={{ margin: '0 20px 0 0' }}
onClick={deleteDataset}
icon={<DeleteOutlined style={{ color: '#1664ff' }} />}
>
删除
</Button>
<Button
type="primary"
disabled={!version}
className={Styles.plusButton}
style={{ margin: '0 20px 0 0' }}
onClick={handleExport}
icon={<DownloadOutlined style={{ color: '#1664ff' }} />}
>
下载
</Button>
</div>
</div>
<div style={{ marginBottom: '10px', fontSize: '14px' }}>
{wordList.length > 0 ? wordList[0].description : null}
</div>
<Table columns={columns} dataSource={wordList} pagination={false} />
</div>
</TabPane>
</Tabs>
</div>
<Modal
title={
<div style={{ display: 'flex', alignItems: 'center', fontWeight: 500 }}>
<img
style={{ width: '20px', marginRight: '10px' }}
src={`/assets/images/pipeline-edit-icon.png`}
alt=""
/>
{dialogTitle}
</div>
}
open={isModalOpen}
className={Styles.modal}
okButtonProps={{
htmlType: 'submit',
form: 'form',
}}
onCancel={handleCancel}
>
<Form <Form
name="form" name="form"
form={form} form={form}
@@ -271,28 +320,71 @@ const Dataset= React.FC = () => {
label="数据集名称" label="数据集名称"
name="name" name="name"
rules={[ rules={[
// {
// required: true,
// message: 'Please input your username!',
// },
{
required: true,
message: '请输入数据集名称',
},
]} ]}
> >
<Input disabled placeholder="请输入数据集名称"/>
<Input disabled placeholder="请输入数据集名称" />
</Form.Item> </Form.Item>
<Form.Item
<Form.Item
label="数据集版本" label="数据集版本"
name="version" name="version"
rules={[
{
required: true,
message: '请输入数据集版本',
},
]}
> >
<Input placeholder="请输入数据集版本"/>
<Input placeholder="请输入数据集版本" maxLength={64} showCount allowClear />
</Form.Item>
<Form.Item
label="版本描述"
name="description"
rules={[
{
required: true,
message: '请输入版本描述',
},
]}
>
<Input.TextArea
placeholder="请输入版本描述"
autoSize={{ minRows: 2, maxRows: 6 }}
maxLength={256}
showCount
allowClear
/>
</Form.Item>
<Form.Item
label="数据集文件"
name="dataset_version_vos"
rules={[
{
required: true,
message: '请上传数据集文件',
},
]}
>
<Upload {...props}>
<Button
style={{
fontSize: '14px',
border: '1px solid',
borderColor: '#1664ff',
background: '#fff',
}}
icon={<UploadOutlined style={{ color: '#1664ff' }} />}
>
上传文件
</Button>
</Upload>
</Form.Item> </Form.Item>
<Form.Item label="数据文件" name="dataset_version_vos">
<Upload {...props}>
<Button style={{fontSize:'14px',border:'1px solid',borderColor:'#1664ff',background:'#fff'}} icon={<UploadOutlined style={{color:'#1664ff'}} />}>上传文件</Button>
</Upload>
</Form.Item>
</Form> </Form>
</Modal> </Modal>

</div>)
</div>
);
}; };
export default Dataset;
export default Dataset;

+ 271
- 277
react-ui/src/pages/Dataset/index.less View File

@@ -1,303 +1,297 @@
.datasetTopBox{
.datasetTopBox {
display: flex;
align-items: center;
width: 100%;
height: 49px;
padding: 0 30px;
padding-right: 30px;
background-image: url(/assets/images/pipeline-back.png);
background-size: 100% 100%;
}
.datasetIntroTopBox {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
height: 110px;
margin-bottom: 10px;
padding: 25px 30px;
background-image: url(/assets/images/dataset-back.png);
background-size: 100% 100%;
.smallTagBox {
display: flex; display: flex;
align-items: center; align-items: center;
padding-right: 30px;
width: 100%;
height: 49px;
background-size: 100% 100%;
background-image: url(/assets/images/pipeline-back.png);
padding: 0 30px;
color: #1664ff;
font-size: 14px;
.tagItem {
margin-right: 20px;
padding: 4px 10px;
background: rgba(22, 100, 255, 0.1);
border-radius: 4px;
}
}
} }
.datasetIntroTopBox{
.dataListBox {
padding: 20px 30px;
color: #1d1d20;
font-size: 16px;
background: #ffffff;
border-radius: 10px;
box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09);
.dataButtonList {
display: flex; display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between; justify-content: space-between;
width: 100%;
height: 110px;
background-size: 100% 100%;
background-image: url(/assets/images/dataset-back.png);
margin-bottom: 10px;
padding: 25px 30px;
.smallTagBox{
display: flex;
align-items: center;
color:#1664ff;
font-size:14px;
.tagItem{
padding: 4px 10px;
background: rgba(22, 100, 255, 0.1);
border-radius:4px;
margin-right: 20px;
}
}
}
.dataListBox{
padding: 20px 30px;
background:#ffffff;
border-radius:10px;
box-shadow:0px 2px 12px rgba(180, 182, 191, 0.09);
color:#1d1d20;
font-size:16px;
.dataButtonList{
display: flex;
justify-content: space-between;
align-items: center;
height: 32px;
margin: 24px 0 30px 0;
color:#575757;
font-size:16px;
}
height: 32px;
margin: 24px 0 30px 0;
color: #575757;
font-size: 16px;
}
} }
.datasetIntroCneterBox{
height: 77vh;
padding: 20px 30px;
background:#ffffff;
border-radius:10px;
box-shadow:0px 2px 12px rgba(180, 182, 191, 0.09);
.datasetIntroCneterBox {
height: 77vh;
padding: 20px 30px;
background: #ffffff;
border-radius: 10px;
box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09);
} }
.datasetIntroTitle{
color:#1d1d20;
font-size:15px;
margin: 37px 0 10px 0;
.datasetIntroTitle {
margin: 37px 0 10px 0;
color: #1d1d20;
font-size: 15px;
} }
.datasetIntroText{
color:#575757;
font-size:14px;
margin-bottom: 30px;
.datasetIntroText {
margin-bottom: 30px;
color: #575757;
font-size: 14px;
} }
.datasetBox{
background:#f9fafb;
font-family: 'Alibaba';
:global{
.ant-tabs-top >.ant-tabs-nav{
margin: 0;
}
.ant-pagination{
text-align: right;
}
.datasetBox {
font-family: 'Alibaba';
background: #f9fafb;
:global {
.ant-tabs-top > .ant-tabs-nav {
margin: 0;
} }
.ant-pagination {
text-align: right;
}
}
} }
.datasetAllBox{
:global{
.ant-tabs-nav .ant-tabs-nav-wrap{
margin: -48px 0 0 30px;
}
.datasetAllBox {
:global {
.ant-tabs-nav .ant-tabs-nav-wrap {
margin: -48px 0 0 30px;
} }
}
} }
.plusButton{
margin: 0 18px 0 20px;
background:rgba(22, 100, 255, 0.06);
border:1px solid;
border-color:rgba(22, 100, 255, 0.11);
border-radius:4px;
color:#1d1d20;
font-size:14px;
font-family: 'Alibaba';
.plusButton {
margin: 0 18px 0 20px;
color: #1d1d20;
font-size: 14px;
font-family: 'Alibaba';
background: rgba(22, 100, 255, 0.06);
border: 1px solid;
border-color: rgba(22, 100, 255, 0.11);
border-radius: 4px;
} }
.plusButton:hover{
background:rgba(22, 100, 255, 0.06)!important;
border:1px solid!important;
border-color:rgba(22, 100, 255, 0.11)!important;
color:#1d1d20!important;
.plusButton:hover {
color: #1d1d20 !important;
background: rgba(22, 100, 255, 0.06) !important;
border: 1px solid !important;
border-color: rgba(22, 100, 255, 0.11) !important;
} }
.datasetCneterBox{
display: flex;
justify-content: space-between;
height: 85vh;
width: 100%;
:global{
.ant-btn{
color:#1d1d20;
font-size:14px;
}
.datasetCneterBox {
display: flex;
justify-content: space-between;
width: 100%;
height: 85vh;
:global {
.ant-btn {
color: #1d1d20;
font-size: 14px;
} }
.datasetCneterLeftBox{
width:340px;
height:100%;
background:#ffffff;
box-shadow:0px 3px 6px rgba(146, 146, 146, 0.09);
margin-right: 10px;
padding-top: 15px;
.custTab{
display: flex;
border-bottom: 1px solid #e0eaff;
height: 32px;
.tabItem{
width: 52px;
height: 100%;
text-align: center;
color:#808080;
font-size:15px;
cursor: pointer;
}
}
.datasetCneterLeftBox {
width: 340px;
height: 100%;
margin-right: 10px;
padding-top: 15px;
background: #ffffff;
box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09);
.custTab {
display: flex;
height: 32px;
border-bottom: 1px solid #e0eaff;
.tabItem {
width: 52px;
height: 100%;
color: #808080;
font-size: 15px;
text-align: center;
cursor: pointer;
}
}
.leftContentBox {
max-height: 80vh;
padding: 15px 20px;
overflow-x: hidden;
overflow-y: auto;
.itemTitle {
margin-bottom: 15px;
color: #1d1d20;
font-size: 14px;
}
.itemBox {
display: flex;
flex-wrap: wrap;
align-content: start;
width: 110%;
.messageBox {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
width: 92px;
height: 62px;
margin: 0 12px 20px 0;
padding: 11px 0px 7px 0px;
color: #1d1d20;
font-size: 12px;
border: 1px solid;
border-color: rgba(22, 100, 255, 0.05);
border-radius: 4px;
cursor: pointer;
.ptIcon {
display: block;
}
.hoverIcon {
display: none;
}
.messageText {
width: 65px;
overflow: hidden;
white-space: nowrap;
text-align: center;
text-overflow: ellipsis;
}
} }
.leftContentBox{
max-height: 80vh;
overflow-y: auto;
overflow-x: hidden;
padding: 15px 20px;
.itemTitle{
color:#1d1d20;
font-size:14px;
margin-bottom: 15px;
}
.itemBox{
width: 110%;
display: flex;
flex-wrap: wrap;
align-content: start;
.messageBox{
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
cursor: pointer;
width:92px;
height:62px;
border:1px solid;
border-color:rgba(22, 100, 255, 0.05);
border-radius:4px;
margin: 0 12px 20px 0;
padding: 11px 0px 7px 0px;
color:#1d1d20;
font-size:12px;
.ptIcon{
display: block;
}
.hoverIcon{
display: none;
}
.messageText{
width: 65px;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.messageBox:hover{
background:rgba(22, 100, 255, 0.03);
border:1px solid;
border-color:#1664ff;
.ptIcon{
display: none;
}
.hoverIcon{
display: block;
}
}
.active{
background:rgba(22, 100, 255, 0.03)!important;
border:1px solid!important;
border-color:#1664ff!important;
.ptIcon{
display: none!important;
}
.hoverIcon{
display: block!important;
}
}
}
.messageBox:hover {
background: rgba(22, 100, 255, 0.03);
border: 1px solid;
border-color: #1664ff;
.ptIcon {
display: none;
}
.hoverIcon {
display: block;
}
} }
.active {
background: rgba(22, 100, 255, 0.03) !important;
border: 1px solid !important;
border-color: #1664ff !important;
.ptIcon {
display: none !important;
}
.hoverIcon {
display: block !important;
}
}
}
} }
}


.datasetCneterRightBox{
display: flex;
flex-direction: column;
padding: 22px 30px 26px 30px;
flex: 1;
height:100%;
background:#ffffff;
box-shadow:0px 3px 6px rgba(146, 146, 146, 0.09);
.dataSource{
display: flex;
justify-content: space-between;
align-items: center;
height: 32px;
margin-bottom: 30px;
color:rgba(29, 29, 32, 0.8);
font-size:15px;
.datasetCneterRightBox {
display: flex;
flex: 1;
flex-direction: column;
height: 100%;
padding: 22px 30px 26px 30px;
background: #ffffff;
box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09);
.dataSource {
display: flex;
align-items: center;
justify-content: space-between;
height: 32px;
margin-bottom: 30px;
color: rgba(29, 29, 32, 0.8);
font-size: 15px;
}
.dataContent {
display: flex;
flex: 1;
flex-wrap: wrap;
align-content: flex-start;
width: 100%;
.dataItem {
position: relative;
width: 32%;
height: 66px;
margin: 0 15px 18px 0;
background: rgba(128, 128, 128, 0.05);
border-radius: 8px;
box-shadow: 0px 0px 12px rgba(75, 84, 137, 0.05);
cursor: pointer;
.itemText {
position: absolute;
top: 10px;
left: 20px;
color: #1d1d20;
font-size: 15px;
}
.itemTime {
position: absolute;
bottom: 10px;
left: 20px;
color: #808080;
font-size: 14px;
} }
.dataContent{
width: 100%;
flex: 1;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
.dataItem{
width: 32%;
margin: 0 15px 18px 0;
height:66px;
position: relative;
background:rgba(128, 128, 128, 0.05);
border-radius:8px;
box-shadow:0px 0px 12px rgba(75, 84, 137, 0.05);
cursor: pointer;
.itemText{
position: absolute;
left: 20px;
top: 10px;
color:#1d1d20;
font-size:15px;
}
.itemTime{
position: absolute;
left: 20px;
bottom: 10px;
color:#808080;
font-size:14px;
}
.itemIcon{
position: absolute;
right: 20px;
bottom: 10px;
color:#808080;
font-size:14px;
}
}
.itemIcon {
position: absolute;
right: 20px;
bottom: 10px;
color: #808080;
font-size: 14px;
} }
}
} }
}
} }
.modal { .modal {
:global {
.ant-modal-content {
background:linear-gradient(180deg,#cfdfff 0%,#d4e2ff 9.77%,#ffffff 40%,#ffffff 100%);
border-radius:21px;
padding: 20px 67px;
width: 825px;

}
.ant-modal-header{
background-color: transparent;
margin: 20px 0;
}
.ant-input{
border-color:#e6e6e6;
height: 40px;
}
.ant-form-item .ant-form-item-label >label{
color:rgba(29, 29, 32, 0.8);
}
.ant-modal-footer{
margin: 40px 0 30px 0;
display: flex;
justify-content: center;
}
.ant-btn{
width:110px;
height:40px;
font-size:18px;
background:rgba(22, 100, 255, 0.06);
border-radius:10px;
border-color: transparent;

}
.ant-btn-primary{
background:#1664ff;
}
:global {
.ant-modal-content {
width: 825px;
padding: 20px 67px;
background: linear-gradient(180deg, #cfdfff 0%, #d4e2ff 9.77%, #ffffff 40%, #ffffff 100%);
border-radius: 21px;
}
.ant-modal-header {
margin: 20px 0;
background-color: transparent;
}
.ant-input {
height: 40px;
border-color: #e6e6e6;
} }
}
.ant-form-item .ant-form-item-label > label {
color: rgba(29, 29, 32, 0.8);
}
.ant-modal-footer {
display: flex;
justify-content: center;
margin: 40px 0 30px 0;
}
.ant-btn {
width: 110px;
height: 40px;
font-size: 18px;
background: rgba(22, 100, 255, 0.06);
border-color: transparent;
border-radius: 10px;
}
.ant-btn-primary {
background: #1664ff;
}
}
}

+ 43
- 53
react-ui/src/pages/Model/index.jsx View File

@@ -1,27 +1,24 @@

import React ,{useEffect,useState}from 'react';
import Styles from './index.less'
import { Input, Space ,Button,Tabs,Pagination,Modal, Form,message, Radio,} from 'antd';
import { PlusOutlined,PlusCircleOutlined, DeleteOutlined, ExclamationCircleOutlined, DownOutlined, EditOutlined ,CopyOutlined} from '@ant-design/icons';
import { Form, Input, Tabs } from 'antd';
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import Styles from './index.less';
import PersonalData from './personalData';
import PublicData from './publicData';
// import {getModelList} from '@/services/dataset/index.js' // import {getModelList} from '@/services/dataset/index.js'
const { Search } = Input; const { Search } = Input;
import { useNavigate} from 'react-router-dom';
import moment from 'moment';
const { TabPane } = Tabs; const { TabPane } = Tabs;
import PublicData from './publicData';
import PersonalData from './personalData'
const leftdataList=[1,2,3]
const leftdataList = [1, 2, 3];


const Dataset= React.FC = () => {
const [queryFlow,setQueryFlow]=useState({
page:0,
size:10,
name:null
const Dataset = () => {
const [queryFlow, setQueryFlow] = useState({
page: 0,
size: 10,
name: null,
}); });
const navgite=useNavigate();
const [isModalOpen,setIsModalOpen]=useState(false)
const [datasetList,setDatasetList]=useState([]);
const [total,setTotal]=useState(0);
const navgite = useNavigate();
const [isModalOpen, setIsModalOpen] = useState(false);
const [datasetList, setDatasetList] = useState([]);
const [total, setTotal] = useState(0);
const [form] = Form.useForm(); const [form] = Form.useForm();
const [dialogTitle, setDialogTitle] = useState('新建数据'); const [dialogTitle, setDialogTitle] = useState('新建数据');
// const getModelLists=()=>{ // const getModelLists=()=>{
@@ -35,49 +32,42 @@ const Dataset= React.FC = () => {
// } // }


const showModal = () => { const showModal = () => {
form.resetFields()
setDialogTitle('新建数据集')
form.resetFields();
setDialogTitle('新建数据集');
setIsModalOpen(true); setIsModalOpen(true);
}; };
const handleOk = () => { const handleOk = () => {
console.log(1111);
console.log(1111);
setIsModalOpen(false); setIsModalOpen(false);
}; };
const handleCancel = () => { const handleCancel = () => {
setIsModalOpen(false); setIsModalOpen(false);
}; };
const onFinish = (values) => {
};
const routeToIntro=(e,record)=>{
e.stopPropagation()
navgite({pathname:'/dataset/datasetIntro' });
}
const onFinish = (values) => {};
const routeToIntro = (e, record) => {
e.stopPropagation();
navgite({ pathname: '/dataset/datasetIntro' });
};
const onFinishFailed = (errorInfo) => { const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo); console.log('Failed:', errorInfo);
}; };
useEffect(()=>{
return ()=>{
}
},[])
return (<div className={Styles.datasetBox}>
<div className={Styles.datasetTopBox}>
</div>
<div className={Styles.datasetAllBox}>
<Tabs
defaultActiveKey="1"
>
<TabPane tab="模型广场" key="1">
<PublicData/>
</TabPane>
<TabPane tab="个人模型" key="2">
<PersonalData/>
</TabPane>
</Tabs>
</div>
</div>)
useEffect(() => {
return () => {};
}, []);
return (
<div className={Styles.datasetBox}>
<div className={Styles.datasetTopBox}></div>
<div className={Styles.datasetAllBox}>
<Tabs defaultActiveKey="1">
<TabPane tab="模型广场" key="1">
<PublicData />
</TabPane>
<TabPane tab="个人模型" key="2">
<PersonalData />
</TabPane>
</Tabs>
</div>
</div>
);
}; };
export default Dataset;
export default Dataset;

+ 269
- 272
react-ui/src/pages/Model/index.less View File

@@ -1,296 +1,293 @@
.datasetTopBox{
.datasetTopBox {
display: flex;
align-items: center;
width: 100%;
height: 49px;
padding: 0 30px;
padding-right: 30px;
background-image: url(/assets/images/pipeline-back.png);
background-size: 100% 100%;
}
.datasetIntroTopBox {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
height: 110px;
margin-bottom: 10px;
padding: 25px 30px;
background-image: url(/assets/images/dataset-back.png);

background-size: 100% 100%;
.smallTagBox {
display: flex; display: flex;
align-items: center; align-items: center;
padding-right: 30px;
width: 100%;
height: 49px;
background-size: 100% 100%;
background-image: url(/assets/images/pipeline-back.png);
padding: 0 30px;
color: #1664ff;
font-size: 14px;
.tagItem {
margin-right: 20px;
padding: 4px 10px;
background: rgba(22, 100, 255, 0.1);
border-radius: 4px;
}
}
} }
.datasetIntroTopBox{
.dataListBox {
padding: 20px 30px;
color: #1d1d20;
font-size: 16px;
background: #ffffff;
border-radius: 10px;
box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09);
.dataButtonList {
display: flex; display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between; justify-content: space-between;
width: 100%;
height: 110px;
background-size: 100% 100%;
background-image: url(/assets/images/dataset-back.png);
margin-bottom: 10px;
padding: 25px 30px;
.smallTagBox{
display: flex;
align-items: center;
color:#1664ff;
font-size:14px;
.tagItem{
padding: 4px 10px;
background: rgba(22, 100, 255, 0.1);
border-radius:4px;
margin-right: 20px;
}
}
}
.dataListBox{
padding: 20px 30px;
background:#ffffff;
border-radius:10px;
box-shadow:0px 2px 12px rgba(180, 182, 191, 0.09);
color:#1d1d20;
font-size:16px;
.dataButtonList{
display: flex;
justify-content: space-between;
align-items: center;
height: 32px;
margin: 24px 0 30px 0;
color:#575757;
font-size:16px;
}
height: 32px;
margin: 24px 0 30px 0;
color: #575757;
font-size: 16px;
}
} }
.datasetIntroCneterBox{
height: 77vh;
padding: 20px 30px;
background:#ffffff;
border-radius:10px;
box-shadow:0px 2px 12px rgba(180, 182, 191, 0.09);
.datasetIntroCneterBox {
height: 77vh;
padding: 20px 30px;
background: #ffffff;
border-radius: 10px;
box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09);
} }
.datasetIntroTitle{
color:#1d1d20;
font-size:15px;
margin: 37px 0 10px 0;
.datasetIntroTitle {
margin: 37px 0 10px 0;
color: #1d1d20;
font-size: 15px;
} }
.datasetIntroText{
color:#575757;
font-size:14px;
margin-bottom: 30px;
.datasetIntroText {
margin-bottom: 30px;
color: #575757;
font-size: 14px;
} }
.datasetBox{
background:#f9fafb;
font-family: 'Alibaba';
:global{
.ant-tabs-top >.ant-tabs-nav{
margin: 0;
}
.ant-pagination{
text-align: right;
}
.datasetBox {
font-family: 'Alibaba';
background: #f9fafb;
:global {
.ant-tabs-top > .ant-tabs-nav {
margin: 0;
}
.ant-pagination {
text-align: right;
} }
}
} }
.datasetAllBox{
:global{
.ant-tabs-nav .ant-tabs-nav-wrap{
margin: -48px 0 0 30px;
}
.datasetAllBox {
:global {
.ant-tabs-nav .ant-tabs-nav-wrap {
margin: -48px 0 0 30px;
} }
}
} }
.plusButton{
margin: 0 18px 0 20px;
background:rgba(22, 100, 255, 0.06);
border:1px solid;
border-color:rgba(22, 100, 255, 0.11);
border-radius:4px;
color:#1d1d20;
font-size:14px;
font-family: 'Alibaba';
.plusButton {
margin: 0 18px 0 20px;
color: #1d1d20;
font-size: 14px;
font-family: 'Alibaba';
background: rgba(22, 100, 255, 0.06);
border: 1px solid;
border-color: rgba(22, 100, 255, 0.11);
border-radius: 4px;
} }
.plusButton:hover{
background:rgba(22, 100, 255, 0.06)!important;
border:1px solid!important;
border-color:rgba(22, 100, 255, 0.11)!important;
color:#1d1d20!important;
.plusButton:hover {
color: #1d1d20 !important;
background: rgba(22, 100, 255, 0.06) !important;
border: 1px solid !important;
border-color: rgba(22, 100, 255, 0.11) !important;
} }
.datasetCneterBox{
display: flex;
justify-content: space-between;
height: 85vh;
width: 100%;
.datasetCneterLeftBox{
width:340px;
height:100%;
background:#ffffff;
box-shadow:0px 3px 6px rgba(146, 146, 146, 0.09);
margin-right: 10px;
padding-top: 15px;
.custTab{
display: flex;
border-bottom: 1px solid #e0eaff;
height: 32px;
.tabItem{
width: 52px;
height: 100%;
text-align: center;
color:#808080;
font-size:15px;
cursor: pointer;
}
.datasetCneterBox {
display: flex;
justify-content: space-between;
width: 100%;
height: 85vh;

.datasetCneterLeftBox {
width: 340px;
height: 100%;
margin-right: 10px;
padding-top: 15px;
background: #ffffff;
box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09);
.custTab {
display: flex;
height: 32px;
border-bottom: 1px solid #e0eaff;
.tabItem {
width: 52px;
height: 100%;
color: #808080;
font-size: 15px;
text-align: center;
cursor: pointer;
}
}
.leftContentBox {
max-height: 80vh;
padding: 15px 20px;
overflow-x: hidden;
overflow-y: auto;
.itemTitle {
margin-bottom: 15px;
color: #1d1d20;
font-size: 14px;
}
.itemBox {
display: flex;
flex-wrap: wrap;
align-content: start;
width: 110%;
.messageBox {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
width: 92px;
height: 62px;
margin: 0 12px 20px 0;
padding: 11px 0px 7px 0px;
color: #1d1d20;
font-size: 12px;
border: 1px solid;
border-color: rgba(22, 100, 255, 0.05);
border-radius: 4px;
cursor: pointer;
.ptIcon {
display: block;
}
.hoverIcon {
display: none;
}
.messageText {
width: 65px;
overflow: hidden;
white-space: nowrap;
text-align: center;
text-overflow: ellipsis;
transition: all 0.2s;
}
}
.messageBox:hover {
background: rgba(22, 100, 255, 0.03);
border: 1px solid;
border-color: #1664ff;
.ptIcon {
display: none;
}
.hoverIcon {
display: block;
}
} }
.leftContentBox{
max-height: 80vh;
overflow-y: auto;
overflow-x: hidden;
padding: 15px 20px;
.itemTitle{
color:#1d1d20;
font-size:14px;
margin-bottom: 15px;
}
.itemBox{
width: 110%;
display: flex;
flex-wrap: wrap;
align-content: start;
.messageBox{
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
cursor: pointer;
width:92px;
height:62px;
border:1px solid;
border-color:rgba(22, 100, 255, 0.05);
border-radius:4px;
margin: 0 12px 20px 0;
padding: 11px 0px 7px 0px;
color:#1d1d20;
font-size:12px;
.ptIcon{
display: block;
}
.hoverIcon{
display: none;
}
.messageText{
width: 65px;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
transition: all 0.2s;
}
}
.messageBox:hover{
background:rgba(22, 100, 255, 0.03);
border:1px solid;
border-color:#1664ff;
.ptIcon{
display: none;
}
.hoverIcon{
display: block;
}
}
.active{
background:rgba(22, 100, 255, 0.03)!important;
border:1px solid!important;
border-color:#1664ff!important;
.ptIcon{
display: none!important;
}
.hoverIcon{
display: block!important;
}
}
}
.active {
background: rgba(22, 100, 255, 0.03) !important;
border: 1px solid !important;
border-color: #1664ff !important;
.ptIcon {
display: none !important;
}
.hoverIcon {
display: block !important;
}
} }
}
} }
.datasetCneterRightBox{
display: flex;
flex-direction: column;
padding: 22px 30px 26px 30px;
flex: 1;
height:100%;
background:#ffffff;
box-shadow:0px 3px 6px rgba(146, 146, 146, 0.09);
.dataSource{
display: flex;
justify-content: space-between;
align-items: center;
height: 32px;
margin-bottom: 30px;
color:rgba(29, 29, 32, 0.8);
font-size:15px;
}
.datasetCneterRightBox {
display: flex;
flex: 1;
flex-direction: column;
height: 100%;
padding: 22px 30px 26px 30px;
background: #ffffff;
box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09);
.dataSource {
display: flex;
align-items: center;
justify-content: space-between;
height: 32px;
margin-bottom: 30px;
color: rgba(29, 29, 32, 0.8);
font-size: 15px;
}
.dataContent {
display: flex;
flex: 1;
flex-wrap: wrap;
align-content: flex-start;
width: 100%;
.dataItem {
position: relative;
width: 32%;
height: 66px;
margin: 0 15px 18px 0;
background: rgba(128, 128, 128, 0.05);
border-radius: 8px;
box-shadow: 0px 0px 12px rgba(75, 84, 137, 0.05);
cursor: pointer;
.itemText {
position: absolute;
top: 10px;
left: 20px;
color: #1d1d20;
font-size: 15px;
}
.itemTime {
position: absolute;
bottom: 10px;
left: 20px;
color: #808080;
font-size: 14px;
} }
.dataContent{
width: 100%;
flex: 1;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
.dataItem{
width: 32%;
margin: 0 15px 18px 0;
height:66px;
position: relative;
background:rgba(128, 128, 128, 0.05);
border-radius:8px;
box-shadow:0px 0px 12px rgba(75, 84, 137, 0.05);
cursor: pointer;
.itemText{
position: absolute;
left: 20px;
top: 10px;
color:#1d1d20;
font-size:15px;
}
.itemTime{
position: absolute;
left: 20px;
bottom: 10px;
color:#808080;
font-size:14px;
}
.itemIcon{
position: absolute;
right: 20px;
bottom: 10px;
color:#808080;
font-size:14px;
}
}
.itemIcon {
position: absolute;
right: 20px;
bottom: 10px;
color: #808080;
font-size: 14px;
} }
}
} }
}
} }
.modal { .modal {
:global {
.ant-modal-content {
background:linear-gradient(180deg,#cfdfff 0%,#d4e2ff 9.77%,#ffffff 40%,#ffffff 100%);
border-radius:21px;
padding: 20px 67px;
width: 825px;

}
.ant-modal-header{
background-color: transparent;
margin: 20px 0;
}
.ant-input{
border-color:#e6e6e6;
height: 40px;
}
.ant-form-item .ant-form-item-label >label{
color:rgba(29, 29, 32, 0.8);
}
.ant-modal-footer{
margin: 40px 0 30px 0;
display: flex;
justify-content: center;
}
.ant-btn{
width:110px;
height:40px;
font-size:18px;
background:rgba(22, 100, 255, 0.06);
border-radius:10px;
border-color: transparent;
}
.ant-btn-primary{
background:#1664ff;
}
:global {
.ant-modal-content {
width: 825px;
padding: 20px 67px;
background: linear-gradient(180deg, #cfdfff 0%, #d4e2ff 9.77%, #ffffff 40%, #ffffff 100%);
border-radius: 21px;
}
.ant-modal-header {
margin: 20px 0;
background-color: transparent;
}
.ant-input {
height: 40px;
border-color: #e6e6e6;
} }
}
.ant-form-item .ant-form-item-label > label {
color: rgba(29, 29, 32, 0.8);
}
.ant-modal-footer {
display: flex;
justify-content: center;
margin: 40px 0 30px 0;
}
.ant-btn {
width: 110px;
height: 40px;
font-size: 18px;
background: rgba(22, 100, 255, 0.06);
border-color: transparent;
border-radius: 10px;
}
.ant-btn-primary {
background: #1664ff;
}
}
}

+ 88
- 39
react-ui/src/pages/Model/modelIntro.jsx View File

@@ -7,7 +7,12 @@ import {
getModelVersionsById, getModelVersionsById,
} from '@/services/dataset/index.js'; } from '@/services/dataset/index.js';
import { downLoadZip } from '@/utils/downloadfile'; import { downLoadZip } from '@/utils/downloadfile';
import { DeleteOutlined, PlusCircleOutlined, UploadOutlined } from '@ant-design/icons';
import {
DeleteOutlined,
DownloadOutlined,
PlusCircleOutlined,
UploadOutlined,
} from '@ant-design/icons';
import { Button, Form, Input, Modal, Select, Table, Tabs, Upload, message } from 'antd'; import { Button, Form, Input, Modal, Select, Table, Tabs, Upload, message } from 'antd';
import moment from 'moment'; import moment from 'moment';
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
@@ -57,15 +62,13 @@ const Dataset = () => {
const getModelByDetail = () => { const getModelByDetail = () => {
getModelById(locationParams.id).then((ret) => { getModelById(locationParams.id).then((ret) => {
console.log(ret); console.log(ret);
if (ret.code == 200) {
setDatasetDetailObj(ret.data);
}
setDatasetDetailObj(ret.data);
}); });
}; };
const getModelVersionsList = () => { const getModelVersionsList = () => {
getModelVersionsById(locationParams.id).then((ret) => { getModelVersionsById(locationParams.id).then((ret) => {
console.log(ret); console.log(ret);
if (ret.code == 200 && ret.data && ret.data.length > 0) {
if (ret.data && ret.data.length > 0) {
setVersionList( setVersionList(
ret.data.map((item) => { ret.data.map((item) => {
return { return {
@@ -101,12 +104,8 @@ const Dataset = () => {


onOk: () => { onOk: () => {
deleteModelVersion({ models_id: locationParams.id, version }).then((ret) => { deleteModelVersion({ models_id: locationParams.id, version }).then((ret) => {
if (ret.code == 200) {
message.success('删除成功');
getModelVersions({ version, models_id: locationParams.id });
} else {
message.error(ret.msg);
}
message.success('删除成功');
getModelVersions({ version, models_id: locationParams.id });
}); });
}, },
}); });
@@ -121,9 +120,7 @@ const Dataset = () => {
const getModelVersions = (params) => { const getModelVersions = (params) => {
getModelVersionIdList(params).then((ret) => { getModelVersionIdList(params).then((ret) => {
console.log(ret); console.log(ret);
if (ret.code == 200) {
setWordList(ret.data);
}
setWordList(ret.data);
}); });
}; };
const handleExport = async () => { const handleExport = async () => {
@@ -150,18 +147,16 @@ const Dataset = () => {
console.log('Failed:', errorInfo); console.log('Failed:', errorInfo);
}; };
const columns = [ const columns = [
// {
// title: '序号',
// dataIndex: 'index',
// key: 'index',
// width: 80,
// render(text, record, index) {
// return (
// <span>{(pageOption.current.page - 1) * 10 + index + 1}</span>
// )
// }
// // render: (text, record, index) => `${((curPage-1)*10)+(index+1)}`,
// },
{
title: '序号',
dataIndex: 'index',
key: 'index',
width: 80,
render(text, record, index) {
return <span>{(pageOption.current.page - 1) * 10 + index + 1}</span>;
},
// render: (text, record, index) => `${((curPage-1)*10)+(index+1)}`,
},
{ {
title: '文件名称', title: '文件名称',
dataIndex: 'file_name', dataIndex: 'file_name',
@@ -184,6 +179,23 @@ const Dataset = () => {
key: 'update_time', key: 'update_time',
render: (text) => <span>{moment(text).format('YYYY-MM-DD HH:mm:ss')}</span>, render: (text) => <span>{moment(text).format('YYYY-MM-DD HH:mm:ss')}</span>,
}, },
{
title: '操作',
dataIndex: 'option',
width: '100px',
key: 'option',
render: (_, record) => [
<Button
type="link"
size="small"
key="download"
icon={<DownloadOutlined />}
onClick={(e) => downloadAlone(e, record)}
>
下载
</Button>,
],
},
]; ];
const pageOption = useRef({ page: 1, size: 10 }); const pageOption = useRef({ page: 1, size: 10 });


@@ -256,12 +268,15 @@ const Dataset = () => {
disabled={!version} disabled={!version}
style={{ margin: '0 20px 0 0' }} style={{ margin: '0 20px 0 0' }}
onClick={handleExport} onClick={handleExport}
icon={<UploadOutlined style={{ color: '#1664ff' }} />}
icon={<DownloadOutlined style={{ color: '#1664ff' }} />}
> >
下载 下载
</Button> </Button>
</div> </div>
</div> </div>
<div style={{ marginBottom: '10px', fontSize: '14px' }}>
{wordList.length > 0 ? wordList[0].description : null}
</div>
<Table columns={columns} dataSource={wordList} pagination={false} /> <Table columns={columns} dataSource={wordList} pagination={false} />
</div> </div>
</TabPane> </TabPane>
@@ -300,21 +315,55 @@ const Dataset = () => {
<Form.Item <Form.Item
label="模型名称" label="模型名称"
name="name" name="name"
rules={
[
// {
// required: true,
// message: 'Please input your username!',
// },
]
}
rules={[
{
required: true,
message: '请输入模型名称',
},
]}
> >
<Input disabled placeholder="请输入数据集名称" />
<Input disabled placeholder="请输入模型名称" />
</Form.Item> </Form.Item>
<Form.Item label="模型版本" name="version">
<Input placeholder="请输入数据集版本" />
<Form.Item
label="模型版本"
name="version"
rules={[
{
required: true,
message: '请输入模型版本',
},
]}
>
<Input placeholder="请输入模型版本" maxLength={64} showCount allowClear />
</Form.Item> </Form.Item>
<Form.Item label="模型文件" name="dataset_version_vos">
<Form.Item
label="版本描述"
name="description"
rules={[
{
required: true,
message: '请输入版本描述',
},
]}
>
<Input.TextArea
placeholder="请输入版本描述"
autoSize={{ minRows: 2, maxRows: 6 }}
maxLength={256}
showCount
allowClear
/>
</Form.Item>
<Form.Item
label="模型文件"
name="dataset_version_vos"
rules={[
{
required: true,
message: '请上传模型文件',
},
]}
>
<Upload {...props}> <Upload {...props}>
<Button <Button
style={{ style={{


+ 269
- 247
react-ui/src/pages/Pipeline/index.jsx View File

@@ -1,250 +1,266 @@
import React ,{ useState,useEffect,useRef }from 'react';
import { Space, Table, Tag,Button,Modal, Form, Input ,message} from 'antd';
import { PlusOutlined,PlusCircleOutlined, DeleteOutlined, ExclamationCircleOutlined, DownOutlined, EditOutlined ,CopyOutlined} from '@ant-design/icons';
import {getWorkflow,addWorkflow,removeWorkflow,cloneWorkflow,getWorkflowById,editWorkflow} from '@/services/pipeline/index.js'
import Styles from './index.less'
import momnet from 'moment'
import { useNavigate} from 'react-router-dom';
import {
addWorkflow,
cloneWorkflow,
editWorkflow,
getWorkflow,
getWorkflowById,
removeWorkflow,
} from '@/services/pipeline/index.js';
import { CopyOutlined, DeleteOutlined, EditOutlined, PlusCircleOutlined } from '@ant-design/icons';
import { Button, Form, Input, Modal, Space, Table, message } from 'antd';
import momnet from 'moment';
import { useEffect, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import Styles from './index.less';
const { TextArea } = Input; const { TextArea } = Input;


const Pipeline = React.FC = () => {
const [form] = Form.useForm();
const navgite=useNavigate();
const [formId,setFormId]=useState(null)
const [dialogTitle,setDialogTitle]=useState('新建流水线')
const [pipeList, setPipeList] = useState([]);
const [total, setTotal] = useState(0);
const [isModalOpen, setIsModalOpen] = useState(false);
const editTable=(e,record)=>{
e.stopPropagation()
getWorkflowById(record.id).then(ret=>{
if(ret.code==200){
form.resetFields()
form.setFieldsValue({...ret.data})
setFormId(ret.data.id)
setDialogTitle('编辑流水线')
setIsModalOpen(true)
const Pipeline = () => {
const [form] = Form.useForm();
const navgite = useNavigate();

const [formId, setFormId] = useState(null);
const [dialogTitle, setDialogTitle] = useState('新建流水线');
const [pipeList, setPipeList] = useState([]);
const [total, setTotal] = useState(0);
const [isModalOpen, setIsModalOpen] = useState(false);
const editTable = (e, record) => {
e.stopPropagation();
getWorkflowById(record.id).then((ret) => {
if (ret.code == 200) {
form.resetFields();
form.setFieldsValue({ ...ret.data });
setFormId(ret.data.id);
setDialogTitle('编辑流水线');
setIsModalOpen(true);
}
});
};
const routeToEdit = (e, record) => {
e.stopPropagation();
navgite({ pathname: `/pipeline/pytorchtext/${record.id}/${record.name}` });
};
const showModal = () => {
form.resetFields();
setDialogTitle('新建流水线');
setIsModalOpen(true);
};
const handleOk = () => {
console.log(1111);
setIsModalOpen(false);
};
const handleCancel = () => {
setIsModalOpen(false);
};
const onFinish = (values) => {
if (formId) {
editWorkflow({ ...values, id: formId }).then((ret) => {
message.success('编辑成功');
getList();
setIsModalOpen(false);
});
} else {
addWorkflow(values).then((ret) => {
console.log(ret);
if (ret.code == 200) {
navgite({ pathname: `/pipeline/pytorchtext/${ret.data.id}/${ret.data.name}` });
} }
})
});
} }
const routeToEdit=(e,record)=>{
e.stopPropagation()
navgite({pathname:`/pipeline/pytorchtext/${record.id}/${record.name}` });
}
const showModal = () => {
form.resetFields()
setDialogTitle('新建流水线')
setIsModalOpen(true);
};
const handleOk = () => {
console.log(1111);
setIsModalOpen(false);
};
const handleCancel = () => {
setIsModalOpen(false);
};
const onFinish = (values) => {
if(formId){
editWorkflow({...values,id:formId}).then(ret=>{
message.success('编辑成功')
getList()
setIsModalOpen(false)
})
}
else{
addWorkflow(values).then(ret=>{
console.log(ret);
if(ret.code==200){
navgite({pathname:`/pipeline/pytorchtext/${ret.data.id}/${ret.data.name}`,});
}
}
)
}
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
const pageOption = useRef({ page: 1, size: 10 });
const paginationProps = {
showQuickJumper: true,
showTotal: () => `共${total}条`,
total: total,
page: pageOption.current.page,
size: pageOption.current.size,
onChange: (current, size) => paginationChange(current, size),
};
// 当前页面切换
const paginationChange = async (current, size) => {
console.log('page', current, size);
pageOption.current = {
page: current,
size: size,
}; };
const pageOption = useRef({page: 1,size: 10})
const paginationProps = {
showQuickJumper: true,
showTotal: () => `共${total}条`,
total: total,
page: pageOption.current.page,
getList();
};
const getList = () => {
let params = {
offset: 1,
page: pageOption.current.page - 1,
size: pageOption.current.size, size: pageOption.current.size,
onChange: (current, size) => paginationChange(current, size)
}
// 当前页面切换
const paginationChange = async (current, size) => {
console.log('page', current, size)
pageOption.current={
page:current,
size:size
};
console.log(params, pageOption);
getWorkflow(params).then((ret) => {
if (ret.code == 200) {
setPipeList(ret.data.content);

setTotal(ret.data.totalElements);
} }
getList()
}
const getList=()=>{
let params={
offset:1,
page:pageOption.current.page-1,
size:pageOption.current.size
}
console.log(params,pageOption);
getWorkflow(params).then(ret=>{
if(ret.code==200){
setPipeList(ret.data.content)
setTotal(ret.data.totalElements)
}
});
};
useEffect(() => {
getList();
}, []);
const columns = [
{
title: '序号',
dataIndex: 'index',
key: 'index',
width: 80,
render(text, record, index) {
return <span>{(pageOption.current.page - 1) * 10 + index + 1}</span>;
},
// render: (text, record, index) => `${((curPage-1)*10)+(index+1)}`,
},
{
title: '流水线名称',
dataIndex: 'name',
key: 'name',
render: (text, record) => <a onClick={(e) => routeToEdit(e, record)}>{text}</a>,
},
{
title: '流水线描述',
dataIndex: 'description',
key: 'description',
},
{
title: '创建时间',
dataIndex: 'create_time',
key: 'create_time',
render: (text) => <span>{momnet(text).format('YYYY-MM-DD HH:mm:ss')}</span>,
},
{
title: '修改时间',
dataIndex: 'update_time',
key: 'update_time',
render: (text) => <span>{momnet(text).format('YYYY-MM-DD HH:mm:ss')}</span>,
},
{
title: '操作',
key: 'action',


})
}
useEffect(()=>{
getList()
},[])
const columns = [
{
title: '序号',
dataIndex: 'index',
key: 'index',
width: 80,
render(text, record, index) {
return (
<span>{(pageOption.current.page - 1) * 10 + index + 1}</span>
)
}
// render: (text, record, index) => `${((curPage-1)*10)+(index+1)}`,
},
{
title: '流水线名称',
dataIndex: 'name',
key: 'name',
render: (text,record) => <a onClick={(e)=>routeToEdit(e,record)}>{text}</a>,
},
{
title: '流水线描述',
dataIndex: 'description',
key: 'description',
},
{
title: '创建时间',
dataIndex: 'create_time',
key: 'create_time',
render: (text) => <span>{momnet(text).format('YYYY-MM-DD HH:mm:ss')}</span>,
},
{
title: '修改时间',
dataIndex: 'update_time',
key: 'update_time',
render: (text) => <span>{momnet(text).format('YYYY-MM-DD HH:mm:ss')}</span>,
},
{
title: '操作',
key: 'action',
render: (_, record) => (
<Space size="small">
<Button
type="link"
size="small"
key="edit"
icon = {< EditOutlined />}
onClick={(e) => {
editTable(e,record)
}}
>
编辑
</Button>
<Button
type="link"
size="small"
key="clone"
icon = {< CopyOutlined />}
onClick={async () => {
Modal.confirm({
title: '复制',
content: '确定复制该条流水线吗?',
okText: '确认',
cancelText: '取消',
onOk: () => {
console.log(record);
cloneWorkflow(record.id).then(ret=>{
if(ret.code==200){
message.success('复制成功')
getList()
render: (_, record) => (
<Space size="small">
<Button
type="link"
size="small"
key="edit"
icon={<EditOutlined />}
onClick={(e) => {
editTable(e, record);
}}
>
编辑
</Button>
<Button
type="link"
size="small"
key="clone"
icon={<CopyOutlined />}
onClick={async () => {
Modal.confirm({
title: '复制',
content: '确定复制该条流水线吗?',
okText: '确认',
cancelText: '取消',
onOk: () => {
console.log(record);
cloneWorkflow(record.id).then((ret) => {
if (ret.code == 200) {
message.success('复制成功');
getList();
} else {
message.error('复制失败');
} }
else{
message.error('复制失败')
});

// if (success) {
// if (actionRef.current) {
// actionRef.current.reload();
// }
// }
},
});
}}
>
复制
</Button>
<Button
type="link"
size="small"
danger
style={{ color: '#f98e1b' }}
key="batchRemove"
icon={<DeleteOutlined />}
onClick={async () => {
Modal.confirm({
title: '删除',
content: '确定删除该条流水线吗?',
okText: '确认',
cancelText: '取消',
onOk: () => {
console.log(record);
removeWorkflow(record.id).then((ret) => {
if (ret.code == 200) {
message.success('删除成功');
getList();
} else {
message.error(ret.msg);
} }
});
// if (success) {
// if (actionRef.current) {
// actionRef.current.reload();
// }
// }
},
});
}}
>
复制
</Button>
});

// if (success) {
// if (actionRef.current) {
// actionRef.current.reload();
// }
// }
},
});
}}
>
删除
</Button>
</Space>
),
},
];
return (
<div>
<div className={Styles.pipelineTopBox}>
<Button <Button
type="link"
size="small"
danger
style={{color:'#f98e1b'}}
key="batchRemove"
icon = {< DeleteOutlined />}
onClick={async () => {
Modal.confirm({
title: '删除',
content: '确定删除该条流水线吗?',
okText: '确认',
cancelText: '取消',
onOk: () => {
console.log(record);
removeWorkflow(record.id).then(ret=>{
if(ret.code==200){
message.success('删除成功')
getList()
}
else{
message.error(ret.msg)
}
});
// if (success) {
// if (actionRef.current) {
// actionRef.current.reload();
// }
// }
},
});
}}
type="primary"
className={Styles.plusButton}
onClick={showModal}
icon={<PlusCircleOutlined style={{ color: '#1664ff' }} />}
> >
删除
</Button>
</Space>
),
},
];
return (<div>
<div className={Styles.pipelineTopBox}>
<Button type="primary" className={Styles.plusButton} onClick={showModal} icon = {<PlusCircleOutlined style={{color:'#1664ff'}} />}>
新建流水线 新建流水线
</Button> </Button>
</div>
<Table columns={columns} dataSource={pipeList} pagination={paginationProps}/>
<Modal title={<div style={{display:'flex',alignItems:'center',fontWeight:500}}>
<img style={{width:'20px',marginRight:'10px'}} src={`/assets/images/pipeline-edit-icon.png`} alt="" />{dialogTitle}
</div>} open={isModalOpen} className={Styles.modal} okButtonProps={{
htmlType: 'submit',
form: 'form',
}} onCancel={handleCancel}>
</div>
<Table columns={columns} dataSource={pipeList} pagination={paginationProps} />
<Modal
title={
<div style={{ display: 'flex', alignItems: 'center', fontWeight: 500 }}>
<img
style={{ width: '20px', marginRight: '10px' }}
src={`/assets/images/pipeline-edit-icon.png`}
alt=""
/>
{dialogTitle}
</div>
}
open={isModalOpen}
className={Styles.modal}
okButtonProps={{
htmlType: 'submit',
form: 'form',
}}
onCancel={handleCancel}
>
<Form <Form
name="form" name="form"
form={form} form={form}
@@ -259,28 +275,34 @@ const Pipeline = React.FC = () => {
<Form.Item <Form.Item
label="流水线名称" label="流水线名称"
name="name" name="name"
rules={[
// {
// required: true,
// message: 'Please input your username!',
// },
]}
rules={
[
// {
// required: true,
// message: 'Please input your username!',
// },
]
}
> >
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="流水线描述" label="流水线描述"
name="description" name="description"
rules={[
// {
// required: true,
// message: 'Please input your username!',
// },
]}
rules={
[
// {
// required: true,
// message: 'Please input your username!',
// },
]
}
> >
<Input /> <Input />
</Form.Item> </Form.Item>
</Form> </Form>
</Modal> </Modal>
</div>)};
export default Pipeline;
</div>
);
};
export default Pipeline;

+ 2
- 1
react-ui/src/requestConfig.ts View File

@@ -40,7 +40,8 @@ export const requestConfig: RequestConfig = {
responseInterceptors: [ responseInterceptors: [
(response: any) => { (response: any) => {
const { status, data } = response; const { status, data } = response;
if (status && status >= 200 && status < 300 && data && data.code === 200) {
// console.log('response', response);
if (status >= 200 && status < 300 && data && (data instanceof Blob || data.code === 200)) {
return response; return response;
} else { } else {
if (data && data.msg) { if (data && data.msg) {


+ 8
- 0
react-ui/src/styles/theme.less View File

@@ -0,0 +1,8 @@
// 全局颜色变量

@primary-color: #1664ff; // 主色调

// 导出变量
:export {
primaryColor: #1664ff; // FIXME: 设置为 @primary-color 不起作用,感觉是哪里被重置了
}

Loading…
Cancel
Save