Browse Source

库表、文件、接口元数据相关配置修改

master
zmh 2 years ago
parent
commit
89b71a9ecf
  1. 3
      web/client/src/components/UploadLocal/index.js
  2. 17
      web/client/src/sections/metadataManagement/components/metadataDatabaseModal.js
  3. 11
      web/client/src/sections/metadataManagement/components/metadataFileModal.js
  4. 2
      web/client/src/sections/metadataManagement/components/metadataRestapiModal.js
  5. 29
      web/client/src/sections/metadataManagement/components/modelModal.js
  6. 8
      web/client/src/sections/metadataManagement/constants/index.js
  7. 27
      web/client/src/sections/metadataManagement/containers/databasesTable.js
  8. 35
      web/client/src/sections/metadataManagement/containers/filesTable.js
  9. 25
      web/client/src/sections/metadataManagement/containers/metaModelManagement.js
  10. 2
      web/client/src/sections/metadataManagement/containers/restapisTable.js

3
web/client/src/components/UploadLocal/index.js

@ -50,11 +50,10 @@ class Uploads extends Component {
if (value) {
// this.setState(value);
this.setState({ fileList: value })
}
}
componentWillReceiveProps(np) {
UNSAFE_componentWillReceiveProps(np) {
const { dispatch, value: thisEditData, onChange } = this.props;
const { value: nextEditData } = np;

17
web/client/src/sections/metadataManagement/components/metadataDatabaseModal.js

@ -12,7 +12,7 @@ const MetadataDatabaseModal = (props) => {
if (onConfirm) {
let dataSave = JSON.parse(JSON.stringify(values));
dataSave.attributesParam = {};
metadataModels.map(m => {
metadataModels.filter(mm => mm.modelType === type).map(m => {
dataSave.attributesParam[m.attributeCode] = values[m.attributeCode];
delete dataSave[m.attributeCode];
})
@ -41,16 +41,18 @@ const MetadataDatabaseModal = (props) => {
{m.attributeName.substring(0, 10) + '...'}
</Tooltip> : m.attributeName}
name={m.attributeCode}
key={m.attributeCode}
rules={rules}>
<Input style={{ width: '90%' }} placeholder={`请输入${m.attributeName}`} />
</Form.Item>
} else if (m.control === '数字输入框') {
const rules = [{ required: !m.nullable, message: `${m.attributeName}不可空` }]
let maxValue = '';
if (m.length) {
while (m.length > 0) {
let length = m.length;
if (length) {
while (length > 0) {
maxValue += '9'
m.length--;
length--;
}
}
return <Form.Item
@ -58,6 +60,7 @@ const MetadataDatabaseModal = (props) => {
{m.attributeName.substring(0, 10) + '...'}
</Tooltip> : m.attributeName}
name={m.attributeCode}
key={m.attributeCode}
rules={rules}>
<InputNumber min={0} max={maxValue ? parseInt(maxValue) : 0} precision={0} style={{ width: '90%' }} placeholder={`请输入${m.attributeName}`} />
</Form.Item>
@ -67,6 +70,7 @@ const MetadataDatabaseModal = (props) => {
{m.attributeName.substring(0, 10) + '...'}
</Tooltip> : m.attributeName}
name={m.attributeCode}
key={m.attributeCode}
rules={[{ required: !m.nullable, message: `${m.attributeName}不可空` }]}>
<Select
placeholder={`请选择${m.attributeName}`}
@ -94,6 +98,7 @@ const MetadataDatabaseModal = (props) => {
<Form.Item
label='元数据名称'
name='name'
key='name'
rules={[{ required: true, message: '' }, { max: 50, message: `元数据名称不超过50个字符` },
({ getFieldValue, validateFields }) => ({
validator(_, value) { return validatorNull(_, value, getFieldValue, validateFields, '元数据名称') }
@ -103,6 +108,7 @@ const MetadataDatabaseModal = (props) => {
<Form.Item
label='元数据代码'
name='code'
key='code'
rules={[{ required: true, message: '' }, { max: 50, message: `元数据代码不超过50个字符` },
({ getFieldValue, validateFields }) => ({
validator(_, value) { return validatorNull(_, value, getFieldValue, validateFields, '元数据代码') }
@ -112,6 +118,7 @@ const MetadataDatabaseModal = (props) => {
<Form.Item
label="元数据类型"
name='type'
key='type'
rules={[{ required: true, message: '请选择元数据类型' }]}>
<Select
placeholder='请选择元数据类型'
@ -130,6 +137,7 @@ const MetadataDatabaseModal = (props) => {
<Form.Item
label='上下文路径'
name='path'
key='path'
rules={[{ required: true }]}
>
<TextArea disabled rows={1} style={{ width: '90%' }} />
@ -137,6 +145,7 @@ const MetadataDatabaseModal = (props) => {
<Form.Item
label='详情'
name='description'
key='description'
rules={[{ max: 255, message: `详情不超过255个字符` }]}>
<TextArea rows={4} style={{ width: '90%' }} placeholder={`请输入详情`} />
</Form.Item>

11
web/client/src/sections/metadataManagement/components/metadataFileModal.js

@ -13,7 +13,7 @@ const MetadataFileModal = (props) => {
if (onConfirm) {
let dataSave = JSON.parse(JSON.stringify(values));
dataSave.attributesParam = {};
metadataModels.map(m => {
metadataModels.filter(mm => mm.modelType === '文件').map(m => {
dataSave.attributesParam[m.attributeCode] = values[m.attributeCode];
delete dataSave[m.attributeCode];
})
@ -42,6 +42,7 @@ const MetadataFileModal = (props) => {
{m.attributeName.substring(0, 10) + '...'}
</Tooltip> : m.attributeName}
name={m.attributeCode}
key={m.attributeCode}
rules={rules}>
<Input style={{ width: '90%' }} placeholder={`请输入${m.attributeName}`} />
</Form.Item>
@ -60,6 +61,7 @@ const MetadataFileModal = (props) => {
{m.attributeName.substring(0, 10) + '...'}
</Tooltip> : m.attributeName}
name={m.attributeCode}
key={m.attributeCode}
rules={rules}>
<InputNumber min={0} max={maxValue ? parseInt(maxValue) : 0} precision={0} style={{ width: '90%' }} placeholder={`请输入${m.attributeName}`} />
</Form.Item>
@ -69,6 +71,7 @@ const MetadataFileModal = (props) => {
{m.attributeName.substring(0, 10) + '...'}
</Tooltip> : m.attributeName}
name={m.attributeCode}
key={m.attributeCode}
rules={[{ required: !m.nullable, message: `${m.attributeName}不可空` }]}>
<Select
placeholder={`请选择${m.attributeName}`}
@ -134,6 +137,7 @@ const MetadataFileModal = (props) => {
<Form.Item
label='文件名称'
name='name'
key='name'
rules={[{ required: true, message: '' }, { max: 50, message: `文件名称不超过50个字符` },
({ getFieldValue, validateFields }) => ({
validator(_, value) { return validatorNull(_, value, getFieldValue, validateFields, '文件名称') }
@ -143,12 +147,14 @@ const MetadataFileModal = (props) => {
<Form.Item
label='文件描述'
name='description'
key='description'
rules={[{ max: 255, message: `文件描述不超过255个字符` }]}>
<TextArea rows={4} style={{ width: '90%' }} placeholder={`请输入文件描述`} />
</Form.Item>
<Form.Item
label='文件'
name='files'
key='files'
rules={[{ required: true, message: '文件不可为空' }]}>
<UploadLocal
addNew={editData.add || !editData.record.files.length}
@ -158,11 +164,10 @@ const MetadataFileModal = (props) => {
onChange={vsjunct}
fileTypes={["jpg", "png", "gif", "txt", "doc", "docx", "pdf", "xls", "xlsx", "zip", "rar"]}
value={editUrl}
defaultValue={editUrl}
fileList={editData.record.files || []}
/>
</Form.Item>
<Form.Item style={{ paddingLeft: 190 }}>
<Form.Item style={{ paddingLeft: 190 }} key='tip'>
<Tag color="orange">文件大小不超过40MB开放资源包含多个文件建议将文件进行压缩形成压缩包再上传</Tag>
<Tag color="orange">支持的文件格式jpg,png,gif,txt,doc,docx,pdf,xsl,xlsx,zip,rar</Tag>
</Form.Item>

2
web/client/src/sections/metadataManagement/components/metadataRestapiModal.js

@ -15,7 +15,7 @@ const MetadataRestapiModal = (props) => {
if (onConfirm) {
let dataSave = JSON.parse(JSON.stringify(values));
dataSave.attributesParam = {};
metadataModels.map(m => {
metadataModels.filter(mm => mm.modelType === '接口').map(m => {
dataSave.attributesParam[m.attributeCode] = values[m.attributeCode];
delete dataSave[m.attributeCode];
})

29
web/client/src/sections/metadataManagement/components/modelModal.js

@ -1,5 +1,6 @@
import React, { useRef } from 'react';
import { Button, Form } from 'antd';
import { InfoCircleOutlined } from '@ant-design/icons';
import {
ModalForm,
ProFormSelect,
@ -17,7 +18,7 @@ const DATA_TYPES = {
"下拉框": "布尔型",
}
export default (props) => {
const { title, triggerRender, editData = null, onFinish, readOnly, models } = props;
const { title, triggerRender, editData = null, onFinish, paramsCode, paramsName } = props;
const formItemLayout = { labelCol: { span: 6 }, wrapperCol: { span: 16 } };
const initialValues = editData ? {
...editData,
@ -50,17 +51,43 @@ export default (props) => {
<ProFormText
rules={[{ required: true, message: '请输入属性名称' },
{ max: 255, message: '属性名称长度不能大于255个字符' },
{
validator: (rule, value, callback) => {
if (paramsName && paramsName.includes(value)) {
callback('不可与元数据基础信息名称一致');
} else {
callback();
}
}
}
]}
name="attributeName"
label="属性名称"
tooltip={{
title: `不可与元数据基础信息名称(${paramsName && paramsName.join(',')})一致`,
icon: <InfoCircleOutlined />,
}}
/>
<ProFormText
rules={[{ required: true, message: '请输入属性代码' },
{ max: 255, message: '属性代码长度不能大于255个字符' },
{
validator: (rule, value, callback) => {
if (paramsCode && paramsCode.includes(value)) {
callback('不可与元数据基础信息代码一致');
} else {
callback();
}
}
}
]}
name="attributeCode"
label="属性代码"
tooltip={{
title: `不可与元数据基础信息代码(${paramsCode && paramsCode.join(',')})一致`,
icon: <InfoCircleOutlined />,
}}
/>
<ProFormSelect

8
web/client/src/sections/metadataManagement/constants/index.js

@ -1,9 +1,15 @@
'use strict';
import React from 'react';
export const ModelTypes = ['目录', '库', '视图', '表', '字段', '索引', '外键', '主键', '唯一约束'];
export const RestapiMethods = ['get', 'post', 'put', 'delete'];
export const ConfigurableTypes = {
'目录': ['库'],
'库': ['视图', '表'],
'表': ['字段', '索引', '外键', '主键', '唯一约束']
}
export const RestapiMethods = ['get', 'post', 'put', 'delete'];
export const RestapiBasicParamsCode = ['name', 'url', 'method', 'queryParam', 'bodyParam', 'return', 'enabled'];
export const RestapiBasicParamsName = ['接口名称', '接口路由', '接口类型', '传参', '请求实体', '返回值', '状态'];
export const FileBasicParamsCode = ['name', 'description', 'files'];
export const FileBasicParamsName = ['文件名称', '文件描述', '文件'];
export const DatabaseBasicParamsCode = ['name', 'code', 'type', 'path', 'description'];
export const DatabaseBasicParamsName = ['元数据名称', '元数据代码', '元数据类型', '上下文路径', '详情'];

27
web/client/src/sections/metadataManagement/containers/databasesTable.js

@ -75,7 +75,8 @@ const DatabaseTable = (props) => {
if (res.success) {
const obj = { tagSet: [], tags: [], id: id };
if (res.payload.data.length) {
obj.tagSet = res.payload.data.map(d => d.tagSet);
const tagSetIds = res.payload.data.map(d => d.tagSet)
obj.tagSet = [...new Set(tagSetIds)];
obj.tags = res.payload.data.map(d => d.id);
}
setEditTagData({ record: obj });
@ -198,7 +199,7 @@ const DatabaseTable = (props) => {
if (isAll) {
dispatch(metadataManagement.getMetadataDatabases({ catalog: resourceCatalogId })).then(res => {
if (res.success) {
handleExportTable(tableHeader, res.payload.data.rows, isAll);
handleExportTable(tableHeader, res.payload.data.rows);
}
})
} else {
@ -211,7 +212,7 @@ const DatabaseTable = (props) => {
handleExportTable(tableHeader, data);
}
}
const handleExportTable = (tableHeader, contentData, isAll = false) => {
const handleExportTable = (tableHeader, contentData) => {
let tableContent = '';
contentData.map(cd => {
tableContent += `<tr>`;
@ -267,7 +268,7 @@ const DatabaseTable = (props) => {
</Popconfirm>
}
<Button type='primary' style={{ marginLeft: 16, float: 'right' }} onClick={onSearch}>查询</Button>
<Input style={{ width: 220, float: 'right' }} placeholder="输入名称/代码/类型"
<Input style={{ width: 220, float: 'right' }} placeholder="名称/代码/类型"
allowClear onPressEnter={onSearch} onChange={e => setKeywords(e.target.value || '')} />
</div >
<Table
@ -283,22 +284,7 @@ const DatabaseTable = (props) => {
showSizeChanger: true,
// showQuickJumper: true,
showTotal: (total) => { return <span style={{ fontSize: 15 }}>{`${Math.ceil(total / limit)}页,${total}`}</span> },
onShowSizeChange: (currentPage, pageSize) => {
setCurrentPage(currentPage);
setLimit(pageSize);
},
onChange: (page, pageSize) => {
setSelectedRowKeys([]);
setSelectedRows([]);
setCurrentPage(page);
setLimit(pageSize);
let queryParams = {
orderDirection: SortValues[createAtSort],
page: page - 1,
size: pageSize
};
initData(queryParams);
}
}}
rowSelection={{
onChange: (selectedRowKeys, selectedRows) => {
@ -345,7 +331,6 @@ function mapStateToProps(state) {
|| tagMetadata.isRequesting || metadataResourceApplications.isRequesting,
metadataModels: metadataModels.data,
tagList: tagList.data || [],
tagMetadata: tagMetadata.data || [],
metadataResourceApplications: metadataResourceApplications.data || []
};
}

35
web/client/src/sections/metadataManagement/containers/filesTable.js

@ -34,7 +34,7 @@ const FilesTable = (props) => {
dispatch(metadataManagement.getTagList());
setUpdateAtSort('descend');
initData({ limit, offset: currentPage - 1, orderDirection: SortValues[updateAtSort] });
}, [resourceCatalogId]);
}, []);
const initData = (query = {}) => {
dispatch(metadataManagement.getMetadataFiles({ catalog: resourceCatalogId, keywords, orderBy: 'updateAt', ...query })).then(res => {
@ -85,7 +85,8 @@ const FilesTable = (props) => {
if (res.success) {
const obj = { tagSet: [], tags: [], id: id };
if (res.payload.data.length) {
obj.tagSet = res.payload.data.map(d => d.tagSet);
const tagSetIds = res.payload.data.map(d => d.tagSet)
obj.tagSet = [...new Set(tagSetIds)];
obj.tags = res.payload.data.map(d => d.id);
}
setEditTagData({ record: obj });
@ -232,7 +233,7 @@ const FilesTable = (props) => {
if (isAll) {
dispatch(metadataManagement.getMetadataFiles({ catalog: resourceCatalogId })).then(res => {
if (res.success) {
handleExportTable(tableHeader, res.payload.data.rows, isAll);
handleExportTable(tableHeader, res.payload.data.rows);
}
})
} else {
@ -245,7 +246,7 @@ const FilesTable = (props) => {
handleExportTable(tableHeader, data);
}
}
const handleExportTable = (tableHeader, contentData, isAll = false) => {
const handleExportTable = (tableHeader, contentData) => {
let tableContent = '';
contentData.map(cd => {
tableContent += `<tr>`;
@ -254,7 +255,7 @@ const FilesTable = (props) => {
tableContent += `<th style="font-weight:600"><div>${cd.type}</div></th>`;
let tagName = cd.tagFiles.map(tagSet => tagSet.tag.name);
tableContent += `<th style="font-weight:600"><div>${tagName.join(',')}</div></th>`;
tableContent += `<th style="font-weight:600"><div>${cd.size}</div></th>`;
tableContent += `<th style="font-weight:600"><div>${cd.size ? getfilesize(cd.size) : ''}</div></th>`;
tableContent += `<th style="font-weight:600"><div>${moment(cd.updateAt).format('YYYY-MM-DD HH:mm:ss')}</div></th>`;
tableContent += `</tr>`;
})
@ -315,7 +316,7 @@ const FilesTable = (props) => {
</Popconfirm>
}
<Button type='primary' style={{ marginLeft: 16, float: 'right' }} onClick={onSearch}>查询</Button>
<Input style={{ width: 220, float: 'right' }} placeholder="输入名称/类型"
<Input style={{ width: 220, float: 'right' }} placeholder="名称/类型"
allowClear onPressEnter={onSearch} onChange={e => setKeywords(e.target.value || '')} />
</div >
<Table
@ -331,22 +332,7 @@ const FilesTable = (props) => {
showSizeChanger: true,
// showQuickJumper: true,
showTotal: (total) => { return <span style={{ fontSize: 15 }}>{`${Math.ceil(total / limit)}页,${total}`}</span> },
onShowSizeChange: (currentPage, pageSize) => {
setCurrentPage(currentPage);
setLimit(pageSize);
},
onChange: (page, pageSize) => {
setSelectedRowKeys([]);
setSelectedRows([]);
setCurrentPage(page);
setLimit(pageSize);
let queryParams = {
orderDirection: SortValues[updateAtSort],
page: page - 1,
size: pageSize
};
initData(queryParams);
}
}}
rowSelection={{
onChange: (selectedRowKeys, selectedRows) => {
@ -394,16 +380,15 @@ const FilesTable = (props) => {
</Spin >
}
function mapStateToProps(state) {
const { global, auth, metadataDatabases, metadataModels, tagList, tagMetadata, metadataResourceApplications } = state;
const { global, auth, metadataFiles, metadataModels, tagList, tagMetadata, metadataResourceApplications } = state;
return {
user: auth.user,
actions: global.actions,
clientHeight: global.clientHeight,
isRequesting: metadataDatabases.isRequesting || metadataModels.isRequesting || tagList.isRequesting
isRequesting: metadataFiles.isRequesting || metadataModels.isRequesting || tagList.isRequesting
|| tagMetadata.isRequesting || metadataResourceApplications.isRequesting,
metadataModels: metadataModels.data,
tagList: tagList.data || [],
tagMetadata: tagMetadata.data || [],
metadataResourceApplications: metadataResourceApplications.data || []
};
}

25
web/client/src/sections/metadataManagement/containers/metaModelManagement.js

@ -3,13 +3,18 @@ import { Spin, Popconfirm, Tree, Row, Col, Button } from 'antd';
import { connect } from 'react-redux';
import ProTable from '@ant-design/pro-table';
import MetaModelModal from '../components/modelModal'
import { ModelTypes as DATABASE_TYPE } from '../constants/index';
import {
ModelTypes as DATABASE_TYPE, RestapiBasicParamsName, RestapiBasicParamsCode, FileBasicParamsName, FileBasicParamsCode,
DatabaseBasicParamsName, DatabaseBasicParamsCode
} from '../constants/index';
const TreeNode = Tree.TreeNode;
function MetaModelManagement(props) {
const { loading, clientHeight, actions, dispatch, metaModel } = props;
const [selectedKeys, setSelectKeys] = useState([DATABASE_TYPE[0]])
const [pageSize, setPageSize] = useState(10);
const [currentPage, setCurrentPage] = useState(1);
const [paramsName, setParamsName] = useState(DatabaseBasicParamsName);
const [paramsCode, setParamsCode] = useState(DatabaseBasicParamsCode);
const queryData = (search) => {
const query = {
@ -123,8 +128,9 @@ function MetaModelManagement(props) {
editData={record}
title="编辑模型"
onFinish={onFinish}
models={metaModel?.rows || []}
key="editModel"
paramsName={paramsName}
paramsCode={paramsCode}
/>)
options.push(
@ -154,7 +160,17 @@ function MetaModelManagement(props) {
onSelect={(keys, e) => {
if (e.selected) {
setCurrentPage(1);
setSelectKeys(keys)
setSelectKeys(keys);
if (keys[0] === '接口') {
setParamsCode(RestapiBasicParamsCode);
setParamsName(RestapiBasicParamsName);
} else if (keys[0] === '文件') {
setParamsCode(FileBasicParamsCode);
setParamsName(FileBasicParamsName);
} else {
setParamsCode(DatabaseBasicParamsCode);
setParamsName(DatabaseBasicParamsName);
}
}
}}
defaultExpandAll={true}
@ -212,7 +228,8 @@ function MetaModelManagement(props) {
title="新建模型"
onFinish={onFinish}
key="addModel"
models={metaModel?.rows || []}
paramsName={paramsName}
paramsCode={paramsCode}
/>
]}
options={false}

2
web/client/src/sections/metadataManagement/containers/restapisTable.js

@ -188,7 +188,7 @@ const RestapisTable = (props) => {
})
}}>新建</Button>
<Button type='primary' style={{ marginLeft: 16, float: 'right' }} onClick={onSearch}>查询</Button>
<Input style={{ width: 220, float: 'right' }} placeholder="输入名称"
<Input style={{ width: 220, float: 'right' }} placeholder="名称"
allowClear onPressEnter={onSearch} onChange={e => setKeywords(e.target.value || '')} />
</div >
<Table

Loading…
Cancel
Save