Commit 0840d503 by fanyj

地铁功能迁移

parent b755ba12
import React from "react"
import styles from "./index.module.less"
interface treeprops{
topAction:any;
mainBody:any;
}
const ActionTreePanel:React.FC<treeprops>=(props)=>{
const {topAction,mainBody} = props
return(
<div className={styles.lefttreepanel}>
<div className={styles.lefttree}>
{topAction}
</div>
<div className={styles.treebody}>
{mainBody}
</div>
</div>
)
}
export default ActionTreePanel
\ No newline at end of file
import React from "react"
import {Descriptions,Typography,Row,Col, Tooltip} from "antd"
import styles from "./index.module.less"
import png from "./imgs/note.png"
import {pageUtil} from "@/utils"
const {Item} = Descriptions
const {Text} = Typography
const TopPanel:React.FC<any>=(props)=>{
const {total,attrs,treeNode} = props
return (
<div className={styles.topmessage}>
<div className={styles.message}>
<Row gutter={[10,10]}>
{
attrs.map((item:any,key:any)=>{
return (
<Col span={item.span||8} key={key}>
<Text ellipsis={true}>
<span style={{marginRight:10}}>{item.cnName}:</span>
<Tooltip title={treeNode[item.name]} placement="top">
{treeNode[item.name]}
</Tooltip>
</Text>
</Col>
)
})
}
</Row>
{/* <Descriptions size="small">
{
attrs.map((item:any,key:any)=>{
return <Item key={key} label={item.cnName}></Item>
})
}
</Descriptions> */}
</div>
<div className={styles.count}>
<img src={png} />
<div className={styles.countnum}>
<div>记录数</div>
<div>{total}</div>
</div>
</div>
</div>
)
}
export default TopPanel
\ No newline at end of file
@showtree:~`'showtree'`;
@hidetree:~`'hidetree'`;
@showtable:~`'showtable'`;
@hidetable:~`'hidetable'`;
.main{
height: 100%;
display: flex;
.left{
width:245px;
background: #ECEEF3;
height:100%;
display: flex;
.paneltree{
width:230px;
background: #ECEEF3;
height:100%;
}
.bar{
width:15px;
height:100%;
background-color: #f0f2f5;
}
:global{
.centerinfo-tree .centerinfo-tree-treenode{
white-space: nowrap;
}
.react-contexify{
min-width: 120px;
}
}
}
.middle{
width:15px;
height:100%;
background-color: #f0f2f5;
position: relative;
.point{
display: -webkit-flex;
display: flex;
-webkit-justify-content: center;
justify-content: center;
-webkit-align-items: center;
align-items: center;
left: 0;
right: 0;
background: #f2f5fc;
position: absolute;
top: calc(50% - 40px);
font-size: 14px;
width: 12px;
height: 80px;
border-radius: 0 12px 12px 0;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
cursor: pointer;
}
}
.right{
width:calc(100% - 245px);
height:100%;
position: relative;
// padding-left: 20px;
.actionbar{
width:15px;
height:100%;
position:absolute;
.point{
display: -webkit-flex;
display: flex;
-webkit-justify-content: center;
justify-content: center;
-webkit-align-items: center;
align-items: center;
left: 0;
right: 0;
background: #f2f5fc;
position: absolute;
top: calc(50% - 40px);
font-size: 14px;
width: 12px;
height: 80px;
border-radius: 0 12px 12px 0;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
cursor: pointer;
}
}
.catalog{
height:123px;
padding:20px 15px;
.topmessage{
display: flex;
align-items: center;
justify-content: space-between;
color:#5b5b5b;
height: 100%;
.message{
width:100%;
height:82px;
overflow: hidden;
}
.count{
width:200px;
display: flex;
color:#5b5b5b;
align-items: center;
justify-content: center;
>img{
width: 53px;
height: 53px;
}
.countnum{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-left: 10px;
>div:nth-child(1){
box-sizing: border-box
}
>div:nth-child(2){
margin-top: -9px;
font-size: 25px;
font-weight: bold;
box-sizing: border-box
}
}
}
}
}
.middle{
height:15px;
background-color: #f0f2f5;
width: 100%;
}
.metamain{
height:calc(100% - 138px);
overflow: hidden;
padding-left: 3px;
}
:global{
.centerinfo-table-thead > tr > th {
padding: 8px 8px !important;
}
.centerinfo-table-tbody > tr > td {
padding: 12px 8px !important;
}
.centerinfo-table-tbody > .centerinfo-table-measure-row > td {
padding: 0px !important;
}
.centerinfo-table-tbody > tr .centerinfo-table-row-selected > td {
background: #fff !important;
}
tr.centerinfo-table-expanded-row > td {
background: #fff !important;
}
.centerinfo-table-thead > tr > th {
background-color: #F2F5FC !important;
}
}
}
.showtrees{
width:100%;
overflow: hidden;
animation:@showtree .3s ease-in forwards;
}
.hidetrees{
width:0;
overflow: hidden;
animation:@hidetree .3s ease-in forwards;
}
.showtables{
width:100%;
overflow: hidden;
animation:@showtable .3s ease-in forwards;
}
.hidetables{
width:0;
overflow: hidden;
animation:@hidetable .3s ease-in forwards;
}
:global{
@keyframes @showtree {
0% {
width:0px
}
100% {
width:245px
}
}
@keyframes @hidetree {
0% {
width:245px;
}
100% {
width:0px;
}
}
@keyframes @showtable {
0% {
width:calc(100% - 245px);
}
100% {
width:calc(100% - 20px);
}
}
@keyframes @hidetable {
0% {
width:calc(100% - 20px);
}
100% {
width:calc(100% - 245px);
}
}
}
}
.lefttreepanel{
height: 100%;
background-color: #fff;
.lefttree{
border-bottom:1px solid #EFEFEF;
padding: 0 12px;
height:45px;
align-items: center;
display: flex;
}
.treebody{
height: calc(100% - 46px);
overflow: auto;
padding:12px;
}
}
.inputpanel{
border-bottom:1px solid #EFEFEF;
padding:12px;
>div{
height: 32px;
}
}
.maintable{
height:calc(100% - 100px);
padding:12px
}
.mainpage{
text-align: center;
}
import React,{ useState} from "react"
import styles from "./index.module.less"
import {CaretLeftOutlined ,CaretRightOutlined } from "@ant-design/icons"
import TopPanel from "./TopPanel"
interface panelprops{
leftPanel:Function;
rightPanel:Function;
topPanel:any;
}
const LeftTreePanel:React.FC<panelprops>=(props)=>{
const {leftPanel,rightPanel,topPanel} = props
const [open,setOpen] = useState('')
const pointclick = ()=>{
if(open==='hidetree'){
setOpen('opentree')
}else{
setOpen('hidetree')
}
}
return(
<div className={styles.main} >
<div className={`${ styles.left} ${open?(open==='opentree'?styles.showtrees:styles.hidetrees):''}`}>
<div className={styles.paneltree}>
{leftPanel&&leftPanel()}
</div>
<div className={styles.bar} />
</div>
{/* <div className={styles.middle}>
<div className={styles.point} onClick={pointclick}>
{
open==='hidetree'?(
<CaretRightOutlined />
):(
<CaretLeftOutlined />
)
}
</div>
</div> */}
<div className={`${styles.right} ${open?(open==='opentree'?styles.hidetables:styles.showtables):''}`}>
<div className={styles.actionbar}>
<div className={styles.point} onClick={pointclick}>
{
open==='hidetree'?(
<CaretRightOutlined />
):(
<CaretLeftOutlined />
)
}
</div>
</div>
<div className={styles.catalog}>
{topPanel}
</div>
<div className={styles.middle}>
</div>
<div className={styles.metamain}>
{rightPanel&&rightPanel(open,pointclick)}
</div>
</div>
</div>
)
}
export default LeftTreePanel
\ No newline at end of file
import React,{useMemo} from "react"
import styles from "./index.module.less"
import {Table} from "antd"
import ScrollTable from "@/component/scrolltable";
interface bodyprops{
topPanel:any;
bodyPanel:any;
pagePanel:any;
}
const ActionBodyPanel:React.FC<bodyprops>=(props)=>{
const {topPanel,bodyPanel,pagePanel} = props
const columns:any = useMemo(()=>{
let list:Array<any> = [
{
title:'序号',
key:'index',
width:80,
resize:true,
},
{
title:'字段英文名称',
key:'name',
dataIndex:'name',
ellipsis:true,
resize:true,
},
{
title:'字段中文名称',
key:'cnName',
dataIndex:'cnName',
ellipsis:true,
resize:true,
render:(text:any,record:any)=>{
return ''
}
},
{
title:'字段说明',
key:'description',
dataIndex:'description',
ellipsis:true,
resize:true,
render:(text:any,record:any)=>{
return ''
}
},
{
title:'表英文名称',
key:'parentName',
dataIndex:'parentName',
ellipsis:true,
resize:true,
render:(text:any,record:any)=>{
try {
return ''
} catch (error) {
return ''
}
}
},
{
title:'表中文名称',
key:'parentCnName',
dataIndex:'parentCnName',
ellipsis:true,
resize:true,
render:(text:any,record:any)=>{
try {
return ''
} catch (error) {
return ''
}
}
},
{
title:'表说明',
key:'parentDescription',
dataIndex:'parentDescription',
ellipsis:true,
resize:true,
render:(text:any,record:any)=>{
try {
return ''
} catch (error) {
return ''
}
}
},
{
title:'标签',
key:'tag',
ellipsis:true,
width:200,
resize:true,
},
]
return list
},[])
return(
<>
<div className={styles.inputpanel}>
<div>
{topPanel}
</div>
</div>
<div className={styles.maintable}>
{/* <ScrollTable
pagination={false}
columns={columns}
components={{}}
resize={true}
virtual={true}
otherwidth={50}
size="middle"
/> */}
{bodyPanel}
</div>
<div className={styles.mainpage}>
{pagePanel}
</div>
</>
)
}
export default ActionBodyPanel
\ No newline at end of file
import React,{useMemo} from "react"
import styles from "./index.module.less"
interface bodyprops{
topPanel:any;
bodyPanel:any;
}
const ActionRightPanel:React.FC<bodyprops>=(props)=>{
const {topPanel,bodyPanel} = props
return(
<>
<div className={styles.inputpanel}>
{topPanel}
</div>
<div className={styles.mainaction}>
{bodyPanel}
</div>
</>
)
}
export default ActionRightPanel
\ No newline at end of file
import React from "react"
import styles from "./index.module.less"
interface treeprops{
topAction:any;
mainBody:any;
}
const ActionTreePanel:React.FC<treeprops>=(props)=>{
const {topAction,mainBody} = props
return(
<div className={styles.lefttreepanel}>
<div className={styles.lefttree}>
{topAction}
</div>
<div className={styles.treebody}>
{mainBody}
</div>
</div>
)
}
export default ActionTreePanel
\ No newline at end of file
@showtree:~`'showtree'`;
@hidetree:~`'hidetree'`;
@showtable:~`'showtable'`;
@hidetable:~`'hidetable'`;
.main{
height: 100%;
display: flex;
width: 100%;
.left{
flex: 0 0 auto;
background: #ECEEF3;
height:100%;
>div:nth-child(1){
height: 100%;
}
:global{
.react-resizable {
position: relative;
background-clip: padding-box;
}
.react-resizable-handle {
position: absolute;
width: 10px;
height: 100%;
bottom: 0;
right: -5px;
cursor: col-resize;
z-index: 1;
}
.centerinfo-tree .centerinfo-tree-treenode{
white-space: nowrap;
}
.react-contexify{
min-width: 120px;
}
.centerinfo-tree-list-holder{
overflow: hidden;
}
// .centerinfo-tree-list-scrollbar{
// width: 15px !important;
// display: inline-block !important;
// }
}
}
.middle{
width:15px;
height:100%;
border-left: 1px solid #efefef;
position: relative;
.point{
display: -webkit-flex;
display: flex;
-webkit-justify-content: center;
justify-content: center;
-webkit-align-items: center;
align-items: center;
left: 0;
right: 0;
background: #f2f5fc;
position: absolute;
top: calc(50% - 40px);
font-size: 14px;
width: 12px;
height: 80px;
border-radius: 0 12px 12px 0;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
cursor: pointer;
}
}
.right{
flex:1 1;
height:100%;
// padding-left: 20px;
// width: calc(100% - 250px);
overflow: hidden;
:global{
.centerinfo-table-thead > tr > th {
padding: 8px 8px !important;
}
.centerinfo-table-tbody > tr > td {
padding: 12px 8px !important;
}
.centerinfo-table-tbody > .centerinfo-table-measure-row > td {
padding: 0px !important;
}
.centerinfo-table-tbody > tr .centerinfo-table-row-selected > td {
background: #fff !important;
}
tr.centerinfo-table-expanded-row > td {
background: #fff !important;
}
.centerinfo-table-thead > tr > th {
background-color: #F2F5FC !important;
}
}
}
.showtrees{
width:100%;
overflow: hidden;
animation:@showtree .3s ease-in forwards;
}
.hidetrees{
width:0;
overflow: hidden;
animation:@hidetree .3s ease-in forwards;
}
.showtables{
width:100%;
overflow: hidden;
animation:@showtable .3s ease-in forwards;
}
.hidetables{
width:0;
overflow: hidden;
animation:@hidetable .3s ease-in forwards;
}
:global{
@keyframes @showtree {
0% {
width:0px
}
100% {
width:230px
}
}
@keyframes @hidetree {
0% {
width:230px;
}
100% {
width:0px;
}
}
@keyframes @showtable {
0% {
width:calc(100% - 250px);
}
100% {
width:calc(100% - 20px);
}
}
@keyframes @hidetable {
0% {
width:calc(100% - 20px);
}
100% {
width:calc(100% - 250px);
}
}
}
}
.lefttreepanel{
height: 100%;
background-color: #fff;
.lefttree{
border-bottom:1px solid #EFEFEF;
padding: 12px;
height:57px;
align-items: center;
display: flex;
}
.treebody{
height: calc(100% - 58px);
overflow: auto;
padding:12px;
}
}
.inputpanel{
width: 100%;
border-bottom:1px solid #EFEFEF;
padding:12px;
>div{
height: 32px;
}
}
.maintable{
height:calc(100% - 100px);
padding:12px;
width: 100%;
}
.mainaction{
height:calc(100% - 32px);
padding:12px;
width: 100%;
}
.mainpage{
text-align: center;
}
import React,{useState} from "react"
import styles from "./index.module.less"
import {CaretLeftOutlined ,CaretRightOutlined } from "@ant-design/icons"
import { Resizable } from 'react-resizable';
interface panelprops{
leftPanel:any;
rightPanel:any;
middlecolor?:string;
}
const LeftTreePanel:React.FC<panelprops>=(props)=>{
const {leftPanel,rightPanel,middlecolor='#fff'} = props
const [open,setOpen] = useState('')
const pointclick = ()=>{
if(open==='hidetree'){
setOpen('opentree')
}else{
setOpen('hidetree')
}
}
const getStyle=()=>{
if(open==='hidetree'){
return {width:0,display:'none'}
}else{
return {minWidth:230}
}
}
return(
<div className={styles.main} >
<div className={`${ styles.left}`} style={getStyle()}>
<Resizable
width={230}
height={Infinity}
axis='x'
minConstraints={[230, Infinity]} maxConstraints={[Infinity, Infinity]}
>
{leftPanel||null}
</Resizable>
</div>
<div className={styles.middle} style={{background:middlecolor}}>
<div className={styles.point} onClick={pointclick}>
{
open==='hidetree'?(
<CaretRightOutlined />
):(
<CaretLeftOutlined />
)
}
</div>
</div>
<div className={`${styles.right}`}>
{rightPanel||null}
{/* {rightPanel||null} */}
</div>
</div>
)
}
export default LeftTreePanel
\ No newline at end of file
.omodel {
position: relative;
.header {
display: flex;
width: 100%;
height: 44px;
padding: 0 15px;
background-color: #464d6e;
align-items: center;
position: fixed;
justify-content: space-between;
border-bottom: 1px solid #EFEFEF;
z-index: 100;
}
.container {
top: 44px;
width: 100%;
height: calc(100vh - 44px - 64px);
overflow: auto;
background: #EDF0F5;
padding: 10px 20px;
position: absolute;
:global{
.centerinfo-table-thead > tr > th {
padding: 8px 8px !important;
}
.centerinfo-table-tbody > tr > td {
padding: 12px 8px !important;
}
.centerinfo-table-tbody > .centerinfo-table-measure-row > td {
padding: 0px !important;
}
.centerinfo-table-tbody > tr .centerinfo-table-row-selected > td {
background: #fff !important;
}
tr.centerinfo-table-expanded-row > td {
background: #fff !important;
}
.centerinfo-table-thead > tr > th {
background-color: #F2F5FC !important;
}
}
}
.containercard {
padding: 20px;
background: #fff;
}
.footer {
display: flex;
bottom: 0;
width: 100%;
height: 64px;
position: fixed;
justify-content: flex-end;
opacity: 0.9;
background: #fff;
box-shadow: 0 -1px 4px 0 #e5e9ea;
padding: 0 20px;
}
}
\ No newline at end of file
import React from "react"
import styles from "./index.module.less"
interface outside{
title:string;
body:any;
footer:any;
}
const OutSidePanel:React.FC<outside>=(props)=>{
const {title,body,footer} = props
return(
<div className={styles.omodel}>
<div className={styles.header}>
<span style={{ fontSize: 16, fontWeight: 'bold', color: '#fff' }}>{title}</span>
</div>
<div className={styles.container}>
<div className={styles.containercard}>
{body}
</div>
</div>
<div className={styles.footer}>
{footer}
</div>
</div>
)
}
export default OutSidePanel
\ No newline at end of file
import request from "@/utils/request"
import qs from "qs"
import config from "@/commons"
const {api:{asset}} =config
declare global {
interface Navigator {
msSaveBlob?: (blob: any, defaultName?: string) => boolean
}
}
class AssetsActionManageService{
async getCompareInfo(payload:any,autotip=false){
let result = await request({ url: `${asset}/dataAssetApi/compareBusinessColumnAndMetadataColumn`, method: "post", data:qs.stringify(payload) },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async exportAssetsColumns(payload:any,autotip=false){
await request({ url: `${asset}/dataAssetColumnApi/exportBusinessColumnsByDataAssetId`, method: "postdownload", data:qs.stringify(payload),responseType:'blob' },autotip).then((data:any)=>{
let types = data.data.type
var blob = new Blob([data.data], {type: types});
let fileName = ''
let contentDisposition = data.headers['content-disposition'];
if (contentDisposition) {
fileName = window.decodeURI(data.headers['content-disposition'].split('=')[1]);
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(blob, fileName);
}
else {
var csvURL = window.URL.createObjectURL(blob);
var tempLink = document.createElement('a');
tempLink.href = csvURL;
tempLink.setAttribute('download', fileName);
tempLink.setAttribute('target', '_blank');
document.body.appendChild(tempLink);
tempLink.click();
document.body.removeChild(tempLink);
}
}).catch(error=>{
console.log(error)
})
}
async exportBusinessColumnsByDataAssetId(payload:any,autotip=false){
await request({ url: `${asset}/dataAssetColumnApi/exportBusinessColumnsByDataAssetId`, method: "postdownload", data:qs.stringify(payload),responseType:'blob' },autotip).then((data:any)=>{
let types = data.data.type
var blob = new Blob([data.data], {type: types});
let fileName = ''
let contentDisposition = data.headers['content-disposition'];
if (contentDisposition) {
fileName = window.decodeURI(data.headers['content-disposition'].split('=')[1]);
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(blob, fileName);
}
else {
var csvURL = window.URL.createObjectURL(blob);
var tempLink = document.createElement('a');
tempLink.href = csvURL;
tempLink.setAttribute('download', fileName);
tempLink.setAttribute('target', '_blank');
document.body.appendChild(tempLink);
tempLink.click();
document.body.removeChild(tempLink);
}
}).catch(error=>{
console.log(error)
})
}
async getAssetColumnDetail(payload:any,autotip=false){
let result = await request({ url: `${asset}/dataAssetColumnApi/getDataAssetColumnDetail`, method: "post", data:qs.stringify(payload) },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
}
export default new AssetsActionManageService()
import standardsService from "./standardsService"
import assetsManageService from "./assetsManageService"
import assetsActionManageService from "./assetsActionManageService"
import metaManageService from "./metaManageService"
import metaAdminManageService from "./metaAdminManageService"
import metaUserManageService from "./metaUserManageService"
export {
standardsService,
assetsManageService
assetsManageService,
assetsActionManageService,
metaAdminManageService,
metaManageService,
metaUserManageService
}
\ No newline at end of file
import request from "@/utils/request"
import qs from "qs"
import config from "@/commons"
const {api:{metaRepo,sessionInfo}} =config
declare global {
interface Navigator {
msSaveBlob?: (blob: any, defaultName?: string) => boolean
}
}
class metaAdminManageService{
async getTreeSystem(payload:any,autotip=false){
let result = await request({ url: `${metaRepo}/rest/admin/getAdminSystem`, method: "get", data:payload },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getChildrenBySystem(payload:any,autotip=false){
let result = await request({ url: `${metaRepo}/rest/admin/getChildBySystem`, method: "get", data:payload },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getChildrenByParentId(payload:any,autotip=false){
let result = await request({ url: `${metaRepo}/rest/admin/getChildByParentId`, method: "get", data:payload },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getSystemChildrenByPage(payload:any,autotip=false,hashrequest=false){
let result = await request({ url: `${metaRepo}/rest/admin/getPageChildBySys`, method: "post",params:payload.params, data:payload.data,hashrequest },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getChildByIdAndSysByPage(payload:any,autotip=false,hashrequest=false){
let result = await request({ url: `${metaRepo}/rest/admin/getPageChild`, method: "post",params:payload.params,data:payload.data,hashrequest },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getMetaDiscByPermission(payload={},autotip=false,hashrequest=false){
let result = await request({ url: `${metaRepo}/rest/admin/searchDic`, method: "post", data: qs.stringify(payload),hashrequest },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getMetaByAdminPerssion(payload={},autotip=false,hashrequest=false){
let result = await request({ url: `${metaRepo}/rest/admin/getById`, method: "get", data: payload,hashrequest },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getMetaReadableByAdminPerssion(payload={},autotip=false,hashrequest=false){
let result = await request({ url: `${metaRepo}/rest/admin/readable/:id`, method: "get", data: payload,urldata:payload },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getModelColumnByAuth(payload:any,autotip=false){
let result = await request({ url: `${metaRepo}/rest/admin/getAttributeAuth`, method: "post", data:qs.stringify(payload) },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async saveModelColumnByAuth(payload:any,autotip=false){
let result = await request({ url: `${metaRepo}/rest/admin/saveAttributeAuth`, method: "post", data:payload },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getModelAttrs(payload:any,autotip=false){
let result = await request({ url: `${metaRepo}/rest/admin/getAttributes/${payload}`, method: "get" },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getModelAllowSortList(payload:any,autotip=false){
let result = await request({ url: `${metaRepo}/rest/admin/findSortColumnByModel`, method: "post",data:qs.stringify(payload) },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
}
export default new metaAdminManageService()
import request from "@/utils/request"
import qs from "qs"
import config from "@/commons"
const {api:{metaRepo,sessionInfo}} =config
declare global {
interface Navigator {
msSaveBlob?: (blob: any, defaultName?: string) => boolean
}
}
class metaUserManageService{
async getTreeSystem(payload:any,autotip=false){
let result = await request({ url: `${metaRepo}/rest/user/getUserSystem`, method: "get", data:payload },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getChildrenBySystem(payload:any,autotip=false){
let result = await request({ url: `${metaRepo}/rest/user/getChildBySystem`, method: "get", data:payload },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getChildrenByParentId(payload:any,autotip=false){
let result = await request({ url: `${metaRepo}/rest/user/getChildByParentId`, method: "get", data:payload },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getSystemChildrenByPage(payload:any,autotip=false,hashrequest=false){
let result = await request({ url: `${metaRepo}/rest/user/getPageChildBySys`, method: "post",params:payload.params, data:payload.data,hashrequest },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getChildByIdAndSysByPage(payload:any,autotip=false,hashrequest=false){
let result = await request({ url: `${metaRepo}/rest/user/getPageChild`, method: "post",params:payload.params,data:payload.data,hashrequest },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getMetaDiscByPermission(payload={},autotip=false,hashrequest=false){
let result = await request({ url: `${metaRepo}/rest/user/searchDic`, method: "post", data: qs.stringify(payload),hashrequest },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getMetaSearhList(payload:any,autotip=false){
let result = await request({ url: `${metaRepo}/rest/user/findPage`, method: "post", data:qs.stringify(payload.params) },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getMetaByUserPerssion(payload={},autotip=false,hashrequest=false){
let result = await request({ url: `${metaRepo}/rest/user/getById`, method: "get", data: payload,hashrequest },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getMetaReadableByUserPerssion(payload={},autotip=false,hashrequest=false){
let result = await request({ url: `${metaRepo}/rest/user/readable/:id`, method: "get", data: payload,urldata:payload },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getModelColumnByAuth(payload:any,autotip=false){
let result = await request({ url: `${metaRepo}/rest/user/getAttributeAuth`, method: "post", data:qs.stringify(payload) },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async saveModelColumnByAuth(payload:any,autotip=false){
let result = await request({ url: `${metaRepo}/rest/user/saveAttributeAuth`, method: "post", data:payload },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
async getModelAllowSortList(payload:any,autotip=false){
let result = await request({ url: `${metaRepo}/rest/user/findSortColumnByModel`, method: "post",data:qs.stringify(payload) },autotip).then(data=>{
return data;
}).catch(error=>{
return error
})
return result;
}
}
export default new metaUserManageService()
......@@ -28,6 +28,10 @@ import MetaMatchStandard from './MetaMatchStandard';
import './AssetAction.less';
import { useGetStandardMatchByIds } from '@/hooks/standard';
import ImportActionComment from "./ImportActionComment"
import { useGetModalInfoAndAction } from '@/hooks/common';
import AssetsCompareModal from './AssetsCompareModal';
import TagCell, { TagSelectPopup } from './tag-help'
import MatchMetaInfo from './MatchMetaInfo';
const AssetAction = React.forwardRef(function (props, ref) {
const { id, dirId, action, terms, onChange, reference, readonly = false, permissionId, catalog, template } = props;
......@@ -70,17 +74,28 @@ const AssetAction = React.forwardRef(function (props, ref) {
const [businessElements, setBusinessElements] = useState();
const [businessColumns, setBusinessColumns] = useState();
const [sqlinfo,setSqlInfo] = useState([])
const [resoureTagMap, setResourceTagMap] = useState()
const [loadingSaveAsDraft, setLoadingSaveAsDraft] = React.useState(false)
const [needSaveAsDraft, setNeedSaveAsDraft] = React.useState()
const [selectData,setSelectData] = useState({
metadataId:'',
metadataPath:''
})
const app = useContext(AppContext);
const uploadRef = useRef(undefined);
const [columnForm] = Form.useForm()
const relationAssetsRef = useRef();
const comparemodal = useGetModalInfoAndAction()
const [form] = Form.useForm();
useEffect(()=>{
if(assets?.metadataId)
setSelectData({metadataId:assets.metadataId,metadataPath:assets.metadataPath})
},[assets])
React.useImperativeHandle(ref, () => ({
validate: async () => {
// await form.validateFields();
......@@ -238,6 +253,7 @@ const AssetAction = React.forwardRef(function (props, ref) {
{ item.name }
</span>,
dataIndex: item.enName,
width:160,
ellipsis: true,
render: (text, record, index) => {
let value = ''
......@@ -309,6 +325,12 @@ const AssetAction = React.forwardRef(function (props, ref) {
return item.metadataColumnId
})
},[tableData])
useEffect(()=>{
if(tableData.length){
getResourceTag()
}
},[tableData])
const checkStandard=true
const {standardmap} = useGetStandardMatchByIds({metadataIds:resourceIds,checkStandard})
......@@ -323,6 +345,53 @@ const AssetAction = React.forwardRef(function (props, ref) {
}
}
const tagCol = {
title: '标签',
dataIndex: 'tag',
width: 360,
className: 'table-tag-cell',
render: (_, record) => {
return(
<div onClick={(e) => e.stopPropagation()}>
<TagCell
id={record.id}
did={record.dirId}
type={record?.columnType}
tags={resoureTagMap?.[record.id]}
onChange={(val) => {
setResourceTagMap((prevResourceTagMap) => {
return produce(prevResourceTagMap||{}, (draft) => {
draft[record.id] = val
})
})
}}
/>
</div>
)
}
}
const getResourceTag = () => {
const ids = (tableData??[]).map(item => item.id)
if (ids.length > 0) {
dispatch({
type: 'tag.getResourceTagIn',
payload: {
params: {
resourceIds: ids,
includeAll: true,
includePrivate: true
}
},
callback: data => {
setResourceTagMap(data?.data)
}
});
} else {
setResourceTagMap()
}
}
const cols = useMemo(() => {
let newCols = []
......@@ -331,7 +400,7 @@ const AssetAction = React.forwardRef(function (props, ref) {
newCols.push(businessActionCol)
}
return [...newCols,standardmatch]
return [...newCols,standardmatch,tagCol]
}, [currentAction, isStructured, columns, businessColumns, businessActionCol])
......@@ -667,7 +736,7 @@ const AssetAction = React.forwardRef(function (props, ref) {
if (reference === AssetDraftReference) {
let data = action==='add' ? { elements: newElements } : { ...assets, elements: newElements }
data = {...data,columns:tempcolumns,questionSqlPairs:sqlinfo, businessRelations: relationAssetsRef.current?.assets, businessColumns: modifyMetadataColumnList}
data = {...data,...selectData,columns:tempcolumns,questionSqlPairs:sqlinfo, businessRelations: relationAssetsRef.current?.assets, businessColumns: modifyMetadataColumnList}
dispatch({
type: 'assetmanage.updateDraft',
......@@ -691,13 +760,13 @@ const AssetAction = React.forwardRef(function (props, ref) {
} else {
let params = {
dirId,
metadataId: metadataId??'',
metadataId: selectData.metadataId??'',
operation: 'change',
}
let data = action==='add' ? { elements: newElements } : { ...assets, elements: newElements }
data = {...data,columns:tempcolumns,questionSqlPairs:sqlinfo, businessRelations: relationAssetsRef.current?.assets, businessColumns: modifyMetadataColumnList}
data = {...data,...selectData,columns:tempcolumns,questionSqlPairs:sqlinfo, businessRelations: relationAssetsRef.current?.assets, businessColumns: modifyMetadataColumnList}
dispatch({
type: needSaveAsDraft?'assetmanage.saveAsDraft':'assetmanage.addOrUpdateDataAsset',
......@@ -866,7 +935,7 @@ const AssetAction = React.forwardRef(function (props, ref) {
</Radio.Group>
{
action!=='add' && <Space>
<QuestionModalButton list={sqlinfo} readOnly={currentAction==='detail'} setList={setSqlInfo} />
{/* <QuestionModalButton list={sqlinfo} readOnly={currentAction==='detail'} setList={setSqlInfo} /> */}
{
(!readonly && (reference===AssetManageReference||canEdit)) && <React.Fragment>
{
......@@ -994,9 +1063,23 @@ const AssetAction = React.forwardRef(function (props, ref) {
</Form>
</Spin>
{
assets?.structedState==='unStructured'&&(
<MatchMetaInfo
item={assets} reference={reference} AssetDraftReference={AssetDraftReference} getAsset={getAsset}
dirId={dirId} metadataId={metadataId} needSaveAsDraft={needSaveAsDraft} currentAction={currentAction}
selectData={selectData} setSelectData={setSelectData}
/>
)
}
<div>
<div style={{display:'flex',justifyContent:'space-between',alignItems:'center',gap:10}}>
<div style={{flex:1}}>
<Divider orientation='left'>字段级资产目录信息</Divider>
</div>
{action!=='add'&&<Button size='small' onClick={()=>{comparemodal.openModal()}}>对比</Button>}
</div>
{
isStructured ?
<Form form={columnForm}>
......@@ -1077,6 +1160,7 @@ const AssetAction = React.forwardRef(function (props, ref) {
}
</div>
<ImportActionComment modelerData={assets} />
<AssetsCompareModal visible={comparemodal.visible} item={assets} onCancel={()=>{comparemodal.cancelModal()}} />
{contextHolder}
</div>
)
......
......@@ -581,7 +581,7 @@ const AssetTable = (props) => {
};
if (name === '编号') {
params.width = 60;
params.width = 150;
// params.fixed = 'left';
} else if (name === '中文名称' || name === '岗位中文名') {
params.width = isSzseEnv?230:160;
......
import { Button, Drawer,Space } from "antd"
import React from "react"
import AssetsMetaCompare from "./AssetsMetaCompare"
import config from "@/commons"
const {api:{asset}} = config
const AssetsCompareModal:React.FC<any>=(props)=>{
const {visible,onCancel,item} = props
const openexcel=()=>{
window.open(`${asset}/dataAssetApi/exportDiffBetweenBusinessColumnAndMetadataColumn?dataAssetId=${item.id}`)
}
return(
<Drawer
title={'资源项对比'}
visible={visible}
width={'80%'}
onClose={onCancel}
extra={
<Space>
<Button onClick={openexcel}>导出</Button>
</Space>
}
>
<AssetsMetaCompare item={item} />
</Drawer>
)
}
export default AssetsCompareModal
\ No newline at end of file
import React,{useState} from "react"
import {Spin} from "antd"
import { useGetMetaAssetsCompareInfo } from "../hooks"
import VersionCompareTable from './VersionCompareTable';
import './VersionCompare.less';
const AssetsMetaCompare:React.FC<any>=(props)=>{
const {item} = props
console.log(item)
const [selectedColumnTitles, setSelectedColumnTitles] = useState()
const {compareloading,comparedata} = useGetMetaAssetsCompareInfo({dataAssetId:item.id})
return(
<Spin spinning={compareloading}>
<div className='flex model-version-compare'>
<div style={{ flex: 1, borderRight: '1px solid #EFEFEF', paddingRight: 10, overflow: 'hidden'}}>
<VersionCompareTable
data={comparedata}
title="资源字段"
columntype="assets"
selectedColumnTitles={selectedColumnTitles}
onFilterChange={(val) => setSelectedColumnTitles(val)}
/>
</div>
<div style={{ flex: 1, paddingLeft: 10, overflow: 'hidden'}}>
<VersionCompareTable
data={comparedata}
title={"元数据字段"}
columntype="meta"
selectedColumnTitles={selectedColumnTitles}
onFilterChange={(val) => setSelectedColumnTitles(val)}
direction='right'
/>
</div>
</div>
</Spin>
)
}
export default AssetsMetaCompare
\ No newline at end of file
import React, { useState } from "react"
import {Divider,Descriptions,Tooltip,Drawer, Space, Button, message} from "antd"
import {SettingOutlined} from "@ant-design/icons"
import { useGetModalInfoAndAction } from "../../../../hooks/common"
import SelectMeta from "@/view/meta/selectmeta/SelectMeta"
import { pageUtil } from "@/utils"
import qs from 'qs'
const MatchMetaInfo:React.FC<any>=(props)=>{
const {currentAction,selectData,setSelectData} = props
const selectmodal = useGetModalInfoAndAction()
const bodyheight = pageUtil.getBodyHeight()
const [tempdata,setTempData] = useState({
metadataId:'',
metadataPath:''
})
const [confirmLoading,setConfirmLoading] = useState(false)
const openSelect=()=>{
selectmodal.openModal()
}
const selectMeta=(data:any,systemmap)=>{
const paths = data.namePathList;
let temp = [...paths];
temp.shift();
// let system:any = null;
// try {
// let sys = data.sysList
// system = Number(sys[0])
// let systemmsg = systemmap[system]
// let owner = systemmsg.catalogInfo;
// let templist = [owner.catalogName,systemmsg.scopeName]
// temp = [...templist,...temp]
// } catch (error) {
// console.log(error)
// }
setTempData({metadataId:data._id,metadataPath:temp.join('/')})
}
console.log(tempdata)
const saveItem=()=>{
if(tempdata.metadataId){
setSelectData?.(tempdata)
selectmodal.cancelModal()
}else{
message.info("请选择元数据")
}
}
const opendetail=()=>{
const payload={
mid:selectData.metadataId,
action:'metadetail',
type:'detail',
manager:false,
activekey:1,
}
window.open(`/center-home/metadetail?${qs.stringify(payload)}`)
}
return(
<div>
<Divider orientation='left'>关联元数据</Divider>
<Descriptions column={1} bordered>
<Descriptions.Item
label="元数据路径"
labelStyle={{ width: 180 }}
>
<div className='flex' style={{ alignItems: 'center' }}>
<div style={{ flex: 1,cursor:'pointer',color:'blue' }} onClick={()=>{opendetail()}}>
{selectData?.metadataPath}
</div>
<div style={{ flex: '0 0 auto', marginLeft: 10, width: 16 }}>
<Tooltip placement="left" title={'关联元数据'}>
{currentAction!=='detail'&&<SettingOutlined onClick={openSelect} style={{ fontSize: 16,cursor:'pointer' }} />}
</Tooltip>
</div>
</div>
</Descriptions.Item>
</Descriptions>
<Drawer
title="选择表信息"
visible={selectmodal.visible}
width={'80%'}
onClose={()=>{
selectmodal.cancelModal()
}}
destroyOnClose
>
<div style={{height:bodyheight-150}}>
<SelectMeta height={bodyheight-150} selectMeta={selectMeta} />
</div>
<div style={{marginTop:12}}>
<Space>
<Button loading={confirmLoading} type="primary" onClick={saveItem}>确定</Button>
<Button onClick={()=>{selectmodal.cancelModal()}}>返回</Button>
</Space>
</div>
</Drawer>
</div>
)
}
export default MatchMetaInfo
\ No newline at end of file
import { assetsActionManageService } from "@/services"
import { httpUtil } from "@/utils"
import { useSetState } from "ahooks"
import {useEffect} from "react"
interface p1{
dataAssetId:string
}
export const useGetMetaAssetsCompareInfo=(props:p1)=>{
const {dataAssetId} = props
const [state,setState] = useSetState({
compareloading:false,
comparedata:{},
columns:[],
defaultSelect:[],
sourceList:[],
targetList:[]
})
useEffect(()=>{
const getTableInfo=async()=>{
setState({compareloading:true})
const result:any = await assetsActionManageService.getCompareInfo({dataAssetId})
if(httpUtil.checkSuccess(result,1)){
setState({comparedata:result.data,compareloading:false})
}else{
httpUtil.showError(result,1)
setState({comparedata:{},compareloading:false})
}
}
if(dataAssetId)
getTableInfo()
},[dataAssetId])
return state
}
\ No newline at end of file
export * from "./Detail"
export * from "./Compare"
\ No newline at end of file
import { useSetState,useDebounceEffect } from "ahooks"
import {useEffect} from "react"
import {metaManageService,metaAdminManageService,metaUserManageService} from "@/services"
import {httpUtil} from "@/utils"
export const useGetMetaCnName=()=>{
const [state,setState] = useSetState({
cnNameLoad:false,
modelCnName:{}
})
useEffect(()=>{
getCnNameInfo()
},[])
const getCnNameInfo=async()=>{
setState({cnNameLoad:true})
const result:any = await metaManageService.getModelsCnName({});
if(httpUtil.checkSuccess(result,1)){
setState({cnNameLoad:true,modelCnName:result.data})
}else{
setState({cnNameLoad:true,modelCnName:{}})
}
}
return state
}
export const useGetSearchType=()=>{
const [state,setState] = useSetState({
typelistload:false,
typelist:[]
})
useEffect(()=>{
getCnNameInfo()
},[])
const getCnNameInfo=async()=>{
setState({typelistload:true})
const result:any = await metaManageService.getModelsCnName({});
if(httpUtil.checkSuccess(result,1)){
let list:any=[]
for(let key in result.data){
list.push({value:result.data[key],name:key})
}
setState({typelistload:true,typelist:list})
}else{
setState({typelistload:true,typelist:[]})
}
}
return state
}
interface p3{
treeNode:any,
currentDomain:any,
type?:string,
keyword?:string
}
export const useGetMetaTableInfo=(props:p3)=>{
const {treeNode,currentDomain,type='admin',keyword} = props
const [state,setState] = useSetState({
pageable:{
pageNum:1,
pageSize:20,
},
order:{
order:'',
orderBy:''
},
})
const [select,setSelect] = useSetState({
selectedRowKeys:[],
selectedRowDatas:[]
})
const [payload,setPayload] = useSetState({
tablelist:[],
tableload:false,
tabletotal:0
})
useEffect(()=>{
setState({pageable:{
pageNum:1,
pageSize:20,
}})
},[treeNode,keyword])
useDebounceEffect(()=>{
if(currentDomain.domainId)
getTableInfo()
},[treeNode,state,currentDomain],{wait:600})
const getTableInfo=async()=>{
setPayload({tableload:true})
let payload:any={}
payload={
data:treeNode.path?[treeNode.path]:[],
params:{
parentClass:'Catalog',
parentNamePath:currentDomain.domainId,
system:treeNode.system?treeNode.system:treeNode.value,
pageNum:state.pageable.pageNum,
pageSize:state.pageable.pageSize,
keyword:keyword,
catalog:currentDomain.domainId,
parentId:treeNode.path?treeNode.parentId:treeNode.value,
...state.order,
sortField:state.order.orderBy
}
}
let result = null;
if(typeof((treeNode.value?treeNode.value:treeNode.key))==='string'){
if(type==='admin'){
result = await metaAdminManageService.getChildByIdAndSysByPage(payload,undefined,true)
}else{
result = await metaUserManageService.getChildByIdAndSysByPage(payload,undefined,true)
}
//const result:any= await metaManageService.getChildByIdAndSysByPage(payload,undefined,true)
if(httpUtil.checkSuccess(result,1)){
//dispatch(setField({tablelist:result.data.content,tableload:false,tabletotal:result.data.totalElements}))
}else{
//dispatch(setField({tablelist:[],tableload:false,tabletotal:0}))
httpUtil.showError(result,1)
}
}else{
if(type==='admin'){
result = await metaAdminManageService.getSystemChildrenByPage(payload,undefined,true)
}else{
result = await metaUserManageService.getSystemChildrenByPage(payload,undefined,true)
}
//const result:any= await metaManageService.getSystemChildrenByPage(payload,undefined,true)
if(httpUtil.checkSuccess(result,1)){
//dispatch(setField({tablelist:result.data.content,tableload:false,tabletotal:result.data.totalElements}))
}else{
//dispatch(setField({tablelist:[],tableload:false,tabletotal:0}))
httpUtil.showError(result,1)
}
}
console.log(result)
if(httpUtil.checkSuccess(result,1)){
setPayload({tablelist:result.data.content,tableload:false,tabletotal:result.data.totalElements})
}else{
setPayload({tablelist:[],tableload:false,tabletotal:0})
}
}
const changePage=(pageNum:any,pageSize:any)=>{
setState({pageable:{pageNum,pageSize}})
}
const changeOrder=(order:any)=>{
setState({order})
}
const changeSelect=(keys:any,datas?:any)=>{
setSelect({selectedRowKeys:keys,selectedRowDatas:datas})
}
return {...payload,...state,...select,changePage,changeOrder,changeSelect}
}
\ No newline at end of file
export * from "./Meta"
\ No newline at end of file
.selectmeta{
.ant-table-tbody{
.selectTable{
>td{
background-color: rgb(211, 230, 235);
}
&:hover{
>td{
background-color:rgb(211, 230, 235);
}
}
}
}
}
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