diff --git a/api/app/lib/controllers/resourceConsumption/index.js b/api/app/lib/controllers/resourceConsumption/index.js index 7f76a13..09af903 100644 --- a/api/app/lib/controllers/resourceConsumption/index.js +++ b/api/app/lib/controllers/resourceConsumption/index.js @@ -23,6 +23,10 @@ function getApproveList(opts) { model: models.User, as: 'approveUser', attributes: ['id', 'name'] + }, { + model: models.MetadataFile, + as: 'metadataFile', + attributes: ['id', 'fileName'] }, { model: models.MetadataDatabase, @@ -38,7 +42,7 @@ function getApproveList(opts) { }, { model: models.RestfulApi, - attributes: ['id', 'name'], + // attributes: ['id', 'name'], include: [{ model: models.ResourceCatalog, attributes: ['id', 'name'], diff --git a/api/app/lib/index.js b/api/app/lib/index.js index 14424bc..57b4a20 100644 --- a/api/app/lib/index.js +++ b/api/app/lib/index.js @@ -113,4 +113,6 @@ module.exports.models = function (dc) { MetadataFile.belongsTo(ResourceCatalog, { foreignKey: 'catalog', targetKey: 'id' }); ResourceCatalog.belongsTo(Organization, { foreignKey: 'orgId', targetKey: 'id' }); + + ResourceConsumption.belongsTo(MetadataFile, { foreignKey: 'resourceId', targetKey: 'id' }); }; diff --git a/api/app/lib/routes/latestMetadata/index.js b/api/app/lib/routes/latestMetadata/index.js index 0f192f0..31b0ee7 100644 --- a/api/app/lib/routes/latestMetadata/index.js +++ b/api/app/lib/routes/latestMetadata/index.js @@ -107,7 +107,7 @@ module.exports = function (app, router, opts) { tokens = s.token } }) - if (tokens && tokens == token) { + if (tokens && (tokens == token || tokens == token[1] || tokens == token[0])) { if (findOne.enabled) { const pool = new Pool({ user: ctx.fs.dc.orm.config.username, @@ -175,7 +175,7 @@ module.exports = function (app, router, opts) { } }); - + async function release (apps, opts) { @@ -208,7 +208,7 @@ module.exports = function (app, router, opts) { } }) - if (tokens && tokens == token) { + if (tokens && (tokens == token || tokens == token[1] || tokens == token[0])) { if (findOne.enabled) { const pool = new Pool({ user: ctx.fs.dc.orm.config.username, diff --git a/web/client/assets/files/common/1698915773497_5.jpg b/web/client/assets/files/common/1698915773497_5.jpg new file mode 100644 index 0000000..900b37d Binary files /dev/null and b/web/client/assets/files/common/1698915773497_5.jpg differ diff --git a/web/client/src/sections/metadataManagement/components/businessDatabaseModal.js b/web/client/src/sections/metadataManagement/components/businessDatabaseModal.js index 376f38f..07af42f 100644 --- a/web/client/src/sections/metadataManagement/components/businessDatabaseModal.js +++ b/web/client/src/sections/metadataManagement/components/businessDatabaseModal.js @@ -6,7 +6,7 @@ const basicInfo = [{ name: '元数据名称:', key: 'name' }, { name: '上下文路径:', key: 'path' }, { name: '元数据详情:', key: 'description' }]; const BusinessDatabaseModal = (props) => { - const { onConfirm, onCancel, editData, metadataModels, resourceCatalogPath, businessType } = props; + const { onConfirm, onCancel, editData, metadataModels, resourceCatalogPath, businessType, isAdmin } = props; const [form] = Form.useForm(); useEffect(() => { }, []); @@ -66,6 +66,7 @@ const BusinessDatabaseModal = (props) => { return ( handleOk(null)} onCancel={onCancel}> {editData.record && editData.record.businessMetadata.length ? @@ -87,7 +88,7 @@ const BusinessDatabaseModal = (props) => { ({ getFieldValue, validateFields }) => ({ validator(_, value) { return validatorNull(_, value, getFieldValue, validateFields, item.name) } })]}> - + )} diff --git a/web/client/src/sections/metadataManagement/containers/businessDatabaseTable.js b/web/client/src/sections/metadataManagement/containers/businessDatabaseTable.js index f9de168..17ccef9 100644 --- a/web/client/src/sections/metadataManagement/containers/businessDatabaseTable.js +++ b/web/client/src/sections/metadataManagement/containers/businessDatabaseTable.js @@ -6,7 +6,7 @@ import FileSaver from 'file-saver'; import BusinessDatabaseModal from '../components/businessDatabaseModal'; const BusinessDatabaseTable = (props) => { const { user, dispatch, actions, clientHeight, resourceCatalogId, - resourceCatalogPath, isRequesting, metadataModels } = props; + resourceCatalogPath, isRequesting, metadataModels, isAdmin } = props; const { metadataManagement } = actions; const SortValues = { 'ascend': 'asc', 'descend': 'desc' }; const [tableData, setTableData] = useState([]); @@ -201,13 +201,13 @@ const BusinessDatabaseTable = (props) => { if (record.businessMetadataDatabases.length) { return
onAdd(record, false)}>查看 - confirmDelete(record.businessMetadataDatabases[0].id)} - > 删除 + > 删除}
} else - return onAdd(record, true)}>新建 + return isAdmin && onAdd(record, true)}>新建 } }]; @@ -329,7 +329,8 @@ const BusinessDatabaseTable = (props) => { editData={editData} onCancel={() => setModalVisible(false)} onConfirm={onConfirm} - resourceCatalogPath={resourceCatalogPath} /> : '' + resourceCatalogPath={resourceCatalogPath} + isAdmin={isAdmin} /> : '' } } diff --git a/web/client/src/sections/metadataManagement/containers/businessFilesTable.js b/web/client/src/sections/metadataManagement/containers/businessFilesTable.js index 49e91bb..bc18f9d 100644 --- a/web/client/src/sections/metadataManagement/containers/businessFilesTable.js +++ b/web/client/src/sections/metadataManagement/containers/businessFilesTable.js @@ -6,7 +6,7 @@ import FileSaver from 'file-saver'; import BusinessDatabaseModal from '../components/businessDatabaseModal'; const BusinessFilesTable = (props) => { const { user, dispatch, actions, clientHeight, resourceCatalogId, - resourceCatalogPath, isRequesting, metadataModels } = props; + resourceCatalogPath, isRequesting, metadataModels, isAdmin } = props; const { metadataManagement } = actions; const SortValues = { 'ascend': 'asc', 'descend': 'desc' }; const [tableData, setTableData] = useState([]); @@ -190,13 +190,13 @@ const BusinessFilesTable = (props) => { if (record.businessMetadataFiles.length) { return
onAdd(record, false)}>查看 - confirmDelete(record.businessMetadataFiles[0].id)} - > 删除 + > 删除}
} else - return onAdd(record, true)}>新建 + return isAdmin && onAdd(record, true)}>新建 } }]; @@ -317,7 +317,8 @@ const BusinessFilesTable = (props) => { onCancel={() => setModalVisible(false)} onConfirm={onConfirm} resourceCatalogPath={resourceCatalogPath} - businessType='文件' /> : '' + businessType='文件' + isAdmin={isAdmin} /> : '' } } diff --git a/web/client/src/sections/metadataManagement/containers/businessMetadata.js b/web/client/src/sections/metadataManagement/containers/businessMetadata.js index 23e115d..67be5d6 100644 --- a/web/client/src/sections/metadataManagement/containers/businessMetadata.js +++ b/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'; let expandedKeysData = []; let allTreeNodeKeys = []; +let resourceCatalogRawData = []; const BusinessMetadata = (props) => { const { user, dispatch, actions, clientHeight, isRequesting, resourceCatalog } = props; const { metadataManagement } = actions; + const [isAdmin, setIsAdmin] = useState(false); const [resourceCatalogData, setResourceCatalogData] = useState([]); const [selectedKeys, setSelectedKeys] = useState([]); const [expandedKeys, setExpandedKeys] = useState([]); @@ -23,6 +25,7 @@ const BusinessMetadata = (props) => { dispatch(metadataManagement.getResourceCatalog()).then(res => { const { data } = res.payload; if (res.success) { + resourceCatalogRawData = data; allTreeNodeKeys = [] const resourceCatalogData = getTreeNodeData(data, null, 'rc', [], null); setResourceCatalogData(resourceCatalogData); @@ -44,7 +47,10 @@ const BusinessMetadata = (props) => { const keyArr = selectedData[0].split('-'); keyArr.shift();//['rc-2-5']->返回'rc';keyArr:['2','5'] 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]); const resourceCatalogPath = allExpandedKeys.map(a => a.name); setResourceCatalogPath(resourceCatalogPath); @@ -161,7 +167,8 @@ const BusinessMetadata = (props) => { + resourceCatalogPath={resourceCatalogPath} + isAdmin={isAdmin} /> diff --git a/web/client/src/sections/metadataManagement/containers/businessRestapisTable.js b/web/client/src/sections/metadataManagement/containers/businessRestapisTable.js index 7c79801..0c8e8c6 100644 --- a/web/client/src/sections/metadataManagement/containers/businessRestapisTable.js +++ b/web/client/src/sections/metadataManagement/containers/businessRestapisTable.js @@ -6,7 +6,7 @@ import FileSaver from 'file-saver'; import BusinessDatabaseModal from '../components/businessDatabaseModal'; const BusinessFilesTable = (props) => { const { user, dispatch, actions, clientHeight, resourceCatalogId, - resourceCatalogPath, isRequesting, metadataModels } = props; + resourceCatalogPath, isRequesting, metadataModels, isAdmin } = props; const { metadataManagement } = actions; const SortValues = { 'ascend': 'asc', 'descend': 'desc' }; const [tableData, setTableData] = useState([]); @@ -190,13 +190,13 @@ const BusinessFilesTable = (props) => { if (record.businessMetadataRestapis.length) { return
onAdd(record, false)}>查看 - confirmDelete(record.businessMetadataRestapis[0].id)} - > 删除 + > 删除}
} else - return onAdd(record, true)}>新建 + return isAdmin && onAdd(record, true)}>新建 } }]; @@ -317,7 +317,8 @@ const BusinessFilesTable = (props) => { onCancel={() => setModalVisible(false)} onConfirm={onConfirm} resourceCatalogPath={resourceCatalogPath} - businessType='接口' /> : '' + businessType='接口' + isAdmin={isAdmin} /> : '' } } diff --git a/web/client/src/sections/metadataManagement/containers/businessTab.js b/web/client/src/sections/metadataManagement/containers/businessTab.js index 2fcda8f..cfca376 100644 --- a/web/client/src/sections/metadataManagement/containers/businessTab.js +++ b/web/client/src/sections/metadataManagement/containers/businessTab.js @@ -6,7 +6,7 @@ import BusinessFilesTable from './businessFilesTable'; import BusinessRestapisTable from './businessRestapisTable'; const BusinessTab = (props) => { - const { resourceCatalogId, resourceCatalogKey, resourceCatalogPath, actions, dispatch } = props; + const { resourceCatalogId, resourceCatalogKey, resourceCatalogPath, actions, dispatch, isAdmin } = props; const [activeKey, setActiveKey] = useState('databases'); useEffect(() => { setActiveKey('databases'); @@ -36,11 +36,11 @@ const BusinessTab = (props) => { { activeKey === 'databases' && resourceCatalogId ? : + resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} isAdmin={isAdmin} /> : activeKey === 'files' && resourceCatalogId ? : + resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} isAdmin={isAdmin} /> : activeKey === 'restapis' && resourceCatalogId ? : + resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} isAdmin={isAdmin} /> : null } diff --git a/web/client/src/sections/metadataManagement/containers/databasesTable.js b/web/client/src/sections/metadataManagement/containers/databasesTable.js index 8f3b569..2099041 100644 --- a/web/client/src/sections/metadataManagement/containers/databasesTable.js +++ b/web/client/src/sections/metadataManagement/containers/databasesTable.js @@ -11,7 +11,7 @@ import MetadataResourceModal from '../components/metadataResourceModal'; import ReleaseModal from '../components/releaseModal'; 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; const { metadataManagement } = actions; 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); return onView(record)}>查看 - {user.role == '数据消费者' ? null : + {!isAdmin ? null : <> onEdit(record)}>编辑 { {record.type === '表' ? marking(record.id)}>打标 : null} } - - {user.role !== '数据消费者' ? null : record.type === '表' ? resourceApplicationsRecords.length === 0 ? + {isAdmin ? null : record.type === '表' ? resourceApplicationsRecords.length === 0 ? applyResources(record)}>申请资源 : 申请资源 : null} - {user.role == '数据消费者' ? null : + {!isAdmin ? null : record.type === '表' ? servicePublication(record)}>REST服务发布 : null } @@ -272,7 +271,7 @@ const DatabaseTable = (props) => { return - {user.role == '数据消费者' ? null : <> + {!isAdmin ? null : <> } { : + match={match} + isAdmin={isAdmin} /> : // { - 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 [activeKey, setActiveKey] = useState('info'); const [databasesRecord, setDatabasesRecord] = useState(null); @@ -108,7 +108,7 @@ const MetadataDetails = (props) => { return databasesRecord && (ConfigurableTypes['表'].includes(databasesRecord.type) || databasesRecord.type === '视图') ? null :
- {user?.role == '系统管理员' && } diff --git a/web/client/src/sections/metadataManagement/containers/metadataTab.js b/web/client/src/sections/metadataManagement/containers/metadataTab.js index a79a43d..ed61f76 100644 --- a/web/client/src/sections/metadataManagement/containers/metadataTab.js +++ b/web/client/src/sections/metadataManagement/containers/metadataTab.js @@ -7,7 +7,7 @@ import RestapisTable from './restapisTable'; import { push } from 'react-router-redux'; 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'); useEffect(() => { if (!params?.type) @@ -42,11 +42,11 @@ const MetadataTab = (props) => { { activeKey === 'databases' && resourceCatalogId ? : + resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} setView={onView} isAdmin={isAdmin} /> : activeKey === 'files' && resourceCatalogId ? : + resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} isAdmin={isAdmin} /> : activeKey === 'restapis' && resourceCatalogId ? < RestapisTable params={params} resourceCatalogId={resourceCatalogId} - resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} /> : null + resourceCatalogKey={resourceCatalogKey} resourceCatalogPath={resourceCatalogPath} isAdmin={isAdmin} /> : null }
} diff --git a/web/client/src/sections/metadataManagement/containers/restapisTable.js b/web/client/src/sections/metadataManagement/containers/restapisTable.js index 7824a79..a8cea8b 100644 --- a/web/client/src/sections/metadataManagement/containers/restapisTable.js +++ b/web/client/src/sections/metadataManagement/containers/restapisTable.js @@ -8,7 +8,7 @@ import MetadataResourceModal from '../components/metadataResourceModal'; const RestapisTable = (props) => { const { user, dispatch, actions, clientHeight, resourceCatalogId, resourceCatalogKey, - isRequesting, metadataModels, tagList, metadataResourceApplications, params } = props; + isRequesting, metadataModels, tagList, metadataResourceApplications, params, isAdmin } = props; const { metadataManagement } = actions; const [tableData, setTableData] = useState([]); const [tableDataCount, setTableDataCount] = useState(0);//Table数据 @@ -143,7 +143,7 @@ const RestapisTable = (props) => { let resourceApplicationsRecords = metadataResourceApplications.filter(ra => ra.applyBy == user.id && ra.resourceName === record.name && ra.resourceId == record.id && !!record.token); return - {user.role == '数据消费者' ? null : + {!isAdmin ? null : <> onEdit(record)}>编辑 { } - {user.role == '系统管理员' ? '' : resourceApplicationsRecords.length === 0 ? + {isAdmin ? '' : resourceApplicationsRecords.length === 0 ? applyResources(record)}>申请资源 : 申请资源} @@ -187,7 +187,7 @@ const RestapisTable = (props) => { return - {user.role == '数据消费者' ? null : <> + } }]; + const restTableExport = (name, data = []) => { + let dataKey = Object.keys(data[0])||[] + + let excelTitle = dataKey.map(s => { + return { k: s, v: s } + }); + let workBook = { + SheetNames: [], //sheet名称 + Sheets: {} //根据SheetNames名称顺序依次添加每个sheet数据 + }; + + let sheetName = '元数据列表'; + let sheetDataMap = new Map(); + let sheetData = [excelTitle]; + let index = 1; + data.map(data => { + const arr = [] + dataKey.map(s => { + arr.push( + { k: s, v: JSON.stringify(data[s]) }, + ); + }); + sheetData.push(arr) + index = index + 1; + }) + + sheetDataMap.set(sheetName, sheetData); + sheetDataMap.forEach((values, key) => { + // 写入excel + workBook.Sheets[key] = xlsx.utils.aoa_to_sheet(values); + workBook.Sheets[key]['!cols'] = [{ wpx: 50 }, { wpx: 150 }, { wpx: 180 }, { wpx: 230 }, { wpx: 230 }, { wpx: 230 }] + }) + workBook.SheetNames = [sheetName]; + // 将workBook写入文件 + xlsx.writeFile(workBook, `${name}-data.xlsx`); + } + return <> @@ -143,7 +289,7 @@ function MyApplication({ loading, clientHeight, actions, dispatch, user }) { } -function mapStateToProps(state) { +function mapStateToProps (state) { const { global, auth, resourceCatalog } = state; return { user: auth.user,