wenlele 1 year ago
parent
commit
f259640d33
  1. 1
      api/app/lib/controllers/auth/index.js
  2. 19
      api/app/lib/controllers/metadataSearch/index.js
  3. 3
      api/app/lib/index.js
  4. 2
      web/client/src/sections/backups/nav-item.js
  5. 2
      web/client/src/sections/memberManagement/nav-item.js
  6. 2
      web/client/src/sections/metadataAcquisition/nav-item.js
  7. 5
      web/client/src/sections/metadataManagement/components/businessDatabaseModal.js
  8. 11
      web/client/src/sections/metadataManagement/containers/businessDatabaseTable.js
  9. 11
      web/client/src/sections/metadataManagement/containers/businessFilesTable.js
  10. 11
      web/client/src/sections/metadataManagement/containers/businessMetadata.js
  11. 11
      web/client/src/sections/metadataManagement/containers/businessRestapisTable.js
  12. 8
      web/client/src/sections/metadataManagement/containers/businessTab.js
  13. 11
      web/client/src/sections/metadataManagement/containers/databasesTable.js
  14. 8
      web/client/src/sections/metadataManagement/containers/filesTable.js
  15. 60
      web/client/src/sections/metadataManagement/containers/latestMetadata.js
  16. 4
      web/client/src/sections/metadataManagement/containers/metadataDetails.js
  17. 8
      web/client/src/sections/metadataManagement/containers/metadataTab.js
  18. 8
      web/client/src/sections/metadataManagement/containers/restapisTable.js
  19. 8
      web/client/src/sections/metadataManagement/nav-item.js
  20. 2
      web/client/src/sections/organization/nav-item.js
  21. 16
      web/client/src/sections/resourceRetrieval/containers/retrieval.js

1
api/app/lib/controllers/auth/index.js

@ -56,6 +56,7 @@ async function login(ctx, next) {
// await transaction.commit(); // await transaction.commit();
} catch (error) { } catch (error) {
// await transaction.rollback(); // await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400; ctx.status = 400;
ctx.body = { ctx.body = {
message: typeof error == 'string' ? error : '登录失败' message: typeof error == 'string' ? error : '登录失败'

19
api/app/lib/controllers/metadataSearch/index.js

@ -15,6 +15,14 @@ function searchMeta(opts) {
where['$or'] = [{ name: { $iLike: `%${keywords}%` } } where['$or'] = [{ name: { $iLike: `%${keywords}%` } }
] ]
} }
const resourceCatalogOrganization = {
model: models.ResourceCatalog,
attributes: ['id', 'name'],
include: [{
model: models.Organization,
attributes: ['id', 'name'],
}]
}
const findObj = { const findObj = {
include: [ include: [
{ {
@ -22,7 +30,9 @@ function searchMeta(opts) {
include: [{ include: [{
model: models.Tag, model: models.Tag,
}] }]
}], },
resourceCatalogOrganization
],
where: { where: {
...where, ...where,
type: { $in: ['表', '库'] } type: { $in: ['表', '库'] }
@ -35,7 +45,9 @@ function searchMeta(opts) {
include: [{ include: [{
model: models.Tag, model: models.Tag,
}] }]
}], },
resourceCatalogOrganization
],
where: where where: where
} }
const findObj3 = { const findObj3 = {
@ -45,7 +57,8 @@ function searchMeta(opts) {
include: [{ include: [{
model: models.Tag, model: models.Tag,
}] }]
}], },
],
where: where where: where
} }

3
api/app/lib/index.js

