9 changed files with 325 additions and 27 deletions
			
			
		| @ -0,0 +1,53 @@ | |||||
|  | 'use strict'; | ||||
|  | 
 | ||||
|  | import { basicAction } from '@peace/utils' | ||||
|  | import { ApiTable } from '$utils' | ||||
|  | 
 | ||||
|  | export function getResourceCatalog(params) { | ||||
|  |     return dispatch => basicAction({ | ||||
|  |         type: 'get', | ||||
|  |         dispatch: dispatch, | ||||
|  |         query: params, | ||||
|  |         actionType: 'GET_RESOURCE_CATALOG', | ||||
|  |         url: ApiTable.getResourceCatalog, | ||||
|  |         msg: { error: '获取资源目录失败' }, | ||||
|  |         reducer: { name: 'resourceCatalog' } | ||||
|  |     }); | ||||
|  | } | ||||
|  | 
 | ||||
|  | export function postResourceCatalog(data) { | ||||
|  |     return dispatch => basicAction({ | ||||
|  |         type: 'post', | ||||
|  |         data: data, | ||||
|  |         dispatch: dispatch, | ||||
|  |         actionType: 'POST_RESOURCE_CATALOG', | ||||
|  |         url: ApiTable.postResourceCatalog, | ||||
|  |         msg: { option: '新增资源目录' }, | ||||
|  |         reducer: {} | ||||
|  |     }); | ||||
|  | } | ||||
|  | 
 | ||||
|  | export function putResourceCatalog(id, data) { | ||||
|  |     return dispatch => basicAction({ | ||||
|  |         type: 'put', | ||||
|  |         data: data, | ||||
|  |         dispatch, | ||||
|  |         actionType: 'PUT_RESOURCE_CATALOG', | ||||
|  |         url: ApiTable.putResourceCatalog.replace('{id}', id), | ||||
|  |         msg: { | ||||
|  |             option: '修改资源目录', | ||||
|  |         } | ||||
|  |     }); | ||||
|  | } | ||||
|  | 
 | ||||
