Commit 29645d31 by fanyj

资产选择元数据

parent 007e1d01
const CracoLessPlugin = require('craco-less');
const { name } = require('./package');
const path = require('path');
const proxyurl = true?'http://192.168.0.39:8089/':'http://139.198.127.54:18079/'
module.exports = {
plugins: [
......@@ -24,6 +27,10 @@ module.exports = {
},
],
webpack: {
// 别名
alias: {
"@": path.resolve("src"),
},
configure: {
output: {
library: `${name}-[name]`,
......@@ -49,11 +56,11 @@ module.exports = {
},
proxy: {
'/api': {
target: 'http://192.168.0.179:8089',
target: proxyurl,
changeOrigin: true,
},
'/data-quality-szse': {
target: 'http://192.168.0.38:8089',
target: proxyurl,
changeOrigin: true,
},
},
......
......@@ -38,7 +38,7 @@
"react-dom": "^17.0.1",
"react-loadable": "^5.5.0",
"react-redux": "^7.1.0",
"react-resizable": "^3.0.4",
"react-resizable": "3.0.4",
"react-router-dom": "^5.0.1",
"react-scripts": "5.0.1",
"react-virtualized": "^9.22.3",
......@@ -77,5 +77,8 @@
"last 1 safari version"
]
},
"homepage": "http://myhost/data-govern"
"homepage": "http://myhost/data-govern",
"devDependencies": {
"@types/react-resizable": "^1.7.4"
}
}
......@@ -190,7 +190,7 @@ export class App extends React.Component {
<AppContext.Provider value={{
env: hostParams?.env,
user: hostParams?.user,
setGlobalState,
hostParams,
onGlobalStateChange
}}>
<Router basename={window.__POWERED_BY_QIANKUN__ ? '/data-govern' : '/'}>
......
const outUrl:string = '/center-home';
const appUrl:string = '/center-home';
const Api:string = '/api';
const inapp:boolean = false;//内网true;外网false
const baseUrl = inapp?appUrl:outUrl;
const inszdt:boolean = true
const config = {
baseUrl:baseUrl,
BaseURL: baseUrl,
inapp:inapp,
headerstring:inapp?'Basic Z3Vlc3Q6cHdk':'Basic ZGVtb3Rlc3Q6ZGVtb3Rlc3Q=',
page:{
index:`${baseUrl}/menu/index`,
indexpage:'/menu/index',
loginpage: inszdt?'https://idmuat.szmc.com.cn/idp/profile/OAUTH2/Redirect/GLO?redirctToUrl=http://10.37.54.154:8080/center-home/view/login&redirectToLogin=true&entityId=sjzcmugl':`${baseUrl}/view/login`,
workpage:'/view/task',
jdbc:`${baseUrl}/menu/datasource-manage`,
homeIndex: `${baseUrl}/view`,
roleTree: `${baseUrl}/view/roleTree`,
rolemanage: `${baseUrl}/view/rolemanage`,
metadetail:`${baseUrl}/metadetail`,
metadotheretail:`${baseUrl}/staticmeta/detail`,
standardmanage:`${baseUrl}/menu/datastandard`,
relationpage:`${baseUrl}/menu/sourcemap`,
catalogpage:`${baseUrl}/menu/domain`,
systempage:`${baseUrl}/menu/datasys`,
questionpage:`${baseUrl}/menu/myquestion`,
modelpage:`${baseUrl}/menu/data-model`,
noticepage:`${baseUrl}/menu/systemnotice`,
metasearch:`${baseUrl}/menu/metasearch`,
metamanage:`${baseUrl}/menu/metamanage`,
standard:`${baseUrl}/menu/datastandard`,
quality:`${baseUrl}/menu/data-quality`,
assetssource:`${baseUrl}/menu/asset-resource-browse`,//资源
asserts:`${baseUrl}/menu/asset-browse`,//资产,
lawpolice:`${baseUrl}/menu/specificationbrowse`,
systemdocument:`${baseUrl}/menu/specificationbrowse`,
guideline:`${baseUrl}/menu/specificationbrowse`,
tagmanager:`${baseUrl}/menu/tag-manage`,
assetmap:`${baseUrl}/menu/asset-map`,
assetsearch:`${baseUrl}/menu/asset-browse`,
filedetail:`${baseUrl}/noticeinfo`,
datamodel:`${baseUrl}/datamodeler`,
securitydetail:`${baseUrl}/security/detail`,
dataservicedetail:`${baseUrl}/dataservice/detail`
},
api:{
houseinfo:`${Api}`,
api:`${Api}`,
standard:`${Api}/standard`,
authservice:`${Api}/authservice`,
singin: `${Api}/auth/signin`,
signout: `${Api}/auth/signout`,
users: `${Api}/authservice/users/:userId/domains`,
sessionInfo: `${Api}/auth/sessionInfo`,
userupdate: `${Api}/authservice/users/`,
jdbcmanage: `${Api}/metadataharvester/rest/targetConfig/jdbc`,
sysjdbcmanage: `${Api}/metadataharvester/rest/targetConfig/system/jdbc`,
harveJdbcmanage: `${Api}/metadataharvester/rest/harvestingTarget/jdbc`,
taskResult: `${Api}/metadataharvester/rest/taskResult`,
task: `${Api}/metadataharvester/rest/task`,
role: `${Api}/datacatalog/roleCtrl`,
management: `${Api}/datacatalog/management`,
domains: `${Api}/authservice/domains`,
roleUser: `${Api}/authservice/roles`,
usersRoles: `${Api}/authservice/users`,
dataqualityapi: `${Api}/dataqualityapi`,
dataq:`${Api}/dataq`,
label: `${Api}/tagmanager`,
metaRepo: `${Api}/metadatarepo`,
metaHarvest:`${Api}/metadataharvester`,
information: `${Api}/informationmanagement`,
questionfeedback:`${Api}/questionfeedback`,
fileCatalog: `${Api}/informationmanagement/rest/fileCatalog`,
fileInformation: `${Api}/informationmanagement/rest/fileInformation`,
dataInformation: `${Api}/informationmanagement/rest/dataInformation`,
issuetrack: `${Api}/questionfeedback/rest/issuetrack`,
questionInfo: `${Api}/questionfeedback/rest/questionInfo`,
report: `${Api}/portal/report`,
nodeRelation: `${Api}/metadatarepo/rest/nodeRelation`,
interfaceLog:`${Api}/auditlogger/interfaceLogCtrl`,
finder: `${Api}/finder`,
asset:`${Api}/dataassetmanager`,
metadataRelation: `${Api}/metadatarelation`,
tagger: `${Api}/tagger`,
datamodeler: `${Api}/datamodeler`,
dataservice:`${Api}/dataservicemanager`,
baseservice:`${Api}/baseservice`,
dataquality:`${Api}/dataquality`,
datamodelercomment:`${Api}/subscribe`,
sdataquality: `${Api}/dataquality`,
workorder:`${Api}/workorder`,
pdataservice:`${Api}/pdataservice`,
dbmanager: `${Api}/dbmanager`,
datasource:`${Api}/metadataharvester/datasource`,
classifier:`${Api}/classifier`
}
}
export default config
\ 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
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}
}
}
console.log('styles',styles)
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
.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);
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;
}
}
\ No newline at end of file
import React from "react"
import styles from "./index.module.less"
interface outside{
title:string;
body:any;
}
const OutSidePanel:React.FC<outside>=(props)=>{
const {title,body} = 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>
)
}
export default OutSidePanel
\ No newline at end of file
import { useState,useEffect } from 'react';
import {useMemoizedFn,useUpdateEffect} from "ahooks"
import { isFunction, isUndef } from './utils';
import isBrowser from "./utils/isBrowser"
export type SetState<S> = S | ((prevState?: S) => S);
export interface Options<T> {
defaultValue?: T | (() => T);
serializer?: (value: T) => string;
deserializer?: (value: string) => T;
onError?: (error: unknown) => void;
}
export function createUseStorageState(getStorage: () => Storage | undefined) {
function useStorageState<T>(key: string, options: Options<T> = {}) {
let storage: Storage | undefined;
const {
onError = (e) => {
console.error(e);
},
} = options;
// https://github.com/alibaba/hooks/issues/800
try {
storage = getStorage();
} catch (err) {
onError(err);
}
const listen=(e:any)=>{
if (e.key === key) {
try {
setState(getStoredValue());
} catch (error) {
console.log(error)
}
}
}
useEffect(()=>{
window?.addEventListener("storage", listen);
return ()=>{
window?.removeEventListener("storage",listen)
}
},[])
const serializer = (value: T) => {
if (options.serializer) {
return options.serializer(value);
}
return JSON.stringify(value);
};
const deserializer = (value: string): T => {
if (options.deserializer) {
return options.deserializer(value);
}
return JSON.parse(value);
};
function getStoredValue() {
try {
const raw = storage?.getItem(key);
if (raw) {
return deserializer(raw);
}
} catch (e) {
onError(e);
}
if (isFunction(options.defaultValue)) {
return options.defaultValue();
}
return options.defaultValue;
}
const [state, setState] = useState(getStoredValue);
useUpdateEffect(() => {
setState(getStoredValue());
}, [key]);
const updateState = (value?: SetState<T>) => {
const currentState = isFunction(value) ? value(state) : value;
setState(currentState);
if (isUndef(currentState)) {
storage?.removeItem(key);
} else {
try {
storage?.setItem(key, serializer(currentState));
} catch (e) {
console.error(e);
}
}
};
return [state, useMemoizedFn(updateState)] as const;
}
return useStorageState;
}
export const useMyLocalStorageState = createUseStorageState(() => (isBrowser ? localStorage : undefined));
\ No newline at end of file
import {useCallback} from "react"
import {useSetState} from "ahooks"
interface props1{
visible:boolean,
currentItem:any,
type:string,
[props:string]:any
}
export const useGetModalInfoAndAction=()=>{
const [state,setState] = useSetState<props1>({
visible:false,
currentItem:{},
type:''
})
const openModal=useCallback((item:any,odata?:any)=>{
setState({visible:true,currentItem:item,...odata})
},[])
const cancelModal:any=useCallback((odata?:any)=>{
setState({visible:false,currentItem:{},...odata})
},[])
const payload:props1={
...state,
openModal,cancelModal
}
return payload
}
\ No newline at end of file
import {useState,useEffect} from "react"
interface p3{
url:string
}
export const useGetUrlParams=(props:p3)=>{
const {url} = props
const [state,setState] = useState<any>({})
useEffect(()=>{
if(url){
const theRequest:any = {};
if (url.indexOf("?") !== -1) {
const str = url.slice(1);
const strs = str.split("&");
for(let i = 0; i < strs.length; i ++) {
const types = strs[i].split("=");
const key:string = types.shift()||'';
const value = types.join('=')
theRequest[key] = decodeURI(value.trim());
}
}
setState(theRequest)
}
},[url])
return state
}
\ No newline at end of file
export * from "./Modal"
export * from "./Local"
export * from "./Url"
export const isObject = (value: unknown): value is Record<any, any> =>
value !== null && typeof value === 'object';
export const isFunction = (value: unknown): value is (...args: any) => any =>
typeof value === 'function';
export const isString = (value: unknown): value is string => typeof value === 'string';
export const isBoolean = (value: unknown): value is boolean => typeof value === 'boolean';
export const isNumber = (value: unknown): value is number => typeof value === 'number';
export const isUndef = (value: unknown): value is undefined => typeof value === 'undefined';
const isBrowser = !!(
typeof window !== 'undefined' &&
window.document &&
window.document.createElement
);
export default isBrowser;
import metaManageService from "./metaManageService"
import metaAdminManageService from "./metaAdminManageService"
import metaUserManageService from "./metaUserManageService"
export {
metaManageService,
metaAdminManageService,
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()
export const domainChagneUtil={
getSystemInfo:(resultdata:any,domains:any)=>{
let alldomainmap:any = {}
domains.forEach((i:any)=>{
alldomainmap[i.domainId] = i
})
let systemmap:any ={}
let domainmap:any={}
const data = (resultdata||[]).map((domain:any)=>{
let tempcatalogs = (domain.catalogs||[]).map((tcatalog:any)=>{
let tsystems = (tcatalog.scopes||[]).map((_system:any,index:any)=>{
const system = {..._system,label:_system.scopeName,title:_system.scopeName,key:`system-${_system.scopeId}`,
value:_system.scopeId,catalog:tcatalog.catalogId,domainId:domain.domainId,catalogInfo:tcatalog,
prevnode:domain.catalogs[index-1]||null,nextnode:domain.catalogs[index+1]||null,domain:domain
}
systemmap[_system.scopeId] = system;
return system;
})
let tempcatalog = {catalogId:tcatalog.catalogId,catalogInfo:tcatalog,catalogName:tcatalog.catalogName,label:tcatalog.catalogName,title:tcatalog.catalogName,key:`catalog-${tcatalog.catalogId}-${domain.domainId}`,value:tcatalog.catalogId,domain:domain.domainId,disabled:true,children:tsystems}
return tempcatalog
})
let domaininfo = alldomainmap[domain.domainId]
let tempdomain= {...domaininfo,...domain,label:domain.domainName,title:domain.domainName,key:`domain-${domain.domainId}`,value:domain.domainId,children:tempcatalogs}
domainmap[domain.domainId] = tempdomain
return tempdomain
});
return {domainlist:data,domainmap,systemmap}
},
getSystemInfoFromCatalog:(resultdata:any,domainId:any)=>{
let tempcatalogs = (resultdata||[]).map((tcatalog:any)=>{
let tsystems = (tcatalog.scopes||[]).map((_system:any,index:any)=>{
const system = {..._system,label:_system.scopeName,title:_system.scopeName,key:`system-${_system.scopeId}`,
value:_system.scopeId,catalog:tcatalog.catalogId,domainId:domainId,
prevnode:resultdata[index-1]||null,nextnode:resultdata[index+1]||null
}
return system;
})
let tempcatalog = {catalogId:tcatalog.catalogId,catalogName:tcatalog.catalogName,label:tcatalog.catalogName,title:tcatalog.catalogName,key:`catalog-${tcatalog.catalogId}-${domainId}`,value:tcatalog.catalogId,domain:domainId,disabled:true,children:tsystems}
return tempcatalog
})
return tempcatalogs
},
getSystemInfoFromCatalogForTreeSelect:(resultdata:any,domainId:any)=>{
let tempcatalogs = (resultdata||[]).map((tcatalog:any)=>{
let tsystems = (tcatalog.scopes||[]).map((_system:any,index:any)=>{
const system = {..._system,label:_system.scopeName,title:_system.scopeName,key:`system-${_system.scopeId}`,
value:`system-${_system.scopeId}`,catalog:tcatalog.catalogId,domainId:domainId,
prevnode:resultdata[index-1]||null,nextnode:resultdata[index+1]||null
}
return system;
})
let tempcatalog = {catalogId:tcatalog.catalogId,catalogName:tcatalog.catalogName,label:tcatalog.catalogName,title:tcatalog.catalogName,key:`catalog-${tcatalog.catalogId}-${domainId}`,value:`catalog-${tcatalog.catalogId}-${domainId}`,domain:domainId,disabled:true,children:tsystems}
return tempcatalog
})
return tempcatalogs
}
}
\ No newline at end of file
export const heightLight={
highlightSearchContentByTerms:(content:string, terms:string[])=> {
if (content===null || content==='') return '';
if ((terms||[]).length===0) return content;
let processContent = content||'';
if(typeof(content)!=='string'){
processContent = `${content}`||''
}
(terms||[]).forEach((term:string) => {
processContent = processContent.replace(term, `<em>${term}</em>`);
})
return highlightSearchContent(processContent);
},
heightLightString:(content:string)=>{
return highlightSearchContent(content)
}
}
const highlightSearchContent=(content:string)=> {
if (content===null || content==='') return '';
const startFlag = '<em>';
const endFlag = '</em>';
const start = content.indexOf(startFlag);
const end = content.indexOf(endFlag);
const beforeStr = content.substr(0, start);
const middleStr = content.substr(start + startFlag.length, end - start - startFlag.length);
const afterStr = content.substr(end + endFlag.length);
return (
<>
{
start > -1 ? <span>
{beforeStr}
<span style={{ color: '#f50' }}>{middleStr}</span>
{highlightSearchContent(afterStr)}
</span> : <span>{content}</span>
}
</>
)
}
\ No newline at end of file
import config from "@/commons"
import {notification,message} from "antd"
const {page} = config
export const httpUtil={
checkSuccess:(data:any,type:number)=>{
if(type===1){
if(data.status===200){
return true
}else{
return false
}
}else{
return false;
}
},
logout:()=>{
const url = window.location.href;
if(!url.includes("/view/login")){
window.location.href=`${page.loginpage}?redirectURL=${encodeURIComponent(window.location.href)}`;
}
},
showError:(data:any,type:number,title?:string)=>{
if(data.status&&((data.data||{}).ApiError||(data||{}).ApiError||(data||{}).message||(data.data||{}).message)){
let messages = '未知异常';
try {
messages=data.data.ApiError.cnMessage
} catch (error) {
try {
messages=data.ApiError.cnMessage
} catch (error) {
try {
messages=data.data.message
} catch (error) {
messages='获取异常信息异常'
}
}
}
if(type===1){
notification['error']({
message:'系统异常',
description:messages,
duration:5
})
}else if(type===2){
notification['info']({
message:'提示',
description:"系统暂无环境,请先在环境管理中新增环境",
duration:null
})
}else if(type===3){
notification['error']({
message:title,
description:<pre>{messages}</pre>,
duration:5
})
}
else{
message.error(messages)
}
}
},
getUrlByLevel:(url:string,level:number)=>{
let paths = (url||'').split('/')
let temp = []
for(let i=0;i<level;i++){
temp.push(paths[i]||'')
}
return temp.join('/')
},
getQueryVariable:(variable:string,url:string)=>{
const query = (url||'?').substring(1);
const vars = query.split("&");
for (let i=0;i<vars.length;i++) {
let pair = vars[i].split("=");
let params = [...pair]
params.shift()
if(pair[0] == variable){return params.join('=')}
}
return(false);
}
}
\ No newline at end of file
import {httpUtil} from "./httpUtil"
import request from "./request"
import {heightLight} from "./heightLignt"
import {pageUtil} from "./pageUtil"
import { domainChagneUtil } from "./domainChangeUtil"
import { standardUtil } from "./standardUtil"
export {
httpUtil,
request,
heightLight,
pageUtil,
domainChagneUtil,
standardUtil
}
export const timestampToTime = (timestamp:any) => {
timestamp = timestamp ? timestamp : null;
let date = new Date(timestamp);//时间戳为10位需*1000,时间戳为13位的话不需乘1000
let Y = date.getFullYear() + '-';
let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
let D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' ';
let h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
let m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
return Y + M + D + h + m + s;
}
export function compare(property: any){
return function(a: any, b: any){
var value1 = a[property];
var value2 = b[property];
return value2 - value1;
}
}
export function timeCompare(property: any){
return function(a: any, b: any){
var value1 = new Date(a[property]).getTime();
var value2 = new Date(b[property]).getTime();
return value2 - value1;
}
}
\ No newline at end of file
import React from "react"
import {Tooltip,Typography,notification} from "antd"
import { heightLight } from "./heightLignt"
const {Text} = Typography
export const pageUtil={
getBodyHeight:()=>{
return document.body.clientHeight
},
showToolTip:(text:any,action?:Function,body?:any)=>{
try {
let name = text
let title = text
try {
text = name.replace(/(\r\n|\n|\r)/gm, "↵")
if(title.includes("\n")){
title=<pre style={{fontFamily:"宋体"}}>{title}</pre>
}
} catch (error) {
}
if(action){
const bodys = body?body:(text||'')
return(
<Tooltip title={title||''}>
<div style={{width:'100%',overflow: 'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>
<a onClick={()=>{action()}}>
{bodys}
</a>
</div>
</Tooltip>
)
}else{
const bodys = body?body:<span>{text||''}</span>
return(
<Tooltip title={title||''}>
<div style={{width:'100%',overflow: 'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>
<span>{bodys}</span>
</div>
</Tooltip>
)
}
} catch (error) {
console.log(error)
return text
}
},
showToolTipWithImg:(text:any)=>{
try {
return(
<Tooltip title={<div style={{width:500,maxHeight:300,overflow:'auto'}} dangerouslySetInnerHTML={{__html: text}} ></div>}>
<div style={{width:'100%',overflow: 'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>
{text}
</div>
</Tooltip>
)
} catch (error) {
console.log(error)
return text
}
},
showToolTipWithHighLight:(text:any,action?:Function,body?:any)=>{
let success = true
try {
let name = text
try {
text = name.replace(/(\r\n|\n|\r)/gm, "↵")
text = heightLight.heightLightString(text)
} catch (error) {
success =false
}
if(action){
const bodys = body?body:(text||'')
return(
<Tooltip title={text||''}>
<div style={{width:'100%',overflow: 'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>
<a onClick={()=>{action()}}>
{bodys}
</a>
</div>
</Tooltip>
)
}else{
const bodys = body?body:<span>{text||''}</span>
return(
<Tooltip title={text||''}>
<div style={{width:'100%',overflow: 'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>
<span>{bodys}</span>
</div>
</Tooltip>
)
}
} catch (error) {
console.log(error)
return text
}
},
showChildrenToolTip:(text:any,action?:Function,body?:any)=>{
try {
let name = text
try {
text = name.replace(/(\r\n|\n|\r)/gm, "↵")
} catch (error) {
}
if(action){
const bodys = body?body:(text||'')
return(
<Tooltip title={bodys} color="#fff" overlayStyle={{maxWidth:600}}>
<div style={{width:'100%',overflow: 'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>
<a onClick={()=>{action()}}>
{text}
</a>
</div>
</Tooltip>
)
}else{
const bodys = body?body:<span>{text||''}</span>
return(
<Tooltip title={bodys} color="#fff">
<div style={{width:'100%',overflow: 'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>
<span>{text}</span>
</div>
</Tooltip>
)
}
} catch (error) {
console.log(error)
return text
}
},
checkMenuAdmit:(menuinfo:any,menu:any,menuadmit:any)=>{
console.log('begin')
let tempmenu = menuinfo.split('/')
let queryurl = null
if(tempmenu.length>2){
queryurl = `/view/${tempmenu[tempmenu.length-1]}`
}else{
notification['info']({
message:'提示',
description:`路由${menuinfo}格式异常`,
duration:5
})
return false
}
let menumessage = (menu.mapurl[queryurl])
if(menumessage&&menumessage.href!=='/view/index'){
let type = menumessage.id.split("-")
let key = ""
if (type[0] !== "item") {
key = "sub-" + type[0]
}
if(key){
try {
let parent = menu.parentIdMap[key]||''
let totalbit = menuadmit[parent.name];
if(!parent.hidden){
if((menumessage.bit&totalbit)===menumessage.bit){
return true
}else{
notification['info']({
message:'提示',
description:`暂无访问菜单【${menumessage.name}】的权限`,
duration:5
})
return false
}
}else{
notification['info']({
message:'提示',
description:`暂无访问菜单【${menumessage.name}】的权限`,
duration:5
})
return false
}
} catch (error) {
notification['info']({
message:'提示',
description:`暂无访问路由${menuinfo}的权限`,
duration:5
})
return false
}
}else{
notification['info']({
message:'提示',
description:`暂无访问路由${menuinfo}的权限`,
duration:5
})
return false
}
}else{
return false
}
},
changeLevel:(text:any)=>{
if(text===1||text==='1'){
return '一级'
}else if(text===2||text==='2'){
return '二级'
}else if(text===3||text==='3'){
return '三级'
}else if(text===4||text==='4'){
return '四级'
}else{
return text
}
}
}
\ No newline at end of file
import axios from "axios"
import {compile} from "path-to-regexp"
import { message } from "antd"
import {httpUtil} from "./index"
import config from "@/commons"
const {page:{loginpage},headerstring} =config
const requestList:Array<any> = []
axios.interceptors.request.use(
(config:any) => {
config.headers['WWW-Authenticate'] = null;
const requestMark = `${config.method} ${config.url}`; // 请求标识 为了在响应的时候删除请求队列中的数据
let flagindex:any = null
const flag = requestList.find((item:any,key:any)=>{
if(item.requestMark === requestMark)
flagindex = key
return item.requestMark === requestMark
});
if (flag&&flag.requestMark) {
requestList.splice(flagindex,1); // 在等待重新发起的请求列表中移除
if(flag.hashrequest){
flag.cancel()
}
}
const cancelToken = axios.CancelToken;
const source:any = cancelToken.source();
config.cancelToken = source.token;
config.cancel = source.cancel;
config.requestMark = requestMark; //添加唯一标识符
requestList.push(config);
return config;
},
err => {
return Promise.reject(err);
});
axios.interceptors.response.use(
(response) => {
const config = response.config;
const requestMark = `${config.method} ${config.url}`; // 请求标识 为了在响应的时候删除请求队列中的数据
let flagindex:any = null
const flag = requestList.find((item:any,key:any)=>{
if(item.requestMark === requestMark)
flagindex = key
return item.requestMark === requestMark
});
if (flag&&flag.requestMark) {
requestList.splice(flagindex,1); // 在等待重新发起的请求列表中移除
}
return response;
},
error => {
if (error.response) {
switch (error.response?.status) {
case 401:
{
const config = {
content:"身份信息已过期,正在重新验证……",
key:'logout'
}
message.warning(config)
httpUtil.logout()
//window.location.href=`${loginpage}?redirectURL=${encodeURIComponent(window.location.href)}`
}
}
}
// else if((error.ApiError?.status||'')==='INTERNAL_SERVER_ERROR'){
// }
return Promise.reject(error) // 返回接口返回的错误信息
}
);
const fetch = (options:any) => {
let { method = "get", data,urldata , params , url, config={},hashrequest=false}:any = options
const pathname = window.location.pathname
if(pathname.includes('staticmeta')){
let headers:any = null
let tempconfig:any = config
if(pathname.includes('staticmeta')){
const tempheader = config.headers?config.headers:{}
headers = {
...tempheader,
'Authorization': headerstring
};
tempconfig.headers = headers
tempconfig.hashrequest = hashrequest
}
try {
url = compile(url)(urldata)
} catch (e) {
}
switch (method.toLowerCase()) {
case "get":
const payloadget:any={params: data?data:params,headers,hashrequest}
return axios.get(url,payloadget)
case "delete":
const payloaddelete:any = {data,params,headers,hashrequest}
return axios.delete(url,payloaddelete)
case "post":
if(params){
tempconfig.params = params
}
return axios.post(url, data, tempconfig)
case "put":
return axios.put(url, data, tempconfig)
case "patch":
return axios.patch(url, data, tempconfig)
case "postdownload":
return axios({...options,method:'post',headers})
default:
return axios({...options,headers})
}
}else{
try {
url = compile(url)(urldata)
} catch (e) {
//console.log(e)
}
switch (method.toLowerCase()) {
case "get":
const payloadget:any={params: data?data:params,hashrequest}
return axios.get(url,payloadget)
case "delete":
const payloaddelete:any = {data,params,hashrequest}
return axios.delete(url,payloaddelete)
case "post":
if(params){
config.params = params
}
config.hashrequest = hashrequest
return axios.post(url, data, config)
case "put":
return axios.put(url, data, config)
case "patch":
return axios.patch(url, data, config)
case "postdownload":
return axios({...options,method:'post'})
default:
return axios(options)
}
}
}
export default function request(options:any, autotip:boolean){
return new Promise((resolve)=>{
let result:any = {}
fetch(options).then(response => {
try {
if(response?.status===200){
if(autotip)
message.success('操作成功')
result.status=200
result.data = response?.data
result.headers=response.headers
resolve(result)
}else if(response?.status===401){
if(!options.url.includes("signin"))
httpUtil.logout()
else
resolve({status:500,data:{}})
}else{
if(autotip)
message.error('操作异常')
result.status = 500
result.data = response?.data
result.headers=response.headers
resolve(result)
}
} catch (error) {
if(autotip)
message.error('操作异常')
result.status=500
result = response?.data
resolve(result)
}
}).catch(async (error) => {
if(autotip)
message.error('操作异常')
let data = error;
if(data?.ApiError||data?.status){
result.status=500
result.data=data
}
resolve(result)
})
})
}
export const standardUtil={
getStandardAttrs:(list:Array<any>)=>{
let tempmap:any = {};
let childrenlist:any = []
list.forEach((item:any)=>{
if(item.show){
if(item.childAttr){
childrenlist.push(item)
}else{
if(tempmap[item.status]){
tempmap[item.status] = [...tempmap[item.status],item]
}else{
tempmap[item.status] = [item]
}
}
}
})
let attrtype:any = []
for(let key in tempmap){
attrtype.push({title:key,children:tempmap[key]||[]})
}
return {typelist:attrtype,childrenAttr:childrenlist}
},
getStandardColumns:(list:Array<any>)=>{
let tempmap:any = [];
let childrenlist:any = [];
(list||[]).forEach((item:any)=>{
if(item.show){
if(item.childAttr){
childrenlist.push(item)
}else{
tempmap.push(item)
}
}
})
return {typelist:tempmap,childrenAttr:childrenlist}
},
}
\ No newline at end of file
......@@ -25,6 +25,7 @@ import download from '../../../../util/download';
import RelationAssets from './asset-relation-assets';
import './AssetAction.less';
import MatchMetaInfo from './MatchMetaInfo';
const AssetAction = React.forwardRef(function (props, ref) {
const { id, dirId, action, terms, onChange, reference, readonly = false, permissionId, catalog, template } = props;
......@@ -940,7 +941,7 @@ const AssetAction = React.forwardRef(function (props, ref) {
</Form>
</Spin>
<MatchMetaInfo />
<div>
<Divider orientation='left'>字段级资源目录信息</Divider>
{
......
import React from "react"
import {Divider,Descriptions,Tooltip,Drawer, Space, Button} from "antd"
import {SettingOutlined} from "@ant-design/icons"
import { useGetModalInfoAndAction } from "../../../../hooks/common"
import SelectMeta from "@/view/meta/selectmeta/SelectMeta"
import { pageUtil } from "@/utils"
const MatchMetaInfo:React.FC<any>=()=>{
const selectmodal = useGetModalInfoAndAction()
const bodyheight = pageUtil.getBodyHeight()
const openSelect=()=>{
console.log('item')
selectmodal.openModal()
}
console.log(selectmodal)
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 }}>
6666
</div>
<div style={{ flex: '0 0 auto', marginLeft: 10, width: 16 }}>
<Tooltip placement="left" title={'关联元数据'}>
<SettingOutlined onClick={openSelect} style={{ fontSize: 16,cursor:'pointer' }} />
</Tooltip>
</div>
</div>
</Descriptions.Item>
</Descriptions>
<Drawer
title="选择表信息"
visible={selectmodal.visible}
width={'80%'}
onClose={()=>{
selectmodal.cancelModal()
}}
>
<div style={{height:bodyheight-140}}>
<SelectMeta height={bodyheight-140} />
</div>
<div style={{marginTop:5}}>
<Space>
<Button>返回</Button>
<Button>确定</Button>
</Space>
</div>
</Drawer>
</div>
)
}
export default MatchMetaInfo
const SelectMetaPanel=()=>{
return(
<div>
</div>
)
}
\ 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
}
export const useGetMetaTableInfo=(props:p3)=>{
const {treeNode,currentDomain,type='admin'} = props
const [state,setState] = useSetState({
pageable:{
pageNum:1,
pageSize:20,
},
order:{
order:'',
orderBy:''
}
})
const [payload,setPayload] = useSetState({
tablelist:[],
tableload:false,
tabletotal:0
})
useEffect(()=>{
setState({pageable:{
pageNum:1,
pageSize:20,
}})
},[treeNode])
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:'',
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)){
alert(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})
}
return {...payload,...state,changePage,changeOrder}
}
\ 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);
}
}
}
}
}
{
"compilerOptions": {
"jsx": "react",
"baseUrl": "src",
"paths": {
"@/*": ["*"]
}
}
}
\ No newline at end of file
......@@ -22,5 +22,6 @@
},
"include": [
"src"
]
],
"extends": "./tsconfig-extand.json"
}
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