@ -110,7 +110,8 @@ module.exports.models = function (dc) {
MetadataDatabase.belongsTo(ResourceCatalog, { foreignKey: 'catalog', targetKey: 'id' }); MetadataDatabase.belongsTo(ResourceCatalog, { foreignKey: 'catalog', targetKey: 'id' });
RestfulApi.belongsTo(ResourceCatalog, { foreignKey: 'catalog', targetKey: 'id' }); RestfulApi.belongsTo(ResourceCatalog, { foreignKey: 'catalog', targetKey: 'id' });
MetadataFile.belongsTo(ResourceCatalog, { foreignKey: 'catalog', targetKey: 'id' });
ResourceCatalog.belongsTo(Organization, { foreignKey: 'orgId', targetKey: 'id' }); ResourceCatalog.belongsTo(Organization, { foreignKey: 'orgId', targetKey: 'id' });
ResourceConsumption.belongsTo(MetadataFile, { foreignKey: 'resourceId', targetKey: 'id' }); ResourceConsumption.belongsTo(MetadataFile, { foreignKey: 'resourceId', targetKey: 'id' });

2
web/client/src/sections/backups/nav-item.js

@ -7,7 +7,7 @@ const SubMenu = Menu.SubMenu;
export function getNavItem(user) { export function getNavItem(user) {
return ( return (
user?.role == '系统管理员' && <SubMenu key="数据备份恢复" icon={<ControlOutlined />} title='数据备份恢复'> user?.username == 'SuperAdmin' && <SubMenu key="数据备份恢复" icon={<ControlOutlined />} title='数据备份恢复'>
<Menu.Item key="backups"> <Menu.Item key="backups">
<Link to="/backups/restore">备份恢复</Link> <Link to="/backups/restore">备份恢复</Link>
</Menu.Item> </Menu.Item>

2
web/client/src/sections/memberManagement/nav-item.js

@ -7,7 +7,7 @@ const SubMenu = Menu.SubMenu;
export function getNavItem(user) { export function getNavItem(user) {
return ( return (
user?.role == '系统管理员' && <Menu.Item icon={<UserOutlined />} key="auth"> user?.username == 'SuperAdmin' && <Menu.Item icon={<UserOutlined />} key="auth">
<Link to="/memberManagement/auth">用户管理</Link> <Link to="/memberManagement/auth">用户管理</Link>
</Menu.Item> </Menu.Item>
// user?.role == '系统管理员' && <SubMenu key="memberManagement" icon={<UserOutlined />} title='用户管理'> // user?.role == '系统管理员' && <SubMenu key="memberManagement" icon={<UserOutlined />} title='用户管理'>

2
web/client/src/sections/metadataAcquisition/nav-item.js

@ -6,7 +6,7 @@ const SubMenu = Menu.SubMenu;
export function getNavItem(user) { export function getNavItem(user) {
return ( return (
user?.role == '系统管理员' && <SubMenu key="metadataAcquisition" icon={<BarChartOutlined />} title='元数据采集'> user?.username == 'SuperAdmin' && <SubMenu key="metadataAcquisition" icon={<BarChartOutlined />} title='元数据采集'>
<Menu.Item key="Adapter"> <Menu.Item key="Adapter">
<Link to="/metadataAcquisition/Adapter">适配器管理</Link> <Link to="/metadataAcquisition/Adapter">适配器管理</Link>
</Menu.Item> </Menu.Item>

5
web/client/src/sections/metadataManagement/components/businessDatabaseModal.js

@ -6,7 +6,7 @@ const basicInfo = [{ name: '元数据名称:', key: 'name' },
{ name: '上下文路径:', key: 'path' }, { name: '上下文路径:', key: 'path' },
{ name: '元数据详情:', key: 'description' }]; { name: '元数据详情:', key: 'description' }];
const BusinessDatabaseModal = (props) => { const BusinessDatabaseModal = (props) => {
const { onConfirm, onCancel, editData, metadataModels, resourceCatalogPath, businessType } = props; const { onConfirm, onCancel, editData, metadataModels, resourceCatalogPath, businessType, isAdmin } = props;
const [form] = Form.useForm(); const [form] = Form.useForm();
useEffect(() => { useEffect(() => {
}, []); }, []);
@ -66,6 +66,7 @@ const BusinessDatabaseModal = (props) => {
return ( return (
<Modal title={editData.title} open={true} destroyOnClose <Modal title={editData.title} open={true} destroyOnClose
okText='确定' width={800} okText='确定' width={800}
footer={!isAdmin ? null : undefined}
onOk={() => handleOk(null)} onOk={() => handleOk(null)}
onCancel={onCancel}> onCancel={onCancel}>
{editData.record && editData.record.businessMetadata.length ? {editData.record && editData.record.businessMetadata.length ?
@ -87,7 +88,7 @@ const BusinessDatabaseModal = (props) => {
({ getFieldValue, validateFields }) => ({ ({ getFieldValue, validateFields }) => ({
validator(_, value) { return validatorNull(_, value, getFieldValue, validateFields, item.name) } validator(_, value) { return validatorNull(_, value, getFieldValue, validateFields, item.name) }
})]}> })]}>
<Input style={{ width: '90%' }} placeholder={`请输入${item.name}`} /> <Input style={{ width: '90%' }} placeholder={`请输入${item.name}`} disabled={!isAdmin} />
</Form.Item> </Form.Item>
)} )}
</Form> </Form>

11
web/client/src/sections/metadataManagement/containers/businessDatabaseTable.js

@ -6,7 +6,7 @@ import FileSaver from 'file-saver';
import BusinessDatabaseModal from '../components/businessDatabaseModal'; import BusinessDatabaseModal from '../components/businessDatabaseModal';
const BusinessDatabaseTable = (props) => { const BusinessDatabaseTable = (props) => {
const { user, dispatch, actions, clientHeight, resourceCatalogId, const { user, dispatch, actions, clientHeight, resourceCatalogId,
resourceCatalogPath, isRequesting, metadataModels } = props; resourceCatalogPath, isRequesting, metadataModels, isAdmin } = props;
const { metadataManagement } = actions; const { metadataManagement } = actions;
const SortValues = { 'ascend': 'asc', 'descend': 'desc' }; const SortValues = { 'ascend': 'asc', 'descend': 'desc' };
const [tableData, setTableData] = useState([]); const [tableData, setTableData] = useState([]);
@ -201,13 +201,13 @@ const BusinessDatabaseTable = (props) => {
if (record.businessMetadataDatabases.length) { if (record.businessMetadataDatabases.length) {
return <div> return <div>
<a style={{ marginLeft: 10 }} onClick={() => onAdd(record, false)}>查看</a> <a style={{ marginLeft: 10 }} onClick={() => onAdd(record, false)}>查看</a>
<Popconfirm {isAdmin && <Popconfirm
title="是否确认删除该业务元数据?" title="是否确认删除该业务元数据?"
onConfirm={() => confirmDelete(record.businessMetadataDatabases[0].id)} onConfirm={() => confirmDelete(record.businessMetadataDatabases[0].id)}
> <a style={{ marginLeft: 10 }}>删除</a></Popconfirm> > <a style={{ marginLeft: 10 }}>删除</a></Popconfirm>}
</div> </div>
} else } else
return <a style={{ marginLeft: 10 }} onClick={() => onAdd(record, true)}>新建</a> return isAdmin && <a style={{ marginLeft: 10 }} onClick={() => onAdd(record, true)}>新建</a>
} }
}]; }];
@ -329,7 +329,8 @@ const BusinessDatabaseTable = (props) => {
editData={editData} editData={editData}
onCancel={() => setModalVisible(false)} onCancel={() => setModalVisible(false)}
onConfirm={onConfirm} onConfirm={onConfirm}
resourceCatalogPath={resourceCatalogPath} /> : '' resourceCatalogPath={resourceCatalogPath}
isAdmin={isAdmin} /> : ''
} }
</Spin > </Spin >
} }

11
web/client/src/sections/metadataManagement/containers/businessFilesTable.js

@ -6,7 +6,7 @@ import FileSaver from 'file-saver';
import BusinessDatabaseModal from '../components/businessDatabaseModal'; import BusinessDatabaseModal from '../components/businessDatabaseModal';
const BusinessFilesTable = (props) => { const BusinessFilesTable = (props) => {
const { user, dispatch, actions, clientHeight, resourceCatalogId, const { user, dispatch, actions, clientHeight, resourceCatalogId,
resourceCatalogPath, isRequesting, metadataModels } = props; resourceCatalogPath, isRequesting, metadataModels, isAdmin } = props;
const { metadataManagement } = actions; const { metadataManagement } = actions;
const SortValues = { 'ascend': 'asc', 'descend': 'desc' }; const SortValues = { 'ascend': 'asc', 'descend': 'desc' };
const [tableData, setTableData] = useState([]); const [tableData, setTableData] = useState([]);
@ -190,13 +190,13 @@ const BusinessFilesTable = (props) => {
if (record.businessMetadataFiles.length) { if (record.businessMetadataFiles.length) {
return <div> return <div>
<a style={{ marginLeft: 10 }} onClick={() => onAdd(record, false)}>查看</a> <a style={{ marginLeft: 10 }} onClick={() => onAdd(record, false)}>查看</a>
<Popconfirm {isAdmin && <Popconfirm
title="是否确认删除该业务元数据?" title="是否确认删除该业务元数据?"
onConfirm={() => confirmDelete(record.businessMetadataFiles[0].id)} onConfirm={() => confirmDelete(record.businessMetadataFiles[0].id)}
> <a style={{ marginLeft: 10 }}>删除</a></Popconfirm> > <a style={{ marginLeft: 10 }}>删除</a></Popconfirm>}
</div> </div>
} else } else
return <a style={{ marginLeft: 10 }} onClick={() => onAdd(record, true)}>新建</a> return isAdmin && <a style={{ marginLeft: 10 }} onClick={() => onAdd(record, true)}>新建</a>
} }
}]; }];
@ -317,7 +317,8 @@ const BusinessFilesTable = (props) => {
onCancel={() => setModalVisible(false)} onCancel={() => setModalVisible(false)}
onConfirm={onConfirm} onConfirm={onConfirm}
resourceCatalogPath={resourceCatalogPath} resourceCatalogPath={resourceCatalogPath}
businessType='文件' /> : '' businessType='文件'
isAdmin={isAdmin} /> : ''
} }
</Spin > </Spin >
} }

