Commit 3b52d2f5 by zhaochengxiang

资产管理

parent d13c8ab7
......@@ -109,6 +109,7 @@ const AddAssetModel = (props) => {
form={form}
dirId={nodeId}
action='add'
reference={reference}
onMetadataChange={onMetadataChange}
onElementsChange={onElementsChange}
/>
......
......@@ -101,7 +101,7 @@ const MetaModelSelect = ({ value = {}, metaModelTreeData = [], onChange, ...rest
}
const AttributeRelationModal = (props) => {
const { visible, onCancel, type = ResourceManageReference } = props;
const { visible, onCancel, type = AssetManageReference } = props;
const [ confirmLoading, setConfirmLoading ] = useState(false);
const [ metadataModelTreeData, setMetadataModelTreeData ] = useState([]);
......@@ -201,7 +201,10 @@ const AttributeRelationModal = (props) => {
dispatch({
type: 'assetmanage.saveEleAndAttrRel',
payload: {
data: newRels
data: newRels,
params: {
dataAssetType: getAssetType(type)
}
},
callback: data => {
reset();
......
import React from 'react'
import { Button, Modal, Spin, Tree, AutoComplete } from 'antd'
import { dispatch } from '../../../model'
import produce from 'immer'
import { highlightSearchContentByTerms, showMessage, showNotifaction } from '../../../util'
import { generateList } from '../AssetResourceManage/tree'
const FC = (props) => {
const { visible, items, onCancel } = props
const [waiting, setWaiting] = React.useState(false)
const basicRef = React.useRef()
const close = (refresh = false) => {
setWaiting(false)
onCancel?.(refresh)
}
const save = () => {
const checkedKeys = basicRef.current?.getCheckedKeys()
if ((checkedKeys??[]).length === 0) {
showMessage('warn', '请先选择资源目录')
return
}
setWaiting(true)
dispatch({
type: 'assetmanage.loadDataAssets',
payload: {
params: {
dirId: checkedKeys.join(","),
},
data: (items??[]).map(item => item.id)
},
callback: data => {
setWaiting(false)
if (data?.message) {
showNotifaction('提示', data?.message, 5)
}
onCancel?.(true)
},
error: () => {
setWaiting(false)
}
})
}
const footer = React.useMemo(() => {
return [
<Button key={'cancel'}
onClick={() => close()}
>取消</Button>,
<Button key={'save'} type='primary'
disabled={waiting}
onClick={() => save()}
>保存</Button>
]
}, [close, save, waiting])
return (
<Modal
visible={visible}
footer={footer}
width='400px'
bodyStyle={{ padding: '15px 15px 0px 15px', overflowX: 'auto', maxHeight: '80vh', height: 500 }}
title='变更目录'
centered destroyOnClose
onCancel={() => { close() }}
>
<Spin spinning={waiting}>
<Basic ref={basicRef} items={items} />
</Spin>
</Modal>
)
}
export default FC
export const Basic = React.forwardRef(function ({ items, onCheck }, ref) {
const [data, setData] = React.useState()
const [dataList, setDataList] = React.useState()
const [loading, setLoading] = React.useState(false)
const [checkedKeys, setCheckedKeys] = React.useState()
const [expandedKeys, setExpandedKeys] = React.useState([])
const [autoExpandParent, setAutoExpandParent] = React.useState(false)
const [options, setOptions] = React.useState()
const [keyword, setKeyword] = React.useState()
React.useImperativeHandle(ref, () => ({
getCheckedKeys: () => checkedKeys
}), [checkedKeys])
React.useEffect(() => {
getTreeData()
getAssetPaths()
}, [])
const treeData = React.useMemo(() => {
if (data) {
const newTreeData = produce(data, draft => {
const setNode = (g) => {
g.key = g.nodeId
g.title = g.text
g.children?.forEach((child) => {
setNode(child)
})
}
draft.forEach((child) => {
setNode(child)
})
})
return newTreeData
}
return []
}, [data])
const getAssetPaths = () => {
if ((items??[]).length > 0) {
dispatch({
type: 'assetmanage.getAssetPaths',
payload: {
dataAssetId: items[0].id,
},
callback: data => {
setCheckedKeys((data??[]).map(item => item.dirId))
}
})
}
}
const getTreeData = () => {
setLoading(true)
dispatch({
type: 'assetmanage.queryAllDirectoryAsTree',
callback: data => {
setLoading(false)
const newData = (data??[]).filter(item => item.resourceType !== 'custom')
setData(newData)
if ((newData??[]).length > 0) {
const newDataList = []
generateList(newData, newDataList)
setDataList(newDataList)
const firstNode = newData[0]
setExpandedKeys([firstNode.nodeId])
setAutoExpandParent(true)
}
},
error: () => {
setLoading(false)
}
})
}
const onTreeExpand = (expandedKeys) => {
setExpandedKeys(expandedKeys)
setAutoExpandParent(false)
}
const onTreeCheck = (values, e) => {
//同一主题下只能挂载一个目录
if (e.node?.level === 1) {
showMessage('warn', '栏目不允许勾选')
return
}
const newCheckedKeys = values.checked??[]
if (e.checked) {
const index = (dataList??[]).findIndex(item => item.nodeId === e.node?.key)
if (index !== -1) {
const currentSubjectNodeId = dataList[index].subjectNodeId
const filterChecktedKeys = newCheckedKeys.filter(key => {
if (key !== e.node?.key) {
const index = (dataList??[]).findIndex(item => item.nodeId === key)
if (index !== -1) {
return (dataList[index].subjectNodeId !== currentSubjectNodeId)
} else {
return false
}
}
return true
})
setCheckedKeys(filterChecktedKeys)
onCheck?.(filterChecktedKeys)
}
} else {
setCheckedKeys(newCheckedKeys)
onCheck?.(newCheckedKeys)
}
}
const onAutoCompleteSearch = (searchText) => {
setKeyword(searchText)
setOptions(!searchText?[]:(dataList||[]).filter(item => item.value.indexOf(searchText)!==-1))
}
const onAutoCompleteSelect = (value, option) => {
const paths = value.split('/')
setKeyword(paths[paths.length-1])
const newExpandedKeys = [...expandedKeys, option.key]
setExpandedKeys(Array.from(new Set(newExpandedKeys)))
setAutoExpandParent(true)
}
return (
<Spin spinning={loading}>
<AutoComplete
allowClear
value={keyword}
style={{ marginBottom: 10, width: '100%' }}
onSelect={onAutoCompleteSelect}
onSearch={onAutoCompleteSearch}
onClear={() => {
setKeyword()
}}
>
{
(options||[]).map((item, index) => {
return (
<AutoComplete.Option key={item.key} value={item.value}>
<div style={{ whiteSpace: 'normal' }}>
{highlightSearchContentByTerms(item.value, [keyword])}
</div>
</AutoComplete.Option>
);
})
}
</AutoComplete>
<Tree
checkable
checkStrictly
showLine
showIcon={false}
treeData={treeData}
autoExpandParent={autoExpandParent}
expandedKeys={expandedKeys}
checkedKeys={checkedKeys}
onExpand={onTreeExpand}
onCheck={onTreeCheck}
/>
</Spin>
)
})
\ No newline at end of file
import React, { useState } from 'react';
import classNames from 'classnames';
import { Form } from 'antd';
import { CaretLeftOutlined, CaretRightOutlined } from '@ant-design/icons';
import { ResizableBox } from 'react-resizable';
import AssetTree from './Component/AssetManageTree';
import AssetDirectory from './Component/AssetDirectory';
import AssetTable from './Component/AssetTable';
import AssetAction from './Component/AssetAction';
import Separate from './Component/Separate';
import { AssetManageReference } from '../../../util/constant';
import './index.less';
const AssetManage = (props) => {
const [ nodeId, setNodeId ] = useState('');
const [ nodeType, setNodeType ] = useState('');
const [ nodeLevel, setNodeLevel ] = useState(null);
const [ assetParams, setAssetParams ] = useState({ assetId: '', assetDirId: '' })
const [ expandTree, setExpandTree ] = useState(true);
const [ assetFullScreen, setAssetFullScreen ] = useState(false);
const [ assetCount, setAssetCount ] = useState(0);
const [ directoryChanged, setDirectoryChanged ] = useState(false);
const [ elementsChanged, setElementsChanged ] = useState(false);
const [ assetActionChanged, setAssetActionChanged ] = useState(false);
const [ form ] = Form.useForm();
const { assetId, assetDirId } = assetParams;
const onTreeSelect = (value, type, level) => {
setNodeId(value||'');
setNodeType(type);
setNodeLevel(level);
import React from "react"
import classNames from 'classnames'
import { ResizableBox } from 'react-resizable'
import { Form } from "antd"
import { CaretLeftOutlined, CaretRightOutlined } from '@ant-design/icons'
import Tree from './tree'
import Separate from './Component/Separate'
import NodeDetail from './Component/AssetDirectory'
import AssetList from './table'
import AssetDetail from './Component/AssetAction'
import { AssetManageReference } from "../../../util/constant"
import './index.less'
const FC = (props) => {
const [collapseTree, setCollapseTree] = React.useState(false)
const [node, setNode] = React.useState()
const [asset, setAsset] = React.useState()
const [assetListFullScreen, setAssetListFullScreen] = React.useState(false)
const [directoryChanged, setDirectoryChanged] = React.useState(false)
const [form] = Form.useForm()
const onTreeClick = (value) => {
setDirectoryChanged(!directoryChanged)
setNode(value)
}
const onTableSelect = (id, did) => {
setAssetParams({ assetId: id, assetDirId: did });
const onAssetListClick = (value) => {
setAsset(value)
}
const treeToggleClick = () => {
setExpandTree(!expandTree);
const onAssetListFullScreenChange = (value) => {
setAssetListFullScreen(value)
}
const onElementsChange = () => {
setElementsChanged(!elementsChanged);
}
const onDirectoryChange = () => {
setDirectoryChanged(!directoryChanged);
}
const onAssetActionChange = () => {
setAssetActionChanged(!assetActionChanged);
}
const onAssetCountChange = (count) => {
setAssetCount(count);
}
const onFullScreenChange = (value) => {
setAssetFullScreen(value);
const treeToggleClick = () => {
setCollapseTree(!collapseTree)
}
const classes = classNames('asset-manage', {
'asset-manage-collapse': !expandTree
});
const rootClasses = classNames('asset-manage', {
'asset-manage-collapse': collapseTree
})
const middleClasses = classNames('middle', {
'middle-fullscreen': assetFullScreen
});
'middle-fullscreen': assetListFullScreen
})
return (
<div className={classes}>
<div className={rootClasses}>
<ResizableBox
className='left'
width={230}
height={Infinity}
axis='x'
minConstraints={[230, Infinity]} maxConstraints={[Infinity, Infinity]}
minConstraints={[230, Infinity]}
maxConstraints={[Infinity, Infinity]}
>
<AssetTree onSelect={onTreeSelect} onDirectoryChange={onDirectoryChange} {...props} />
<Tree onClick={onTreeClick} {...props} />
</ResizableBox>
{
expandTree && <Separate width={15} />
!collapseTree && <Separate width={15} />
}
<div className={middleClasses}>
<AssetDirectory id={nodeId} assetCount={assetCount} directoryChanged={directoryChanged} onElementsChange={onElementsChange} />
<NodeDetail
reference={AssetManageReference}
id={node?.nodeId}
assetCount={node?.dataAssetAndSubDirCount}
directoryChanged={directoryChanged}
/>
<Separate height={15} />
<AssetTable nodeId={nodeId} nodeType={nodeType} nodeLevel={nodeLevel} reference={AssetManageReference} elementsChanged={elementsChanged} assetActionChanged={assetActionChanged} onSelect={onTableSelect} onCountChange={onAssetCountChange} onFullScreenChange={onFullScreenChange} {...props} />
<AssetList
node={node}
onClick={onAssetListClick}
onFullScreenChange={onAssetListFullScreenChange}
{...props}
/>
<div className='tree-toggle' onClick={treeToggleClick}>
{ expandTree ? <CaretLeftOutlined /> : <CaretRightOutlined /> }
{ !collapseTree ? <CaretLeftOutlined /> : <CaretRightOutlined /> }
</div>
</div>
<Separate width='15px' />
<div className='right'>
<AssetAction form={form} id={assetId} dirId={assetDirId} action='detail' reference={AssetManageReference} onChange={onAssetActionChange} />
<AssetDetail
form={form}
id={asset?.id}
dirId={asset?.dirId}
action='detail'
reference={AssetManageReference}
/>
</div>
</div>
)
}
export default AssetManage;
\ No newline at end of file
export default FC
\ No newline at end of file
......@@ -21,7 +21,7 @@ const FC = (props) => {
const checkedKeys = basicRef.current?.getCheckedKeys()
if ((checkedKeys??[]).length === 0) {
showMessage('warn', '请先选择资目录')
showMessage('warn', '请先选择资目录')
return
}
......@@ -139,7 +139,7 @@ export const Basic = React.forwardRef(function ({ items, onCheck }, ref) {
type: 'assetmanage.queryResourceDirectoryAsTree',
callback: data => {
setLoading(false)
const newData = (data??[]).filter(item => item.resourceType !== 'resource')
const newData = (data??[]).filter(item => item.resourceType !== 'custom')
setData(newData)
if ((newData??[]).length > 0) {
const newDataList = []
......
......@@ -1674,7 +1674,7 @@ export const MetadataColumnTooltipTitle = ({ data }) => {
)
}
const MetadataColumn = ({ data }) => {
export const MetadataColumn = ({ data }) => {
const decodeData = React.useMemo(() => {
if (data) {
try {
......
......@@ -4,7 +4,7 @@ import { PlusOutlined, ReloadOutlined, ImportOutlined, ExportOutlined, SettingOu
import produce from 'immer'
import { dispatch } from '../../../model'
import { showMessage, highlightSearchContentByTerms, showNotifaction, getAssetType } from '../../../util'
import { showMessage, highlightSearchContentByTerms, showNotifaction, getAssetType, getAssetRange } from '../../../util'
import Tree from '../../../util/Component/Tree'
import PermissionButton from '../../../util/Component/PermissionButton'
import UpdateNode from './update-node'
......@@ -27,7 +27,7 @@ export const generateList = (data, list, path = null, subjectNodeId = null) => {
}
}
const updateTreeData = (list, key, children) => {
export const updateTreeData = (list, key, children) => {
return list.map((node) => {
if (node.nodeId === key) {
return {...node, children}
......@@ -111,7 +111,7 @@ const FC = (props) => {
<span className={(g.level===1)?'title-color':'text-color'}>
{g.text}
{
//自定义类型栏目不统计资
//自定义类型栏目不统计资
(g.level === 1 && g.resourceType === 'custom') ? null : <span>{` (${g.dataAssetAndSubDirCount})`}</span>
}
</span>
......@@ -231,7 +231,7 @@ const FC = (props) => {
dispatch({
type: 'assetmanage.getPrivilegeByRange',
payload: {
range: 'dataAsset_dataAssetManage',
range: getAssetRange(ResourceManageReference),
},
callback: data => {
setPermissions(data);
......
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