|  | export function delResourceCatalog(id) { | ||||
|  |     return dispatch => basicAction({ | ||||
|  |         type: 'del', | ||||
|  |         dispatch, | ||||
|  |         actionType: 'DELETE_RESOURCE_CATALOG', | ||||
|  |         url: ApiTable.delResourceCatalog.replace('{id}', id), | ||||
|  |         msg: { | ||||
|  |             option: '删除资源目录', | ||||
|  |         } | ||||
|  |     }); | ||||
|  | } | ||||
| @ -0,0 +1,86 @@ | |||||
|  | import React, { useEffect, useState } from 'react'; | ||||
|  | import { Modal, Input, Form, message } from 'antd'; | ||||
|  | const { TextArea } = Input; | ||||
|  | const ResourceCatalogModal = (props) => { | ||||
|  |     const { resourceCatalog, onConfirm, onCancel, editData } = props; | ||||
|  |     const [form] = Form.useForm(); | ||||
|  |     useEffect(() => { | ||||
|  |     }, []); | ||||
|  |     const handleOk = () => { | ||||
|  |         form.validateFields().then(values => { | ||||
|  |             if (onConfirm) { | ||||
|  |                 if (editData.add) { | ||||
|  |                     //新建
 | ||||
|  |                     let exist = resourceCatalog.find(rc => rc.name === values.name); | ||||
|  |                     if (exist) { | ||||
|  |                         message.error('该资源目录名称已存在'); | ||||
|  |                         return false; | ||||
|  |                     } | ||||
|  |                     exist = resourceCatalog.find(rc => rc.code === values.code); | ||||
|  |                     if (exist) { | ||||
|  |                         message.error('该资源目录代码已存在'); | ||||
|  |                         return false; | ||||
|  |                     } | ||||
|  |                 } else {//修改
 | ||||
|  |                     let exist = resourceCatalog.find(rc => rc.name === values.name && rc.id != editData.record.id); | ||||
|  |                     if (exist) { | ||||
|  |                         message.error('该资源目录名称已存在'); | ||||
|  |                         return false; | ||||
|  |                     } | ||||
|  |                     exist = resourceCatalog.find(rc => rc.code === values.code && rc.id != editData.record.id); | ||||
|  |                     if (exist) { | ||||
|  |                         message.error('该资源目录代码已存在'); | ||||
|  |                         return false; | ||||
|  |                     } | ||||
|  |                 } | ||||
|  |                 onConfirm(values) | ||||
|  |             } | ||||
|  |         }) | ||||
|  |     } | ||||
|  |     const validatorNull = (rule, value, getFieldValue, validateFields) => { | ||||
|  |         if (!value || !value.trim().length) { | ||||
|  |             return Promise.reject(new Error(`${rule.field === 'name' ? '名称' : '代码'}不可空字符串`)); | ||||
|  |         } | ||||
|  |         return Promise.resolve(); | ||||
|  |     } | ||||
|  |     return ( | ||||
|  |         <Modal title={editData.title} visible={true} destroyOnClose | ||||
|  |             okText='确定' width={800} | ||||
|  |             onOk={() => handleOk(null)} | ||||
|  |             onCancel={onCancel}> | ||||
|  |             <Form form={form} labelCol={{ span: 6 }} wrapperCol={{ span: 18 }} initialValues={editData.record || {}}> | ||||
|  |                 {editData.child ? <Form.Item | ||||
|  |                     label='上级目录' | ||||
|  |                     name='parentName' | ||||
|  |                 > | ||||
|  |                     <Input disabled style={{ width: '90%' }} /> | ||||
|  |                 </Form.Item> : null} | ||||
|  |                 <Form.Item | ||||
|  |                     label='名称' | ||||
|  |                     name='name' | ||||
|  |                     rules={[{ required: true, message: '' }, { max: 50, message: `名称不超过50个字符` }, | ||||
|  |                     ({ getFieldValue, validateFields }) => ({ | ||||
|  |                         validator(_, value) { return validatorNull(_, value, getFieldValue, validateFields) } | ||||
|  |                     })]}> | ||||
|  |                     <Input style={{ width: '90%' }} placeholder={`请输入名称`} /> | ||||
|  |                 </Form.Item> | ||||
|  |                 <Form.Item | ||||
|  |                     label='代码' | ||||
|  |                     name='code' | ||||
|  |                     rules={[{ required: true, message: '' }, { max: 50, message: `代码不超过50个字符` }, | ||||
|  |                     ({ getFieldValue, validateFields }) => ({ | ||||
|  |                         validator(_, value) { return validatorNull(_, value, getFieldValue, validateFields) } | ||||
|  |                     })]}> | ||||
|  |                     <Input style={{ width: '90%' }} placeholder={`请输入代码`} /> | ||||
|  |                 </Form.Item> | ||||
|  |                 <Form.Item | ||||
|  |                     label='描述' | ||||
|  |                     name='description' | ||||
|  |                     rules={[{ max: 255, message: `描述不超过255个字符` }]}> | ||||
|  |                     <TextArea rows={4} style={{ width: '90%' }} placeholder={`请输入描述`} /> | ||||
|  |                 </Form.Item> | ||||
|  |             </Form> | ||||
|  |         </Modal> | ||||
|  |     ) | ||||
|  | } | ||||
|  | export default ResourceCatalogModal; | ||||
| @ -1,24 +1,160 @@ | |||||
| import React, { useEffect, useState } from 'react'; | import React, { useEffect, useState } from 'react'; | ||||
| import { connect } from 'react-redux'; | import { connect } from 'react-redux'; | ||||
| import { Button, } from 'antd' | import { Spin, Row, Col, Tree, Button, Tooltip, Popconfirm } from 'antd'; | ||||
|  | import { PlusCircleOutlined, EditOutlined, MinusCircleOutlined } from '@ant-design/icons'; | ||||
|  | import theStyle from './style.css'; | ||||
|  | import ResourceCatalogModal from '../components/resourceCatalogModal'; | ||||
|  | let expandedKeysData = []; | ||||
| 
 | 
 | ||||
| const LatestMetadata = (props) => { | const LatestMetadata = (props) => { | ||||
|     const { user, dispatch, actions, history } = props; |     const { user, dispatch, actions, clientHeight, resourceCatalog, isRequesting } = props; | ||||
|  |     const { metadataManagement } = actions; | ||||
|  |     const [resourceCatalogData, setResourceCatalogData] = useState([]); | ||||
|  |     const [selectedKeys, setSelectedKeys] = useState([]); | ||||
|  |     const [expandedKeys, setExpandedKeys] = useState([]); | ||||
|  |     const [modalVisible, setModalVisible] = useState(false); | ||||
|  |     const [editData, setEditData] = useState({}); | ||||
| 
 | 
 | ||||
|     useEffect(() => { |     useEffect(() => { | ||||
|  |         initData(true); | ||||
|     }, []) |     }, []) | ||||
|  |     const initData = (configRefresh) => { | ||||
|  |         dispatch(metadataManagement.getResourceCatalog()).then(res => { | ||||
|  |             const { data } = res.payload; | ||||
|  |             if (res.success) { | ||||
|  |                 const resourceCatalogData = getTreeNodeData(data, null, 'rc'); | ||||
|  |                 setResourceCatalogData(resourceCatalogData); | ||||
|  |                 if (data.length) { | ||||
|  |                     if (configRefresh) { | ||||
|  |                         setExpandedKeys(expandedKeysData); | ||||
|  |                         setSelectedKeys(expandedKeysData); | ||||
|  |                     } | ||||
|  |                 } else { | ||||
|  |                     setExpandedKeys([]); | ||||
|  |                     setSelectedKeys([]); | ||||
|  |                 }; | ||||
|  |             } | ||||
|  |         }) | ||||
|  |     } | ||||
|  |     const getTreeNodeData = (dataSource, parent, key) => { | ||||
|  |         let treeData = []; | ||||
|  |         let data = []; | ||||
|  |         if (!parent) { | ||||
|  |             data = dataSource.filter(ds => !ds.parent); | ||||
|  |             if (!expandedKeysData.length && data.length) { | ||||
|  |                 expandedKeysData.push(`rc-${data[0].id}`); | ||||
|  |             } | ||||
|  |         } else { | ||||
|  |             data = dataSource.filter(ds => ds.parent == parent); | ||||
|  |         } | ||||
|  |         treeData = data.map(ds => { | ||||
|  |             return { title: renderTreeNode(ds, dataSource), key: `${key}-${ds.id}`, id: ds.id } | ||||
|  |         }); | ||||
|  |         for (let d of treeData) { | ||||
|  |             d.children = getTreeNodeData(dataSource, d.id, d.key); | ||||
|  |         } | ||||
|  |         return treeData | ||||
|  |     } | ||||
| 
 | 
 | ||||
|     return <>最新元数据 |     const setTreeNodeTitle = (name) => { | ||||
|         <Button type="primary" onClick={() => { history.push(`/metadataManagement/latestMetadata/detail/${1}`) }} >查看详情</Button> |         let content = <span>{name}</span> | ||||
|     </> |         if (name.length > 10) { | ||||
| } |             content = <Tooltip title={name}> | ||||
|  |                 {name.substring(0, 10) + '...'} | ||||
|  |             </Tooltip> | ||||
|  |         } | ||||
|  |         return content; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     const renderTreeNode = (ds, dataSource) => { | ||||
|  |         return <div className={theStyle.icon}> | ||||
|  |             {setTreeNodeTitle(ds.name)} | ||||
|  |             <EditOutlined title='修改' style={{ marginLeft: 10 }} className={theStyle.tip} onClick={() => { | ||||
|  |                 let record = JSON.parse(JSON.stringify(ds)); | ||||
|  |                 let parentData = dataSource.filter(rc => rc.id === record.parent); | ||||
|  |                 record.parentName = parentData.length ? parentData[0].name : ''; | ||||
|  |                 setEditData({ record: record, title: '修改子类', child: ds.parent ? true : false, }); | ||||
|  |                 setModalVisible(true); | ||||
|  |             }} /> | ||||
|  |             <Popconfirm placement="top" title={'确定删除该资源目录吗?'} onConfirm={() => { | ||||
|  |                 dispatch(metadataManagement.delResourceCatalog(ds.id)).then((res) => { | ||||
|  |                     if (res.success) { | ||||
|  |                         expandedKeysData = []; initData(true); | ||||
|  |                     } | ||||
|  |                     setModalVisible(false); | ||||
|  |                 }); | ||||
|  |             }} okText="确定" cancelText="取消"> | ||||
|  |                 <MinusCircleOutlined title='删除' style={{ marginLeft: 10 }} className={theStyle.tip} /> | ||||
|  |             </Popconfirm> | ||||
|  |             <PlusCircleOutlined title='新建' style={{ marginLeft: 10 }} className={theStyle.tip} onClick={() => { | ||||
|  |                 setEditData({ record: { parent: ds.id, parentName: ds.name }, title: '新建子类', child: true, add: true }); | ||||
|  |                 setModalVisible(true); | ||||
|  |             }} /> | ||||
|  |         </div > | ||||
|  |     }; | ||||
|  |     //新建、修改
 | ||||
|  |     const onConfirm = (values) => { | ||||
|  |         let obj = { ...values } | ||||
|  |         if (editData.add) { | ||||
|  |             obj = { ...values, ...editData.record || {} } | ||||
|  |             dispatch(metadataManagement.postResourceCatalog(obj)).then(() => { | ||||
|  |                 initData(); setModalVisible(false); | ||||
|  |             }); | ||||
|  |         } else { | ||||
|  |             dispatch(metadataManagement.putResourceCatalog(editData.record.id, obj)).then(() => { | ||||
|  |                 initData(); setModalVisible(false); | ||||
|  |             }); | ||||
|  |         } | ||||
|  |     } | ||||
|  |     return <Spin spinning={isRequesting}> | ||||
|  |         <Row> | ||||
|  |             <Col style={{ width: 240 }}> | ||||
|  |                 <Button type='primary' style={{ marginBottom: 16 }} onClick={() => { | ||||
|  |                     setEditData({ title: '新建资源目录', add: true }); | ||||
|  |                     setModalVisible(true); | ||||
|  |                 }}>新建资源目录</Button> | ||||
|  |                 <Tree | ||||
|  |                     // showLine
 | ||||
|  |                     height={clientHeight - 180} | ||||
|  |                     expandedKeys={expandedKeys} | ||||
|  |                     selectedKeys={selectedKeys} | ||||
|  |                     onSelect={(keys, e) => { | ||||
|  |                         if (e.selected) { | ||||
|  |                             // setCurrentPage(1);
 | ||||
|  |                             setSelectedKeys(keys); | ||||
|  |                             // let keyArr = allTreeNodeKeys.filter(ak => ak.key.includes(keys[0]));
 | ||||
|  |                             // let ids = keyArr.map(key => key.id);
 | ||||
|  |                             // console.log('all-' + JSON.stringify(ids))
 | ||||
|  |                         } | ||||
|  |                     }} | ||||
|  |                     onExpand={(keys) => { | ||||
|  |                         setExpandedKeys(keys); | ||||
|  |                     }} | ||||
|  |                     treeData={resourceCatalogData} | ||||
|  |                 /> | ||||
|  |             </Col> | ||||
|  |             <Col style={{ width: 'calc(100% - 240px)' }}> | ||||
| 
 | 
 | ||||
|  |             </Col> | ||||
|  |         </Row> | ||||
|  |         { | ||||
|  |             modalVisible ? | ||||
|  |                 <ResourceCatalogModal | ||||
|  |                     resourceCatalog={resourceCatalog} | ||||
|  |                     editData={editData} | ||||
|  |                     onCancel={() => setModalVisible(false)} | ||||
|  |                     onConfirm={onConfirm} /> : '' | ||||
|  |         } | ||||
|  |     </Spin> | ||||
|  | } | ||||
| function mapStateToProps(state) { | function mapStateToProps(state) { | ||||
|     const { global, auth } = state; |     const { global, auth, resourceCatalog } = state; | ||||
|     return { |     return { | ||||
|         clientHeight: global.clientHeight, |  | ||||
|         user: auth.user, |         user: auth.user, | ||||
|         actions: global.actions, |         actions: global.actions, | ||||
|  |         clientHeight: global.clientHeight, | ||||
|  |         resourceCatalog: resourceCatalog?.data || [], | ||||
|  |         isRequesting: resourceCatalog.isRequesting | ||||
|     }; |     }; | ||||
| } | } | ||||
| export default connect(mapStateToProps)(LatestMetadata) | export default connect(mapStateToProps)(LatestMetadata) | ||||
| @ -0,0 +1,16 @@ | |||||
|  | .icon .tip { | ||||
|  |     margin-left: 10px; | ||||
|  |     -webkit-transition: opacity 0.1s 0.2s; | ||||
|  |     opacity: 0; | ||||
|  |     pointer-events: none; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .icon:hover .tip { | ||||
|  |     -webkit-transition: opacity 0.2s; | ||||
|  |     opacity: 1; | ||||
|  |     pointer-events: auto; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .icon .tip:hover { | ||||
|  |     -webkit-transition: none; | ||||
|  | } | ||||
					Loading…
					
					
				
		Reference in new issue