11
web/client/src/sections/metadataManagement/containers/businessMetadata.js

@ -4,10 +4,12 @@ import { Spin, Row, Col, Tree, Tooltip, Input } from 'antd';
import BusinessTab from './businessTab'; import BusinessTab from './businessTab';
let expandedKeysData = []; let expandedKeysData = [];
let allTreeNodeKeys = []; let allTreeNodeKeys = [];
let resourceCatalogRawData = [];
const BusinessMetadata = (props) => { const BusinessMetadata = (props) => {
const { user, dispatch, actions, clientHeight, isRequesting, resourceCatalog } = props; const { user, dispatch, actions, clientHeight, isRequesting, resourceCatalog } = props;
const { metadataManagement } = actions; const { metadataManagement } = actions;
const [isAdmin, setIsAdmin] = useState(false);
const [resourceCatalogData, setResourceCatalogData] = useState([]); const [resourceCatalogData, setResourceCatalogData] = useState([]);
const [selectedKeys, setSelectedKeys] = useState([]); const [selectedKeys, setSelectedKeys] = useState([]);
const [expandedKeys, setExpandedKeys] = useState([]); const [expandedKeys, setExpandedKeys] = useState([]);
@ -23,6 +25,7 @@ const BusinessMetadata = (props) => {
dispatch(metadataManagement.getResourceCatalog()).then(res => { dispatch(metadataManagement.getResourceCatalog()).then(res => {
const { data } = res.payload; const { data } = res.payload;
if (res.success) { if (res.success) {
resourceCatalogRawData = data;
allTreeNodeKeys = [] allTreeNodeKeys = []
const resourceCatalogData = getTreeNodeData(data, null, 'rc', [], null); const resourceCatalogData = getTreeNodeData(data, null, 'rc', [], null);
setResourceCatalogData(resourceCatalogData); setResourceCatalogData(resourceCatalogData);
@ -44,7 +47,10 @@ const BusinessMetadata = (props) => {
const keyArr = selectedData[0].split('-'); const keyArr = selectedData[0].split('-');
keyArr.shift();//['rc-2-5']->返回'rc';keyArr:['2','5'] keyArr.shift();//['rc-2-5']->返回'rc';keyArr:['2','5']
const allExpandedKeys = allTreeNodeKeys.filter(k => keyArr.includes(k.id.toString())); const allExpandedKeys = allTreeNodeKeys.filter(k => keyArr.includes(k.id.toString()));
setResourceCatalogId(keyArr.pop()); const resourceCatalogId = keyArr.pop();
setResourceCatalogId(resourceCatalogId);
setIsAdmin(user?.username === 'SuperAdmin'
|| (user?.role === '系统管理员' && user?.orgId == resourceCatalogRawData.find(a => a.id == resourceCatalogId)?.orgId));
setResourceCatalogKey(selectedData[0]); setResourceCatalogKey(selectedData[0]);
const resourceCatalogPath = allExpandedKeys.map(a => a.name); const resourceCatalogPath = allExpandedKeys.map(a => a.name);
setResourceCatalogPath(resourceCatalogPath); setResourceCatalogPath(resourceCatalogPath);
@ -161,7 +167,8 @@ const BusinessMetadata = (props) => {
<Col style={{ width: 'calc(100% - 240px)' }}> <Col style={{ width: 'calc(100% - 240px)' }}>
<BusinessTab resourceCatalogId={resourceCatalogId} <BusinessTab resourceCatalogId={resourceCatalogId}
resourceCatalogKey={resourceCatalogKey} resourceCatalogKey={resourceCatalogKey}
resourceCatalogPath={resourceCatalogPath} /> resourceCatalogPath={resourceCatalogPath}
isAdmin={isAdmin} />
</Col> </Col>
</Row> </Row>
</Spin> </Spin>

11
web/client/src/sections/metadataManagement/containers/businessRestapisTable.js

@ -6,7 +6,7 @@ import FileSaver from 'file-saver';
import BusinessDatabaseModal from '../components/businessDatabaseModal'; import BusinessDatabaseModal from '../components/businessDatabaseModal';
const BusinessFilesTable = (props) => { const BusinessFilesTable = (props) => {
const { user, dispatch, actions, clientHeight, resourceCatalogId, const { user, dispatch, actions, clientHeight, resourceCatalogId,
resourceCatalogPath, isRequesting, metadataModels } = props; resourceCatalogPath, isRequesting, metadataModels, isAdmin } = props;
const { metadataManagement } = actions; const { metadataManagement } = actions;
const SortValues = { 'ascend': 'asc', 'descend': 'desc' }; const SortValues = { 'ascend': 'asc', 'descend': 'desc' };
const [tableData, setTableData] = useState([]); const [tableData, setTableData] = useState([]);
@ -190,13 +190,13 @@ const BusinessFilesTable = (props) => {
if (record.businessMetadataRestapis.length) { if (record.businessMetadataRestapis.length) {
return <div> return <div>
<a style={{ marginLeft: 10 }} onClick={() => onAdd(record, false)}>查看</a> <a style={{ marginLeft: 10 }} onClick={() => onAdd(record, false)}>查看</a>
<Popconfirm {isAdmin && <Popconfirm
title="是否确认删除该业务元数据?" title="是否确认删除该业务元数据?"
onConfirm={() => confirmDelete(record.businessMetadataRestapis[0].id)} onConfirm={() => confirmDelete(record.businessMetadataRestapis[0].id)}
> <a style={{ marginLeft: 10 }}>删除</a></Popconfirm> > <a style={{ marginLeft: 10 }}>删除</a></Popconfirm>}
</div> </div>
} else } else
return <a style={{ marginLeft: 10 }} onClick={() => onAdd(record, true)}>新建</a> return isAdmin && <a style={{ marginLeft: 10 }} onClick={() => onAdd(record, true)}>新建</a>
} }
}]; }];
@ -317,7 +317,8 @@ const BusinessFilesTable = (props) => {
onCancel={() => setModalVisible(false)} onCancel={() => setModalVisible(false)}
onConfirm={onConfirm} onConfirm={onConfirm}
resourceCatalogPath={resourceCatalogPath} resourceCatalogPath={resourceCatalogPath}
businessType='接口' /> : '' businessType='接口'
isAdmin={isAdmin} /> : ''
} }
</Spin > </Spin >
} }

8
web/client/src/sections/metadataManagement/containers/businessTab.js

@ -6,7 +6,7 @@ import BusinessFilesTable from './businessFilesTable';
import BusinessRestapisTable from './businessRestapisTable'; import BusinessRestapisTable from './businessRestapisTable';
const BusinessTab = (props) => { const BusinessTab = (props) => {
const { resourceCatalogId, resourceCatalogKey, resourceCatalogPath, actions, dispatch } = props; const { resourceCatalogId, resourceCatalogKey, resourceCatalogPath, actions, dispatch, isAdmin } = props;
const [activeKey, setActiveKey] = useState('databases'); const [activeKey, setActiveKey] = useState('databases');
useEffect(() => { useEffect(() => {
setActiveKey('databases'); setActiveKey('databases');
@ -36,11 +36,11 @@ const BusinessTab = (props) => {
</Tabs> </Tabs>
{ {
activeKey === 'databases' && resourceCatalogId ? <BusinessDatabaseTable resourceCatalogId={resourceCatalogId} activeKey === 'databases' && resourceCatalogId ? <BusinessDatabaseTable resourceCatalogId={resourceCatalogId}
resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} /> : resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} isAdmin={isAdmin} /> :
activeKey === 'files' && resourceCatalogId ? <BusinessFilesTable resourceCatalogId={resourceCatalogId} activeKey === 'files' && resourceCatalogId ? <BusinessFilesTable resourceCatalogId={resourceCatalogId}
resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} /> : resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} isAdmin={isAdmin} /> :
activeKey === 'restapis' && resourceCatalogId ? <BusinessRestapisTable resourceCatalogId={resourceCatalogId} activeKey === 'restapis' && resourceCatalogId ? <BusinessRestapisTable resourceCatalogId={resourceCatalogId}
resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} /> : resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} isAdmin={isAdmin} /> :
null null
} }
</div> </div>

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

@ -11,7 +11,7 @@ import MetadataResourceModal from '../components/metadataResourceModal';
import ReleaseModal from '../components/releaseModal'; import ReleaseModal from '../components/releaseModal';
const DatabaseTable = (props) => { const DatabaseTable = (props) => {
const { user, dispatch, actions, clientHeight, resourceCatalogId, resourceCatalogKey, const { user, dispatch, actions, clientHeight, resourceCatalogId, resourceCatalogKey, isAdmin,
resourceCatalogPath, isRequesting, metadataModels, setView, tagList, metadataResourceApplications, params } = props; resourceCatalogPath, isRequesting, metadataModels, setView, tagList, metadataResourceApplications, params } = props;
const { metadataManagement } = actions; const { metadataManagement } = actions;
const SortValues = { 'ascend': 'asc', 'descend': 'desc' }; const SortValues = { 'ascend': 'asc', 'descend': 'desc' };
@ -182,7 +182,7 @@ const DatabaseTable = (props) => {
ra.applyBy == user.id && ra.resourceName === record.name && ra.resourceId == record.id); ra.applyBy == user.id && ra.resourceName === record.name && ra.resourceId == record.id);
return <ButtonGroup> return <ButtonGroup>
<a onClick={() => onView(record)}>查看</a> <a onClick={() => onView(record)}>查看</a>
{user.role == '数据消费者' ? null : {!isAdmin ? null :
<> <>
<a style={{ marginLeft: 10 }} onClick={() => onEdit(record)}>编辑</a> <a style={{ marginLeft: 10 }} onClick={() => onEdit(record)}>编辑</a>
<Popconfirm <Popconfirm
@ -192,11 +192,10 @@ const DatabaseTable = (props) => {
{record.type === '表' ? <a style={{ marginLeft: 10 }} onClick={() => marking(record.id)}>打标</a> : null} {record.type === '表' ? <a style={{ marginLeft: 10 }} onClick={() => marking(record.id)}>打标</a> : null}
</> </>
} }
{isAdmin ? null : record.type === '表' ? resourceApplicationsRecords.length === 0 ?
{user.role !== '数据消费者' ? null : record.type === '表' ? resourceApplicationsRecords.length === 0 ?
<a style={{ marginLeft: 10 }} onClick={() => applyResources(record)}>申请资源</a> : <a style={{ marginLeft: 10 }} onClick={() => applyResources(record)}>申请资源</a> :
<span style={{ marginLeft: 10, color: "#c0c0c0" }} title='已存在资源申请'>申请资源</span> : null} <span style={{ marginLeft: 10, color: "#c0c0c0" }} title='已存在资源申请'>申请资源</span> : null}
{user.role == '数据消费者' ? null : {!isAdmin ? null :
record.type === '表' ? record.type === '表' ?
<a style={{ marginLeft: 10 }} onClick={() => servicePublication(record)}>REST服务发布</a> : null <a style={{ marginLeft: 10 }} onClick={() => servicePublication(record)}>REST服务发布</a> : null
} }
@ -272,7 +271,7 @@ const DatabaseTable = (props) => {
return <Spin spinning={isRequesting}> return <Spin spinning={isRequesting}>
<Row style={{ marginBottom: 16 }}> <Row style={{ marginBottom: 16 }}>
<Col span={12}> <Col span={12}>
{user.role == '数据消费者' ? null : <> {!isAdmin ? null : <>
<Button type='primary' onClick={() => { <Button type='primary' onClick={() => {
dispatch(metadataManagement.getMetadataModels({ modelTypes: ModelTypes.join(',') })).then(res => { dispatch(metadataManagement.getMetadataModels({ modelTypes: ModelTypes.join(',') })).then(res => {
if (res.success) { if (res.success) {

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

@ -12,7 +12,7 @@ import { RouteTable } from '$utils'
const FilesTable = (props) => { const FilesTable = (props) => {
const { user, dispatch, actions, clientHeight, resourceCatalogId, resourceCatalogKey, const { user, dispatch, actions, clientHeight, resourceCatalogId, resourceCatalogKey,
isRequesting, metadataModels, tagList, metadataResourceApplications, params } = props; isRequesting, metadataModels, tagList, metadataResourceApplications, params, isAdmin } = props;
const { metadataManagement } = actions; const { metadataManagement } = actions;
const SortValues = { 'ascend': 'asc', 'descend': 'desc' }; const SortValues = { 'ascend': 'asc', 'descend': 'desc' };
const [tableData, setTableData] = useState([]); const [tableData, setTableData] = useState([]);
@ -207,7 +207,7 @@ const FilesTable = (props) => {
let resourceApplicationsRecords = metadataResourceApplications.filter(ra => let resourceApplicationsRecords = metadataResourceApplications.filter(ra =>
ra.applyBy == user.id && ra.resourceName === record.name && ra.resourceId == record.id && !!record.token); ra.applyBy == user.id && ra.resourceName === record.name && ra.resourceId == record.id && !!record.token);
return <ButtonGroup> return <ButtonGroup>
{user.role == '数据消费者' ? null : {!isAdmin ? null :
<> <>
<a style={{ marginLeft: 10 }} onClick={() => onEdit(record)}>编辑</a> <a style={{ marginLeft: 10 }} onClick={() => onEdit(record)}>编辑</a>
<Popconfirm <Popconfirm
@ -218,7 +218,7 @@ const FilesTable = (props) => {
</> </>
} }
{user.role == '系统管理员' ? '' : resourceApplicationsRecords.length === 0 ? {isAdmin ? '' : resourceApplicationsRecords.length === 0 ?
<a style={{ marginLeft: 10 }} onClick={() => applyResources(record)}>申请资源</a> : <a style={{ marginLeft: 10 }} onClick={() => applyResources(record)}>申请资源</a> :
<span style={{ marginLeft: 10, color: "#c0c0c0" }} title='已存在资源申请'>申请资源</span>} <span style={{ marginLeft: 10, color: "#c0c0c0" }} title='已存在资源申请'>申请资源</span>}
</ButtonGroup> </ButtonGroup>
@ -305,7 +305,7 @@ const FilesTable = (props) => {
return <Spin spinning={isRequesting}> return <Spin spinning={isRequesting}>
<Row style={{ marginBottom: 16 }}> <Row style={{ marginBottom: 16 }}>
<Col span={12}> <Col span={12}>
{user.role == '数据消费者' ? null : <> {!isAdmin ? null : <>
<Button type='primary' onClick={() => { <Button type='primary' onClick={() => {
dispatch(metadataManagement.getMetadataModels({ modelTypes: '文件' })).then(res => { dispatch(metadataManagement.getMetadataModels({ modelTypes: '文件' })).then(res => {
if (res.success) { if (res.success) {

60
web/client/src/sections/metadataManagement/containers/latestMetadata.js

@ -8,10 +8,12 @@ import MetadataTab from './metadataTab';
import MetadataDetails from './metadataDetails'; import MetadataDetails from './metadataDetails';
let expandedKeysData = []; let expandedKeysData = [];
let allTreeNodeKeys = []; let allTreeNodeKeys = [];
let resourceCatalogRawData = [];
const LatestMetadata = (props) => { const LatestMetadata = (props) => {
const { user, dispatch, actions, history, clientHeight, resourceCatalog, isRequesting, location, match, organization } = props; const { user, dispatch, actions, history, clientHeight, resourceCatalog, isRequesting, location, match, organization } = props;
const { metadataManagement } = actions; const { metadataManagement } = actions;
const [isAdmin, setIsAdmin] = useState(false);
const [resourceCatalogData, setResourceCatalogData] = useState([]); const [resourceCatalogData, setResourceCatalogData] = useState([]);
const [selectedKeys, setSelectedKeys] = useState([]); const [selectedKeys, setSelectedKeys] = useState([]);
const [expandedKeys, setExpandedKeys] = useState([]); const [expandedKeys, setExpandedKeys] = useState([]);
@ -36,6 +38,7 @@ const LatestMetadata = (props) => {
dispatch(metadataManagement.getResourceCatalog()).then(res => { dispatch(metadataManagement.getResourceCatalog()).then(res => {
const { data } = res.payload; const { data } = res.payload;
if (res.success) { if (res.success) {
resourceCatalogRawData = data;
allTreeNodeKeys = [] allTreeNodeKeys = []
const resourceCatalogData = getTreeNodeData(data, null, 'rc', [], null); const resourceCatalogData = getTreeNodeData(data, null, 'rc', [], null);
setResourceCatalogData(resourceCatalogData); setResourceCatalogData(resourceCatalogData);
@ -47,6 +50,8 @@ const LatestMetadata = (props) => {
params?.catalogKey ? setSelectedKeys([params?.catalogKey]) : setSelectedKeys(expandedKeysData); params?.catalogKey ? setSelectedKeys([params?.catalogKey]) : setSelectedKeys(expandedKeysData);
params?.catalogKey ? setExpandedKeys(getExpandKeys([params?.catalogKey])) : setExpandedKeys(expandedKeys); params?.catalogKey ? setExpandedKeys(getExpandKeys([params?.catalogKey])) : setExpandedKeys(expandedKeys);
params?.treeId && setResourceCatalogId(params?.treeId); params?.treeId && setResourceCatalogId(params?.treeId);
params?.treeId && params?.treeId && setIsAdmin(user?.username === 'SuperAdmin'
|| (user?.role === '系统管理员' && user?.orgId == resourceCatalogRawData.find(a => a.id == params?.treeId)?.orgId));
expandedKeysData = []; expandedKeysData = [];
} }
} else { } else {
@ -60,7 +65,10 @@ const LatestMetadata = (props) => {
const keyArr = selectedData[0].split('-'); const keyArr = selectedData[0].split('-');
keyArr.shift();//['rc-2-5']->返回'rc';keyArr:['2','5'] keyArr.shift();//['rc-2-5']->返回'rc';keyArr:['2','5']
const allExpandedKeys = allTreeNodeKeys.filter(k => keyArr.includes(k.id.toString())); const allExpandedKeys = allTreeNodeKeys.filter(k => keyArr.includes(k.id.toString()));
!params?.treeId && setResourceCatalogId(keyArr.pop()); const resourceCatalogId = keyArr.pop();
!params?.treeId && setResourceCatalogId(resourceCatalogId);
!params?.treeId && setIsAdmin(user?.username === 'SuperAdmin'
|| (user?.role === '系统管理员' && user?.orgId == resourceCatalogRawData.find(a => a.id == resourceCatalogId)?.orgId));
setResourceCatalogKey(selectedData[0]); setResourceCatalogKey(selectedData[0]);
const resourceCatalogPath = allExpandedKeys.map(a => a.name); const resourceCatalogPath = allExpandedKeys.map(a => a.name);
setResourceCatalogPath(resourceCatalogPath); setResourceCatalogPath(resourceCatalogPath);
@ -104,27 +112,29 @@ const LatestMetadata = (props) => {
const renderTreeNode = (ds, dataSource) => { const renderTreeNode = (ds, dataSource) => {
return <div className={theStyle.icon} style={{ width: 180 }}> return <div className={theStyle.icon} style={{ width: 180 }}>
{setTreeNodeTitle(ds.name)} {setTreeNodeTitle(ds.name)}
<EditOutlined title='修改' className={theStyle.tip} onClick={() => { {(user?.username === 'SuperAdmin' || (user?.role === '系统管理员' && user?.orgId == ds?.orgId)) && <>
let record = JSON.parse(JSON.stringify(ds)); <EditOutlined title='修改' className={theStyle.tip} onClick={() => {
let parentData = dataSource.filter(rc => rc.id === record.parent); let record = JSON.parse(JSON.stringify(ds));
record.parentName = parentData.length ? parentData[0].name : ''; let parentData = dataSource.filter(rc => rc.id === record.parent);
setEditData({ record: record, title: '修改子类', child: ds.parent ? true : false, }); record.parentName = parentData.length ? parentData[0].name : '';
setModalVisible(true); setEditData({ record: record, title: '修改子类', child: ds.parent ? true : false, });
}} /> setModalVisible(true);
<Popconfirm placement="top" title={'确定删除该资源目录吗?'} onConfirm={() => { }} />
dispatch(metadataManagement.delResourceCatalog(ds.id)).then((res) => { <Popconfirm placement="top" title={'确定删除该资源目录吗?'} onConfirm={() => {
if (res.success) { dispatch(metadataManagement.delResourceCatalog(ds.id)).then((res) => {
expandedKeysData = []; initData(true); if (res.success) {
} expandedKeysData = []; initData(true);
setModalVisible(false); }
}); setModalVisible(false);
}} okText="确定" cancelText="取消"> });
<MinusCircleOutlined title='删除' className={theStyle.tip} /> }} okText="确定" cancelText="取消">
</Popconfirm> <MinusCircleOutlined title='删除' className={theStyle.tip} />
<PlusCircleOutlined title='新建' className={theStyle.tip} onClick={() => { </Popconfirm>
setEditData({ record: { parent: ds.id, parentName: ds.name }, title: '新建子类', child: true, add: true }); <PlusCircleOutlined title='新建' className={theStyle.tip} onClick={() => {
setModalVisible(true); setEditData({ record: { parent: ds.id, parentName: ds.name, orgId: ds?.orgId }, title: '新建子类', child: true, add: true });
}} /> setModalVisible(true);
}} />
</>}
</div > </div >
}; };
//新建、修改 //新建、修改
@ -194,7 +204,7 @@ const LatestMetadata = (props) => {
allowClear onChange={onChangeSearch} allowClear onChange={onChangeSearch}
onKeyPress={onChangeSearch} /> onKeyPress={onChangeSearch} />
{user?.role == '系统管理员' && <Button type='primary' style={{ marginBottom: 16 }} onClick={() => { {user?.role == '系统管理员' && <Button type='primary' style={{ marginBottom: 16 }} onClick={() => {
setEditData({ title: '新建资源目录', add: true }); setEditData({ title: '新建资源目录', add: true, record: { orgId: user?.orgId } });
setModalVisible(true); setModalVisible(true);
}}>新建资源目录</Button>} }}>新建资源目录</Button>}
<Tree <Tree
@ -222,11 +232,13 @@ const LatestMetadata = (props) => {
<MetadataDetails resourceCatalogId={resourceCatalogId} <MetadataDetails resourceCatalogId={resourceCatalogId}
resourceCatalogKey={resourceCatalogKey} resourceCatalogKey={resourceCatalogKey}
resourceCatalogPath={resourceCatalogPath} resourceCatalogPath={resourceCatalogPath}
match={match} /> : match={match}
isAdmin={isAdmin} /> :
<MetadataTab resourceCatalogId={resourceCatalogId} <MetadataTab resourceCatalogId={resourceCatalogId}
resourceCatalogKey={resourceCatalogKey} resourceCatalogKey={resourceCatalogKey}
resourceCatalogPath={resourceCatalogPath} resourceCatalogPath={resourceCatalogPath}
params={params} params={params}
isAdmin={isAdmin}
/> />
// <MetadataTab resourceCatalogId={params?.treeId} // <MetadataTab resourceCatalogId={params?.treeId}
// resourceCatalogKey={params?.catalogKey} // resourceCatalogKey={params?.catalogKey}

4
web/client/src/sections/metadataManagement/containers/metadataDetails.js

@ -7,7 +7,7 @@ import MetadataDatabaseModal from '../components/metadataDatabaseModal';
import { ModelTypes, ConfigurableTypes } from '../constants/index'; import { ModelTypes, ConfigurableTypes } from '../constants/index';
const MetadataDetails = (props) => { const MetadataDetails = (props) => {
const { user, actions, dispatch, clientHeight, metadataModels, isRequesting, resourceCatalogPath, match } = props; const { user, actions, dispatch, clientHeight, metadataModels, isRequesting, resourceCatalogPath, match, isAdmin } = props;
const { metadataManagement } = actions; const { metadataManagement } = actions;
const [activeKey, setActiveKey] = useState('info'); const [activeKey, setActiveKey] = useState('info');
const [databasesRecord, setDatabasesRecord] = useState(null); const [databasesRecord, setDatabasesRecord] = useState(null);
@ -108,7 +108,7 @@ const MetadataDetails = (props) => {
return databasesRecord && (ConfigurableTypes['表'].includes(databasesRecord.type) || databasesRecord.type === '视图') ? null : <Spin spinning={isRequesting}> return databasesRecord && (ConfigurableTypes['表'].includes(databasesRecord.type) || databasesRecord.type === '视图') ? null : <Spin spinning={isRequesting}>
<div style={{ marginBottom: 16 }}> <div style={{ marginBottom: 16 }}>
{user?.role == '系统管理员' && <Button type='primary' onClick={() => { {isAdmin && <Button type='primary' onClick={() => {
setEditData({ add: true, title: '新建库表元数据', record: { path: '/' + resourceCatalogPath.join('/'), type: ConfigurableTypes[databasesRecord.type][0] } }); setEditData({ add: true, title: '新建库表元数据', record: { path: '/' + resourceCatalogPath.join('/'), type: ConfigurableTypes[databasesRecord.type][0] } });
setModalVisible(true); setModalVisible(true);
}}>新建</Button>} }}>新建</Button>}

8
web/client/src/sections/metadataManagement/containers/metadataTab.js

@ -7,7 +7,7 @@ import RestapisTable from './restapisTable';
import { push } from 'react-router-redux'; import { push } from 'react-router-redux';
const MetadataTab = (props) => { const MetadataTab = (props) => {
const { resourceCatalogId, resourceCatalogKey, resourceCatalogPath, actions, dispatch, params } = props; const { resourceCatalogId, resourceCatalogKey, resourceCatalogPath, actions, dispatch, params, isAdmin } = props;
const [activeKey, setActiveKey] = useState(params?.type || 'databases'); const [activeKey, setActiveKey] = useState(params?.type || 'databases');
useEffect(() => { useEffect(() => {
if (!params?.type) if (!params?.type)
@ -42,11 +42,11 @@ const MetadataTab = (props) => {
</Tabs> </Tabs>
{ {
activeKey === 'databases' && resourceCatalogId ? <DatabaseTable params={params} resourceCatalogId={resourceCatalogId} activeKey === 'databases' && resourceCatalogId ? <DatabaseTable params={params} resourceCatalogId={resourceCatalogId}
resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} setView={onView} /> : resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} setView={onView} isAdmin={isAdmin} /> :
activeKey === 'files' && resourceCatalogId ? <FilesTable params={params} resourceCatalogId={resourceCatalogId} activeKey === 'files' && resourceCatalogId ? <FilesTable params={params} resourceCatalogId={resourceCatalogId}
resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} /> : resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} isAdmin={isAdmin} /> :
activeKey === 'restapis' && resourceCatalogId ? < RestapisTable params={params} resourceCatalogId={resourceCatalogId} activeKey === 'restapis' && resourceCatalogId ? < RestapisTable params={params} resourceCatalogId={resourceCatalogId}
resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} /> : null resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} isAdmin={isAdmin} /> : null
} }
</div> </div>
} }

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

@ -8,7 +8,7 @@ import MetadataResourceModal from '../components/metadataResourceModal';
const RestapisTable = (props) => { const RestapisTable = (props) => {
const { user, dispatch, actions, clientHeight, resourceCatalogId, resourceCatalogKey, const { user, dispatch, actions, clientHeight, resourceCatalogId, resourceCatalogKey,
isRequesting, metadataModels, tagList, metadataResourceApplications, params } = props; isRequesting, metadataModels, tagList, metadataResourceApplications, params, isAdmin } = props;
const { metadataManagement } = actions; const { metadataManagement } = actions;
const [tableData, setTableData] = useState([]); const [tableData, setTableData] = useState([]);
const [tableDataCount, setTableDataCount] = useState(0);//Table数据 const [tableDataCount, setTableDataCount] = useState(0);//Table数据
@ -143,7 +143,7 @@ const RestapisTable = (props) => {
let resourceApplicationsRecords = metadataResourceApplications.filter(ra => let resourceApplicationsRecords = metadataResourceApplications.filter(ra =>
ra.applyBy == user.id && ra.resourceName === record.name && ra.resourceId == record.id && !!record.token); ra.applyBy == user.id && ra.resourceName === record.name && ra.resourceId == record.id && !!record.token);
return <ButtonGroup> return <ButtonGroup>
{user.role == '数据消费者' ? null : {!isAdmin ? null :
<> <>
<a style={{ marginLeft: 10 }} onClick={() => onEdit(record)}>编辑</a> <a style={{ marginLeft: 10 }} onClick={() => onEdit(record)}>编辑</a>
<Popconfirm <Popconfirm
@ -154,7 +154,7 @@ const RestapisTable = (props) => {
</> </>
} }
{user.role == '系统管理员' ? '' : resourceApplicationsRecords.length === 0 ? {isAdmin ? '' : resourceApplicationsRecords.length === 0 ?
<a style={{ marginLeft: 10 }} onClick={() => applyResources(record)}>申请资源</a> : <a style={{ marginLeft: 10 }} onClick={() => applyResources(record)}>申请资源</a> :
<span style={{ marginLeft: 10, color: "#c0c0c0" }} title='已存在资源申请'>申请资源</span>} <span style={{ marginLeft: 10, color: "#c0c0c0" }} title='已存在资源申请'>申请资源</span>}
</ButtonGroup> </ButtonGroup>
@ -187,7 +187,7 @@ const RestapisTable = (props) => {
return <Spin spinning={isRequesting}> return <Spin spinning={isRequesting}>
<Row style={{ marginBottom: 16 }}> <Row style={{ marginBottom: 16 }}>
<Col span={12}> <Col span={12}>
{user.role == '数据消费者' ? null : <> <Button type='primary' onClick={() => { {!isAdmin ? null : <> <Button type='primary' onClick={() => {
dispatch(metadataManagement.getMetadataModels({ modelTypes: '接口' })).then(res => { dispatch(metadataManagement.getMetadataModels({ modelTypes: '接口' })).then(res => {
if (res.success) { if (res.success) {
setEditData({ add: true, title: '新建接口元数据', record: {} }); setEditData({ add: true, title: '新建接口元数据', record: {} });

8
web/client/src/sections/metadataManagement/nav-item.js

@ -15,12 +15,12 @@ export function getNavItem(user) {
<Menu.Item key="businessMetadata"> <Menu.Item key="businessMetadata">
<Link to="/metadataManagement/businessMetadata">业务元数据管理</Link> <Link to="/metadataManagement/businessMetadata">业务元数据管理</Link>
</Menu.Item> </Menu.Item>
<Menu.Item key="metaModelManagement"> {user?.username == 'SuperAdmin' && <> <Menu.Item key="metaModelManagement">
<Link to="/metadataManagement/metaModelManagement">模型管理</Link> <Link to="/metadataManagement/metaModelManagement">模型管理</Link>
</Menu.Item> </Menu.Item>
<Menu.Item key="tagManagement"> <Menu.Item key="tagManagement">
<Link to="/metadataManagement/tagManagement">标签管理</Link> <Link to="/metadataManagement/tagManagement">标签管理</Link>
</Menu.Item> </Menu.Item></>}
</> </>
} }

2
web/client/src/sections/organization/nav-item.js

@ -7,7 +7,7 @@ const SubMenu = Menu.SubMenu;
export function getNavItem(user) { export function getNavItem(user) {
return ( return (
user?.role == '系统管理员' && <Menu.Item icon={<UserOutlined />} key="organization"> user?.username == 'SuperAdmin' && <Menu.Item icon={<UserOutlined />} key="organization">
<Link to="/organization">机构管理</Link> <Link to="/organization">机构管理</Link>
</Menu.Item> </Menu.Item>
// user?.role == '系统管理员' && <SubMenu key="memberManagement" icon={<UserOutlined />} title='用户管理'> // user?.role == '系统管理员' && <SubMenu key="memberManagement" icon={<UserOutlined />} title='用户管理'>

16
web/client/src/sections/resourceRetrieval/containers/retrieval.js

@ -201,15 +201,19 @@ function Retrieval(props) {
</div> </div>
<div className='column2'>相关操作<a onClick={() => { window.open(`/metadataManagement/latestMetadata?type=${METADTA_TYPE[s.type]}&treeId=${s?.catalog}&resourceId=${s.id}&catalogKey=${s.catalogKey}`) }}>定位</a> <div className='column2'>相关操作<a onClick={() => { window.open(`/metadataManagement/latestMetadata?type=${METADTA_TYPE[s.type]}&treeId=${s?.catalog}&resourceId=${s.id}&catalogKey=${s.catalogKey}`) }}>定位</a>
{s?.type == '表' || s?.type == '文件' ? {s?.type == '表' || s?.type == '文件' ?
user?.role == '数据消费者' ? user?.username !== 'SuperAmin' ?
<a onClick={() => { <a onClick={() => {
const token = approveList?.rows?.find(x => x.resourceId == s.id)?.token const isOrgAdmin = user?.role == '系统管理员' && user?.orgId == s?.resourceCatalog?.organization?.id
if (!token) { if (isOrgAdmin) {
message.warning('您暂未申请该数据资源,请先申请该数据资源') downloadData(s)
} else { } else {
setCurrentData(s) const token = approveList?.rows?.find(x => x.resourceId == s.id)?.token
if (!token) {
message.warning('您暂未申请该数据资源,请先申请该数据资源')
} else {
setCurrentData(s)
}
} }
}}>下载</a> : }}>下载</a> :
<a onClick={() => { downloadData(s) }}>下载</a> : ''} <a onClick={() => { downloadData(s) }}>下载</a> : ''}
</div> </div>

Loading…
Cancel
Save