Commit 48189180 by zhaochengxiang

增加ddl导出 规范

parent b5426710
......@@ -89,7 +89,7 @@ div[id^='__qiankun_microapp_wrapper_'] {
}
.yy-table-cell{
word-break:break-all;
word-break: break-all;
}
......
......@@ -100,4 +100,15 @@ export function* deleteDataModel(payload) {
export function* getDataModel(payload) {
return yield call(datamodelerService.getDataModel, payload);
}
\ No newline at end of file
}
export function* ddlGenerators() {
return yield call(datamodelerService.ddlGenerators);
}
export function* exportDDLString(payload) {
const { ids, ddlGeneratorName } = payload;
return yield call(datamodelerService.exportDDLString, { id: ids[0], ddlGeneratorName: ddlGeneratorName });
}
import { filePost, GetJSON, PostJSON, Post } from "../util/axios"
import { filePost, Get, GetJSON, PostJSON, Post } from "../util/axios"
export function loadDataModelCatalog() {
return GetJSON("/datamodeler/easyDataModelerCURD/loadDataModelCatalog");
......@@ -63,3 +63,10 @@ export function getDataModel(payload) {
return GetJSON("/datamodeler/easyDataModelerCURD/getDataModel", payload);
}
export function ddlGenerators() {
return GetJSON("/datamodeler/easyDataModelerExport/ddlGenerators");
}
export function exportDDLString(payload) {
return Get("/datamodeler/easyDataModelerExport/ddlString", payload);
}
......@@ -101,6 +101,15 @@ const callback = resp => {
return resp.data || resp;
}
export function Get(url, params) {
const cancelToken = __source ? __source.token : null;
return textplain.get(url, {
params, cancelToken
}).then(
callback
)
}
export function GetJSON(url, params) {
const cancelToken = __source ? __source.token : null;
return instance.get(url, {
......
......@@ -114,12 +114,13 @@ export const showMessage = function(action, content) {
}
}
export const showNotifaction = function(title, tip) {
export const showNotifaction = function(title, tip, duration=0) {
notification.config({ prefixCls: "yy-notification" });
notification.open({
message: title||'提示',
description: <span dangerouslySetInnerHTML={{ __html: tip||''}} />,
duration: 0,
description: (typeof tip === 'string' ? (<span dangerouslySetInnerHTML={{ __html: tip||''}} />) : tip),
duration: duration,
});
}
......
import React, { useState } from 'react';
import { Modal, Button, Upload, notification } from 'antd';
import { Modal, Button, Upload } from 'antd';
import { DownloadOutlined, UploadOutlined } from '@ant-design/icons';
import { dispatchLatest } from '../../../../model';
......@@ -28,7 +28,8 @@ const ImportModal = (props) => {
setFileList([file]);
return false;
},
fileList: fileList||[]
fileList: fileList||[],
accept:".xlsx",
};
const handleOk = () => {
......
import React, { useState, useEffect } from 'react';
import { Button, Table, Pagination, notification } from 'antd';
import { Button, Table, Pagination } from 'antd';
import { dispatchLatest } from '../../../model';
import ImportModal from './Component/ImportModal';
......
import React from 'react';
import { Modal, Radio, Button } from 'antd';
import { Modal, Radio, Button, Select } from 'antd';
import { showMessage } from '../../../../util';
import { dispatch } from '../../../../model';
const { Option } = Select;
const modes = [
{
......@@ -10,6 +15,10 @@ const modes = [
title: '导出Word',
key: 'word',
},
{
title: '导出ddl',
key: 'ddl',
}
]
class ExportModal extends React.Component {
......@@ -18,38 +27,112 @@ class ExportModal extends React.Component {
super();
this.state = {
selectedKey: '',
loadingDDLGenerators: false,
ddlGenerators: [],
selectDDLGeneratorName: null,
confirmLoading: false,
}
}
componentDidMount() {
this.getDDLGenerators();
}
getDDLGenerators = () => {
this.setState({ loadingDDLGenerators: true }, () => {
dispatch({
type: 'datamodel.ddlGenerators',
callback: data => {
this.setState({ ddlGenerators: data, loadingDDLGenerators: false });
},
error: () => {
this.setState({ loadingDDLGenerators: false });
}
});
})
}
onModeClick = (e) => {
this.setState({ selectedKey: e.target.value });
}
handleOk = () => {
const { onCancel, ids } = this.props;
const { selectedKey } = this.state;
const { selectedKey, ddlGenerators, loadingDDLGenerators, selectDDLGeneratorName } = this.state;
if (selectedKey === '') {
showMessage('info', '请先选择导出方式');
return;
}
if (selectedKey === 'excel') {
window.open(`/api/datamodeler/easyDataModelerExport/excel?ids=${ids.join(',')}`);
this.reset();
onCancel && onCancel();
} else if (selectedKey === 'word') {
window.open(`/api/datamodeler/easyDataModelerExport/word?ids=${ids.join(',')}`);
}
this.reset();
onCancel && onCancel();
} else if (selectedKey === 'ddl') {
if (loadingDDLGenerators) {
showMessage('info', '正在加载ddl支持的数据库类型');
return;
}
if ((ddlGenerators||[]).length===0) {
showMessage('info', 'ddl支持的数据库类型没有查找到,重新查找中');
this.getDDLGenerators();
return;
}
if (!selectDDLGeneratorName || selectDDLGeneratorName==='') {
showMessage('info', '请选择ddl支持的数据库类型');
return;
}
this.reset();
onCancel && onCancel();
this.setState({ confirmLoading: true }, () => {
dispatch({
type: 'datamodel.exportDDLString',
payload: {
ids,
ddlGeneratorName: selectDDLGeneratorName
},
callback: data => {
this.setState({ confirmLoading: false }, () => {
this.reset();
onCancel && onCancel([ data ]);
});
},
error: () => {
this.setState({ confirmLoading: false });
}
});
})
}
}
reset = () => {
this.setState({ selectedKey: '' });
this.setState({ selectedKey: '', ddlGeneratorName: '' });
}
onDDLGeneratorChange = (value) => {
this.setState({ selectDDLGeneratorName: value||'' });
}
render() {
const { visible, onCancel } = this.props;
const { selectedKey } = this.state;
const { selectedKey, ddlGenerators, loadingDDLGenerators, confirmLoading, selectDDLGeneratorName } = this.state;
return (
<Modal
visible={visible}
title={"导出方式"}
loading={confirmLoading}
onOk={this.handleOk}
onCancel={() => {
this.reset();
......@@ -64,18 +147,38 @@ class ExportModal extends React.Component {
导出
</Button>
]}
>
<Radio.Group value={selectedKey} onChange={this.onModeClick}>
{
modes && modes.map((mode, index) => {
return (
<Radio key={mode.key||''} value={mode.key||''}>
{ mode.title||'' }
</Radio>
);
})
}
</Radio.Group>
>
<>
<Radio.Group value={selectedKey} onChange={this.onModeClick}>
{
modes && modes.map((mode, index) => {
return (
<Radio key={mode.key||''} value={mode.key||''}>
{ mode.title||'' }
</Radio>
);
})
}
</Radio.Group>
{
selectedKey==='ddl' && <div className='d-flex mt-5' style={{ alignItems: 'center' }}>
<span className='mr-2' >数据库类型: </span>
<Select
value={selectDDLGeneratorName}
loading={loadingDDLGenerators}
style={{ width: 180 }}
placeholder='请选择数据库类型'
onChange={this.onDDLGeneratorChange}
>
{
ddlGenerators && ddlGenerators.map((ddlGenerator, index) => {
return <Option key={index} value={ddlGenerator.name||''}>{ddlGenerator.cnName||''}</Option>
})
}
</Select>
</div>
}
</>
</Modal>
)
}
......
import React, { useState, useCallback, useRef, useEffect } from 'react';
import { Table, Input, InputNumber, Form, Typography, Radio, Divider, Button, Popconfirm, Select, Row, Col } from 'antd';
import { Table, Input, InputNumber, Form, Typography, Radio, Divider, Button, Popconfirm, Select, Row, Col, Popover } from 'antd';
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import update from 'immutability-helper';
import { generateUUID } from '../../../../util';
import { dispatchLatest } from '../../../../model';
import './ImportActionTable.less';
const { Option } = Select;
const type = 'DragableTableBodyRow';
......@@ -227,6 +230,7 @@ const ImportActionTable = (props) => {
const [form] = Form.useForm();
const [editingKey, setEditingKey] = useState('');
const [suggests, setSuggests] = useState([]);
const [standards, setStandards] = useState([]);
//规则改变的时候 数据表为可编辑状态
useEffect(() => {
......@@ -294,6 +298,12 @@ const ImportActionTable = (props) => {
newData.splice(index, 1, { ...item, ...row });
onChange && onChange(newData);
// setStandards([{
// iid: editingKey,
// contents: ['不符合唯一主键命名规范', '不符合唯一主键命名规范2']
// }]);
setEditingKey('');
setSuggests([]);
......@@ -339,26 +349,26 @@ const ImportActionTable = (props) => {
title: '序号',
dataIndex: 'key',
editable: false,
width:80,
width: 80,
render: (text, record, index) => {
return (index+1).toString();
}
},
{
title: '中文名称',
width:120,
width: 120,
dataIndex: 'cnName',
editable: true,
},
{
title: '英文名称',
width:120,
width: 120,
dataIndex: 'name',
editable: true,
},
{
title: '类型',
width:200,
width: 200,
dataIndex: 'datatype',
editable: true,
......@@ -387,14 +397,14 @@ const ImportActionTable = (props) => {
{
title: '操作',
dataIndex: 'action',
width:100,
width: 100,
render: (_, record) => {
if (!editable) return null;
return isEditing(record) ? (
<>
<Typography.Link className='mr-3' disabled={editingKey === ''} onClick={() => save()}>
<Typography.Link className='mr-3' disabled={editingKey === ''} onClick={() => save()}>
保存
</Typography.Link>
<Typography.Link disabled={editingKey === ''} onClick={() => {cancel()}}>
......@@ -415,9 +425,65 @@ const ImportActionTable = (props) => {
},
]
const standardColumn = {
title: '规范',
dataIndex: 'standard',
width: 120,
render: (text, record, index) => {
let _contents = [];
(standards||[]).forEach((standard,index) => {
if (standard.iid === record.iid) {
_contents = standard.contents||[]
}
});
return (
<div className='d-flex' key={index} style={{ alignItems: 'center' }}>
<div>
{
_contents && _contents.map((_content, index) => {
return (
<div key={index}>
<span style={{ color: '#f5222d' }}>{_content||''}</span>
</div>
);
})
}
</div>
{
(_contents||[]).length>0 && <Popover
content={
<div style={{ maxWidth: 200, maxHeight: 200, wordWrap: 'break-word', overflow: 'auto' }}>
详情
</div>
}
title="规则详情"
trigger="click"
>
<a href="">详情</a>
</Popover>
}
</div>
)
}
};
const includeStandardColumn = [
...columns,
standardColumn
]
const includeStandardEditableColumn = [
...editableColumn,
standardColumn
]
const mergedColumns = () => {
if (editable) {
return editableColumn.map((col) => {
let _columns = (standards||[]).length>0 ? includeStandardEditableColumn: editableColumn;
return _columns.map((col) => {
if (!col.editable) {
return col;
}
......@@ -436,7 +502,7 @@ const ImportActionTable = (props) => {
});
}
return columns;
return (standards||[]).length>0 ? includeStandardColumn : columns;
}
const moveRow = useCallback(
......@@ -457,7 +523,7 @@ const ImportActionTable = (props) => {
);
return (
<>
<div className='model-import-action-table'>
<Divider>数据表结构</Divider>
{
editable && <div className='d-flex mb-3'>
......@@ -496,7 +562,7 @@ const ImportActionTable = (props) => {
{
suggests && suggests.length>0 && (
<>
<Divider orientation="left">智能推荐</Divider>
{/* <Divider orientation="left">智能推荐</Divider> */}
<Radio.Group onChange={onSuggestChange} className='mb-3 ml-7'>
{
suggests && suggests.map((suggest, index) => {
......@@ -524,7 +590,7 @@ const ImportActionTable = (props) => {
/>
</Form>
</DndProvider>
</>
</div>
);
};
......
.model-import-action-table {
.yy-table-expanded-row {
.yy-radio-wrapper {
white-space: normal !important;
}
}
}
\ No newline at end of file
......@@ -41,7 +41,8 @@ class ImportExcel extends React.Component {
fileList: [file],
}))
return false;
}
},
accept:".xlsx",
};
return (
......
......@@ -3,7 +3,7 @@ import { Tooltip, Tree, Button, Modal, Spin } from "antd";
import { PlusOutlined, EditOutlined, SyncOutlined, DeleteOutlined } from '@ant-design/icons';
import UpdateTreeItemModal from './UpdateTreeItemModal';
import { dispatchLatest } from '../../../../model';
import { dispatch } from '../../../../model';
import { showMessage } from '../../../../util';
import './ModelTree.less';
......@@ -30,7 +30,7 @@ const ModelTree = (props) => {
const getTreeData = () => {
setLoading(true);
dispatchLatest({
dispatch({
type: 'datamodel.loadDataModelCatalog',
callback: data => {
......@@ -115,7 +115,7 @@ const ModelTree = (props) => {
content: '删除目录会删除相关的模型,您确定删除吗?',
onOk: () => {
setLoading(true);
dispatchLatest({
dispatch({
type: 'datamodel.deleteDataModelCatalog',
payload: {
params: {
......
import React from 'react';
import { Row, Col, Button } from 'antd';
import { Row, Col, Button, Typography } from 'antd';
import ModelTree from './Component/ModelTree';
import ModelTable from './Component/ModelTable';
import ImportModal from './Component/ImportModal';
import ExportModal from './Component/ExportModal';
import { showMessage } from '../../../util';
import { dispatchLatest } from '../../../model';
import { showMessage, showNotifaction } from '../../../util';
import { dispatch } from '../../../model';
class Model extends React.Component {
......@@ -37,7 +37,7 @@ class Model extends React.Component {
const { catalogId } = this.state;
this.setState({ loadingTableData: true }, () => {
dispatchLatest({
dispatch({
type: 'datamodel.getCurrentDataModelCatalog',
payload: {
easyDataModelerCatalogId: catalogId
......@@ -85,8 +85,32 @@ class Model extends React.Component {
refresh && this.onTableChange();
}
onExportModalCancel = () => {
onExportModalCancel = (ddlStrings = []) => {
this.setState({ exportModalVisible: false });
if (ddlStrings.length>0) {
const tip = (
<>
{
ddlStrings && ddlStrings.map((ddlString, index) => {
return (
<Typography.Paragraph
key='index'
copyable={{
tooltips: ['复制', '复制成功'],
}}
>
{ ddlString||'' }
</Typography.Paragraph>
)
})
}
</>
);
showNotifaction('ddl', tip);
}
}
render() {
......
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