Commit 086fefdf by fanyongjun

edit

parent 97e63a7e
......@@ -64,4 +64,16 @@ export function* apply(payload) {
export function* getDataFlowCount(payload) {
return yield call(service.getDataFlowCount, payload);
}
export function* uploadAttachment(payload) {
return yield call(service.uploadAttachment, payload);
}
export function* treeQuery(payload) {
return yield call(service.treeQuery,payload);
}
export function* fileQuery(payload) {
return yield call(service.fileQuery, payload);
}
\ No newline at end of file
......@@ -35,6 +35,10 @@ export const routes = [
// name: 'dataquality',
// text: '数据质量'
// }
{
name: 'file',
text: '文档下载'
},
]
},
{
......
import { PostJSON, Post, GetJSON } from "../util/axios"
import { PostJSON, Post, GetJSON, testPost } from "../util/axios"
export function domains(payload) {
return GetJSON("/authservice/domains", payload);
......@@ -54,4 +54,18 @@ export async function apply(payload){
export function getDataFlowCount(payload) {
return GetJSON('/metadatarepo/rest/jobInfo/getDataFlowCount')
}
\ No newline at end of file
}
export function uploadAttachment(payload) {
return testPost('/datacatalog/front/uploadAttachment',payload)
}
export function treeQuery(payload) {
return GetJSON('/informationmanagement/rest/fileCatalog/query')
}
export function fileQuery(payload) {
return GetJSON('/informationmanagement/rest/fileInformation/queryAll',payload)
}
......@@ -63,6 +63,21 @@ textplain.interceptors.request.use(
}
);
const testA = axios.create({
baseURL,
timeout: 5000,
headers:{'Content-Type':'multipart/form-data'},
processData:true,
validateStatus: (status) => {
return true;
}
});
let __source = null;
export const Cancel = function (msg) {
return new Promise(res => __source && __source.cancel(msg));
......@@ -111,4 +126,14 @@ export function Post(url, payload) {
}).then(
callback
)
}
export function testPost(url, payload) {
const { fileList = null,} = payload||{};
let formData = new FormData();
formData.append('attachment',fileList)
const cancelToken = __source ? __source.token : null;
return testA.post(url, formData, ).then(
callback
)
}
\ No newline at end of file
import React, { Component } from "react";
import { Icon, Row, Col, Typography, Skeleton, List, Button } from 'antd';
const { Text } = Typography;
export default class ListBox extends Component {
constructor(props) {
super(props);
this.state = {
tableModel : null,
tabKey: 'description',
dataDesc: null,
dataPreview: null,
showModal:false,
loading1:false,
loading2:false,
};
}
getMyDate=(str)=>{
var oDate = new Date(parseInt(str)),
oYear = oDate.getFullYear(),
oMonth = oDate.getMonth()+1,
oDay = oDate.getDate(),
oHour = oDate.getHours(),
oMin = oDate.getMinutes(),
oSen = oDate.getSeconds(),
oTime = oYear +'-'+ this.getzf(oMonth) +'-'+ this.getzf(oDay) +' '+ this.getzf(oHour) +':'+ this.getzf(oMin) +':'+ this.getzf(oSen);//最后拼接时间
return oTime;
};
//补0操作
getzf=(num)=>{
if(parseInt(num) < 10){
num = '0'+num;
}
return num;
}
download=(data)=>{
window.open(`/api/informationmanagement/rest/fileInformation/downloadFile?id=${data.id}`)
}
render() {
const { tableModels, loading } = this.props
const getIcon = () => {
return <Icon type="file" className="mr-2" />;
};
const getActions = (item) => {
return[
<Button size="small" type="link" icon="download" onClick={()=>this.download(item)} >下载</Button>,
<span></span>
]
};
const ListContent = ({ item }) => (
<React.Fragment>
<Row>
<Col md={12}> <Text>文件名:</Text> {item.name} </Col>
<Col md={12}> <Text>文件类型:</Text> {item.file_type} </Col>
<Col md={12}> <Text>发布者:</Text> {item.create_user} </Col>
<Col md={12}> <Text>发布作者:</Text> {this.getMyDate(item.create_date)} </Col>
</Row>
</React.Fragment>
);
return (
<React.Fragment>
<List
className='asset-list'
loading={loading}
itemLayout="vertical"
dataSource={tableModels || []}
renderItem={item => (
<List.Item
actions={[
...getActions(item),
]}
>
<Skeleton title={false} loading={loading} active>
<List.Item.Meta
title={
<div className="pointer text-primary">
{getIcon()}
<span >{item.name}.{item.file_type}</span>
</div>
}
description={<ListContent item={item} />}
/>
</Skeleton>
</List.Item>
)}
/>
</React.Fragment>
);
}
}
import React from 'react'
import { Tree, Input, Spin } from "antd"
const { TreeNode, DirectoryTree } = Tree;
const { Search } = Input;
const getParentKey = (key, tree) => {
let parentKey;
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
if (node.children) {
if (node.children.some(item => item.key === key)) {
parentKey = node.key;
} else if (getParentKey(key, node.children)) {
parentKey = getParentKey(key, node.children);
}
}
}
return parentKey;
};
class SearchTree extends React.Component {
constructor(props){
super(props)
this.state = {
expandedKeys: [],
selectedKeys:[],
searchValue: '',
searchMessage:'',
autoExpandParent: true,
}
}
componentDidMount() {
const {defaultKeys, selectKey} = this.props
if(defaultKeys[0]!==undefined){
const selectkeys = []
for (let item of defaultKeys){
selectkeys.push(item)
}
this.setState({expandedKeys:selectkeys,selectedKeys:selectKey})
}
}
componentDidUpdate(prevProps){
if(prevProps.defaultKeys.sort().toString()!==this.props.defaultKeys.sort().toString()){
const {defaultKeys, selectKey } = this.props
if(defaultKeys){
const selectkeys = []
for (let item of defaultKeys){
selectkeys.push(item)
}
this.setState({expandedKeys:selectkeys,selectedKeys:selectKey},()=>{
})
}
}
}
onExpand = expandedKeys => {
this.setState({
expandedKeys,
autoExpandParent: false,
});
};
onSelectNode=(keys,data)=>{
const {node} = data
let {expandedKeys} = this.state
let tempkey = keys
if(!expandedKeys.includes(node.props.dataRef.key))
expandedKeys.push(node.props.dataRef.key)
if(!tempkey[0]){
tempkey = this.state.selectedKeys
}
this.setState({checkedkey:tempkey[0],selectedKeys:tempkey,expandedKeys,autoExpandParent:true},()=>{
this.props.onClick(node.props.dataRef)
this.setState({autoExpandParent:false})
})
}
onSearch = () => {
const { searchMessage } = this.state;
const { dataList, gData } = this.props
if(searchMessage!==''){
const expandedKeys = dataList
.map(item => {
if (item.title.indexOf(searchMessage) > -1) {
return getParentKey(item.key, gData);
}
return null;
})
.filter((item, i, self) => item && self.indexOf(item) === i);
this.setState({
expandedKeys,
searchValue: searchMessage,
autoExpandParent: true,
});
}else{
this.setState({
expandedKeys:[],
searchValue: searchMessage,
autoExpandParent: false,
});
}
};
render() {
const { searchValue, expandedKeys, autoExpandParent, searchMessage, selectedKeys } = this.state;
const { gData, showLine, showIcon, directoryTree, style, placeholder, bodyHeight, loading, build, ifSearch } = this.props
const loop = data =>
data.map(item => {
const index = item.title.indexOf(searchValue);
const beforeStr = item.title.substr(0, index);
const afterStr = item.title.substr(index + searchValue.length);
const title =
index > -1 ? (
<span>
{beforeStr}
<span style={{ color: '#f50' }}>{searchValue}</span>
{afterStr}
</span>
) : (
<span>{item.title}</span>
);
if (item.children) {
return (
<TreeNode key={item.key} dataRef={item} title={title}>
{loop(item.children)}
</TreeNode>
);
}else{
if(item.typ==0)
return <TreeNode key={item.key} dataRef={item} title={title} />;
if(item.no)
return <TreeNode key={item.key} dataRef={item} title={title} />;
return <TreeNode key={item.key} dataRef={item} title={title} isLeaf/>;
}
});
return (
<div style={style?style:null}>
<div style={{padding:'0 8px',display:ifSearch?'':'none'}}>
<Search
style={{ marginBottom: 4 }}
placeholder={placeholder?placeholder:'搜索'}
value={searchMessage}
onChange={(e)=>{this.setState({searchMessage:e.target.value})}}
onSearch = {this.onSearch}
/>
</div>
<Spin spinning={loading}>
<div style={{height:ifSearch?`calc(${bodyHeight}px - 32px)`:bodyHeight,overflowY:'auto',overflowX:'hidden'}} >
{directoryTree?
build?
<DirectoryTree
showLine={showLine?showLine:false}
showIcon={showIcon?showIcon:false}
onExpand={this.onExpand}
onSelect={this.onSelectNode}
expandedKeys={expandedKeys}
selectedKeys={selectedKeys}
autoExpandParent={autoExpandParent}
>
{loop(gData)}
</DirectoryTree>
:
null
:
build?
<Tree
showLine={showLine?showLine:false}
showIcon={showIcon?showIcon:false}
onExpand={this.onExpand}
expandedKeys={expandedKeys}
selectedKeys={selectedKeys}
autoExpandParent={autoExpandParent}
onSelect={this.onSelectNode}
>
{loop(gData?gData:[])}
</Tree>
:
null}
</div>
</Spin>
</div>
)
}
}
export default SearchTree
\ No newline at end of file
import React, { Component } from "react"
import { Row, Col, Card, Input, Pagination } from 'antd';
import SyncTree from './components/SyncTree';
import ListBox from './components/ListBox';
import PageHeaderWrapper from '../../layout/PageHeaderWrapper';
import { dispatchLatest } from '../../model';
const { Search } = Input;
class Assets extends Component {
constructor(props) {
super(props);
this.state = {
TreeBox:[],
gData:[],
dataList:[],
treeload:false,
bulidTree:false,
defaultKeys:[],
pageNum:1,
pageSize:10,
total:0
};
}
componentDidMount() {
this.getTreeData();
}
getTreeData=()=>{
this.setState({treeload:true,bulidTree:false,gData:[],dataList:[],defaultKeys:[]})
dispatchLatest({
type: 'assets.treeQuery',
payload:null,
callback: data => {
try{
const treeData = data
const gData = this.getTree(treeData,'1')
const dataList = this.generateList(gData,[])
let defaultKeys = []
if(gData[0]!==undefined){
for (let key of gData){
defaultKeys.push(`${key.id}`)
}
}
this.setState({TreeBox:treeData,gData,dataList,defaultKeys,selectKey:[defaultKeys[0]],treeload:false,bulidTree:true},()=>{
if(this.state.gData[0]!==undefined){
this.selectTree(this.state.gData[0])
}
})
}catch(err){
console.log(err)
}
console.log('111')
}
})
}
getTree=(data, pid)=>{
let result = []
let temp
if(data[0]===undefined)
return data
let value = JSON.parse(JSON.stringify(data))
for (let treenode of value){
if(treenode.pid === pid){
treenode.title = treenode.name
treenode.key = `${treenode.id}`
if(treenode.no)
treenode.value = `${treenode.no}`
temp = this.getTree(value, treenode.id)
if (temp.length > 0) {
treenode.children = temp
}
result.push(treenode)
}
}
return result
}
generateList=(data,dataList)=>{
if(data[0]===undefined)
return data
for (let item of data){
const { key,title } = item;
dataList.push({ key, title });
if (item.children) {
dataList.concat(this.generateList(item.children,dataList))
}
}
return dataList
};
selectTree=(dataRef)=>{
this.setState({menuType:true, dataBox:dataRef,current:1},()=>{
this.getTable()
})
}
getTable = () => {
const {
pageNum,
pageSize,
keyword,
dataBox,
} = this.state
this.setState({ tableload: true })
dispatchLatest({
type: 'assets.fileQuery',
payload:{
catalogId: dataBox.id,
name: keyword&&keyword!==''?keyword:undefined,
page: pageNum,
rows: pageSize,
},
callback: data => {
this.setState({
tablelist: data.rows,
total: data.total,
tableload: false,
})
}
})
}
changecurrent = (page, size) => {
this.setState({ pageNum: page, pageSize: size }, () => {
this.getTable()
})
}
render() {
const { gData, dataList, tablelist, total, pageNum, pageSize, tableload,defaultKeys,
selectKey, treeload, bulidTree
} = this.state;
return (
<PageHeaderWrapper
{...this.props}
extra={
<Search
placeholder="请输入"
onSearch={value => {
this.setState({ keyword: value,pageNum:1 }, ()=> {
this.getTable()
})
}}
style={{ width: 300 }}
/>
}
>
<Row gutter={16} className="manage-asset">
<Col md={6} >
<Card bordered={false} className='asset-table'>
<SyncTree bodyHeight={'100%'} gData={gData} dataList={dataList} onClick={this.selectTree} defaultKeys={defaultKeys} selectKey={selectKey} loading={treeload} build={bulidTree} />
</Card>
</Col>
<Col md={18}>
<Card bordered={false} className='asset-table'>
<ListBox
loading={tableload}
tableModels={tablelist}
/>
<Pagination
className="text-center"
showSizeChanger
showQuickJumper
onChange={this.changecurrent}
onShowSizeChange={this.changecurrent}
current={pageNum}
pageSize={pageSize}
defaultCurrent={1}
total={total}
showTotal={total => `共 ${total} 条`}
/>
</Card>
</Col>
</Row>
</PageHeaderWrapper>
);
}
}
export default Assets;
\ No newline at end of file
......@@ -94,6 +94,25 @@ export class HomeMenu extends Component {
<Row type="flex">
{homeMenu.map((menu, i) => (
<Col key={i} xs={24} className="col-lg pl-between-1">
{menu.url ?
<Link to={menu.url}>
<Row className="home-menu px-4 py-6 text-center" onMouseEnter={ e=> {
e.preventDefault();
e.stopPropagation();
this.setState({ hoverIndex: i });
}} onMouseLeave={ e=> {
e.stopPropagation();
this.setState({ hoverIndex: -1 });
}}>
<Col xl={24} xxl={12}>
<img src={(hoverIndex===i)?menu.imgH:menu.img} alt='' />
</Col>
<Col xl={24} xxl={10}>
<span>{menu.title}</span>
</Col>
</Row>
</Link>
:
<Row className="home-menu px-4 py-6 text-center" onMouseEnter={ e=> {
e.preventDefault();
e.stopPropagation();
......@@ -106,15 +125,10 @@ export class HomeMenu extends Component {
<img src={(hoverIndex===i)?menu.imgH:menu.img} alt='' />
</Col>
<Col xl={24} xxl={10}>
{menu.url ? (
<Link to={menu.url}>
{menu.title}
</Link>
) : (
<span>{menu.title}</span>
)}
<span>{menu.title}</span>
</Col>
</Row>
}
</Col>
))}
</Row>
......
......@@ -103,30 +103,42 @@ class AssetListCOM extends Component {
}
apply= (columnPositions, reason, expireDate) => {
apply= (columnPositions, reason, expireDate, fileList) => {
const { tableModel, activeBtn } = this.state;
if (tableModel) {
console.log(columnPositions)
dispatch({
type: 'assets.apply',
payload: { params :{
tableModelId: tableModel.tableModelId,
columnPositions: columnPositions,
reason,
expireDate,
} },
callback: () => {
this.setState({ activeBtn: (activeBtn ^ 1) & 1 });
message.success('申请成功');
type: 'assets.uploadAttachment',
payload : {fileList:fileList,config :{
headers:{'Content-Type':'multipart/form-data'}
}
});
},
callback: (data) => {
dispatch({
type: 'assets.apply',
payload: { params :{
tableModelId: tableModel.tableModelId,
columnPositions: columnPositions,
reason,
expireDate,
},data:{
id:data,
name:fileList.name
}},
callback: () => {
this.setState({ activeBtn: (activeBtn ^ 1) & 1 });
message.success('申请成功');
}
});
}
})
}
}
render() {
const { tableModels, loading, subscribeTableModel, updateItems, subscrible = false } = this.props;
const { tableModel, showModal, tabKey, metedata, dataDesc, dataPreview, activeBtn } = this.state;
const IconText = ({ type, text }) => (
<span>
<Icon type={type} style={{ marginRight: 8 }} />
......@@ -297,7 +309,7 @@ class AssetListCOM extends Component {
{tableModel && (
<Modal
className="modal-lg"
title={<span>数据资产详情:{tableModel.displayName}</span>}
title={<span>数据资产详情:<span dangerouslySetInnerHTML={{ __html: tableModel.displayName }} /></span>}
visible={showModal}
width="calc(100vw - 50px)"
onCancel={e => {
......
import React, { Component, Fragment, useState } from 'react';
import { Table, Descriptions, Row, Col, Input, Checkbox, Divider, Pagination, Form, DatePicker, Button, message } from 'antd';
import { Table, Descriptions, Row, Col, Input, Checkbox, Divider, Pagination, Form, DatePicker, Button, message, Upload } from 'antd';
import classnames from 'classnames';
import { CheckOutlined } from '@ant-design/icons';
......@@ -107,7 +107,7 @@ export class DataDetail extends Component {
<Descriptions.Item label="资产名称">
<span dangerouslySetInnerHTML={{ __html: `${tableModel.name}` }} />
</Descriptions.Item>
<Descriptions.Item label="所属目录">{tableModel.topic}</Descriptions.Item>
<Descriptions.Item label="所属目录">{tableModel.catalog}</Descriptions.Item>
<Descriptions.Item label="所属系统">{tableModel.system}</Descriptions.Item>
<Descriptions.Item label="发布时间">{tableModel.createTime_str}</Descriptions.Item>
{/* <Descriptions.Item label="资产密级">{tableModel.assetStrictLevel_}</Descriptions.Item> */}
......@@ -186,6 +186,25 @@ const ApplyDescFunc = ({ dataDesc, form, apply }) => {
};
});
const normFile = e => {
let data = []
if(e.fileList[0]){
data = e.fileList.slice(-1)
}
return data;
};
const props = {
beforeUpload: file => {
const isLt20M = file.size / 1024 / 1024 < 20;
if (!isLt20M) {
return message.error('上传文件不能超过 20MB!')
}
return false;
},
};
return (
<Fragment>
<Row>
......@@ -258,6 +277,17 @@ const ApplyDescFunc = ({ dataDesc, form, apply }) => {
rules: [{ required: true, message: '请选择结束时间' }],
})(<DatePicker />)}
</Form.Item>
<Form.Item label="附件" >
{getFieldDecorator('file', {
rules: [{ required: true, message: '请上传附件'}],
valuePropName: 'fileList',
getValueFromEvent: normFile,
})(
<Upload {...props}>
<Button type='link' icon="plus" style={{padding:5}} > 添加附件</Button>
</Upload>
)}
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" onClick={()=>{
validateFields((err, values) =>{
......@@ -272,9 +302,9 @@ const ApplyDescFunc = ({ dataDesc, form, apply }) => {
set_checkedPostions({ checkedPositions: [] });
set_checkAll({ checkAll: false});
resetFields();
apply(checkedPositions, values.apply, values.expire.format('YYYY-MM-DD'));
apply(checkedPositions, values.apply, values.expire.format('YYYY-MM-DD'),values.file[0].originFileObj);
}
}
}
});
}}>
申请
......
......@@ -15,7 +15,7 @@ import Subscrible from '../User/Subscrible';
import Authorized from '../User/Authorized';
import Question from '../User/Question';
import Apply from '../User/Apply';
import FileManage from '../File'
class Manage extends Component {
constructor() {
super()
......@@ -47,6 +47,7 @@ class Manage extends Component {
<Route path={`${match.path}/authorized`} component={Authorized} />
<Route path={`${match.path}/question`} component={Question} />
<Route path={`${match.path}/apply`} component={Apply} />
<Route path={`${match.path}/file`} component={FileManage} />
</Switch>
) : (
<GetSession {...this.props} />
......
......@@ -12,7 +12,7 @@ export const DetailBox = props =>{
<Descriptions.Item label="资产名称">
<span dangerouslySetInnerHTML={{ __html: `${tableModel.name}` }} />
</Descriptions.Item>
<Descriptions.Item label="所属目录">{tableModel.topic}</Descriptions.Item>
<Descriptions.Item label="所属目录">{tableModel.catalog}</Descriptions.Item>
<Descriptions.Item label="所属系统">{tableModel.system}</Descriptions.Item>
<Descriptions.Item label="发布时间">{tableModel.createTime_str}</Descriptions.Item>
<Descriptions.Item label="更新周期">{tableModel.updateCycle}</Descriptions.Item>
......
......@@ -84,6 +84,10 @@ export default class ListBox extends Component {
});
}
download=(data)=>{
window.open(`/api/datacatalog/front/downloadAttachment?attachmentId=${data}`)
}
render() {
const { tableModels, loading } = this.props
......@@ -145,6 +149,12 @@ export default class ListBox extends Component {
{item.expireDate}
</Col>
</Row>
{(item.attachment!=null&&item.attachment.id!=null)&&(
<Row>
<Col md={24}> <Text>附件:</Text><Button type={'link'} style={{padding:0,height:22}} onClick={()=>this.download(item.attachment.id)}>{item.attachment.name}</Button> </Col>
</Row>
)}
</React.Fragment>
);
......
import React, { Component } from "react";
import { Card, Table, Radio, Pagination, Input, Button, Modal } from 'antd';
import { dispatchLatest, dispatch } from '../../../model';
import { paginate } from '../../../util';
import PageHeaderWrapper from '../../../layout/PageHeaderWrapper';
import ListBox from './components/ListBox'
......@@ -11,7 +9,6 @@ export default class index extends Component {
constructor(props) {
super(props);
this.state = {
loading: false,
total: 0,
......@@ -33,14 +30,11 @@ export default class index extends Component {
getList = () => {
const { pageNum, pageSize } = this.state
this.setState({ loading: true },() => {
const payload = {
page: pageNum,
pageSize: pageSize,
};
dispatchLatest({
type: 'user.listProcessByPage',
payload: payload,
......@@ -58,16 +52,15 @@ export default class index extends Component {
updateItems() {
const { tableModels } = this.state;
this.setState({ tableModels: tableModels });
}
}
render() {
const { tableModels, loading, pageNum, pageSize, total }= this.state
const _items = paginate(tableModels, pageNum, pageSize);
return (
<PageHeaderWrapper {...this.props}>
<Card bordered={false}>
<ListBox tableModels={_items} loading={loading} updateItems={this.updateItems.bind(this)}/>
<ListBox tableModels={tableModels} loading={loading} updateItems={this.updateItems.bind(this)}/>
<Pagination
className="text-center"
showSizeChanger
......
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