Commit f5e017ed by zhaochengxiang

数据模型静态页面

parent d34b1819
......@@ -14,9 +14,12 @@
"core-js": "^3.4.2",
"craco-less": "^1.17.1",
"crypto-js": "^4.0.0",
"immutability-helper": "^3.1.1",
"less": "^4.1.1",
"less-loader": "^8.0.0",
"react": "^17.0.1",
"react-dnd": "^14.0.2",
"react-dnd-html5-backend": "^14.0.0",
"react-dom": "^17.0.1",
"react-redux": "^7.1.0",
"react-router-dom": "^5.0.1",
......
import * as service from '../service/assets';
import { call } from 'redux-saga/effects';
export function* getDomainsAndHotwords(payload) {
const domains = yield call(service.domains, null);
const hotwords = yield call(service.getHotWord, payload);
return {domains: domains||[], hotwords: hotwords||[]};
}
export function* domains(payload) {
return yield call(service.domains, payload);
}
export function* getHotWord(payload) {
return yield call(service.getHotWord, payload);
}
export function* searchTableModelsByPage(payload) {
return yield call(service.searchTableModelsByPage, payload);
}
export function* queryTopicAsTree(payload) {
return yield call(service.queryTopicAsTree, payload);
}
export function* listCatalogTableModelsByPage(payload) {
return yield call(service.listCatalogTableModelsByPage, payload);
}
export function* listTableModelColumnsWithQuerySql(payload) {
return yield call(service.listTableModelColumnsWithQuerySql, payload);
}
export function* listTableModelSampleDatas(payload) {
return yield call(service.listTableModelSampleDatas, payload);
}
export function* getMetadata(payload) {
const items = yield call(service.getMetadata, payload);
const args = { metedata: items, download: false};
if(items && items.namePath){
const download = yield call(service.isHaveUploadFile, items.namePath);
if(download === 1) args.download = true
}
return args;
}
export function* subscribeTableModel(payload) {
return yield call(service.subscribeTableModel, payload);
}
export function* unSubscribeTableModel(payload) {
return yield call(service.unSubscribeTableModel, payload);
}
export function* setTableModelScore(payload) {
return yield call(service.setTableModelScore, payload);
}
export function* apply(payload) {
return yield call(service.apply, payload);
}
export function* getDataFlowCount(payload) {
return yield call(service.getDataFlowCount, payload);
}
export function* uploadAttachment(payload) {
return yield call(service.uploadAttachment, payload);
}
export function* treeQuery(payload) {
return yield call(service.treeQuery,payload);
}
export function* fileQuery(payload) {
return yield call(service.fileQuery, payload);
}
\ No newline at end of file
import * as userService from '../service/user';
import * as metadataService from '../service/metadata';
import { call } from 'redux-saga/effects';
export function* getAllSystemAndDatabase() {
const roleData = yield call(userService.queryRoles);
let isAdminMode = false;
roleData && roleData.roleData && roleData.roleData.forEach((item) => {
if(item.roleId === 2) {
isAdminMode=true;
}
})
const systems = yield call(userService.queryUserSystem, { isAdminMode });
let dbData = [];
if (systems.length) {
const _system = systems[0].scopeId;
dbData = yield call(metadataService.queryDatabase, { sysCodeList: _system });
}
return { systems, dbs: [ { value: '', name: '所有数据源' } , ...(dbData||[])] };
}
export function* getAllSystemDatabase(payload) {
const dbData = yield call(metadataService.queryDatabase, payload);
return [ { value: '', name: '所有数据源' } , ...(dbData||[])];
}
export function* getAllScheme(payload) {
let value = payload.db.split(',');
const schemaData = yield call(metadataService.querySchemeByParentId, {parentId:value[0]});
return [ { value: '', name: '所有Schema' } , ...(schemaData||[])]
}
export function* getAllDataTable(payload) {
return yield call(metadataService.queryAllDataTable, payload);
}
export function* getAllFileds(payload) {
return yield call(metadataService.queryAllFields, payload);
}
\ No newline at end of file
......@@ -7,11 +7,10 @@ import { SetSource, Cancel } from '../util/axios'
import { Connect } from '../util';
import { reducers } from './reducer';
import * as user from './user';
import * as assets from './assets';
import * as metadata from './metadata';
import * as map from './map';
import * as datamodel from './datamodel';
const funcs = Connect({ user, assets, metadata, map })
const funcs = Connect({ user, datamodel, map })
function* request(args) {
const { type, payload, callback, error } = args.args;
......
import * as service from '../service/metadata';
import { call } from 'redux-saga/effects';
export function* queryTopicAsTree(payload) {
let treeData = yield call(service.queryTopicAsTree, payload);
treeData = treeData || [];
for (let node of treeData) {
let children = yield call(service.queryChildTopicAsTree, {
parentId: node._id,
model: payload.model
});
children = children||[];
children.map(cnode=> {
cnode.title = cnode.name || '';
cnode.key = cnode._id;
return cnode;
})
node.loadData = true;
node.children = children;
node.title = node.name || '';
node.key = node._id;
node.isLeaf = (children.length===0)?true:false;
}
return treeData;
}
export function* queryChildTopicAsTree(payload) {
let childTreeData = yield call(service.queryChildTopicAsTree, payload);
childTreeData = childTreeData||[];
childTreeData.map(cnode=> {
cnode.title = cnode.name || '';
cnode.key = cnode._id;
return cnode;
})
return childTreeData;
}
export function* tableModelsByPage(payload) {
return yield call(service.tableModelsByPage, payload);
}
......@@ -12,31 +12,3 @@ export function* signin(payload) {
export function* signout() {
return yield call(service.signout);
}
export function* getUserSubscribeTableModels(payload) {
return yield call(service.getUserSubscribeTableModels, payload);
}
export function* listPrivilegeTableModels(payload) {
return yield call(service.listPrivilegeTableModels, payload);
}
export function* questions(payload) {
return yield call(service.questions, payload);
}
export function* saveQuestion(payload) {
return yield call(service.saveQuestion, payload);
}
export function* domains(payload) {
return yield call(service.domains, payload);
}
export function* listProcessByPage(payload) {
return yield call(service.listProcessByPage, payload);
}
export function* confirmProcess(payload){
return yield call(service.confirmProcess, payload);
}
import { PostJSON, Post, GetJSON, testPost } from "../util/axios"
export function domains(payload) {
return GetJSON("/authservice/domains", payload);
}
export function getHotWord(payload) {
return GetJSON("/datacatalog/front/getHotWord", payload)
}
export function searchTableModelsByPage(payload) {
return GetJSON("/datacatalog/front/searchTableModelsByPage", payload)
}
export function queryTopicAsTree(payload) {
return GetJSON("/datacatalog/front/queryTopicAsTree", payload)
}
export function listCatalogTableModelsByPage(payload) {
return GetJSON("/datacatalog/front/listCatalogTableModelsByPage", payload)
}
export function listTableModelColumnsWithQuerySql(payload) {
return GetJSON("/datacatalog/front/listTableModelColumnsWithQuerySql", payload);
}
export function listTableModelSampleDatas(payload) {
return GetJSON("/datacatalog/front/listTableModelSampleDatas", payload);
}
export async function getMetadata(payload) {
return GetJSON(`/metadatarepo/rest/metadata/get/${encodeURIComponent(payload)}`, null);
}
export async function isHaveUploadFile(payload) {
return GetJSON(`/metadataharvester/rest/fileExcelPdf/isHaveUploadFile?namePath=${payload}`,null);
}
export async function subscribeTableModel(payload) {
return PostJSON("/datacatalog/front/subscribeTableModel",payload);
}
export async function unSubscribeTableModel(payload) {
return PostJSON("/datacatalog/front/unSubscribeTableModel",payload);
}
export async function setTableModelScore(payload) {
return Post("/datacatalog/front/setTableModelScore",payload);
}
export async function apply(payload){
return Post('/datacatalog/front/apply', payload);
}
export function getDataFlowCount(payload) {
return GetJSON('/metadatarepo/rest/jobInfo/getDataFlowCount')
}
export function uploadAttachment(payload) {
return testPost('/datacatalog/front/uploadAttachment',payload)
}
export function treeQuery(payload) {
return GetJSON('/informationmanagement/rest/fileCatalog/query')
}
export function fileQuery(payload) {
return GetJSON('/informationmanagement/rest/fileInformation/queryAll',payload)
}
import { GetJSON } from "../util/axios"
export function queryTopicAsTree(payload) {
return GetJSON("/metadatarepo/rest/metadata/getChildByPathAndClass", payload);
export function queryDatabase(payload) {
return GetJSON("/metadatarepo/rest/tag/getDatabaseBySystemCode", payload);
}
export function queryChildTopicAsTree(payload) {
export function querySchemeByParentId(payload) {
return GetJSON("/metadatarepo/rest/metadata/getChild", payload);
}
export function tableModelsByPage(payload) {
return GetJSON("/metadatarepo/rest/metadata/getPageChild", payload)
export function queryAllDataTable(payload) {
return GetJSON("/metadatarepo/rest/tag/pageTree", payload);
}
export function queryAllFields(payload) {
return GetJSON("/metadatarepo/rest/metadata/getChild", payload);
}
\ No newline at end of file
......@@ -11,31 +11,10 @@ export function signout() {
return Post("/auth/signout")
}
export function getUserSubscribeTableModels(payload) {
return GetJSON("/datacatalog/front/getUserSubscribeTableModels")
export function queryRoles() {
return GetJSON("/authservice/personal/roles");
}
export function listPrivilegeTableModels(payload) {
return GetJSON("/datacatalog/front/listPrivilegeTableModels")
}
export async function questions(payload) {
return GetJSON("/questionfeedback/rest/issuetrack/mylist", payload);
}
export async function saveQuestion(payload) {
return PostJSON("/questionfeedback/rest/issuetrack/save", payload);
}
export async function domains(payload) {
return GetJSON(`/authservice/users/${payload.userId}/domains`, payload);
}
export async function listProcessByPage(payload) {
return GetJSON("/datacatalog/front/listProcessByPage",payload)
}
export async function confirmProcess(payload) {
return PostJSON(`/datacatalog/front/confirmProcess?processId=${payload.processId}`)
export function queryUserSystem(payload) {
return GetJSON("/authservice/personal/grantedScopes", payload);
}
\ No newline at end of file
import axios from 'axios';
import { message } from 'antd';
import { Open, ContextPath, IsArr } from './index';
import { IsArr } from './index';
const CancelToken = axios.CancelToken;
const baseURL = '/api/';
......
import React from 'react';
import { Modal, Radio, Button } from 'antd';
const modes = [
{
title: '导出DDL',
},
{
title: '导出Erwin',
},
{
title: '导出Excel',
},
{
title: '导出模型文档'
},
]
class ExportModal extends React.Component {
constructor() {
super();
this.state = {
confirmLoading: false
}
}
onModeClick = (index) => {
}
handleOk = () => {
const { onCancel } = this.props;
if (onCancel) {
onCancel();
}
}
render() {
const { visible, onCancel } = this.props;
const { confirmLoading } = this.state;
return (
<Modal
visible={visible}
title={"导出方式"}
destroyOnClose
onOk={this.handleOk}
onCancel={onCancel}
footer={[
<Button
key="0"
loading={confirmLoading}
type="primary"
onClick={this.handleOk}
>
导出
</Button>
]}
>
<Radio.Group>
{
modes && modes.map((mode, index) => {
return (
<Radio key={index} value={index}>
{ mode.title||'' }
</Radio>
);
})
}
</Radio.Group>
</Modal>
)
}
}
export default ExportModal
\ No newline at end of file
import React, { useState, useCallback, useRef } from 'react';
import { Table, Input, InputNumber, Popconfirm, Form, Typography } from 'antd';
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import update from 'immutability-helper';
const originData = [];
const type = 'DragableBodyRow';
for (let i = 0; i < 20; i++) {
originData.push({
key: i.toString(),
name: `交易流水${i}`,
cnName: 'trade_id',
type: 'varchar',
length: 32,
desc: '流水单号'
});
}
const DragableBodyRow = ({ index, moveRow, className, style, ...restProps }) => {
const ref = useRef();
const [{ isOver, dropClassName }, drop] = useDrop(
() => ({
accept: type,
collect: monitor => {
const { index: dragIndex } = monitor.getItem() || {};
if (dragIndex === index) {
return {};
}
return {
isOver: monitor.isOver(),
dropClassName: dragIndex < index ? ' drop-over-downward' : ' drop-over-upward',
};
},
drop: item => {
moveRow(item.index, index);
},
}),
[index],
);
const [, drag] = useDrag(
() => ({
type,
item: { index },
collect: monitor => ({
isDragging: monitor.isDragging(),
}),
}),
[index],
);
drop(drag(ref));
return (
<tr
ref={ref}
className={`${className}${isOver ? dropClassName : ''}`}
style={{ cursor: 'move', ...style }}
{...restProps}
/>
);
};
const EditableCell = ({
editing,
dataIndex,
title,
inputType,
record,
index,
children,
...restProps
}) => {
const inputNode = inputType === 'number' ? <InputNumber /> : <Input />;
return (
<td {...restProps}>
{editing ? (
<Form.Item
name={dataIndex}
style={{
margin: 0,
}}
rules={[
{
required: true,
message: `Please Input ${title}!`,
},
]}
>
{inputNode}
</Form.Item>
) : (
children
)}
</td>
);
};
const ImportAction = () => {
const [form] = Form.useForm();
const [data, setData] = useState(originData);
const [editingKey, setEditingKey] = useState('');
const dataRef = useRef();
dataRef.current = data;
const isEditing = (record) => record.key === editingKey;
const edit = (record) => {
form.setFieldsValue({
name: '',
age: '',
address: '',
...record,
});
setEditingKey(record.key);
};
const cancel = () => {
setEditingKey('');
};
const save = async (key) => {
try {
const row = await form.validateFields();
const newData = [...data];
const index = newData.findIndex((item) => key === item.key);
if (index > -1) {
const item = newData[index];
newData.splice(index, 1, { ...item, ...row });
setData(newData);
setEditingKey('');
dataRef.current = newData;
} else {
newData.push(row);
setData(newData);
setEditingKey('');
dataRef.current = newData;
}
} catch (errInfo) {
console.log('Validate Failed:', errInfo);
}
};
const columns = [
{
title: '中文名称',
dataIndex: 'name',
editable: true,
},
{
title: '英文名称',
dataIndex: 'cnName',
editable: true,
},
{
title: '类型',
dataIndex: 'type',
editable: true,
},
{
title: '长度',
dataIndex: 'length',
editable: true,
},
{
title: '描述',
dataIndex: 'desc',
editable: true,
},
{
title: '操作',
dataIndex: 'action',
render: (_, record) => {
const editable = isEditing(record);
return editable ? (
<span>
<a
href="javascript:;"
onClick={() => save(record.key)}
style={{
marginRight: 8,
}}
>
保存
</a>
<Popconfirm title="Sure to cancel?" onConfirm={cancel}>
<a>取消</a>
</Popconfirm>
</span>
) : (
<Typography.Link disabled={editingKey !== ''} onClick={() => edit(record)}>
编辑
</Typography.Link>
);
},
},
];
const mergedColumns = columns.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record) => ({
record,
inputType: col.dataIndex === 'age' ? 'number' : 'text',
dataIndex: col.dataIndex,
title: col.title,
editing: isEditing(record),
}),
};
});
const moveRow = useCallback(
(dragIndex, hoverIndex) => {
const dragRow = dataRef.current[dragIndex];
const newData = update(dataRef.current, {
$splice: [
[dragIndex, 1],
[hoverIndex, 0, dragRow],
],
});
setData(newData);
dataRef.current = newData;
},
[data],
);
return (
<DndProvider backend={HTML5Backend}>
<Form form={form} component={false}>
<Table
components={{
body: {
cell: EditableCell,
row: DragableBodyRow,
},
}}
onRow={(record, index) => ({
index,
moveRow,
})}
bordered
dataSource={data}
columns={mergedColumns}
size='small'
rowClassName="editable-row"
pagination={false}
/>
</Form>
</DndProvider>
);
};
export default ImportAction;
\ No newline at end of file
import React from 'react';
import { Button, Upload } from 'antd';
import { DownloadOutlined, UploadOutlined } from '@ant-design/icons';
class ImportExcel extends React.Component {
constructor() {
super();
this.state = {
fileList: []
};
}
render() {
const uploadProps = {
onRemove: file => {
this.setState(state => {
const index = state.fileList.indexOf(file)
const newFileList = state.fileList.slice()
newFileList.splice(index, 1)
return {
fileList: newFileList,
}
})
},
beforeUpload: file => {
this.setState(state => ({
fileList: [file],
}))
return false;
}
};
return (
<>
<div>
<Button icon={<DownloadOutlined />}>
模版下载
</Button>
</div>
<div className='mt-3'>
<Upload {...uploadProps}>
<Button icon={<UploadOutlined />}>
选择文件上传
</Button>
</Upload>
</div>
</>
)
}
}
export default ImportExcel;
\ No newline at end of file
import React from 'react';
import { Table, Space, Tooltip, Button, Pagination, Divider } from 'antd';
import { ReconciliationOutlined } from '@ant-design/icons';
import { paginate } from '../../../../util';
const columns = [
{
title: '导入名称',
dataIndex: 'name',
},
{
title: '导入方式',
dataIndex: 'model',
},
{
title: '开始时间',
dataIndex: 'startTime',
},
{
title: '结束时间',
dataIndex: 'endTime'
},
{
title: '状态',
dataIndex: 'status'
},
{
title: '操作',
key: 'action',
render: (text,record) => {
return (
<Space size='small'>
<Tooltip placement='bottom' title={'详情'}>
<Button icon={<ReconciliationOutlined />} size='small' />
</Tooltip>
</Space>
)
}
}
];
const data = [];
for (let i = 0; i < 46; i++) {
data.push({
key: i,
name: `t_szse_transaction${i}`,
model: 'excel导入',
startTime: '2020-01-01 00:00:01',
endTime: '2020-01-01 00:10:01',
status: '成功'
});
}
class ImportLog extends React.Component {
constructor() {
super();
this.state = {
pageNum: 1,
pageSize: 10
};
}
render() {
const { pageNum, pageSize } = this.state;
const _data = paginate(data, pageNum, pageSize);
return (
<>
<Divider orientation="left">导入日志</Divider>
<Table
columns={columns}
dataSource={_data}
pagination={false}
size='small'
/>
<Pagination
className="text-center mt-3"
showSizeChanger
showQuickJumper
onChange={(_pageNum, _pageSize) => {
this.setState({ pageNum: _pageNum, pageSize: _pageSize || 10 });
}}
onShowSizeChange={(_pageNum, _pageSize) => {
this.setState({ pageNum: _pageNum || 1, pageSize: _pageSize });
}}
current={pageNum}
pageSize={pageSize}
defaultCurrent={1}
total={(data||[]).length}
showTotal={total => `共 ${total} 条`}
/>
</>
)
}
}
export default ImportLog;
\ No newline at end of file
import React from 'react';
import { Select, Pagination, Input, Table, Row, Col } from "antd"
import { dispatchLatest } from '../../../../model';
const { Option } = Select;
class ImportMetadata extends React.Component {
constructor() {
super();
this.state = {
systems: [],
dbs: [{ value: '', name: '所有数据源' }],
schemas: [{ value: '', name: '所有Schema' }],
modelPaths: [
{ value: '', name: '所有类型' },
{ value: 'Catalog,Database,Schema,HanaView', name: 'HANA视图' },
{ value: 'Catalog,Database,Schema,Table', name: '数据表' },
{ value: 'Catalog,Database,Schema,View', name: '数据视图' },
{ value: 'Catalog,Database,Schema,Function', name: '函数' },
{ value: 'Catalog,Database,Schema,Procedure', name: '存储过程' },
],
dataTables: [],
totalDataTables: 0,
dataFileds: [],
system: '',
db: '',
schema: '',
modelPath: '',
keyboard: '',
pageNumDataTables: 1,
pageSizeDataTables: 20,
loadingDataTable: false,
loadingDataFiled: false,
loadingSystem: false,
loadingDb: false,
loadingSchema: false,
selectedDataTableRowKeys: [],
selectedDataFiledRowKeys: [],
dataTableColumns: [
{ title: '名称', dataIndex: 'name', key: 'name' },
{ title: '中文名称', dataIndex: 'cnName', key: 'cnName' },
{ title: '描述', dataIndex: 'comment', key: 'comment' },
],
dataFiledColumns: [
{ title: '目标表字段', dataIndex: 'name', key: 'name' },
]
};
}
componentDidMount() {
this.setState({ loadingSystem: true, loadingDb: true }, () => {
dispatchLatest({
type: 'datamodel.getAllSystemAndDatabase',
callback: data => {
if (data && data.systems && data.systems.length) {
const _system = data.systems[0].scopeId;
this.setState({ loadingSystem: false, loadingDb: false, systems: data.systems, system: _system, dbs: data.dbs, db: '', schema: '' }, () => {
this.fetchAllDataTable();
})
} else {
this.setState({ loadingSystem: false });
}
}
})
})
}
systemOnChanged = (value) => {
if (value === '') {
this.setState({
system: value,
dbs: [{ value: '', name: '所有数据源' }],
schemas: [{ value: '', name: '所有Schema' }],
db: '',
schema: ''
})
} else {
this.setState({ loadingDb: true, system: value }, () => {
dispatchLatest({
type: "datamodel.getAllSystemDatabase",
payload: {
sysCodedataTables: value
},
callback: dbs => {
this.setState({ loadingDb: false, dbs: dbs||[], db: '', schema: '' })
}
});
});
}
}
dbOnChanged = (value) => {
if (value === '') {
this.setState({ db: value, schemas: [{ value: '', name: '所有Schema' }], schema: '' })
} else {
this.setState({ loadingSchema: true, db: value }, () => {
dispatchLatest({
type: "datamodel.getAllScheme",
payload: {
db: value
},
callback: schemas => {
this.setState({ loadingSchema: false, schemas, schema: '' });
}
});
})
}
}
schemaOnChanged = (value) => {
this.setState({ schema: value });
}
modelPathOnChanged = (value) => {
this.setState({ modelPath: value });
}
sizeChangeOnDataTable = (pageNum, pageSize=20) => {
this.setState({ pageNumDataTables: pageNum, pageSizeDataTables: pageSize });
}
sizeChangeOnDataField = (pageNum, pageSize=20) => {
this.setState({ pageNumDataFileds: pageNum, pageSizeDataFileds: pageSize });
}
fetchAllDataTable = () => {
const { system, db, schema, modelPath, pageNumDataTables, pageSizeDataTables, keyboard } = this.state;
let _db = '';
if(db !== '' && db.split(',').length > 1) {
_db = db.split(',')[1];
}
this.setState({ loadingDataTable: true }, () => {
dispatchLatest({
type: "datamodel.getAllDataTable",
payload: {
pageNum: pageNumDataTables,
pageSize: pageSizeDataTables,
name: keyboard,
sysId: system,
database: _db,
schema,
modelPath
},
callback: data => {
this.setState({ loadingDataTable: false, dataTables: (data||[]).content||[], totalDataTables: (data||[]).totalElements||0 })
}
});
})
}
render() {
const { systems, dbs, schemas, modelPaths, system, db, schema, modelPath, pageNumDataTables, pageSizeDataTables, loadingDataTable, loadingDataFiled, loadingSystem, loadingDb, loadingSchema, dataTables, dataFileds, totalDataTables, dataTableColumns, dataFiledColumns } = this.state;
const rowDataTableSelection = {
type: 'radio',
onChange: (selectedRowKeys, selectedRows) => {
this.setState({ selectedDataTableRowKeys: selectedRowKeys, loadingDataFiled: true }, () => {
dispatchLatest({
type: "datamodel.getAllFileds",
payload: {
parentId: selectedRowKeys[0],
model:'Column,InterfaceColumn,HanaViewColumn'
},
callback: data => {
this.setState({ loadingDataFiled: false, dataFileds: data||[] })
}
});
})
},
};
const rowDataFiledSelection = {
type: 'radio',
onChange: (selectedRowKeys, selectedRows) => {
this.setState({ selectedDataFiledRowKeys: selectedRowKeys });
},
};
return (
<>
<div style={{paddingTop:10}}>
<Select
value={system}
style={{ width: 146 }}
loading={loadingSystem}
onChange={this.systemOnChanged}
>
{
systems && systems.map((item, index) => {
return <Option key={index} value={item.scopeId}>{item.scopeName||''}</Option>;
})
}
</Select>
<Select
value={db}
onChange={this.dbOnChanged}
loading={loadingDb}
style={{ width: 150,marginLeft:10 }}
>
{
dbs && dbs.map((item, index) => {
return <Option key={index} value={item.value===''?'':(item._id+','+item.name)}>{item.name}</Option>;
})
}
</Select>
<Select
value={schema}
loading={loadingSchema}
onChange={this.schemaOnChanged}
style={{ width: 150,marginLeft:10 }}
>
{
schemas && schemas.map((item, index) => {
return <Option key={index} value={item.value===''?'':item.name}>{item.name}</Option>;
})
}
</Select>
<Select
value={modelPath}
onChange={this.modelPathOnChanged}
style={{ width: 150,marginLeft:10 }}
>
{
modelPaths && modelPaths.map((item, index) => {
return <Option key={index} value={item.value}>{item.name}</Option>;
})
}
</Select>
</div>
<div style={{margin:'10px 0'}}>
<Input.Search style={{width:180,marginLeft:10}}
onChange={e=>{ this.setState({ keyboard: e.target.value })}}
placeholder={"请输入关键字"}
enterButton
onSearch={()=>{this.fetchAllDataTable()}}
/>
</div>
<Row gutter={10}>
<Col span={12}>
<Table
columns={dataTableColumns}
rowKey="_id"
size="small"
loading={loadingDataTable}
dataSource={dataTables}
pagination={false}
rowSelection={rowDataTableSelection}
/>
<Pagination
showTotal={total => `共 ${total} 条`}
showSizeChanger
size="small"
pageSize={pageSizeDataTables}
pageSizeOptions={['20','60','100']}
current={pageNumDataTables}
onShowSizeChange={this.sizeChangeOnDataTable}
onChange={this.sizeChangeOnDataTable}
total={totalDataTables}
style={{marginTop:10}}
/>
</Col>
<Col span={12}>
<Table
columns={dataFiledColumns}
rowKey="_id"
size="small"
loading={loadingDataFiled}
dataSource={dataFileds}
pagination={false}
rowSelection={rowDataFiledSelection}
/>
</Col>
</Row>
</>
)
}
}
export default ImportMetadata;
\ No newline at end of file
import React from 'react';
import { Modal, Radio, Button } from 'antd';
import ImportLog from './ImportLog';
import ImportExcel from './ImportExcel';
import ImportMetadata from './ImportMetadata';
import ImportAction from './ImportAction';
const modes = [
{
title: 'Excel导入',
},
{
title: 'Excel复制粘贴',
},
{
title: 'Erwin',
},
{
title: '元数据输入',
},
{
title: '数据模型输入',
}
]
class ImportModal extends React.Component {
constructor() {
super();
this.state = {
step: 0,
radioValue: ''
}
}
onRadioChange = e => {
this.setState({
radioValue: e.target.value
});
};
prev = () => {
this.setState({
step: (this.state.step-1)
})
}
next = () => {
this.setState({
step: (this.state.step+1)
})
}
render() {
const { visible, onCancel } = this.props;
const { radioValue, step } = this.state;
return (
<Modal
visible={visible}
title={"导入方式"}
width={1000}
maskClosable={false}
destroyOnClose
onCancel={() => {
this.setState({ step: 0 }, () => {
if (onCancel) {
onCancel();
}
})
}}
footer={[
<Button
key="0"
type="primary"
style={{ display: (step!==0)?'':'none' }}
onClick={this.prev}
>
上一步
</Button>,
<Button
key="1"
type="primary"
style={{ display: (step<2)?'':'none' }}
onClick={this.next}
>
下一步
</Button>,
<Button
key="2"
type="primary"
style={{ display: (step===2)?'':'none' }}
>
保存
</Button>
]}
>
<>
{
step===0 && <>
<Radio.Group onChange={this.onRadioChange}>
{
modes && modes.map((mode, index) => {
return (
<Radio key={index} value={index}>
{ mode.title||'' }
</Radio>
);
})
}
</Radio.Group>
<ImportLog />
</>
}
{
step===1 && radioValue===0 && <ImportExcel />
}
{
step===1 && radioValue===1 && <></>
}
{
step===1 && radioValue===2 && <></>
}
{
step===1 && radioValue===3 && <ImportMetadata />
}
{
step===1 && radioValue===4 && <></>
}
{
step===2 && <ImportAction />
}
</>
</Modal>
)
}
}
export default ImportModal;
\ No newline at end of file
import React from "react";
import { Table, Pagination, Space, Button, Tooltip } from 'antd';
import { EditOutlined, CheckOutlined, ReconciliationOutlined, DeleteOutlined } from '@ant-design/icons';
import { paginate } from '../../../../util';
const columns = [
{
title: '模型名称',
dataIndex: 'name',
},
{
title: '中文名称',
dataIndex: 'cnName',
},
{
title: '模型描述',
dataIndex: 'remark',
},
{
title: '状态',
dataIndex: 'status'
},
{
title: '更新时间',
dataIndex: 'updateTime'
},
{
title: '操作',
key: 'action',
render: (text,record) => {
return (
<Space size='small'>
<Tooltip placement='bottom' title={'修改'}>
<Button icon={<EditOutlined />} size='small' />
</Tooltip>
<Tooltip placement='bottom' title={'详情'}>
<Button icon={<ReconciliationOutlined />} size='small' />
</Tooltip>
<Tooltip placement='bottom' title={'提交审核'}>
<Button icon={<CheckOutlined />} size='small' />
</Tooltip>
<Tooltip placement='bottom' title={'删除'}>
<Button icon={<DeleteOutlined />} size='small' />
</Tooltip>
</Space>
)
}
}
];
const data = [];
for (let i = 0; i < 46; i++) {
data.push({
key: i,
name: `t_szse_transaction${i}`,
cnName: '所内交易表',
remark: '测试',
status: '未通过',
updateTime: '2021-03-22'
});
}
class ModelTable extends React.Component {
constructor() {
super();
this.state = {
selectedRowKeys: null,
pageNum: 1,
pageSize: 10
};
}
onSelectChange = selectedRowKeys => {
console.log('selectedRowKeys changed: ', selectedRowKeys);
this.setState({ selectedRowKeys });
};
render() {
const { selectedRowKeys, pageNum, pageSize } = this.state;
const rowSelection = {
selectedRowKeys,
onChange: this.onSelectChange,
};
const _data = paginate(data, pageNum, pageSize);
return (
<>
<Table
rowSelection={rowSelection}
columns={columns}
dataSource={_data}
pagination={false}
/>
<Pagination
className="text-center mt-3"
showSizeChanger
showQuickJumper
onChange={(_pageNum, _pageSize) => {
this.setState({ pageNum: _pageNum, pageSize: _pageSize || 10 });
}}
onShowSizeChange={(_pageNum, _pageSize) => {
this.setState({ pageNum: _pageNum || 1, pageSize: _pageSize });
}}
current={pageNum}
pageSize={pageSize}
defaultCurrent={1}
total={(data||[]).length}
showTotal={total => `共 ${total} 条`}
/>
</>
);
}
}
export default ModelTable;
\ No newline at end of file
import React from "react";
import { Tooltip, Tree, Spin, Empty, message } from "antd";
import { Tooltip, Tree, message, Button } from "antd";
import { PlusOutlined, EditOutlined, SyncOutlined, DeleteOutlined } from '@ant-design/icons';
import UpdateTreeItemModal from './UpdateTreeItemModal';
......@@ -129,30 +129,35 @@ class ModelTree extends React.Component {
borderBottom: "1px solid #EFEFEF",
}}
>
<Tooltip title={"新增目录"} placement="bottom">
<PlusOutlined
style={{ fontSize: 18, cursor: "pointer" }}
<Tooltip title="新增目录">
<Button
type="primary"
shape="circle"
icon={<PlusOutlined />}
onClick={this.add}
/>
</Tooltip>
<Tooltip title={"修改"} placement="bottom">
<EditOutlined
className='pl-3'
style={{ fontSize: 18, cursor: "pointer" }}
<Tooltip title="修改" className='ml-3'>
<Button
type="primary"
shape="circle"
icon={<EditOutlined />}
onClick={this.update}
/>
</Tooltip>
<Tooltip title={"刷新"} placement="bottom">
<SyncOutlined
className='pl-3'
style={{ fontSize: 18, cursor: "pointer" }}
<Tooltip title="刷新" className='ml-3'>
<Button
type="primary"
shape="circle"
icon={<SyncOutlined />}
onClick={this.refresh}
/>
</Tooltip>
<Tooltip title={"删除"} placement="bottom">
<DeleteOutlined
className='pl-3'
style={{ fontSize: 18, cursor: "pointer" }}
<Tooltip title="删除" className='ml-3'>
<Button
type="primary"
shape="circle"
icon={<DeleteOutlined />}
onClick={this.delete}
/>
</Tooltip>
......
import React from 'react'
import { Modal, Form, Input, Select } from 'antd'
const { Option } = Select;
import { Modal, Form, Input, Radio } from 'antd'
class UpdateTreeItemForm extends React.Component {
......@@ -9,7 +7,7 @@ class UpdateTreeItemForm extends React.Component {
super(props);
this.state = {
itemType: 'sub',
itemTypeSelectDisable: false
radioDisable: false
}
}
......@@ -17,22 +15,22 @@ class UpdateTreeItemForm extends React.Component {
const { type, item } = this.props;
if (type === 'add') {
if (item) {
this.setState({ itemType: 'sub', itemTypeSelectDisable: false });
this.setState({ itemType: 'sub', radioDisable: false });
} else {
this.setState({ itemType: 'root', itemTypeSelectDisable: true })
this.setState({ itemType: 'root', radioDisable: true })
}
} else {
this.setState({ itemType: 'sub', itemTypeSelectDisable: true });
this.setState({ itemType: 'sub', radioDisable: true });
}
}
TreeItemTypeOnChange = (value) => {
this.setState({ itemType: value });
onRadioChange = (e) => {
this.setState({ itemType: e.target.value });
}
render() {
const { item, type } = this.props;
const { itemType, itemTypeSelectDisable } = this.state;
const { itemType, radioDisable } = this.state;
const formItemLayout = {
labelCol: {
......@@ -48,7 +46,8 @@ class UpdateTreeItemForm extends React.Component {
return (
<Form
{...formItemLayout}
initialValue={
name="basic"
initialValues={
type!=='add'?{
title: item?item.title:''
}:null
......@@ -56,14 +55,14 @@ class UpdateTreeItemForm extends React.Component {
>
{
type==='add'&&<Form.Item label="目录类型">
<Select
<Radio.Group
onChange={this.onRadioChange}
value={itemType}
onChange={this.TreeItemTypeOnChange}
disabled={itemTypeSelectDisable}
disabled={radioDisable}
>
<Option value="root">根目录</Option>
<Option value="sub">子目录</Option>
</Select>
<Radio value='root'>根目录</Radio>
<Radio value='sub'>子目录</Radio>
</Radio.Group>
</Form.Item>
}
<Form.Item
......@@ -89,7 +88,7 @@ class UpdateTreeItemModal extends React.Component {
}
handleOk = () => {
const { onOk, item, type } = this.props;
const { onOk, type } = this.props;
this.setState({ confirmLoading: true }, () => {
this.form.current.validateFields((err,values) => {
......@@ -119,8 +118,6 @@ class UpdateTreeItemModal extends React.Component {
const { visible, type, item, onCancel } = this.props;
const { confirmLoading } = this.state;
console.log('item', item);
return (
<Modal
confirmLoading={confirmLoading}
......
import React from 'react';
import { Row, Col } from 'antd';
import { Row, Col, Button } from 'antd';
import Tree from './Component/Tree';
import ModelTree from './Component/ModelTree';
import ModelTable from './Component/ModelTable';
import ImportModal from './Component/ImportModal';
import ExportModal from './Component/ExportModal';
class Model extends React.Component {
constructor() {
super();
this.state = {
importModalVisible: false,
exportModalVisible: false,
}
}
onImportBtnClick = () => {
this.setState({ importModalVisible: true });
}
onExportBtnClick = () => {
this.setState({ exportModalVisible: true });
}
onImportModalCancel = () => {
this.setState({ importModalVisible: false });
}
onExportModalCancel = () => {
this.setState({ exportModalVisible: false });
}
render() {
const { importModalVisible, exportModalVisible } = this.state;
return (
<div style={{ backgroundColor: '#fff', height: '100%' }}>
<Row gutter={10} style={{ height: '100%' }}>
<Col span={8}>
<Tree />
<Col span={6}>
<ModelTree />
</Col>
<Col span={18}>
<div
className='p-3'
style={{
display: 'flex',
borderBottom: "1px solid #EFEFEF",
}}
>
<Button type="primary" style={{marginLeft: 'auto'}}>全选</Button>
<Button type="primary" className='ml-3'>提交审核</Button>
<Button type="primary" className='ml-3' onClick={this.onImportBtnClick}>模型创建</Button>
<Button type="primary" className='ml-3' onClick={this.onExportBtnClick}>模型导出</Button>
</div>
<div className='p-3'>
<ModelTable />
</div>
</Col>
</Row>
<ImportModal
visible={importModalVisible}
onCancel={this.onImportModalCancel}
/>
<ExportModal
visible={exportModalVisible}
onCancel={this.onExportModalCancel}
/>
</div>
);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment