Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
szse
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zhaochengxiang
szse
Commits
82cac42b
Commit
82cac42b
authored
Dec 29, 2023
by
zhaochengxiang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
增加服务
parent
ee27b8a2
Show whitespace changes
Inline
Side-by-side
Showing
66 changed files
with
3234 additions
and
4351 deletions
+3234
-4351
App.js
src/App.js
+54
-35
index.js
src/model/index.js
+2
-1
pds.js
src/model/pds.js
+167
-0
routes.js
src/routes.js
+2
-14
pds.js
src/service/pds.js
+167
-0
axios.js
src/util/axios.js
+45
-0
download.ts
src/util/download.ts
+23
-0
DefineTable.jsx
src/view/Manage/DataMaster/Define/Component/DefineTable.jsx
+0
-254
DefineTable.less
src/view/Manage/DataMaster/Define/Component/DefineTable.less
+0
-14
DefineTree.jsx
src/view/Manage/DataMaster/Define/Component/DefineTree.jsx
+0
-332
DefineTree.less
src/view/Manage/DataMaster/Define/Component/DefineTree.less
+0
-26
UpdateBasicInfo.jsx
...ew/Manage/DataMaster/Define/Component/UpdateBasicInfo.jsx
+0
-55
UpdateDefineTreeNodeModal.jsx
...DataMaster/Define/Component/UpdateDefineTreeNodeModal.jsx
+0
-85
UpdateField.jsx
src/view/Manage/DataMaster/Define/Component/UpdateField.jsx
+0
-541
UpdateNodeForm.jsx
...iew/Manage/DataMaster/Define/Component/UpdateNodeForm.jsx
+0
-54
UpdateTemplateModal.jsx
...anage/DataMaster/Define/Component/UpdateTemplateModal.jsx
+0
-151
UpdateTemplateModal.less
...nage/DataMaster/Define/Component/UpdateTemplateModal.less
+0
-21
index.jsx
src/view/Manage/DataMaster/Define/index.jsx
+0
-54
index.less
src/view/Manage/DataMaster/Define/index.less
+0
-50
ImportDataDrawer.jsx
...w/Manage/DataMaster/Manage/Component/ImportDataDrawer.jsx
+0
-271
ManageTable.jsx
src/view/Manage/DataMaster/Manage/Component/ManageTable.jsx
+0
-284
ManageTree.jsx
src/view/Manage/DataMaster/Manage/Component/ManageTree.jsx
+0
-228
UpdateDataMasterModal.jsx
...age/DataMaster/Manage/Component/UpdateDataMasterModal.jsx
+0
-135
UpdateDataMasterModal.less
...ge/DataMaster/Manage/Component/UpdateDataMasterModal.less
+0
-7
index.jsx
src/view/Manage/DataMaster/Manage/index.jsx
+0
-54
index.less
src/view/Manage/DataMaster/Manage/index.less
+0
-0
ColSettingModal.jsx
src/view/Manage/Model/Component/ColSettingModal.jsx
+57
-34
ExchangeOwner.jsx
src/view/Manage/Model/Component/ExchangeOwner.jsx
+148
-0
ExchangeOwner.less
src/view/Manage/Model/Component/ExchangeOwner.less
+6
-0
ExpandedModelTable.jsx
src/view/Manage/Model/Component/ExpandedModelTable.jsx
+3
-3
GrantedList.jsx
src/view/Manage/Model/Component/GrantedList.jsx
+132
-0
HistoryAndVersionDrawer.jsx
src/view/Manage/Model/Component/HistoryAndVersionDrawer.jsx
+3
-3
ImportActionHeader.jsx
src/view/Manage/Model/Component/ImportActionHeader.jsx
+2
-4
ImportActionIndex.jsx
src/view/Manage/Model/Component/ImportActionIndex.jsx
+7
-7
ImportActionTable.jsx
src/view/Manage/Model/Component/ImportActionTable.jsx
+33
-34
ImportExcel.jsx
src/view/Manage/Model/Component/ImportExcel.jsx
+1
-1
ImportMetadata.jsx
src/view/Manage/Model/Component/ImportMetadata.jsx
+0
-1
ImportServices.jsx
src/view/Manage/Model/Component/ImportServices.jsx
+360
-0
JDBCInformation.jsx
src/view/Manage/Model/Component/JDBCInformation.jsx
+99
-0
ModelSvg.jsx
src/view/Manage/Model/Component/ModelSvg.jsx
+1
-1
ModelTable.jsx
src/view/Manage/Model/Component/ModelTable.jsx
+730
-285
ModelTree.jsx
src/view/Manage/Model/Component/ModelTree.jsx
+133
-80
ODataConfigModal.jsx
src/view/Manage/Model/Component/ODataConfigModal.jsx
+96
-0
Offline.jsx
src/view/Manage/Model/Component/Offline.jsx
+23
-60
RecatalogModal.jsx
src/view/Manage/Model/Component/RecatalogModal.jsx
+4
-4
SampleModal.jsx
src/view/Manage/Model/Component/SampleModal.jsx
+89
-0
SelectFilter.jsx
src/view/Manage/Model/Component/SelectFilter.jsx
+51
-0
SelectUsers.jsx
src/view/Manage/Model/Component/SelectUsers.jsx
+88
-0
ServiceDetail.jsx
src/view/Manage/Model/Component/ServiceDetail.jsx
+128
-0
ServiceDetailModal.jsx
src/view/Manage/Model/Component/ServiceDetailModal.jsx
+33
-0
StartAuthorize.jsx
src/view/Manage/Model/Component/StartAuthorize.jsx
+91
-0
StartRelease.jsx
src/view/Manage/Model/Component/StartRelease.jsx
+91
-0
SuggestTable.jsx
src/view/Manage/Model/Component/SuggestTable.jsx
+2
-2
UpdateTreeItemModal.jsx
src/view/Manage/Model/Component/UpdateTreeItemModal.jsx
+13
-4
VersionHistory.jsx
src/view/Manage/Model/Component/VersionHistory.jsx
+2
-2
index.jsx
src/view/Manage/Model/index.jsx
+346
-93
ConstraintDetail.jsx
src/view/Manage/ModelConfig/Component/ConstraintDetail.jsx
+0
-125
EditTemplate.jsx
src/view/Manage/ModelConfig/Component/EditTemplate.jsx
+0
-148
PartitionCURD.jsx
src/view/Manage/ModelConfig/Component/PartitionCURD.jsx
+0
-220
TemplateAction.jsx
src/view/Manage/ModelConfig/Component/TemplateAction.jsx
+0
-155
TemplateActionHeader.jsx
...iew/Manage/ModelConfig/Component/TemplateActionHeader.jsx
+0
-72
TemplateCURD.jsx
src/view/Manage/ModelConfig/Component/TemplateCURD.jsx
+0
-172
WordTemplate.jsx
src/view/Manage/ModelConfig/Component/WordTemplate.jsx
+0
-119
index.jsx
src/view/Manage/ModelConfig/index.jsx
+0
-41
index.less
src/view/Manage/ModelConfig/index.less
+0
-7
index.jsx
src/view/Manage/index.jsx
+2
-8
No files found.
src/App.js
View file @
82cac42b
...
...
@@ -15,7 +15,6 @@ const Signin = loadable(()=> import('./view/Signin'));
const
Home
=
loadable
(()
=>
import
(
'./view/Home'
));
const
Manage
=
loadable
(()
=>
import
(
'./view/Manage'
));
const
Model
=
loadable
(()
=>
import
(
'./view/Manage/Model'
));
const
ModelConfig
=
loadable
(()
=>
import
(
'./view/Manage/ModelConfig'
));
const
AssetManage
=
loadable
(()
=>
import
(
'./view/Manage/AssetManage'
));
const
AssetResourceBrowse
=
loadable
(()
=>
import
(
'./view/Manage/AssetResourceBrowse'
));
const
AssetBrowse
=
loadable
(()
=>
import
(
'./view/Manage/AssetBrowse'
));
...
...
@@ -24,11 +23,10 @@ const DatasourceManage = loadable(()=> import('./view/Manage/DatasourceManage'))
const
AssetDetailPage
=
loadable
(()
=>
import
(
'./view/Manage/AssetManage/Component/AssetDetailPage'
));
const
AssetDetail
=
loadable
(()
=>
import
(
'./view/Manage/AssetManage/Component/AssetDetail'
));
const
ImportAction
=
loadable
(()
=>
import
(
'./view/Manage/Model/Component/ImportAction'
));
const
EditModel
=
loadable
(()
=>
import
(
'./view/Manage/Model/Component/EditModel'
));
const
EditTemplate
=
loadable
(()
=>
import
(
'./view/Manage/ModelConfig/Component/EditTemplate'
));
const
AssetTree
=
loadable
(()
=>
import
(
'./view/Manage/AssetManage/Component/AssetManageTree'
));
const
DataMasterDefine
=
loadable
(()
=>
import
(
'./view/Manage/DataMaster/Define'
));
const
DataMasterManage
=
loadable
(()
=>
import
(
'./view/Manage/DataMaster/Manage'
));
const
DataService
=
loadable
(()
=>
import
(
'./view/Manage/Model'
));
const
DataServiceDetail
=
loadable
(()
=>
import
(
'./view/Manage/Model/Component/ServiceDetail'
));
const
GrantedDataServiceList
=
loadable
(()
=>
import
(
'./view/Manage/Model/Component/GrantedList'
));
export
class
App
extends
React
.
Component
{
constructor
()
{
...
...
@@ -67,21 +65,6 @@ export class App extends React.Component {
terms
=
hostParams
.
terms
||
[];
}
if
(
message
===
'showDataModelDetail'
)
{
return
(
<
AppContext
.
Provider
value
=
{{
setGlobalState
,
onGlobalStateChange
}}
>
<
ImportAction
modelerId
=
{
id
}
action
=
'detail'
terms
=
{
terms
}
/
>
<
/AppContext.Provider
>
);
}
if
(
message
===
'showAssetDetail'
)
{
return
(
<
AppContext
.
Provider
value
=
{{
...
...
@@ -123,6 +106,57 @@ export class App extends React.Component {
);
}
if
(
message
===
'showDataService'
||
message
===
'showDataServiceManage'
)
{
return
(
<
AppContext
.
Provider
value
=
{{
env
:
hostParams
?.
env
,
user
:
hostParams
?.
user
,
openAdmit
:
hostParams
?.
openAdmit
,
openDetail
:
hostParams
?.
openDetail
,
editServer
:
hostParams
?.
editServer
,
applyServer
:
hostParams
?.
applyServer
,
setGlobalState
,
onGlobalStateChange
}}
>
<
DataService
isOnlyEnding
=
{
message
===
'showDataServiceManage'
}
location
=
{
this
.
props
.
location
}
/
>
<
/AppContext.Provider
>
);
}
if
(
message
===
'showDataServiceDetail'
)
{
return
(
<
AppContext
.
Provider
value
=
{{
setGlobalState
,
onGlobalStateChange
}}
>
<
DataServiceDetail
id
=
{
id
}
terms
=
{
terms
}
/
>
<
/AppContext.Provider
>
);
}
if
(
message
===
'showGrantedDataService'
)
{
return
(
<
AppContext
.
Provider
value
=
{{
env
:
hostParams
?.
env
,
user
:
hostParams
?.
user
,
openAdmit
:
hostParams
?.
openAdmit
,
openDetail
:
hostParams
?.
openDetail
,
editServer
:
hostParams
?.
editServer
,
applyServer
:
hostParams
?.
applyServer
,
setGlobalState
,
onGlobalStateChange
}}
>
<
GrantedDataServiceList
/>
<
/AppContext.Provider
>
);
}
return
(
<
AppContext
.
Provider
value
=
{{
env
:
hostParams
?.
env
,
...
...
@@ -135,29 +169,14 @@ export class App extends React.Component {
<
Route
path
=
{
`
${
ContextPath
}
/login`
}
component
=
{
Signin
}
exact
/>
<
Route
path
=
{
`
${
ContextPath
}
/home`
}
component
=
{
Home
}
/
>
<
Route
path
=
{
`
${
ContextPath
}
/manage`
}
component
=
{
Manage
}
/
>
<
Route
path
=
{
`
${
ContextPath
}
/data-model-action`
}
component
=
{
EditModel
}
exact
/>
<
Route
path
=
{
`
${
ContextPath
}
/model-template-action`
}
component
=
{
EditTemplate
}
exact
/>
<
Route
path
=
{
`
${
ContextPath
}
/asset-detail`
}
component
=
{
AssetDetailPage
}
exact
/>
<
Route
path
=
{
'/center-home/view/datasource-manage'
}
component
=
{
DatasourceManage
}
exact
/>
<
Route
path
=
{
'/center-home/view/data-model'
}
component
=
{
Model
}
exact
/>
<
Route
path
=
{
'/center-home/view/model-config'
}
component
=
{
ModelConfig
}
exact
/>
<
Route
path
=
{
'/center-home/view/asset-manage'
}
component
=
{
AssetManage
}
exact
/>
<
Route
path
=
{
'/center-home/view/asset-resource-browse'
}
component
=
{
AssetResourceBrowse
}
exact
/>
<
Route
path
=
{
'/center-home/view/asset-browse'
}
component
=
{
AssetBrowse
}
exact
/>
<
Route
path
=
{
'/center-home/view/asset-recycle'
}
component
=
{
AssetRecycle
}
exact
/>
<
Route
path
=
{
'/center-home/menu/datasource-manage'
}
component
=
{
DatasourceManage
}
exact
/>
<
Route
path
=
{
'/center-home/menu/data-model'
}
component
=
{
Model
}
exact
/>
<
Route
path
=
{
'/center-home/menu/model-config'
}
component
=
{
ModelConfig
}
exact
/>
<
Route
path
=
{
'/center-home/menu/asset-manage'
}
component
=
{
AssetManage
}
exact
/>
<
Route
path
=
{
'/center-home/menu/asset-resource-browse'
}
component
=
{
AssetResourceBrowse
}
exact
/>
<
Route
path
=
{
'/center-home/menu/asset-browse'
}
component
=
{
AssetBrowse
}
exact
/>
<
Route
path
=
{
'/center-home/menu/asset-recycle'
}
component
=
{
AssetRecycle
}
exact
/>
<
Route
path
=
{
'/center-home/menu/msd-define'
}
component
=
{
DataMasterDefine
}
exact
/>
<
Route
path
=
{
'/center-home/menu/msd-manage'
}
component
=
{
DataMasterManage
}
exact
/>
<
Route
path
=
{
'/center-home/data-model-action'
}
component
=
{
EditModel
}
exact
/>
<
Route
path
=
{
'/center-home/asset-detail'
}
component
=
{
AssetDetailPage
}
exact
/>
<
/Switch
>
<
/Router
>
...
...
src/model/index.js
View file @
82cac42b
...
...
@@ -11,8 +11,9 @@ import * as datamodel from './datamodel';
import
*
as
assetmanage
from
'./assetmanage'
;
import
*
as
tag
from
'./tag'
;
import
*
as
msd
from
'./msd'
;
import
*
as
pds
from
'./pds'
;
const
funcs
=
Connect
({
user
,
datamodel
,
map
,
assetmanage
,
datasource
,
tag
,
msd
})
const
funcs
=
Connect
({
user
,
datamodel
,
map
,
assetmanage
,
datasource
,
tag
,
msd
,
pds
})
function
*
request
(
args
)
{
const
{
type
,
payload
,
callback
,
error
}
=
args
.
args
;
...
...
src/model/pds.js
0 → 100644
View file @
82cac42b
import
*
as
pds
from
'../service/pds'
;
import
{
call
}
from
'redux-saga/effects'
;
export
function
*
refreshCatalog
(
payload
)
{
return
yield
call
(
pds
.
refreshCatalog
,
payload
);
}
export
function
*
loadDataServiceCatalog
()
{
return
yield
call
(
pds
.
loadDataServiceCatalog
)
}
export
function
*
loadDataServiceCatalogServiceCount
()
{
return
yield
call
(
pds
.
loadDataServiceCatalogServiceCount
)
}
export
function
*
loadStateCatalog
(
payload
)
{
return
yield
call
(
pds
.
loadStateCatalog
,
payload
);
}
export
function
*
loadDataServiceStateCatalogServiceCount
()
{
return
yield
call
(
pds
.
loadDataServiceStateCatalogServiceCount
)
}
export
function
*
saveCatalog
(
payload
)
{
return
yield
call
(
pds
.
saveCatalog
,
payload
);
}
export
function
*
deleteCatalog
(
payload
)
{
return
yield
call
(
pds
.
deleteCatalog
,
payload
);
}
export
function
*
upDownCatalog
(
payload
)
{
return
yield
call
(
pds
.
upDownCatalog
,
payload
);
}
export
function
*
getServices
(
payload
)
{
return
yield
call
(
pds
.
getServices
,
payload
);
}
export
function
*
getGrantedServices
(
payload
)
{
return
yield
call
(
pds
.
getGrantedServices
,
payload
)
}
export
function
*
getStateServices
(
payload
)
{
return
yield
call
(
pds
.
getStateServices
,
payload
)
}
export
function
*
searchService
(
payload
)
{
return
yield
call
(
pds
.
searchService
,
payload
)
}
export
function
*
getDataService
(
payload
)
{
return
yield
call
(
pds
.
getDataService
,
payload
)
}
export
function
*
deleteService
(
payload
)
{
return
yield
call
(
pds
.
deleteService
,
payload
);
}
export
function
*
recatalogService
(
payload
)
{
return
yield
call
(
pds
.
recatalogService
,
payload
);
}
export
function
*
nextState
(
payload
)
{
return
yield
call
(
pds
.
nextState
,
payload
);
}
export
function
*
checkoutService
(
payload
)
{
return
yield
call
(
pds
.
checkoutService
,
payload
);
}
export
function
*
getCheckoutService
(
payload
)
{
return
yield
call
(
pds
.
getCheckoutService
,
payload
)
}
export
function
*
getServiceDigest
(
payload
)
{
return
yield
call
(
pds
.
getServiceDigest
,
payload
)
}
export
function
*
getVersions
(
payload
)
{
return
yield
call
(
pds
.
getVersions
,
payload
)
}
export
function
*
getDataServiceLocation
(
payload
)
{
return
yield
call
(
pds
.
getDataServiceLocation
,
payload
)
}
export
function
*
getSample
(
payload
)
{
return
yield
call
(
pds
.
getSample
,
payload
)
}
export
function
*
enableOData
(
payload
)
{
return
yield
call
(
pds
.
enableOData
,
payload
)
}
export
function
*
disableOData
(
payload
)
{
return
yield
call
(
pds
.
disableOData
,
payload
)
}
export
function
*
authorize
(
payload
)
{
return
yield
call
(
pds
.
authorize
,
payload
)
}
export
function
*
release
(
payload
)
{
return
yield
call
(
pds
.
release
,
payload
)
}
export
function
*
offline
(
payload
)
{
return
yield
call
(
pds
.
offline
,
payload
);
}
export
function
*
getSmartBiUrl
(
payload
)
{
return
yield
call
(
pds
.
getSmartBiUrl
,
payload
)
}
export
function
*
getOwners
()
{
return
yield
call
(
pds
.
getOwners
)
}
export
function
*
getDepartments
()
{
return
yield
call
(
pds
.
getDepartments
)
}
export
function
*
saveOwner
(
payload
)
{
return
yield
call
(
pds
.
saveOwner
,
payload
)
}
export
function
*
changeOwner
(
payload
)
{
return
yield
call
(
pds
.
changeOwner
,
payload
)
}
export
function
*
saveCols
(
payload
)
{
return
yield
call
(
pds
.
saveCols
,
payload
);
}
export
function
*
getCols
(
payload
)
{
return
yield
call
(
pds
.
getCols
,
payload
);
}
export
function
*
getAttrs
(
payload
)
{
return
yield
call
(
pds
.
getAttrs
,
payload
);
}
export
function
*
getJdbcInformation
()
{
return
yield
call
(
pds
.
getJdbcInformation
);
}
export
function
*
subscribe
(
payload
)
{
return
yield
call
(
pds
.
subscribe
,
payload
);
}
export
function
*
addImportWithConfirm
(
payload
)
{
return
yield
call
(
pds
.
addImportWithConfirm
,
payload
);
}
export
function
*
importConfirm
(
payload
)
{
return
yield
call
(
pds
.
importConfirm
,
payload
);
}
export
function
*
getImportLogs
(
payload
)
{
return
yield
call
(
pds
.
getImportLogs
,
payload
);
}
export
function
*
exportAll
(
payload
)
{
return
yield
call
(
pds
.
exportAll
,
payload
);
}
\ No newline at end of file
src/routes.js
View file @
82cac42b
...
...
@@ -16,14 +16,6 @@ export const routes = [
text
:
'数据源管理'
,
},
{
name
:
'data-model'
,
text
:
'模型设计'
,
},
{
name
:
'model-config'
,
text
:
'模型配置'
,
},
{
name
:
'asset-manage'
,
text
:
'资产管理'
,
},
...
...
@@ -40,12 +32,8 @@ export const routes = [
text
:
'未挂载资产'
,
},
{
name
:
'msd-define'
,
text
:
'主数据定义'
},
{
name
:
'msd-manage'
,
text
:
'主数据管理'
name
:
'data-service'
,
text
:
'服务管理'
,
},
]
}
...
...
src/service/pds.js
0 → 100644
View file @
82cac42b
import
{
PostFile
,
GetJSON
,
PostJSON
,
Post
,
Get
,
GetJSONRaw
,
callFetchRawByFormData
,
callFetchRaw
}
from
"../util/axios"
import
{
ContextPath
}
from
"../util"
;
export
function
refreshCatalog
()
{
return
GetJSON
(
"/pdataservice/pdsCURD/refreshDataServiceCatalog"
)
}
export
function
loadDataServiceCatalog
()
{
return
GetJSON
(
"/pdataservice/pdsCURD/loadDataServiceCatalog"
);
}
export
function
loadDataServiceCatalogServiceCount
()
{
return
GetJSON
(
"/pdataservice/pdsCURD/loadDataServiceCatalogServiceCount"
);
}
export
function
loadStateCatalog
(
payload
)
{
return
GetJSON
(
"/pdataservice/pdsCURD/loadDataServiceStateCatalog"
,
payload
)
}
export
function
loadDataServiceStateCatalogServiceCount
()
{
return
GetJSON
(
"/pdataservice/pdsCURD/loadDataServiceStateCatalogServiceCount"
);
}
export
function
saveCatalog
(
payload
)
{
return
PostJSON
(
"/pdataservice/pdsCURD/saveDataServiceCatalog"
,
payload
)
}
export
function
deleteCatalog
(
payload
)
{
return
PostJSON
(
"/pdataservice/pdsCURD/deleteDataServiceCatalog"
,
payload
)
}
export
function
upDownCatalog
(
payload
)
{
return
GetJSON
(
"/pdataservice/pdsCURD/upDownDataServiceCatalog"
,
payload
)
}
export
function
getServices
(
payload
)
{
return
GetJSON
(
"/pdataservice/pdsCURD/getCurrentDataServiceCatalog"
,
payload
)
}
export
function
getGrantedServices
(
payload
)
{
return
GetJSON
(
"/pdataservice/pdsCURD/getGrantedDataService"
,
payload
)
}
export
function
getStateServices
(
payload
)
{
return
GetJSON
(
"/pdataservice/pdsCURD/getCurrentDataServiceStateCatalog"
,
payload
)
}
export
function
searchService
(
payload
)
{
return
GetJSON
(
"/pdataservice/pdsCURD/searchPDSDataServicesByNaming"
,
payload
)
}
export
function
getDataService
(
payload
)
{
return
GetJSON
(
"/pdataservice/pdsCURD/getDataService"
,
payload
)
}
export
function
deleteService
(
payload
)
{
return
PostJSON
(
"/pdataservice/pdsCURD/deleteDataService"
,
payload
);
}
export
function
recatalogService
(
payload
)
{
return
Post
(
"/pdataservice/pdsCURD/recatalogDataService"
,
payload
);
}
export
function
nextState
(
payload
)
{
return
GetJSON
(
"/pdataservice/pdsCURD/nextState"
,
payload
);
}
export
function
checkoutService
(
payload
)
{
return
PostJSON
(
"/pdataservice/pdsCURD/checkOutDataService"
,
payload
)
}
export
function
getCheckoutService
(
payload
)
{
return
GetJSON
(
"/pdataservice/pdsCURD/getCheckoutDataService"
,
payload
)
}
export
function
getServiceDigest
(
payload
)
{
return
GetJSON
(
"/pdataservice/pdsCURD/getDataServiceDigest"
,
payload
)
}
export
function
getVersions
(
payload
)
{
return
PostJSON
(
"/pdataservice/pdsCURD/getVersions"
,
payload
)
}
export
function
getDataServiceLocation
(
payload
)
{
return
GetJSON
(
"/pdataservice/pdsCURD/getDataServiceLocation"
,
payload
)
}
export
function
getSample
(
payload
)
{
return
PostJSON
(
"/pdataservice/pdsCURD/getSample"
,
payload
)
}
export
function
enableOData
(
payload
)
{
return
Post
(
"/pdataservice/pdsOData/enableOData"
,
payload
)
}
export
function
disableOData
(
payload
)
{
return
Post
(
"/pdataservice/pdsOData/disableOData"
,
payload
)
}
export
function
authorize
(
payload
)
{
return
PostJSON
(
"/pdataservice/pdsWorkflow/kickoffAuthorize"
,
payload
)
}
export
function
release
(
payload
)
{
return
PostJSON
(
"/pdataservice/pdsWorkflow/kickoffRelease"
,
payload
)
}
export
function
offline
(
payload
)
{
return
PostJSON
(
"/pdataservice/pdsWorkflow/kickoffOffline"
,
payload
)
}
export
function
getSmartBiUrl
(
payload
)
{
return
Get
(
`/
${
payload
.
url
}
`
);
}
export
function
getOwners
()
{
return
GetJSON
(
"/informationmanagement/userData/findAll"
)
}
export
function
getDepartments
()
{
return
GetJSON
(
"/informationmanagement/userData/getAllDepartment"
)
}
export
function
saveOwner
(
payload
)
{
return
GetJSON
(
"/informationmanagement/userData/getUserDataAndInsert"
,
payload
);
}
export
function
changeOwner
(
payload
)
{
return
PostJSON
(
"/pdataservice/pdsCURD/changeOwnerOfDataService"
,
payload
)
}
export
function
saveCols
(
payload
)
{
return
PostJSON
(
"/pdataservice/pdsModel/saveVisibleTitle"
,
payload
);
}
export
function
getCols
(
payload
)
{
return
GetJSON
(
"/pdataservice/pdsModel/getVisibleTitle"
,
payload
);
}
export
function
getAttrs
(
payload
)
{
return
GetJSON
(
"/pdataservice/pdsModel/attrs"
,
payload
);
}
export
function
getJdbcInformation
()
{
return
GetJSON
(
'/pdataservice/pdsDriver/url'
);
}
export
function
subscribe
(
payload
)
{
return
callFetchRawByFormData
(
'post'
,
'/pdataservice/pdsSub/subscribeMsg'
,
payload
);
}
export
function
addImportWithConfirm
(
payload
)
{
return
PostFile
(
"/pdataservice/pdsCURD/addWithConfirm"
,
payload
);
}
export
function
importConfirm
(
payload
)
{
return
PostJSON
(
"/pdataservice/pdsCURD/confirm"
,
payload
);
}
export
function
getImportLogs
(
payload
)
{
return
GetJSON
(
"/pdataservice/pdsCURD/log"
,
payload
);
}
export
function
exportAll
(
payload
)
{
return
callFetchRaw
(
'post'
,
'/pdataservice/pdsCURD/export/all'
,
payload
)
}
\ No newline at end of file
src/util/axios.js
View file @
82cac42b
...
...
@@ -177,3 +177,47 @@ export function PostFile(url, payload, fileName='file') {
callback
)
}
export
const
callFetchRaw
=
(
method
,
url
,
options
)
=>
{
const
{
params
,
...
reqConfig
}
=
options
;
const
config
=
{
baseURL
,
timeout
:
300000
,
cache
:
'no-cache'
,
}
return
axios
.
request
({
method
,
url
,
params
,
...
config
,
...
reqConfig
})
}
export
const
callFetchRawByFormData
=
(
method
,
url
,
options
)
=>
{
const
{
params
,
...
reqConfig
}
=
options
;
const
config
=
{
baseURL
,
timeout
:
300000
,
headers
:
{
'Content-Type'
:
'multipart/form-data'
,
},
cache
:
'no-cache'
,
}
var
bodyFormData
=
new
FormData
();
Object
.
keys
(
params
||
{}).
forEach
(
key
=>
{
bodyFormData
.
append
(
key
,
params
[
key
]);
});
return
axios
.
request
({
method
,
url
,
data
:
bodyFormData
,
...
config
,
...
reqConfig
})
}
\ No newline at end of file
src/util/download.ts
0 → 100644
View file @
82cac42b
import
{
AxiosResponse
}
from
"axios"
export
default
function
(
res
:
AxiosResponse
<
any
>
)
{
const
blob
=
res
.
data
const
headers
=
res
.
headers
let
tempName
=
headers
[
"content-disposition"
]
?.
split
(
";"
)?.[
1
]
?.
split
(
"filename="
)?.[
1
];
tempName
=
decodeURI
(
tempName
);
// const blob = new Blob([content], { type: 'application/octet-stream' })
var
url
=
(
window
.
URL
&&
window
.
URL
.
createObjectURL
)
?
window
.
URL
.
createObjectURL
(
blob
)
:
window
.
webkitURL
.
createObjectURL
(
blob
);
const
link
=
document
.
createElement
(
'a'
);
link
.
style
.
display
=
'none'
;
link
.
href
=
url
;
link
.
setAttribute
(
'download'
,
tempName
);
//or any other extension
document
.
body
.
appendChild
(
link
);
link
.
click
();
URL
.
revokeObjectURL
(
link
.
href
)
// 释放URL 对象
document
.
body
.
removeChild
(
link
)
}
\ No newline at end of file
src/view/Manage/DataMaster/Define/Component/DefineTable.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
{
useEffect
,
useMemo
,
useState
}
from
'react'
;
import
{
Space
,
Button
,
Input
,
Pagination
,
Tooltip
}
from
'antd'
;
import
{
useContextMenu
,
Menu
as
RcMenu
,
Item
as
RcItem
}
from
"react-contexify"
;
import
ResizeableTable
from
'../../../ResizeableTable'
;
import
DebounceInput
from
'../../../Model/Component/DebounceInput'
;
import
{
UpdateTemplateModal
}
from
'./UpdateTemplateModal'
;
import
{
inputWidth
,
showMessage
}
from
'../../../../../util'
;
import
'./DefineTable.less'
;
import
'react-contexify/dist/ReactContexify.css'
;
import
{
dispatch
}
from
'../../../../../model'
;
const
InputDebounce
=
DebounceInput
(
300
)(
Input
);
const
DefineTable
=
(
props
)
=>
{
const
{
nodeId
}
=
props
;
const
[
keyword
,
setKeyword
]
=
useState
(
''
);
const
[
checkedKeys
,
setCheckedKeys
]
=
useState
([]);
const
[
isTemplateModalVisible
,
setIsTemplateModalVisible
]
=
useState
(
false
);
const
[
currentTemplate
,
setCurrentTemplate
]
=
useState
({});
const
[
action
,
setAction
]
=
useState
(
''
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
deleteLoading
,
setDeleteLoading
]
=
useState
(
false
);
const
[
tableData
,
setTableData
]
=
useState
([]);
const
[
total
,
setTotal
]
=
useState
(
0
);
const
[
pagination
,
setPagination
]
=
useState
({
pageNum
:
1
,
pageSize
:
20
});
const
{
pageNum
,
pageSize
}
=
pagination
;
useEffect
(()
=>
{
setCheckedKeys
([]);
setPagination
({...
pagination
,
pageNum
:
1
});
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
nodeId
])
useEffect
(()
=>
{
if
(
!
nodeId
||
nodeId
===
''
)
{
setTableData
([]);
setTotal
(
0
);
}
else
{
getTemplates
();
}
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
keyword
,
pagination
])
const
columns
=
useMemo
(()
=>
{
return
([
{
title
:
'序号'
,
dataIndex
:
'key'
,
render
:
(
text
,
record
,
index
)
=>
{
return
(
index
+
1
).
toString
();
},
width
:
60
,
ellipsis
:
true
,
},
{
title
:
'模版名称'
,
dataIndex
:
'name'
,
width
:
200
,
ellipsis
:
true
,
render
:
(
text
,
record
,
index
)
=>
{
return
<
a
onClick=
{
()
=>
{
onItemClick
(
record
);}
}
>
{
text
}
</
a
>
},
},
{
title
:
'模版中文名称'
,
dataIndex
:
'cnName'
,
width
:
200
,
ellipsis
:
true
,
},
{
title
:
'修改时间'
,
dataIndex
:
'lastUpdateTime'
,
width
:
200
,
ellipsis
:
true
,
},
{
title
:
'模版描述'
,
dataIndex
:
'comment'
,
width
:
200
,
ellipsis
:
true
,
}
]);
},
[]);
const
MENU_ID
=
'data-master-table-contextmenu'
;
const
{
show
}
=
useContextMenu
({
id
:
MENU_ID
,
});
const
getTemplates
=
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'msd.getModels'
,
payload
:
{
params
:
{
nodeId
,
keyword
,
pageNum
,
pageSize
}
},
callback
:
(
data
)
=>
{
setLoading
(
false
);
setTableData
(
data
?.
content
||
[]);
setTotal
(
data
?.
totalElements
||
0
);
},
error
:
()
=>
{
setLoading
(
false
);
}
});
}
const
onAddClick
=
()
=>
{
setAction
(
'add'
);
setCurrentTemplate
(
null
);
setIsTemplateModalVisible
(
true
);
}
const
onItemClick
=
(
record
)
=>
{
setAction
(
'detail'
);
setCurrentTemplate
(
record
);
setIsTemplateModalVisible
(
true
);
}
const
onTemplateModalCancel
=
(
refresh
=
false
)
=>
{
setIsTemplateModalVisible
(
false
);
if
(
refresh
)
{
getTemplates
();
}
}
const
onBatchDeleteClick
=
()
=>
{
setDeleteLoading
(
true
);
dispatch
({
type
:
'msd.deleteModels'
,
payload
:
{
params
:
{
modelIds
:
(
checkedKeys
||
[]).
join
(
','
)
}
},
callback
:
(
data
)
=>
{
setDeleteLoading
(
false
);
showMessage
(
'success'
,
'删除成功'
);
getTemplates
();
},
error
:
()
=>
{
setDeleteLoading
(
false
);
}
});
}
const
onSearchInputChange
=
(
value
)
=>
{
setKeyword
(
value
);
}
const
onTableSelectChange
=
keys
=>
{
setCheckedKeys
(
keys
);
};
const
handleItemClick
=
({
event
,
props
,
data
,
triggerEvent
})
=>
{
const
key
=
event
.
currentTarget
.
id
;
if
(
key
===
'update'
)
{
setAction
(
'update'
);
setIsTemplateModalVisible
(
true
);
}
}
const
changeCurrent
=
(
page
,
size
)
=>
{
setCheckedKeys
([]);
setPagination
({
pageNum
:
page
,
pageSize
:
size
});
}
const
rowSelection
=
{
selectedRowKeys
:
checkedKeys
,
onChange
:
onTableSelectChange
,
};
return
(
<
div
className=
'data-master-table'
>
<
div
className=
'data-master-header px-3'
>
<
Space
>
<
Space
>
<
Button
onClick=
{
onAddClick
}
>
新建
</
Button
>
</
Space
>
<
Space
>
<
Tooltip
title=
{
(
checkedKeys
||
[]).
length
===
0
?
'请先选择模版'
:
''
}
>
<
Button
onClick=
{
onBatchDeleteClick
}
disabled=
{
(
checkedKeys
||
[]).
length
===
0
}
loading=
{
deleteLoading
}
>
删除
</
Button
>
</
Tooltip
>
</
Space
>
</
Space
>
<
InputDebounce
placeholder=
"请输入关键字"
allowClear
value=
{
keyword
}
onChange=
{
onSearchInputChange
}
style=
{
{
width
:
inputWidth
,
marginLeft
:
'auto'
}
}
/>
</
div
>
<
div
className=
'data-master-content p-3'
>
<
ResizeableTable
loading=
{
loading
}
rowKey=
'_id'
rowSelection=
{
rowSelection
}
columns=
{
columns
}
dataSource=
{
tableData
}
onRow=
{
(
record
)
=>
{
return
{
onContextMenu
:
event
=>
{
setCurrentTemplate
(
record
);
show
(
event
);
},
};
}
}
pagination=
{
false
}
scroll=
{
{
y
:
'calc(100vh - 94px - 32px - 57px - 24px - 39px - 36px)'
}
}
/>
<
Pagination
size=
"small"
className=
"text-center mt-3"
showSizeChanger
showQuickJumper
onChange=
{
changeCurrent
}
onShowSizeChange=
{
changeCurrent
}
current=
{
pageNum
}
pageSize=
{
pageSize
}
defaultCurrent=
{
1
}
total=
{
total
}
showTotal=
{
total
=>
`共 ${total} 条`
}
/>
</
div
>
<
UpdateTemplateModal
action=
{
action
}
nodeId=
{
nodeId
}
template=
{
currentTemplate
}
visible=
{
isTemplateModalVisible
}
onCancel=
{
onTemplateModalCancel
}
/>
<
RcMenu
id=
{
MENU_ID
}
>
<
RcItem
id=
"update"
onClick=
{
handleItemClick
}
>
编辑
</
RcItem
>
</
RcMenu
>
</
div
>
);
}
export
default
DefineTable
;
\ No newline at end of file
src/view/Manage/DataMaster/Define/Component/DefineTable.less
deleted
100644 → 0
View file @
ee27b8a2
.data-master-table {
height: 100%;
.data-master-header {
display: flex;
flex: none;
height: 57px;
border-bottom: 1px solid #EFEFEF;
justify-content: space-between;
align-items: center;
}
}
\ No newline at end of file
src/view/Manage/DataMaster/Define/Component/DefineTree.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
{
useEffect
,
useMemo
,
useState
,
useRef
}
from
'react'
;
import
{
Tooltip
,
Spin
,
AutoComplete
,
Tree
,
Modal
}
from
'antd'
;
import
{
PlusOutlined
,
ReloadOutlined
}
from
'@ant-design/icons'
;
import
{
useContextMenu
,
Menu
as
RcMenu
,
Item
as
RcItem
}
from
"react-contexify"
;
import
{
dispatch
}
from
'../../../../../model'
;
import
{
highlightSearchContentByTerms
,
showMessage
}
from
'../../../../../util'
;
import
UpdateDefineTreeNodeModal
from
'./UpdateDefineTreeNodeModal'
;
import
'react-contexify/dist/ReactContexify.css'
;
import
'./DefineTree.less'
;
const
{
Option
}
=
AutoComplete
;
const
DefineTree
=
(
props
)
=>
{
const
{
onClick
}
=
props
;
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
data
,
setData
]
=
useState
();
const
[
options
,
setOptions
]
=
useState
([]);
const
[
keyword
,
setKeyword
]
=
useState
(
''
);
const
[
expandedKeys
,
setExpandedKeys
]
=
useState
([]);
const
[
selectedKeys
,
setSelectedKeys
]
=
useState
([]);
const
[
autoExpandParent
,
setAutoExpandParent
]
=
useState
(
false
);
const
[
updateNodeModalVisible
,
setUpdateNodeModalVisible
]
=
useState
(
false
);
const
[
updateNodeType
,
setUpdateNodeType
]
=
useState
(
''
);
const
[
rightSelectNode
,
setRightSelectNode
]
=
useState
({});
const
selectedKeysRef
=
useRef
([]);
const
[
modal
,
contextHolder
]
=
Modal
.
useModal
();
const
MENU_ID
=
'msd-define-tree'
;
const
{
show
}
=
useContextMenu
({
id
:
MENU_ID
,
});
useEffect
(()
=>
{
getTreeNodes
();
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[])
const
treeData
=
useMemo
(()
=>
{
const
loop
=
(
data
)
=>
(
data
||
[]).
map
((
item
)
=>
{
if
(
item
.
children
)
{
return
{
title
:
item
.
name
||
''
,
key
:
item
.
_id
||
''
,
origin
:
item
,
children
:
loop
(
item
.
children
),
};
}
return
{
title
:
item
.
name
||
''
,
key
:
item
.
_id
||
''
,
};
});
return
loop
(
data
);
},
[
data
])
const
treeList
=
useMemo
(()
=>
{
const
generateList
=
(
data
,
list
,
path
=
null
)
=>
{
(
data
||
[]).
forEach
(
node
=>
{
const
{
_id
,
name
}
=
node
;
const
currentPath
=
path
?
`
${
path
}
/
${
name
}
`
:
name
;
list
.
push
({
key
:
_id
,
title
:
currentPath
});
if
(
node
.
children
)
{
generateList
(
node
.
children
,
list
,
currentPath
);
}
});
};
const
newTreeList
=
[];
generateList
(
data
,
newTreeList
);
return
newTreeList
;
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
data
])
const
selectNode
=
useMemo
(()
=>
{
const
generateList
=
(
data
,
list
)
=>
{
(
data
||
[]).
forEach
(
node
=>
{
list
.
push
({...
node
});
if
(
node
.
children
)
{
generateList
(
node
.
children
,
list
);
}
});
};
const
newTreeList
=
[];
generateList
(
data
,
newTreeList
);
const
filterNodes
=
newTreeList
.
filter
(
item
=>
selectedKeys
.
indexOf
(
item
.
_id
)
!==-
1
);
return
(
filterNodes
||
[]).
length
>
0
?
filterNodes
[
0
]:{};
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
data
,
selectedKeys
])
const
getTreeNodes
=
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'msd.getTreeNodes'
,
callback
:
(
data
)
=>
{
setLoading
(
false
);
setData
(
data
||
[]);
if
((
selectedKeysRef
.
current
||
[]).
length
===
0
&&
(
data
||
[]).
length
>
0
)
{
onTreeSelect
([
data
[
0
].
_id
]);
}
if
((
expandedKeys
||
[]).
length
===
0
&&
(
data
||
[]).
length
>
0
)
{
setExpandedKeys
([
data
[
0
].
_id
]);
}
else
{
setExpandedKeys
(
Array
.
from
(
new
Set
([...
expandedKeys
,
...
selectedKeysRef
.
current
])));
setAutoExpandParent
(
true
);
}
},
error
:
()
=>
{
setLoading
(
false
);
}
})
}
const
onAddClick
=
()
=>
{
setUpdateNodeType
(
'add'
);
setUpdateNodeModalVisible
(
true
);
}
const
onRefreshClick
=
()
=>
{
getTreeNodes
();
}
const
updateNode
=
()
=>
{
setUpdateNodeType
(
'update'
);
setUpdateNodeModalVisible
(
true
);
}
const
upOrDownNode
=
(
steps
=
1
)
=>
{
setLoading
(
true
);
dispatch
({
type
:
'msd.treeNodeSeq'
,
payload
:
{
params
:
{
id
:
rightSelectNode
?.
_id
||
''
,
steps
}
},
callback
:
()
=>
{
rightSelectNode
?.
_id
&&
onTreeSelect
([
rightSelectNode
?.
_id
]);
getTreeNodes
();
},
error
:
()
=>
{
setLoading
(
false
);
}
})
}
const
deleteNode
=
()
=>
{
modal
.
confirm
({
title
:
'提示!'
,
content
:
'删除目录会删除相关的模版,您确定删除吗?'
,
onOk
:
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'msd.deleteTreeNode'
,
payload
:
{
params
:
{
nodeId
:
rightSelectNode
?.
_id
}
},
callback
:
()
=>
{
showMessage
(
'success'
,
'删除目录成功'
);
setLoading
(
false
);
if
(
selectedKeysRef
.
current
.
indexOf
(
rightSelectNode
?.
_id
)
!==-
1
)
{
setSelectedKeys
([]);
selectedKeysRef
.
current
=
[];
}
getTreeNodes
();
},
error
:
()
=>
{
setLoading
(
false
);
}
});
}
});
}
const
onAutoCompleteSearch
=
(
searchText
)
=>
{
setKeyword
(
searchText
);
setOptions
(
treeList
.
filter
(
item
=>
item
.
title
.
indexOf
(
searchText
)
!==-
1
));
};
const
onAutoCompleteSelect
=
(
value
,
option
)
=>
{
const
paths
=
value
.
split
(
'/'
);
setKeyword
(
paths
[
paths
.
length
-
1
]);
onTreeSelect
([
option
.
key
]);
setExpandedKeys
(
Array
.
from
(
new
Set
([...
expandedKeys
,
option
.
key
])));
setAutoExpandParent
(
true
);
};
const
onAutoCompleteClear
=
()
=>
{
setKeyword
(
''
);
}
const
onTreeExpand
=
(
expandedKeys
)
=>
{
setExpandedKeys
(
expandedKeys
);
setAutoExpandParent
(
false
);
}
const
onTreeSelect
=
(
selectedKeys
)
=>
{
if
(
selectedKeys
.
length
===
0
)
{
return
;
}
setSelectedKeys
(
selectedKeys
);
selectedKeysRef
.
current
=
selectedKeys
;
onClick
&&
onClick
(
selectedKeys
[
0
]);
}
const
onUpdateNodeModalCancel
=
(
refresh
=
false
,
nodeId
=
null
)
=>
{
setUpdateNodeModalVisible
(
false
);
if
(
refresh
)
{
nodeId
&&
onTreeSelect
([
nodeId
]);
getTreeNodes
();
}
}
return
(
<
div
className=
'data-master-tree'
>
<
div
className=
'header p-3'
>
<
Tooltip
title=
"新增目录"
>
<
PlusOutlined
className=
'default'
onClick=
{
onAddClick
}
style=
{
{
fontSize
:
16
,
cursor
:
'pointer'
,
flex
:
1
}
}
/>
</
Tooltip
>
<
Tooltip
title=
"刷新目录"
className=
'ml-2'
>
<
ReloadOutlined
className=
'default'
onClick=
{
onRefreshClick
}
style=
{
{
fontSize
:
16
,
cursor
:
'pointer'
,
flex
:
1
}
}
/>
</
Tooltip
>
<
div
style=
{
{
flex
:
3
}
}
/>
</
div
>
<
div
className=
'content p-3'
>
<
Spin
spinning=
{
loading
}
>
<
AutoComplete
className=
'content-search'
allowClear
value=
{
keyword
}
onSelect=
{
onAutoCompleteSelect
}
onSearch=
{
onAutoCompleteSearch
}
onClear=
{
onAutoCompleteClear
}
>
{
(
options
||
[]).
map
((
item
,
index
)
=>
{
return
(
<
Option
key=
{
item
.
key
}
value=
{
item
.
title
}
>
<
div
style=
{
{
whiteSpace
:
'normal'
}
}
>
{
highlightSearchContentByTerms
(
item
.
title
,
[
keyword
])
}
</
div
>
</
Option
>
);
})
}
</
AutoComplete
>
<
Tree
className=
'content-tree'
showLine
showIcon=
{
false
}
autoExpandParent=
{
autoExpandParent
}
treeData=
{
treeData
}
onExpand=
{
onTreeExpand
}
onSelect=
{
onTreeSelect
}
expandedKeys=
{
expandedKeys
}
selectedKeys=
{
selectedKeys
}
onRightClick=
{
({
event
,
node
})
=>
{
setRightSelectNode
(
node
?.
origin
);
show
(
event
,
{
position
:
{
x
:
event
.
clientX
+
30
,
y
:
event
.
clientY
-
10
}
});
}
}
/>
</
Spin
>
</
div
>
<
UpdateDefineTreeNodeModal
visible=
{
updateNodeModalVisible
}
onCancel=
{
onUpdateNodeModalCancel
}
type=
{
updateNodeType
}
node=
{
(
updateNodeType
===
'add'
)?
selectNode
:
rightSelectNode
}
/>
<
RcMenu
id=
{
MENU_ID
}
>
<
RcItem
id=
"edit"
onClick=
{
updateNode
}
>
修改目录
</
RcItem
>
<
RcItem
id=
"up"
onClick=
{
()
=>
{
upOrDownNode
(
-
1
);
}
}
>
上移目录
</
RcItem
>
<
RcItem
id=
"down"
onClick=
{
()
=>
{
upOrDownNode
(
1
);
}
}
>
下移目录
</
RcItem
>
<
RcItem
id=
"delete"
onClick=
{
deleteNode
}
>
删除目录
</
RcItem
>
</
RcMenu
>
{
contextHolder
}
</
div
>
);
}
export
default
DefineTree
;
\ No newline at end of file
src/view/Manage/DataMaster/Define/Component/DefineTree.less
deleted
100644 → 0
View file @
ee27b8a2
@import '../../../../../variables.less';
.data-master-tree {
height: 100%;
.header {
display: inline-flex;
flex: none;
width: 100%;
height: 57px;
justify-content: flex-start;
align-items: center;
border-bottom: 1px solid #EFEFEF;
}
.content-search {
margin-bottom: 10px;
width: 100%;
}
.content-tree {
height: calc(100vh - @header-height - @breadcrumb-height - 25px - 57px - 66px);
overflow: auto;
}
}
\ No newline at end of file
src/view/Manage/DataMaster/Define/Component/UpdateBasicInfo.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
{
Form
,
Input
,
Row
,
Col
,
Descriptions
}
from
"antd"
;
const
{
TextArea
}
=
Input
;
const
UpdateBasicInfo
=
(
props
)
=>
{
const
{
form
,
editable
,
template
}
=
props
;
const
formItemLayout
=
{
labelCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
6
},
},
wrapperCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
18
},
},
};
return
(
<
div
>
<
h3
>
基本信息
</
h3
>
{
editable
?
<
Form
form=
{
form
}
{
...
formItemLayout
}
>
<
Row
gutter=
{
10
}
>
<
Col
xs=
{
24
}
sm=
{
24
}
lg=
{
12
}
>
<
Form
.
Item
label=
'中文名称'
name=
'cnName'
rules=
{
[{
required
:
true
,
message
:
'请填写模版中文名称'
}]
}
>
<
Input
/>
</
Form
.
Item
>
</
Col
>
<
Col
xs=
{
24
}
sm=
{
24
}
lg=
{
12
}
>
<
Form
.
Item
label=
'英文名称'
name=
'name'
rules=
{
[{
required
:
true
,
message
:
'请填写模版名称'
}]
}
>
<
Input
/>
</
Form
.
Item
>
</
Col
>
<
Col
xs=
{
24
}
sm=
{
24
}
lg=
{
12
}
>
<
Form
.
Item
label=
'模版描述'
name=
'comment'
>
<
TextArea
row=
{
4
}
/>
</
Form
.
Item
>
</
Col
>
</
Row
>
</
Form
>
:
<
Descriptions
column=
{
2
}
>
<
Descriptions
.
Item
label=
{
<
div
style=
{
{
textAlign
:
'right'
,
width
:
85
}
}
>
中文名称
</
div
>
}
>
{
template
?.
cnName
||
''
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
{
<
div
style=
{
{
textAlign
:
'right'
,
width
:
85
}
}
>
英文名称
</
div
>
}
>
{
template
?.
name
||
''
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
{
<
div
style=
{
{
textAlign
:
'right'
,
width
:
85
}
}
>
模版描述
</
div
>
}
>
{
template
?.
comment
||
''
}
</
Descriptions
.
Item
>
</
Descriptions
>
}
</
div
>
);
}
export
default
UpdateBasicInfo
;
\ No newline at end of file
src/view/Manage/DataMaster/Define/Component/UpdateDefineTreeNodeModal.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
{
useState
,
useEffect
}
from
'react'
;
import
{
Modal
,
Form
}
from
'antd'
;
import
UpdateNodeForm
from
'./UpdateNodeForm'
;
import
{
dispatch
}
from
'../../../../../model'
;
const
UpdateDefineTreeNodeModal
=
(
props
)
=>
{
const
{
visible
,
onCancel
,
type
,
node
}
=
props
;
const
[
confirmLoading
,
setConfirmLoading
]
=
useState
(
false
);
const
[
form
]
=
Form
.
useForm
();
useEffect
(()
=>
{
if
(
visible
)
{
if
(
type
===
'add'
)
{
form
.
setFieldsValue
({
action
:
node
?
'sub'
:
'root'
,
name
:
''
,
comment
:
''
});
}
else
{
form
.
setFieldsValue
({
action
:
''
,
name
:
node
?.
name
||
''
,
comment
:
node
?.
comment
||
''
});
}
}
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
visible
,
node
,
type
])
const
handleCancel
=
()
=>
{
setConfirmLoading
(
false
);
form
.
setFields
([{
name
:
'name'
,
errors
:
[]
},
{
name
:
'comment'
,
errors
:
[]
}]);
onCancel
&&
onCancel
();
}
const
handleOk
=
async
()
=>
{
setConfirmLoading
(
true
);
try
{
const
values
=
await
form
.
validateFields
();
let
payload
=
null
;
if
(
type
===
'add'
)
{
payload
=
{
name
:
values
.
name
||
''
,
comment
:
values
.
comment
||
''
,
parentId
:
(
values
.
action
===
'root'
)?
'root'
:
node
?.
_id
};
}
else
{
payload
=
{
...
node
,
name
:
values
.
name
||
''
,
comment
:
values
.
comment
||
''
,
}
}
let
url
=
(
type
===
'add'
)?
'msd.addTreeNode'
:
'msd.updateTreeNode'
;
dispatch
({
type
:
url
,
payload
:
{
data
:
payload
},
callback
:
id
=>
{
setConfirmLoading
(
false
);
onCancel
&&
onCancel
(
true
,
id
);
},
error
:
()
=>
{
setConfirmLoading
(
false
);
}
});
}
catch
(
errInfo
)
{
setConfirmLoading
(
false
);
}
}
return
(
<
Modal
confirmLoading=
{
confirmLoading
}
visible=
{
visible
}
title=
{
type
===
'add'
?
"新增目录"
:
"更新目录"
}
onOk=
{
handleOk
}
onCancel=
{
handleCancel
}
>
<
UpdateNodeForm
type=
{
type
}
node=
{
node
}
form=
{
form
}
/>
</
Modal
>
);
}
export
default
UpdateDefineTreeNodeModal
;
\ No newline at end of file
src/view/Manage/DataMaster/Define/Component/UpdateField.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
React
,
{
useState
,
useRef
,
useEffect
,
useMemo
,
useCallback
,
useContext
}
from
"react"
;
import
{
Tooltip
,
Table
,
Space
,
Popover
,
Input
,
Button
,
Form
,
Checkbox
}
from
"antd"
;
import
{
QuestionCircleOutlined
,
PlusOutlined
,
DeleteOutlined
}
from
'@ant-design/icons'
;
import
{
useClickAway
}
from
'ahooks'
;
import
update
from
'immutability-helper'
;
import
{
DndProvider
}
from
'react-dnd'
;
import
{
HTML5Backend
}
from
'react-dnd-html5-backend'
;
import
DebounceInput
from
"../../../Model/Component/DebounceInput"
;
import
{
inputWidth
}
from
"../../../../../util"
;
import
{
DragableBodyRow
,
DatatypeInput
}
from
"../../../Model/Component/ImportActionTable"
;
import
{
dispatch
}
from
"../../../../../model"
;
import
{
EditTemplateContext
}
from
"./UpdateTemplateModal"
;
const
InputDebounce
=
DebounceInput
(
300
)(
Input
);
const
FieldTypeComp
=
(
props
)
=>
{
const
{
dataType
=
{}}
=
props
;
const
[
value
,
setValue
]
=
useState
(
''
);
useEffect
(()
=>
{
try
{
let
dataTypeJson
=
JSON
.
parse
(
dataType
);
if
((
dataTypeJson
?.
name
===
'Char'
||
dataTypeJson
?.
name
===
'Varchar'
)
&&
dataTypeJson
?.
parameterValues
?.
length
>
0
)
{
setValue
(
`
${
dataTypeJson
?.
name
||
''
}(
$
{(
dataTypeJson
?.
parameterValues
[
0
]?
dataTypeJson
?.
parameterValues
[
0
]:
0
)})
`);
} else if ((dataTypeJson?.name==='Decimal'||dataTypeJson?.name==='Numeric') && dataTypeJson?.parameterValues?.length>1) {
setValue(`
$
{
dataTypeJson
?.
name
||
''
}(
$
{(
dataTypeJson
?.
parameterValues
[
0
]?
dataTypeJson
?.
parameterValues
[
0
]:
0
)},
$
{(
dataTypeJson
?.
parameterValues
[
1
]?
dataTypeJson
?.
parameterValues
[
1
]:
0
)})
`);
} else {
setValue(dataTypeJson?.name||'');
}
} catch(error) {
setValue('');
}
}, [dataType])
return (
<span>{value}</span>
)
}
export const EditableCell = ({
editing,
dataIndex,
colTitle,
inputType,
record,
index,
datatypes,
require,
children,
...restProps
}) => {
let editingComponent = null;
if (editing) {
if (dataIndex !== 'dataType') {
const inputNode = inputType === 'check' ? <Checkbox /> : <InputDebounce />
editingComponent = (
<Form.Item
name={dataIndex}
style={{
margin: 0,
}}
valuePropName={(inputType==='check')? 'checked': 'value'}
rules={[
{
required: (require===null)?false:require,
message: `
请输入
$
{
colTitle
}
!
`,
},
]}
>
{ inputNode }
</Form.Item>
);
} else {
editingComponent = (
<Form.Item
name={dataIndex}
style={{
margin: 0,
}}
valuePropName={'value'}
rules={[
{
required: (require===null)?false:require,
message: `
请输入
$
{
colTitle
}
!
`,
},
]}
>
<DatatypeInput datatypes={datatypes} />
</Form.Item>
)
}
}
return (
<td {...restProps}>
{editing ? (
editingComponent
) : (
children
)}
</td>
);
};
const UpdateField = (props) => {
const {editable = true, template, visible, onChange} = props;
const [data, setData] = useState([]);
const [keyword, setKeyword] = useState('');
const [editingKey, setEditingKey] = useState(null);
const [supportedDatatypes, setSupportedDatatypes] = useState([]);
const [loading, setLoading] = useState(false);
const [form] = Form.useForm();
const tableRef = useRef(null);
const dataRef = useRef([]);
const editingKeyRef = useRef(null);
const { attrIsEditingFunction } = useContext(EditTemplateContext);
const cols = [
{
title: '序号',
dataIndex: 'key',
editable: false,
width: 60,
render: (_, __, index) => {
return (index+1).toString();
}
},
{
title: '中文名称',
width: 200,
dataIndex: 'cnName',
editable: true,
ellipsis: true,
require: true,
render: (text, _, __) => {
return (
<Tooltip title={text||''}>
<span>{text}</span>
</Tooltip>
)
}
},
{
title: '英文名称',
width: 200,
dataIndex: 'name',
editable: true,
ellipsis: true,
require: true,
render: (text, record, index) => {
return (
<Tooltip title={text||''}>
<span style={{ fontWeight: 'bold' }} >{text}</span>
</Tooltip>
)
}
},
{
title: '类型',
width: (editingKey!==null)?250:150,
dataIndex: 'dataType',
editable: true,
ellipsis: true,
require: true,
render: (_, record, __) => {
return <FieldTypeComp dataType={record?.dataType} />;
}
},
{
title: '业务含义',
dataIndex: 'comment',
editable: true,
ellipsis: true,
require: true,
width: 200,
render: (text, _, __) => {
return (
<Tooltip title={text||''}>
<span>{text}</span>
</Tooltip>
)
}
}
];
const actionCol = {
title: '操作',
dataIndex: 'action',
width: 90,
fixed: 'right',
render: (_, record) => {
return (
<React.Fragment>
{
editable && <React.Fragment>
{
<React.Fragment>
<Button
className='mr-3'
size='small'
type='text'
icon={<DeleteOutlined style={{ color: 'red' }} />}
onClick={(event) => {
event.stopPropagation();
removeItem(record);
}}
/>
</React.Fragment>
}
</React.Fragment>
}
</React.Fragment>
)
},
};
useEffect(() => {
if (visible) {
setEditingKey(null);
editingKeyRef.current = null;
if (!template) {
setData([]);
dataRef.current = [];
} else {
getFileds();
}
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [visible, template])
const columns = useMemo(() => {
const newColumns = [...cols];
if (editable) {
newColumns.push(actionCol);
}
return newColumns;
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [editable, data, editingKey]);
useClickAway(() => {
save();
}, tableRef);
useEffect(() => {
getSupportedDatatypes();
}, [])
useEffect(() => {
attrIsEditingFunction && attrIsEditingFunction(editingKey!=null);
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [editingKey])
const filterData = useMemo(() => {
return (data||[]).filter(item => (item?.name||'').indexOf(keyword)!==-1 || (item.cnName).indexOf(keyword)!==-1);
}, [keyword, data])
const isEditing = (record) => record?.name === editingKey;
const getSupportedDatatypes = () => {
dispatch({
type: 'msd.getTypes',
callback: data => {
setSupportedDatatypes(data||[]);
}
});
}
const getFileds = () => {
setLoading(true);
dispatch({
type: 'msd.getColumns',
payload: {
params: {
modelId: template?._id||''
}
},
callback: data => {
setLoading(false);
function compare(val1, val2) {
var a = val1.seq;
var b = val2.seq;
return (a - b);
}
(data||[]).sort(compare);
setData(data||[]);
dataRef.current = data||[];
onChange && onChange(data||[]);
},
error: () => {
setLoading(false);
}
});
}
const onAddClick = (event) => {
event.stopPropagation();
save().then(result => {
if (result) {
setKeyword('');
const newData = [...dataRef.current, {name: ''}];
setData(newData);
dataRef.current = newData;
editItem(newData[newData.length-1]);
setTimeout(() => {
document.getElementById(`
field
-
`)?.scrollIntoView();
}, 200)
}
})
}
const removeItemLogic = (record) => {
const newData = [...data];
const index = newData.findIndex((item) => record.name === item.name);
if (index !== -1) {
newData.splice(index, 1);
}
setData(newData);
dataRef.current = newData;
onChange && onChange(newData);
}
const removeItem = (record) => {
if (record.name !== editingKey) {
removeItemLogic(record);
} else {
setEditingKey(null);
editingKeyRef.current = null;
removeItemLogic(record);
}
}
const onSearchInputChange = (value) => {
save().then(result => {
if (result) {
setKeyword(value);
}
});
}
const editItemLogic = (record) => {
form.resetFields();
try {
let dataTypeJson = JSON.parse(record?.dataType);
form.setFieldsValue({...record, dataType: dataTypeJson});
setEditingKey(record?.name);
editingKeyRef.current = record?.name;
} catch {
form.setFieldsValue({...record, dataType: {}});
setEditingKey(record?.name);
editingKeyRef.current = record?.name;
}
}
const editItem = (record) => {
save().then((result) => {
if (result) {
editItemLogic(record);
}
});
};
const save = async() => {
try {
if (editingKeyRef.current !== null) {
const row = await form.validateFields();
if ((row.dataType.name||'')==='') {
form.setFields([{ name: 'dataType', errors: ['必须选择类型'] }]);
return;
}
(row.dataType.parameterNames||[]).forEach((parameterName, index) => {
if (!row.dataType.parameterValues[index] || row.dataType.parameterValues[index]==='') {
row.dataType.parameterValues[index] = 0;
}
})
const newData = [...dataRef.current];
const index = newData.findIndex((item) => editingKeyRef.current === item.name);
const newDataExcludeSelf = [...dataRef.current];
newDataExcludeSelf.splice(index, 1);
//判断字段名称是否唯一
let _index = (newDataExcludeSelf||[]).findIndex(item => item.name === row.name);
if (_index !== -1) {
form.setFields([{ name: 'name', errors: ['字段名称不能重复'] }]);
return false;
}
row.dataType = JSON.stringify(row.dataType);
const item = newData[index];
let attribute = { ...item, ...row};
newData.splice(index, 1, attribute);
setEditingKey(null);
editingKeyRef.current = null;
setData(newData);
dataRef.current = newData;
onChange && onChange(newData);
}
return true;
} catch (errInfo) {
console.log('Validate Failed:', errInfo);
return false;
}
};
const moveRow = useCallback(
(dragIndex, hoverIndex) => {
const dragRow = data[dragIndex];
const newData = update(data, {
$splice: [
[dragIndex, 1],
[hoverIndex, 0, dragRow],
],
});
setData(newData);
dataRef.current = newData;
onChange && onChange(newData);
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [data]);
const onTableRow = (record, index) => {
let rowParams = {
index,
id: `
field
-
$
{
record
.
name
}
`,
};
if (editable) {
if (!isEditing(record)) {
rowParams = {...rowParams, onClick: (event) => {
event.stopPropagation();
editItem(record);
}
}
if (keyword.length===0) {
rowParams = {...rowParams, moveRow};
}
}
}
return rowParams;
}
const mergedColumns = columns.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record) => ({
record,
dataIndex: col.dataIndex,
colTitle: col.title,
editing: isEditing(record),
datatypes: supportedDatatypes,
require: col.require
}),
};
});
return (
<div>
<div className='d-flex mb-3' style={{ justifyContent: 'space-between' }}>
<Space>
<h3 style={{ marginBottom: 0 }}>字段信息</h3>
{
editable && <Popover content='点击行进行编辑,表格可以通过拖拽来排序'>
<QuestionCircleOutlined className='pointer' />
</Popover>
}
</Space>
<Space>
{
editable && <Button onClick={onAddClick}>新建</Button>
}
<div className='d-flex' style={{ alignItems: 'center' }}>
<InputDebounce
placeholder="请输入中文名称或者英文名称"
allowClear
value={keyword}
onChange={onSearchInputChange}
style={{ width: inputWidth }}
/>
</div>
</Space>
</div>
<div id="containerId" ref={tableRef}>
<DndProvider backend={HTML5Backend} >
<Form form={form} component={false}>
<Table
rowKey='_id'
loading={loading}
dataSource={filterData}
columns={mergedColumns}
pagination={false}
components={{
body: {
cell: EditableCell,
//编辑或者搜索状态下不允许拖动
row: (editable&&editingKey===null&&keyword==='')?DragableBodyRow:null,
},
}}
onRow={onTableRow}
/>
</Form>
</DndProvider>
</div>
</div>
);
}
export default UpdateField;
\ No newline at end of file
src/view/Manage/DataMaster/Define/Component/UpdateNodeForm.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
{
useMemo
}
from
"react"
;
import
{
Form
,
Input
,
Radio
}
from
'antd'
;
const
UpdateNodeForm
=
(
props
)
=>
{
const
{
form
,
type
,
node
}
=
props
;
const
radioDisable
=
useMemo
(()
=>
{
return
!
node
;
},
[
node
])
const
formItemLayout
=
{
labelCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
6
},
},
wrapperCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
18
},
},
};
return
(
<
Form
{
...
formItemLayout
}
form=
{
form
}
>
{
type
===
'add'
&&
<
Form
.
Item
label=
"目录类型"
name=
"action"
>
<
Radio
.
Group
disabled=
{
radioDisable
}
>
<
Radio
value=
'root'
>
根目录
</
Radio
>
<
Radio
value=
'sub'
>
子目录
</
Radio
>
</
Radio
.
Group
>
</
Form
.
Item
>
}
<
Form
.
Item
label=
"名称"
name=
"name"
rules=
{
[{
required
:
true
,
message
:
'请输入名称!'
}]
}
>
<
Input
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"描述"
name=
"comment"
rules=
{
[{
required
:
true
,
message
:
'请输入描述!'
}]
}
>
<
Input
/>
</
Form
.
Item
>
</
Form
>
);
}
export
default
UpdateNodeForm
;
\ No newline at end of file
src/view/Manage/DataMaster/Define/Component/UpdateTemplateModal.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
React
,
{
useEffect
,
useMemo
,
useRef
,
useState
}
from
'react'
;
import
{
Modal
,
Form
,
Button
}
from
"antd"
;
import
UpdateBasicInfo
from
"./UpdateBasicInfo"
;
import
UpdateField
from
"./UpdateField"
;
import
{
showMessage
}
from
'../../../../../util'
;
import
{
dispatch
}
from
'../../../../../model'
;
import
'./UpdateTemplateModal.less'
;
export
const
EditTemplateContext
=
React
.
createContext
({
attrIsEditingFunction
:
null
,
});
export
const
UpdateTemplateModal
=
(
props
)
=>
{
const
{
visible
,
onCancel
,
action
=
'add'
,
template
,
nodeId
}
=
props
;
const
[
form
]
=
Form
.
useForm
();
const
[
fields
,
setFields
]
=
useState
([]);
const
[
confirmLoading
,
setConfirmLoading
]
=
useState
(
false
);
const
attrIsEditingRef
=
useRef
(
false
);
useEffect
(()
=>
{
if
(
visible
)
{
form
?.
setFieldsValue
({
name
:
template
?.
name
||
''
,
cnName
:
template
?.
cnName
||
''
,
comment
:
template
?.
comment
||
''
});
setFields
([]);
}
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
visible
])
const
title
=
useMemo
(()
=>
{
if
(
action
===
'add'
)
{
return
'新建模版'
;
}
if
(
action
===
'detail'
)
{
return
'模版详情'
;
}
if
(
action
===
'update'
)
{
return
'编辑模版'
;
}
return
''
;
},
[
action
])
const
attrIsEditingFunction
=
(
value
)
=>
{
attrIsEditingRef
.
current
=
value
;
}
const
onFieldChange
=
(
values
)
=>
{
setFields
(
values
);
}
const
save
=
(
e
)
=>
{
e
.
stopPropagation
();
if
(
attrIsEditingRef
.
current
)
{
showMessage
(
"warn"
,
'还有字段正在编辑,需先保存该字段!'
);
}
else
{
saveLogic
();
}
}
const
saveLogic
=
async
()
=>
{
try
{
const
row
=
await
form
.
validateFields
();
if
((
fields
||
[]).
length
===
0
)
{
showMessage
(
'warn'
,
'请新增字段'
);
return
;
}
setConfirmLoading
(
true
);
let
url
=
''
,
newTemplate
=
{};
if
(
action
===
'add'
)
{
url
=
'msd.addModel'
;
newTemplate
=
{...
row
,
nodeId
:
nodeId
||
''
};
}
else
{
url
=
'msd.updateModel'
;
newTemplate
=
{...
template
,
...
row
}
}
dispatch
({
type
:
url
,
payload
:
{
data
:
newTemplate
},
callback
:
id
=>
{
(
fields
||
[]).
forEach
((
field
,
index
)
=>
{
field
.
parentId
=
id
;
field
.
seq
=
index
;
});
dispatch
({
type
:
'msd.saveColumns'
,
payload
:
{
params
:
{
modelId
:
id
},
data
:
fields
},
callback
:
()
=>
{
setConfirmLoading
(
false
);
onCancel
&&
onCancel
(
true
);
},
error
:
()
=>
{
setConfirmLoading
(
false
);
}
});
},
error
:
()
=>
{
setConfirmLoading
(
false
);
}
});
}
catch
(
errInfo
)
{
console
.
log
(
'Validate Failed:'
,
errInfo
);
}
}
return
(
<
EditTemplateContext
.
Provider
value=
{
{
attrIsEditingFunction
,
}
}
>
<
Modal
forceRender
className=
'update-template-modal'
width=
'80%'
title=
{
title
}
visible=
{
visible
}
onCancel=
{
()
=>
{
onCancel
&&
onCancel
();}
}
onOk=
{
save
}
footer=
{
[
<
Button
key=
"cancel"
onClick=
{
()
=>
{
onCancel
&&
onCancel
();}
}
>
取消
</
Button
>,
action
!==
'detail'
&&
<
Button
key=
"ok"
type=
"primary"
loading=
{
confirmLoading
}
onClick=
{
save
}
>
确定
</
Button
>,
]
}
>
<
UpdateBasicInfo
form=
{
form
}
editable=
{
action
!==
'detail'
}
template=
{
template
}
/>
<
UpdateField
editable=
{
action
!==
'detail'
}
template=
{
template
}
onChange=
{
onFieldChange
}
visible=
{
visible
}
/>
</
Modal
>
</
EditTemplateContext
.
Provider
>
);
}
src/view/Manage/DataMaster/Define/Component/UpdateTemplateModal.less
deleted
100644 → 0
View file @
ee27b8a2
.update-template-modal {
.yy-modal-body {
max-height: 70vh;
overflow: auto;
}
.dynamic-delete-button {
position: relative;
top: 4px;
margin: 0 8px;
color: #999;
font-size: 24px;
cursor: pointer;
transition: all 0.3s;
}
.dynamic-delete-button:hover {
color: #777;
}
}
\ No newline at end of file
src/view/Manage/DataMaster/Define/index.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
{
useMemo
,
useState
}
from
'react'
;
import
classNames
from
'classnames'
;
import
{
ResizableBox
}
from
'react-resizable'
;
import
{
CaretLeftOutlined
,
CaretRightOutlined
}
from
'@ant-design/icons'
;
import
DefineTree
from
'./Component/DefineTree'
;
import
DefineTable
from
'./Component/DefineTable'
;
import
'./index.less'
;
const
DataMasterDefine
=
(
props
)
=>
{
const
[
collapse
,
setCollapse
]
=
useState
(
false
);
const
[
nodeId
,
setNodeId
]
=
useState
(
''
);
const
classes
=
useMemo
(()
=>
{
return
classNames
(
'data-master'
,
{
'data-master-collapse'
:
collapse
,
});
},
[
collapse
]);
const
onTreeClick
=
(
value
)
=>
{
setNodeId
(
value
);
}
const
onCollapseClick
=
()
=>
{
setCollapse
(
!
collapse
);
}
return
(
<
div
className=
{
classes
}
>
<
ResizableBox
className=
'left-wrap'
width=
{
230
}
height=
{
Infinity
}
axis=
'x'
minConstraints=
{
[
230
,
Infinity
]
}
maxConstraints=
{
[
Infinity
,
Infinity
]
}
>
<
DefineTree
onClick=
{
onTreeClick
}
/>
</
ResizableBox
>
<
div
className=
'left-collapse-wrap'
>
<
div
className=
'left-collapse'
onClick=
{
onCollapseClick
}
>
{
collapse
?
<
CaretRightOutlined
/>
:
<
CaretLeftOutlined
/>
}
</
div
>
</
div
>
<
div
className=
'right-wrap'
>
<
DefineTable
nodeId=
{
nodeId
}
/>
</
div
>
</
div
>
)
}
export
default
DataMasterDefine
;
\ No newline at end of file
src/view/Manage/DataMaster/Define/index.less
deleted
100644 → 0
View file @
ee27b8a2
.data-master {
display: flex;
flex: auto;
height: 100%;
background-color: #fff;
.left-wrap {
flex: none;
overflow: hidden;
height: 100%;
border-right: 1px solid #EFEFEF;
}
.left-collapse-wrap {
flex: none;
position: relative;
width: 20px;
height: 100%;
.left-collapse {
display: inline-flex;
justify-content: center;
align-items: center;
left: 0;
right: 0;
background: #f2f5fc;
position: absolute;
top: calc(50% - 40px);
width: 12px;
height: 80px;
border-radius: 0 12px 12px 0;
-ms-transform: translateY(-50%);
transform: translateY(-50%);
cursor: pointer;
}
}
.right-wrap {
flex: 1;
overflow: hidden;
height: 100%;
}
}
.data-master-collapse {
.left-wrap {
width: 0 !important;
}
}
\ No newline at end of file
src/view/Manage/DataMaster/Manage/Component/ImportDataDrawer.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
React
,
{
useState
,
useEffect
}
from
'react'
;
import
{
Button
,
Upload
,
Drawer
,
Pagination
,
Form
,
Spin
}
from
'antd'
;
import
{
UploadOutlined
,
DownloadOutlined
}
from
'@ant-design/icons'
;
import
ResizeableTable
from
'../../../ResizeableTable'
;
import
{
dispatch
,
dispatchLatest
}
from
'../../../../../model'
;
import
{
showMessage
,
formatDate
}
from
'../../../../../util'
;
const
ExpandedRow
=
(
props
)
=>
{
const
{
data
}
=
props
;
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
log
,
setLog
]
=
useState
({});
useEffect
(()
=>
{
getLog
();
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
data
])
const
getLog
=
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'msd.importLog'
,
payload
:
{
logId
:
data
?.
id
},
callback
:
data
=>
{
setLoading
(
false
);
setLog
(
data
||
{});
},
error
:
()
=>
{
setLoading
(
false
);
}
})
}
return
<
Spin
spinning=
{
loading
}
>
<
p
style=
{
{
margin
:
0
}
}
>
{
log
?.
message
||
''
}
</
p
>
</
Spin
>
}
const
ImportDataDrawer
=
(
props
)
=>
{
const
{
onCancel
,
onSuccess
,
visible
,
nodeId
}
=
props
;
const
[
fileList
,
setFileList
]
=
useState
([]);
const
[
confirmLoading
,
setConfirmLoading
]
=
useState
(
false
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
logs
,
setLogs
]
=
useState
([]);
const
[
pagination
,
setPagination
]
=
useState
(
{
pageNum
:
1
,
pageSize
:
20
}
);
const
{
pageNum
,
pageSize
}
=
pagination
;
const
[
total
,
setTotal
]
=
useState
(
0
);
const
columns
=
[
{
title
:
'序号'
,
dataIndex
:
'key'
,
render
:
(
text
,
record
,
index
)
=>
{
return
(
index
+
1
).
toString
();
},
width
:
60
,
ellipsis
:
true
,
},
{
title
:
'开始时间'
,
dataIndex
:
'startTime'
,
width
:
170
,
ellipsis
:
true
,
render
:
(
_
,
record
,
__
)
=>
{
return
formatDate
(
record
.
startTime
);
}
},
{
title
:
'结束时间'
,
dataIndex
:
'endTime'
,
width
:
170
,
ellipsis
:
true
,
render
:
(
_
,
record
,
__
)
=>
{
return
formatDate
(
record
.
endTime
);
}
},
{
title
:
'耗时'
,
dataIndex
:
'costTime'
,
width
:
100
,
ellipsis
:
true
,
render
:
(
_
,
record
,
__
)
=>
{
return
record
.
costTime
?
`
${
Number
(
record
.
costTime
/
1000
)}
秒`
:
''
;
}
},
{
title
:
'导入人'
,
dataIndex
:
'operator'
,
width
:
100
,
ellipsis
:
true
,
render
:
(
text
,
record
,
__
)
=>
{
return
text
.
split
(
':'
)[
0
];
}
},
{
title
:
'导入状态'
,
dataIndex
:
'state'
,
width
:
100
,
ellipsis
:
true
,
}
]
useEffect
(()
=>
{
if
(
visible
)
{
setPagination
({
pageNum
:
1
,
pageSize
:
20
});
}
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
visible
])
useEffect
(()
=>
{
if
(
visible
)
{
getLogs
();
}
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
pagination
])
const
getLogs
=
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'msd.importLogs'
,
payload
:
{
modelId
:
nodeId
,
page
:
pageNum
,
size
:
pageSize
},
callback
:
data
=>
{
setLoading
(
false
);
setTotal
(
data
.
totalElements
);
setLogs
(
data
.
content
||
[]);
},
error
:
()
=>
{
setLoading
(
false
);
}
})
}
const
onRefreshClick
=
()
=>
{
getLogs
();
}
const
changeCurrent
=
(
page
,
size
)
=>
{
setPagination
({
pageNum
:
page
,
pageSize
:
size
});
}
const
downloadTemplate
=
()
=>
{
window
.
open
(
`/api/metadatarepo/rest/msdMgr/exportTemplate?modelId=
${
nodeId
}
`
);
}
const
uploadProps
=
{
onRemove
:
file
=>
{
const
index
=
fileList
.
indexOf
(
file
);
const
newFileList
=
fileList
.
slice
();
newFileList
.
splice
(
index
,
1
);
setFileList
(
newFileList
);
},
beforeUpload
:
file
=>
{
setFileList
([
file
]);
return
false
;
},
fileList
:
fileList
||
[],
accept
:
".xlsx"
,
};
const
handleOk
=
()
=>
{
if
((
fileList
||
[]).
length
===
0
)
{
showMessage
(
'info'
,
'请先选择Excel文件上传'
);
return
;
}
setConfirmLoading
(
true
);
dispatchLatest
({
type
:
'msd.importData'
,
payload
:
{
params
:
{
modelId
:
nodeId
,
},
fileList
},
callback
:
data
=>
{
setConfirmLoading
(
false
);
setFileList
([]);
getLogs
();
onSuccess
&&
onSuccess
();
},
error
:
()
=>
{
setConfirmLoading
(
false
);
}
})
}
const
reset
=
()
=>
{
setConfirmLoading
(
false
);
setFileList
([]);
}
return
(
<
Drawer
forceRender
visible=
{
visible
}
title=
'主数据导入'
width=
{
1000
}
placement=
"right"
closable=
{
true
}
onClose=
{
()
=>
{
reset
();
onCancel
&&
onCancel
();
}
}
>
<
div
className=
'mt-3'
>
<
Form
layout=
'inline'
>
<
Form
.
Item
label=
'Excel上传:'
>
<
Upload
style=
{
{
display
:
'inline'
}
}
{
...
uploadProps
}
>
<
Button
icon=
{
<
UploadOutlined
/>
}
>
选择文件上传
</
Button
>
</
Upload
>
</
Form
.
Item
>
<
Form
.
Item
>
<
Button
type=
'primary'
onClick=
{
handleOk
}
loading=
{
confirmLoading
}
>
确定导入
</
Button
>
</
Form
.
Item
>
<
Form
.
Item
>
<
Button
icon=
{
<
DownloadOutlined
/>
}
onClick=
{
downloadTemplate
}
>
模版下载
</
Button
>
</
Form
.
Item
>
</
Form
>
</
div
>
<
div
className=
'd-flex my-3'
style=
{
{
justifyContent
:
'space-between'
,
alignItems
:
'center'
}
}
>
<
h3
style=
{
{
marginBottom
:
0
}
}
>
导入日志
</
h3
>
<
Button
onClick=
{
onRefreshClick
}
>
刷新
</
Button
>
</
div
>
<
ResizeableTable
className=
'mt-3'
columns=
{
columns
}
rowKey=
{
'id'
}
dataSource=
{
logs
||
[]
}
pagination=
{
false
}
loading=
{
loading
}
expandable=
{
{
expandedRowRender
:
record
=>
<
ExpandedRow
data=
{
record
}
/>
}
}
sticky
/>
<
Pagination
className=
"text-center mt-3"
showSizeChanger
showQuickJumper
onChange=
{
changeCurrent
}
onShowSizeChange=
{
changeCurrent
}
current=
{
pageNum
}
pageSize=
{
pageSize
}
defaultCurrent=
{
1
}
total=
{
total
}
pageSizeOptions=
{
[
10
,
20
]
}
showTotal=
{
total
=>
`共 ${total} 条`
}
/>
</
Drawer
>
)
}
export
default
ImportDataDrawer
;
\ No newline at end of file
src/view/Manage/DataMaster/Manage/Component/ManageTable.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
{
useMemo
,
useState
,
useEffect
}
from
'react'
;
import
{
Space
,
Button
,
Input
,
Pagination
,
Tooltip
}
from
'antd'
;
import
{
useContextMenu
,
Menu
as
RcMenu
,
Item
as
RcItem
}
from
"react-contexify"
;
import
ResizeableTable
from
'../../../ResizeableTable'
;
import
DebounceInput
from
'../../../Model/Component/DebounceInput'
;
import
UpdateDataMasterModal
from
'./UpdateDataMasterModal'
;
import
ImportDataDrawer
from
'./ImportDataDrawer'
;
import
{
inputWidth
,
showMessage
}
from
'../../../../../util'
;
import
{
dispatch
}
from
'../../../../../model'
;
import
'../../Define/Component/DefineTable.less'
;
import
'react-contexify/dist/ReactContexify.css'
;
const
InputDebounce
=
DebounceInput
(
300
)(
Input
);
const
ManageTable
=
(
props
)
=>
{
const
{
nodeId
}
=
props
;
const
[
keyword
,
setKeyword
]
=
useState
(
''
);
const
[
checkedKeys
,
setCheckedKeys
]
=
useState
([]);
const
[
isDataMasterModalVisible
,
setIsDataMasterModalVisible
]
=
useState
(
false
);
const
[
currentData
,
setCurrentData
]
=
useState
(
null
);
const
[
action
,
setAction
]
=
useState
(
''
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
deleteLoading
,
setDeleteLoading
]
=
useState
(
false
);
const
[
fields
,
setFields
]
=
useState
([]);
const
[
tableData
,
setTableData
]
=
useState
([]);
const
[
total
,
setTotal
]
=
useState
(
0
);
const
[
pagination
,
setPagination
]
=
useState
({
pageNum
:
1
,
pageSize
:
20
});
const
[
importDataDrawerVisible
,
setImportDataDrawerVisible
]
=
useState
(
false
);
const
{
pageNum
,
pageSize
}
=
pagination
;
const
columns
=
useMemo
(()
=>
{
const
newColumns
=
[
{
title
:
'序号'
,
dataIndex
:
'key'
,
render
:
(
text
,
record
,
index
)
=>
{
return
(
index
+
1
).
toString
();
},
width
:
60
,
ellipsis
:
true
,
}
];
(
fields
||
[]).
forEach
(
item
=>
{
newColumns
.
push
({
title
:
item
.
name
,
dataIndex
:
item
.
name
,
width
:
200
,
ellipsis
:
true
,
});
})
return
newColumns
;
},
[
fields
]);
const
MENU_ID
=
'data-master-manage-table-contextmenu'
;
const
{
show
}
=
useContextMenu
({
id
:
MENU_ID
,
});
useEffect
(()
=>
{
setCheckedKeys
([]);
setPagination
({...
pagination
,
pageNum
:
1
});
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
nodeId
])
useEffect
(()
=>
{
if
(
!
nodeId
||
nodeId
===
''
)
{
setFields
([]);
setTableData
([]);
setTotal
(
0
);
}
else
{
getFiledsAndDatas
();
}
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
keyword
,
pagination
])
const
getFiledsAndDatas
=
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'msd.getColumns'
,
payload
:
{
params
:
{
modelId
:
nodeId
}
},
callback
:
(
data
)
=>
{
setFields
(
data
||
[]);
const
newKeyList
=
[];
(
data
||
[]).
forEach
(
item
=>
{
newKeyList
.
push
(
item
.
name
||
''
);
});
dispatch
({
type
:
'msd.getDatas'
,
payload
:
{
params
:
{
modelId
:
nodeId
,
keyList
:
newKeyList
.
join
(
','
),
keyword
,
pageNum
,
pageSize
}
},
callback
:
(
data
)
=>
{
setLoading
(
false
);
setTableData
(
data
?.
content
||
[]);
setTotal
(
data
?.
totalElements
||
0
);
},
error
:
()
=>
{
setLoading
(
false
);
}
});
},
error
:
()
=>
{
setLoading
(
false
);
}
});
}
const
onAddClick
=
()
=>
{
setAction
(
'add'
);
setCurrentData
(
null
);
setIsDataMasterModalVisible
(
true
);
}
const
onImportClick
=
()
=>
{
setImportDataDrawerVisible
(
true
);
}
const
onDataMasterModalCancel
=
(
refresh
=
false
)
=>
{
setIsDataMasterModalVisible
(
false
);
if
(
refresh
)
{
getFiledsAndDatas
();
}
}
const
onBatchDeleteClick
=
()
=>
{
setDeleteLoading
(
true
);
dispatch
({
type
:
'msd.deleteDatas'
,
payload
:
{
data
:
checkedKeys
||
[]
},
callback
:
(
data
)
=>
{
setDeleteLoading
(
false
);
showMessage
(
'success'
,
'删除成功'
);
getFiledsAndDatas
();
},
error
:
()
=>
{
setDeleteLoading
(
false
);
}
});
}
const
onSearchInputChange
=
(
value
)
=>
{
setKeyword
(
value
);
}
const
onTableSelectChange
=
keys
=>
{
setCheckedKeys
(
keys
);
};
const
handleItemClick
=
({
event
,
props
,
data
,
triggerEvent
})
=>
{
const
key
=
event
.
currentTarget
.
id
;
if
(
key
===
'detail'
)
{
setAction
(
'detail'
);
setIsDataMasterModalVisible
(
true
);
}
if
(
key
===
'update'
)
{
setAction
(
'update'
);
setIsDataMasterModalVisible
(
true
);
}
}
const
changeCurrent
=
(
page
,
size
)
=>
{
setCheckedKeys
([]);
setPagination
({
pageNum
:
page
,
pageSize
:
size
});
}
const
onImportDataDrawerCancel
=
()
=>
{
setImportDataDrawerVisible
(
false
);
}
const
onImportDataSuccess
=
()
=>
{
getFiledsAndDatas
();
}
const
rowSelection
=
{
selectedRowKeys
:
checkedKeys
,
onChange
:
onTableSelectChange
,
};
return
(
<
div
className=
'data-master-table'
>
<
div
className=
'data-master-header px-3'
>
<
Space
>
<
Space
>
<
Button
onClick=
{
onAddClick
}
>
新建
</
Button
>
</
Space
>
<
Space
>
<
Button
onClick=
{
onImportClick
}
>
导入
</
Button
>
</
Space
>
<
Space
>
<
Tooltip
title=
{
(
checkedKeys
||
[]).
length
===
0
?
'请先选择主数据'
:
''
}
>
<
Button
onClick=
{
onBatchDeleteClick
}
disabled=
{
(
checkedKeys
||
[]).
length
===
0
}
loading=
{
deleteLoading
}
>
删除
</
Button
>
</
Tooltip
>
</
Space
>
</
Space
>
<
InputDebounce
placeholder=
"请输入关键字"
allowClear
value=
{
keyword
}
onChange=
{
onSearchInputChange
}
style=
{
{
width
:
inputWidth
,
marginLeft
:
'auto'
}
}
/>
</
div
>
<
div
className=
'data-master-content p-3'
>
<
ResizeableTable
rowKey=
'_id'
loading=
{
loading
}
rowSelection=
{
rowSelection
}
columns=
{
columns
}
dataSource=
{
tableData
}
onRow=
{
(
record
)
=>
{
return
{
onContextMenu
:
event
=>
{
setCurrentData
(
record
);
show
(
event
);
},
};
}
}
pagination=
{
false
}
scroll=
{
{
y
:
'calc(100vh - 94px - 32px - 57px - 24px - 39px - 36px)'
}
}
/>
<
Pagination
size=
"small"
className=
"text-center m-3"
showSizeChanger
showQuickJumper
onChange=
{
changeCurrent
}
onShowSizeChange=
{
changeCurrent
}
current=
{
pageNum
}
pageSize=
{
pageSize
}
defaultCurrent=
{
1
}
total=
{
total
}
showTotal=
{
total
=>
`共 ${total} 条`
}
/>
</
div
>
<
UpdateDataMasterModal
action=
{
action
}
data=
{
currentData
}
fields=
{
fields
}
nodeId=
{
nodeId
}
visible=
{
isDataMasterModalVisible
}
onCancel=
{
onDataMasterModalCancel
}
/>
<
ImportDataDrawer
visible=
{
importDataDrawerVisible
}
nodeId=
{
nodeId
}
onCancel=
{
onImportDataDrawerCancel
}
onSuccess=
{
onImportDataSuccess
}
/>
<
RcMenu
id=
{
MENU_ID
}
>
<
RcItem
id=
"detail"
onClick=
{
handleItemClick
}
>
详情
</
RcItem
>
<
RcItem
id=
"update"
onClick=
{
handleItemClick
}
>
编辑
</
RcItem
>
</
RcMenu
>
</
div
>
);
}
export
default
ManageTable
;
\ No newline at end of file
src/view/Manage/DataMaster/Manage/Component/ManageTree.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
{
useEffect
,
useMemo
,
useState
,
useRef
}
from
'react'
;
import
{
Tooltip
,
Spin
,
AutoComplete
,
Tree
}
from
'antd'
;
import
{
ReloadOutlined
}
from
'@ant-design/icons'
;
import
{
dispatch
}
from
'../../../../../model'
;
import
{
highlightSearchContentByTerms
}
from
'../../../../../util'
;
import
'../../Define/Component/DefineTree.less'
;
const
{
Option
}
=
AutoComplete
;
const
ManageTree
=
(
props
)
=>
{
const
{
onClick
}
=
props
;
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
data
,
setData
]
=
useState
();
const
[
options
,
setOptions
]
=
useState
([]);
const
[
keyword
,
setKeyword
]
=
useState
(
''
);
const
[
expandedKeys
,
setExpandedKeys
]
=
useState
([]);
const
[
selectedKeys
,
setSelectedKeys
]
=
useState
([]);
const
[
autoExpandParent
,
setAutoExpandParent
]
=
useState
(
false
);
const
selectedKeysRef
=
useRef
([]);
useEffect
(()
=>
{
getTreeNodes
();
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[])
const
treeData
=
useMemo
(()
=>
{
const
loop
=
(
data
)
=>
(
data
||
[]).
map
((
item
)
=>
{
if
(
item
.
children
)
{
return
{
title
:
item
.
name
||
''
,
key
:
item
.
_id
||
''
,
origin
:
item
,
children
:
loop
(
item
.
children
),
};
}
return
{
title
:
item
.
name
||
''
,
key
:
item
.
_id
||
''
,
};
});
return
loop
(
data
);
},
[
data
])
const
treeList
=
useMemo
(()
=>
{
const
generateList
=
(
data
,
list
,
path
=
null
)
=>
{
(
data
||
[]).
forEach
(
node
=>
{
const
{
_id
,
name
}
=
node
;
const
currentPath
=
path
?
`
${
path
}
/
${
name
}
`
:
name
;
list
.
push
({
key
:
_id
,
title
:
currentPath
});
if
(
node
.
children
)
{
generateList
(
node
.
children
,
list
,
currentPath
);
}
});
};
const
newTreeList
=
[];
generateList
(
data
,
newTreeList
);
return
newTreeList
;
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
data
])
const
getTreeNodes
=
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'msd.getMgrTreeNodes'
,
callback
:
(
data
)
=>
{
setLoading
(
false
);
setData
(
data
||
[]);
const
firstModelNodeId
=
findFirstModelNode
(
data
||
[]);
if
((
selectedKeysRef
.
current
||
[]).
length
===
0
&&
(
data
||
[]).
length
>
0
)
{
onTreeSelect
([
firstModelNodeId
]);
}
if
((
expandedKeys
||
[]).
length
===
0
&&
(
data
||
[]).
length
>
0
)
{
setExpandedKeys
([
firstModelNodeId
]);
setAutoExpandParent
(
true
);
}
else
{
setExpandedKeys
(
Array
.
from
(
new
Set
([...
expandedKeys
,
...
selectedKeysRef
.
current
])));
setAutoExpandParent
(
true
);
}
},
error
:
()
=>
{
setLoading
(
false
);
}
})
}
const
onRefreshClick
=
()
=>
{
getTreeNodes
();
}
const
onAutoCompleteSearch
=
(
searchText
)
=>
{
setKeyword
(
searchText
);
setOptions
(
treeList
.
filter
(
item
=>
item
.
title
.
indexOf
(
searchText
)
!==-
1
));
};
const
onAutoCompleteSelect
=
(
value
,
option
)
=>
{
const
paths
=
value
.
split
(
'/'
);
setKeyword
(
paths
[
paths
.
length
-
1
]);
if
(
isModelNode
(
option
.
key
))
{
onTreeSelect
([
option
.
key
]);
}
setExpandedKeys
(
Array
.
from
(
new
Set
([...
expandedKeys
,
option
.
key
])));
setAutoExpandParent
(
true
);
};
const
onAutoCompleteClear
=
()
=>
{
setKeyword
(
''
);
}
const
onTreeExpand
=
(
expandedKeys
)
=>
{
setExpandedKeys
(
expandedKeys
);
setAutoExpandParent
(
false
);
}
const
onTreeSelect
=
(
selectedKeys
,
e
=
null
)
=>
{
if
(
selectedKeys
.
length
===
0
)
{
return
;
}
if
(
e
&&
e
?.
node
&&
!
isModelNode
(
e
?.
node
?.
key
))
{
return
;
}
setSelectedKeys
(
selectedKeys
);
selectedKeysRef
.
current
=
selectedKeys
;
onClick
&&
onClick
(
selectedKeys
[
0
]);
}
const
isModelNode
=
(
value
)
=>
{
return
((
value
||
''
).
indexOf
(
'Model='
)
!==
-
1
);
}
const
findFirstModelNode
=
(
values
)
=>
{
const
generateList
=
(
data
,
list
)
=>
{
(
data
||
[]).
forEach
(
node
=>
{
list
.
push
(
node
);
if
(
node
.
children
)
{
generateList
(
node
.
children
,
list
);
}
});
};
const
newTreeList
=
[];
generateList
(
values
,
newTreeList
);
let
firstModelNodeId
=
''
;
newTreeList
.
some
(
item
=>
{
if
(
isModelNode
(
item
.
_id
))
{
firstModelNodeId
=
item
.
_id
;
}
return
isModelNode
(
item
.
_id
);
})
return
firstModelNodeId
;
}
return
(
<
div
className=
'data-master-tree'
>
<
div
className=
'header p-3'
>
<
Tooltip
title=
"刷新目录"
className=
'ml-2'
>
<
ReloadOutlined
className=
'default'
onClick=
{
onRefreshClick
}
style=
{
{
fontSize
:
16
,
cursor
:
'pointer'
,
flex
:
1
}
}
/>
</
Tooltip
>
<
div
style=
{
{
flex
:
3
}
}
/>
</
div
>
<
div
className=
'content p-3'
>
<
Spin
spinning=
{
loading
}
>
<
AutoComplete
className=
'content-search'
allowClear
value=
{
keyword
}
onSelect=
{
onAutoCompleteSelect
}
onSearch=
{
onAutoCompleteSearch
}
onClear=
{
onAutoCompleteClear
}
>
{
(
options
||
[]).
map
((
item
,
index
)
=>
{
return
(
<
Option
key=
{
item
.
key
}
value=
{
item
.
title
}
>
<
div
style=
{
{
whiteSpace
:
'normal'
}
}
>
{
highlightSearchContentByTerms
(
item
.
title
,
[
keyword
])
}
</
div
>
</
Option
>
);
})
}
</
AutoComplete
>
<
Tree
className=
'content-tree'
showLine
showIcon=
{
false
}
autoExpandParent=
{
autoExpandParent
}
treeData=
{
treeData
}
onExpand=
{
onTreeExpand
}
onSelect=
{
onTreeSelect
}
expandedKeys=
{
expandedKeys
}
selectedKeys=
{
selectedKeys
}
/>
</
Spin
>
</
div
>
</
div
>
);
}
export
default
ManageTree
;
\ No newline at end of file
src/view/Manage/DataMaster/Manage/Component/UpdateDataMasterModal.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
{
useEffect
,
useState
,
useMemo
}
from
"react"
;
import
{
Modal
,
Form
,
Input
,
Button
,
Descriptions
}
from
"antd"
;
import
{
dispatch
}
from
"../../../../../model"
;
import
'./UpdateDataMasterModal.less'
;
const
UpdateDataMasterModal
=
(
props
)
=>
{
const
{
visible
,
onCancel
,
data
,
fields
,
action
=
'add'
,
nodeId
}
=
props
;
const
[
confirmLoading
,
setConfirmLoading
]
=
useState
(
false
);
const
[
form
]
=
Form
.
useForm
();
const
formItemLayout
=
{
labelCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
6
},
},
wrapperCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
18
},
},
};
useEffect
(()
=>
{
if
(
visible
)
{
let
newFieldsValue
=
{};
(
fields
||
[]).
forEach
(
item
=>
{
newFieldsValue
[
item
.
name
]
=
data
?
data
[
item
.
name
]:
''
;
});
form
?.
setFieldsValue
(
newFieldsValue
);
}
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
visible
,
data
,
fields
])
const
title
=
useMemo
(()
=>
{
if
(
action
===
'add'
)
{
return
'新建主数据'
;
}
if
(
action
===
'detail'
)
{
return
'主数据详情'
;
}
if
(
action
===
'update'
)
{
return
'编辑主数据'
;
}
return
''
;
},
[
action
])
const
onFormFinish
=
async
()
=>
{
try
{
const
row
=
await
form
.
validateFields
();
setConfirmLoading
(
true
);
let
url
=
''
,
newData
=
{};
if
(
action
===
'add'
)
{
url
=
'msd.addData'
;
newData
=
row
;
}
else
{
url
=
'msd.updateData'
;
newData
=
{...
data
,
...
row
};
}
dispatch
({
type
:
url
,
payload
:
{
params
:
{
modelId
:
nodeId
,
},
data
:
newData
},
callback
:
()
=>
{
setConfirmLoading
(
false
);
onCancel
&&
onCancel
(
true
);
},
error
:
()
=>
{
setConfirmLoading
(
false
);
}
});
}
catch
(
errInfo
)
{
console
.
log
(
'Validate Failed:'
,
errInfo
);
}
}
return
(
<
Modal
className=
'update-data-master-modal'
title=
{
title
}
visible=
{
visible
}
onCancel=
{
()
=>
{
onCancel
&&
onCancel
(
false
);
}
}
onOk=
{
onFormFinish
}
footer=
{
[
<
Button
key=
"cancel"
onClick=
{
()
=>
{
onCancel
&&
onCancel
();}
}
>
取消
</
Button
>,
action
!==
'detail'
&&
<
Button
key=
"ok"
type=
"primary"
loading=
{
confirmLoading
}
onClick=
{
onFormFinish
}
>
确定
</
Button
>,
]
}
>
{
(
action
!==
'detail'
)
?
<
Form
form=
{
form
}
{
...
formItemLayout
}
>
{
(
fields
||
[]).
map
((
item
,
index
)
=>
{
return
(
<
Form
.
Item
key=
{
index
}
label=
{
item
.
name
}
name=
{
item
.
name
}
rules=
{
[{
required
:
false
}]
}
>
<
Input
/>
</
Form
.
Item
>
)
})
}
</
Form
>
:
<
Descriptions
column=
{
1
}
>
{
(
fields
||
[]).
map
((
item
,
index
)
=>
{
return
(
<
Descriptions
.
Item
label=
{
<
div
style=
{
{
textAlign
:
'right'
,
width
:
85
}
}
>
{
item
.
name
||
''
}
</
div
>
}
>
{
data
?
data
[
item
.
name
||
''
]:
''
}
</
Descriptions
.
Item
>
);
})
}
</
Descriptions
>
}
</
Modal
>
);
}
export
default
UpdateDataMasterModal
;
\ No newline at end of file
src/view/Manage/DataMaster/Manage/Component/UpdateDataMasterModal.less
deleted
100644 → 0
View file @
ee27b8a2
.update-data-master-modal {
.yy-modal-body {
max-height: 70vh;
overflow: auto;
}
}
\ No newline at end of file
src/view/Manage/DataMaster/Manage/index.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
{
useMemo
,
useState
}
from
'react'
;
import
classNames
from
'classnames'
;
import
{
ResizableBox
}
from
'react-resizable'
;
import
{
CaretLeftOutlined
,
CaretRightOutlined
}
from
'@ant-design/icons'
;
import
ManageTree
from
'./Component/ManageTree'
;
import
ManageTable
from
'./Component/ManageTable'
;
import
'../Define/index.less'
;
const
DataMasterManage
=
(
props
)
=>
{
const
[
collapse
,
setCollapse
]
=
useState
(
false
);
const
[
nodeId
,
setNodeId
]
=
useState
(
''
);
const
classes
=
useMemo
(()
=>
{
return
classNames
(
'data-master'
,
{
'data-master-collapse'
:
collapse
,
});
},
[
collapse
]);
const
onTreeClick
=
(
value
)
=>
{
setNodeId
(
value
);
}
const
onCollapseClick
=
()
=>
{
setCollapse
(
!
collapse
);
}
return
(
<
div
className=
{
classes
}
>
<
ResizableBox
className=
'left-wrap'
width=
{
230
}
height=
{
Infinity
}
axis=
'x'
minConstraints=
{
[
230
,
Infinity
]
}
maxConstraints=
{
[
Infinity
,
Infinity
]
}
>
<
ManageTree
onClick=
{
onTreeClick
}
/>
</
ResizableBox
>
<
div
className=
'left-collapse-wrap'
>
<
div
className=
'left-collapse'
onClick=
{
onCollapseClick
}
>
{
collapse
?
<
CaretRightOutlined
/>
:
<
CaretLeftOutlined
/>
}
</
div
>
</
div
>
<
div
className=
'right-wrap'
>
<
ManageTable
nodeId=
{
nodeId
}
/>
</
div
>
</
div
>
)
}
export
default
DataMasterManage
;
\ No newline at end of file
src/view/Manage/DataMaster/Manage/index.less
deleted
100644 → 0
View file @
ee27b8a2
src/view/Manage/Model/Component/ColSettingModal.jsx
View file @
82cac42b
...
...
@@ -2,40 +2,50 @@ import { useState, useEffect } from 'react';
import
{
Modal
,
Button
,
Switch
,
Row
,
Col
,
Checkbox
,
Typography
}
from
'antd'
;
import
{
dispatch
}
from
'../../../../model'
;
const
cols
=
[
{
title
:
'模型名称'
,
require
:
true
},
{
title
:
'中文名称'
},
{
title
:
'路径'
},
{
title
:
'状态'
},
{
title
:
'创建人'
},
{
title
:
'版本号'
},
{
title
:
'模型描述'
},
];
import
{
showMessage
}
from
'../../../../util'
;
const
ColSettingModal
=
(
props
)
=>
{
const
{
visible
,
onCancel
}
=
props
;
const
[
loadingAttrs
,
setLoadingAttrs
]
=
useState
(
false
);
const
[
attrs
,
setAttrs
]
=
useState
(
undefined
);
const
[
catagories
,
setCatagories
]
=
useState
(
undefined
);
const
[
checkedKeys
,
setCheckedKeys
]
=
useState
([]);
const
[
confirmLoading
,
setConfirmLoading
]
=
useState
(
false
);
useEffect
(()
=>
{
if
(
visible
)
{
getAttrs
();
getPreference
();
}
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
visible
]);
const
getPreference
=
()
=>
{
const
getAttrs
=
()
=>
{
setLoadingAttrs
(
true
);
dispatch
({
type
:
'datamodel.getPreference'
,
type
:
'pds.getAttrs'
,
payload
:
{
modelName
:
'DataService'
},
callback
:
data
=>
{
if
((
data
.
cols
||
''
)
===
''
)
{
onCheckAllChange
(
true
);
}
else
{
setCheckedKeys
(
data
.
cols
.
split
(
','
));
setAttrs
(
data
);
setCatagories
(
Array
.
from
(
new
Set
((
data
||
[]).
map
(
item
=>
item
.
status
))));
setLoadingAttrs
(
false
);
},
error
:
()
=>
{
setLoadingAttrs
(
false
);
}
})
}
const
getPreference
=
()
=>
{
dispatch
({
type
:
'pds.getCols'
,
payload
:
{
modelName
:
'DataService'
},
callback
:
data
=>
{
setCheckedKeys
(
data
?.
map
(
item
=>
item
.
titleCnName
));
}
})
}
...
...
@@ -44,14 +54,8 @@ const ColSettingModal = (props) => {
const
newCheckedKeys
=
[];
if
(
checked
)
{
cols
.
forEach
(
col
=>
{
newCheckedKeys
.
push
(
col
.
title
);
});
}
else
{
cols
.
forEach
(
col
=>
{
if
(
col
.
require
)
{
newCheckedKeys
.
push
(
col
.
title
);
}
attrs
?.
forEach
(
col
=>
{
newCheckedKeys
.
push
(
col
.
name
);
});
}
...
...
@@ -74,17 +78,24 @@ const ColSettingModal = (props) => {
}
const
onModalOk
=
()
=>
{
if
((
checkedKeys
||
[]).
length
===
0
)
{
showMessage
(
'warn'
,
'不可进行全不选操作'
);
return
;
}
setConfirmLoading
(
true
);
dispatch
({
type
:
'
datamodel.savePreference
'
,
type
:
'
pds.saveCols
'
,
payload
:
{
data
:
{
cols
:
checkedKeys
.
join
(
','
)
}
params
:
{
modelName
:
'DataService'
},
data
:
checkedKeys
?.
map
(
item
=>
{
return
{
titleCnName
:
item
}
})
},
callback
:
()
=>
{
setConfirmLoading
(
false
);
onCancel
&&
onCancel
(
true
);
showMessage
(
'success'
,
'操作成功'
);
},
error
:
()
=>
{
setConfirmLoading
(
false
);
...
...
@@ -123,16 +134,24 @@ const ColSettingModal = (props) => {
/>
</
div
>
<
div
className=
'mt-3'
style=
{
{
maxHeight
:
450
,
overflow
:
'auto'
}
}
>
{
catagories
?.
map
((
catagory
,
index
)
=>
{
return
(
<
div
key=
{
index
}
>
<
div
className=
'flex'
style=
{
{
alignItems
:
'center'
,
padding
:
'5px 0 15px'
}
}
>
<
div
style=
{
{
width
:
3
,
height
:
14
,
backgroundColor
:
'#0069AC'
,
marginRight
:
5
}
}
/>
<
span
style=
{
{
fontWeight
:
'bold'
,
color
:
'#464646'
}
}
>
{
catagory
}
</
span
>
</
div
>
<
Row
>
{
cols
.
map
((
col
,
index
)
=>
{
attrs
?.
filter
(
col
=>
col
.
status
===
catagory
)?
.
map
((
col
,
index
)
=>
{
return
(
<
Col
className=
'mb-3'
key=
{
index
}
md=
{
6
}
>
<
div
className=
'd-flex'
>
<
Checkbox
checked=
{
checkedKeys
.
indexOf
(
col
.
title
||
''
)
!==-
1
}
value=
{
col
.
title
}
onChange=
{
onCheckChange
}
disabled=
{
col
.
requir
e
}
>
<
Checkbox
checked=
{
checkedKeys
.
indexOf
(
col
.
name
||
''
)
!==-
1
}
value=
{
col
.
name
}
onChange=
{
onCheckChang
e
}
>
</
Checkbox
>
<
Typography
.
Paragraph
className=
'ml-1'
title=
{
col
.
titl
e
}
ellipsis
>
{
col
.
titl
e
}
<
Typography
.
Paragraph
className=
'ml-1'
title=
{
col
.
nam
e
}
ellipsis
>
{
col
.
nam
e
}
</
Typography
.
Paragraph
>
</
div
>
</
Col
>
...
...
@@ -141,6 +160,10 @@ const ColSettingModal = (props) => {
}
</
Row
>
</
div
>
)
})
}
</
div
>
</
Modal
>
)
}
...
...
src/view/Manage/Model/Component/ExchangeOwner.jsx
0 → 100644
View file @
82cac42b
import
React
,
{
useState
,
useEffect
}
from
'react'
;
import
{
Modal
,
Button
,
Form
,
Descriptions
,
Space
,
Spin
}
from
'antd'
;
import
{
dispatch
}
from
'../../../../model'
;
import
SelectUsers
from
'./SelectUsers'
;
import
'./ExchangeOwner.less'
;
const
FC
=
({
visible
,
id
,
onCancel
})
=>
{
const
[
service
,
setService
]
=
useState
(
undefined
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
loadingOwners
,
setLoadingOwners
]
=
useState
(
false
);
const
[
owners
,
setOwners
]
=
useState
(
undefined
);
const
[
currentOwner
,
setCurrentOwner
]
=
useState
(
undefined
);
useEffect
(()
=>
{
if
(
visible
)
{
getService
();
getOwners
();
}
},
[
visible
,
id
])
const
getService
=
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'pds.getDataService'
,
payload
:
{
id
},
callback
:
(
data
)
=>
{
setLoading
(
false
);
setService
(
data
);
setCurrentOwner
(
data
?.
editor
);
},
error
:
()
=>
{
setLoading
(
false
);
}
})
}
const
getOwners
=
()
=>
{
setLoadingOwners
(
true
);
dispatch
({
type
:
'pds.getOwners'
,
callback
:
(
data
)
=>
{
setLoadingOwners
(
false
);
setOwners
(
data
);
},
error
:
()
=>
{
setLoadingOwners
(
false
);
}
})
}
const
onOwnerChange
=
(
value
)
=>
{
setCurrentOwner
(
value
);
if
(
value
)
{
dispatch
({
type
:
'pds.saveOwner'
,
payload
:
{
jobNumber
:
value
}
})
}
}
const
cancel
=
(
refresh
=
false
)
=>
{
reset
();
onCancel
?.(
refresh
);
}
const
onOk
=
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'pds.changeOwner'
,
payload
:
{
params
:
{
id
,
ownerName
:
currentOwner
}
},
callback
:
()
=>
{
setLoading
(
false
);
cancel
(
true
);
},
error
:
()
=>
{
setLoading
(
false
);
}
})
}
const
reset
=
()
=>
{
setService
(
undefined
);
setLoading
(
false
);
setLoadingOwners
(
false
);
}
const
footer
=
[
<
Button
key=
"0"
onClick=
{
()
=>
{
cancel
()
}
}
>
取消
</
Button
>,
<
Button
key=
"1"
type=
"primary"
onClick=
{
onOk
}
>
确定
</
Button
>,
];
return
(
<
Modal
className=
'exchange-owner'
visible=
{
visible
}
title=
'更换管理人'
width=
{
800
}
destroyOnClose
onCancel=
{
()
=>
{
cancel
()
}
}
footer=
{
footer
}
>
<
Spin
spinning=
{
loading
}
>
<
Descriptions
title=
{
<
Space
>
<
div
style=
{
{
height
:
18
,
width
:
3
,
background
:
'rgb(2, 105, 172)'
}
}
></
div
>
<
div
>
基本信息
</
div
>
</
Space
>
}
>
<
Descriptions
.
Item
label=
"数据服务名称"
>
{
service
?.
name
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
"数据服务技术名称"
>
{
service
?.
cnName
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
"数据服务描述"
>
{
service
?.
remark
}
</
Descriptions
.
Item
>
</
Descriptions
>
<
Descriptions
title=
{
<
Space
>
<
div
style=
{
{
height
:
18
,
width
:
3
,
background
:
'rgb(2, 105, 172)'
}
}
></
div
>
<
div
>
提供方信息
</
div
>
</
Space
>
}
/>
<
Space
>
<
div
>
管理人:
</
div
>
<
div
style=
{
{
width
:
200
}
}
>
<
SelectUsers
type=
'edit'
loading=
{
loadingOwners
}
users=
{
owners
}
value=
{
currentOwner
}
onChange=
{
onOwnerChange
}
/>
</
div
>
</
Space
>
</
Spin
>
</
Modal
>
)
}
export
default
FC
;
\ No newline at end of file
src/view/Manage/Model/Component/ExchangeOwner.less
0 → 100644
View file @
82cac42b
.exchange-owner {
.yy-descriptions-header {
margin-bottom: 5px;
}
}
\ No newline at end of file
src/view/Manage/Model/Component/ExpandedModelTable.jsx
View file @
82cac42b
...
...
@@ -30,14 +30,14 @@ const ModelNameColumn = (props) => {
ellipsis
:
true
,
},
{
title
:
'
字段中文
名称'
,
title
:
'名称'
,
width
:
160
,
dataIndex
:
'cnName'
,
editable
:
true
,
ellipsis
:
true
,
},
{
title
:
'
字段英文名称
'
,
title
:
'
技术ID(英文名称)
'
,
width
:
160
,
dataIndex
:
'name'
,
editable
:
true
,
...
...
@@ -193,7 +193,7 @@ const ExpandedModelTable = (props) => {
}
},
{
title
:
'
创建
人'
,
title
:
'
管理
人'
,
dataIndex
:
'editor'
,
width
:
100
,
ellipsis
:
true
,
...
...
src/view/Manage/Model/Component/GrantedList.jsx
0 → 100644
View file @
82cac42b
import
React
,
{
useEffect
,
useState
,
useContext
,
useMemo
}
from
'react'
;
import
{
Spin
,
Tooltip
,
Typography
,
Pagination
,
Table
}
from
'antd'
;
import
{
AppContext
}
from
'../../../../App'
;
import
{
dispatch
}
from
'../../../../model'
;
import
{
paginate
}
from
'../../../../util'
;
const
FC
=
(
props
)
=>
{
const
app
=
useContext
(
AppContext
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
data
,
setData
]
=
useState
([]);
const
[
pagination
,
setPagination
]
=
useState
({
pageNum
:
1
,
pageSize
:
20
});
const
{
pageNum
,
pageSize
}
=
pagination
;
const
cols
=
[
{
title
:
'序号'
,
dataIndex
:
'key'
,
render
:
(
text
,
record
,
index
)
=>
{
return
(
index
+
1
).
toString
();
},
width
:
60
,
ellipsis
:
true
,
},
{
title
:
'数据服务资产编码'
,
dataIndex
:
'code'
,
ellipsis
:
true
,
render
:
(
_
,
record
)
=>
record
.
basicInfo
?.
code
},
{
title
:
'数据服务名称'
,
dataIndex
:
'name'
,
ellipsis
:
true
,
render
:
(
_
,
record
)
=>
record
.
basicInfo
?.
name
},
{
title
:
'URI'
,
dataIndex
:
'odata'
,
ellipsis
:
true
,
render
:
(
text
,
_
,
__
)
=>
{
return
(
<
React
.
Fragment
>
{
text
?
<
div
className=
'flex'
>
<
Tooltip
title=
{
text
||
''
}
overlayClassName=
'tooltip-common'
>
<
Typography
.
Text
ellipsis=
{
true
}
>
{
text
||
''
}
</
Typography
.
Text
>
</
Tooltip
>
<
Typography
.
Text
copyable=
{
{
text
}
}
></
Typography
.
Text
>
</
div
>
:
''
}
</
React
.
Fragment
>
);
}
},
{
title
:
'操作'
,
dataIndex
:
'action'
,
width
:
80
,
fixed
:
'right'
,
render
:
(
_
,
record
)
=>
{
return
(
<
a
onClick=
{
()
=>
{
app
.
openDetail
?.({
service
:
record
})
}
}
>
详情
</
a
>
)
}
}
];
useEffect
(()
=>
{
getServices
();
},
[])
const
tableData
=
useMemo
(()
=>
{
if
(
data
)
{
return
paginate
(
data
,
pagination
.
pageNum
,
pagination
.
pageSize
);
}
return
[];
},
[
data
,
pagination
])
const
getServices
=
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'pds.getGrantedServices'
,
payload
:
{
namespace
:
`
${
app
?.
env
?.
domainId
}
`
},
callback: data => {
setLoading(false);
setData(data);
},
error: () => {
setLoading(false);
}
});
}
return (
<div>
<Table
extraColWidth={10}
loading={loading}
columns={cols||[]}
dataSource={tableData}
pagination={false}
scroll={{y: (tableData||[]).length===0?null:'calc(100vh - 121px - 57px - 24px - 38px - 44px)'}}
/>
<Pagination
className="text-center mt-3"
showSizeChanger
onChange={(_pageNum, _pageSize) => {
setPagination({ pageNum: _pageNum, pageSize: _pageSize || 20 });
}}
onShowSizeChange={(_pageNum, _pageSize) => {
setPagination({ pageNum: 1, pageSize: _pageSize });
}}
current={pageNum}
pageSize={pageSize}
defaultCurrent={1}
total={(data||[]).length}
showTotal={total => `
共
$
{
total
}
条
`}
/>
</div>
)
}
export default FC
\ No newline at end of file
src/view/Manage/Model/Component/HistoryAndVersionDrawer.jsx
View file @
82cac42b
...
...
@@ -14,7 +14,7 @@ const HistoryAndVersionDrawer = (props) => {
title=
''
placement=
"right"
closable=
{
true
}
width=
{
'
9
0%'
}
width=
{
'
4
0%'
}
onClose=
{
()
=>
{
onCancel
&&
onCancel
();
}
}
...
...
@@ -25,9 +25,9 @@ const HistoryAndVersionDrawer = (props) => {
<
TabPane
tab=
"版本历史"
key=
"1"
>
<
VersionHistory
id=
{
id
}
/>
</
TabPane
>
<
TabPane
tab=
"版本对比"
key=
"2"
>
{
/*
<TabPane tab="版本对比" key="2">
<VersionCompare id={id} />
</
TabPane
>
</TabPane>
*/
}
</
Tabs
>
}
</
Drawer
>
...
...
src/view/Manage/Model/Component/ImportActionHeader.jsx
View file @
82cac42b
...
...
@@ -103,8 +103,6 @@ const AttributesSelect = ({ value = [], modelerData, onChange, mode = 'multiple'
})
}
console
.
log
(
'currentAttributes'
,
currentAttributes
)
triggerChange
(
currentAttributes
);
}
...
...
@@ -523,7 +521,7 @@ const ImportActionHeader = (props) => {
>
<
h2
className=
'mr-3'
style=
{
{
marginBottom
:
0
}
}
>
基本信息
</
h2
>
{
onlyShowRequireChange
?
<
Button
type=
'
primary'
size=
'small'
onClick=
{
onOnlyShowRequireChange
}
>
展开
<
DownOutlined
/></
Button
>
:
<
Button
type=
'primary'
size=
'small'
onClick=
{
onOnlyShowRequireChange
}
>
收起
<
UpOutlined
/></
Button
>
onlyShowRequireChange
?
<
Button
type=
'
text'
style=
{
{
padding
:
0
,
color
:
'#0069AC'
}
}
onClick=
{
onOnlyShowRequireChange
}
>
展开
<
DownOutlined
/></
Button
>
:
<
Button
type=
'text'
style=
{
{
padding
:
0
,
color
:
'#0069AC'
}
}
onClick=
{
onOnlyShowRequireChange
}
>
收起
<
UpOutlined
/></
Button
>
}
</
div
>
{
...
...
@@ -637,7 +635,7 @@ const ImportActionHeader = (props) => {
label=
"技术主键"
name=
"easyDataModelerPrimaryKey"
>
<
AttributesSelect
modelerData=
{
modelerData
}
mode=
'tags'
/>
<
AttributesSelect
modelerData=
{
modelerData
}
/>
</
Form
.
Item
>
</
Col
>
<
Col
xs=
{
24
}
sm=
{
24
}
lg=
{
12
}
xl=
{
8
}
>
...
...
src/view/Manage/Model/Component/ImportActionIndex.jsx
View file @
82cac42b
...
...
@@ -882,7 +882,7 @@ const ImportActionIndex = (props) => {
onChange
&&
onChange
(
newData
);
},
//eslint-disable-next-line react-hooks/exhaustive-deps
[
dataRef
.
current
,
onChange
],
[
dataRef
.
current
],
);
const
onSearchInputChange
=
(
value
)
=>
{
...
...
@@ -891,15 +891,15 @@ const ImportActionIndex = (props) => {
}
const
displayMenu
=
(
e
)
=>
{
show
(
e
);
show
({
event
:
e
})
}
const
handleItemClick
=
({
event
,
props
,
data
,
triggerEvent
})
=>
{
const
key
=
event
.
currentTarget
.
id
;
if
(
key
===
'up'
)
{
const
handleItemClick
=
({
id
,
event
,
props
})
=>
{
if
(
id
===
'up'
)
{
insertToFront
(
currentItem
);
}
else
if
(
key
===
'down'
)
{
}
else
if
(
id
===
'down'
)
{
insertToBack
(
currentItem
);
}
}
...
...
src/view/Manage/Model/Component/ImportActionTable.jsx
View file @
82cac42b
...
...
@@ -167,15 +167,9 @@ export const EditableCell = ({
let
editingComponent
=
null
;
if
(
editing
)
{
let
inputNode
=
<
InputDebounce
/>;
if
(
dataIndex
!==
'datatype'
)
{
if
(
inputType
===
'check'
)
{
inputNode
=
<
Checkbox
/>;
}
else
if
(
inputType
===
'textarea'
)
{
inputNode
=
<
Input
.
TextArea
autoSize=
{
{
minRows
:
1
,
maxRows
:
6
}
}
/>;
}
else
if
(
inputType
===
'datatype'
)
{
inputNode
=
<
DatatypeInput
datatypes=
{
datatypes
}
/>;
}
const
inputNode
=
inputType
===
'check'
?
<
Checkbox
/>
:
<
InputDebounce
/>
editingComponent
=
(
<
Form
.
Item
...
...
@@ -194,6 +188,26 @@ export const EditableCell = ({
{
inputNode
}
</
Form
.
Item
>
);
}
else
{
editingComponent
=
(
<
Form
.
Item
name=
{
dataIndex
}
style=
{
{
margin
:
0
,
}
}
valuePropName=
{
'value'
}
rules=
{
[
{
required
:
(
require
===
null
)?
false
:
require
,
message
:
`请输入${colTitle}!`
,
},
]
}
>
<
DatatypeInput
datatypes=
{
datatypes
}
/>
</
Form
.
Item
>
)
}
}
...
...
@@ -440,9 +454,9 @@ export const ImportActionTable = (props) => {
render: (text, _, __) => {
return (
<Tooltip title={text||''}>
<
Typography.Text ellipsis={true}
>
<
span
>
{highlightSearchContentByTerms(text, termsRef.current)}
</
Typography.Text
>
</
span
>
</Tooltip>
)
}
...
...
@@ -930,7 +944,7 @@ export const ImportActionTable = (props) => {
value?.setGlobalState && value?.setGlobalState({
message: 'data-govern-show-standard-create',
data: {
column:
{...record, ...{ modelName: modelerData?.name, modelCnName: modelerData?.cnName }}
,
column:
record
,
type: record?.isPossibleNewRecommendedDefinition?.type
}
});
...
...
@@ -1107,27 +1121,12 @@ export const ImportActionTable = (props) => {
return col;
}
let inputType = 'text';
if (
col.dataIndex==='notNull'||
col.dataIndex==='partOfDistributionKey' ||
col.dataIndex==='partOfPrimaryKeyLogically' ||
col.dataIndex==='needAttention' ||
col.dataIndex==='foreignKey'
) {
inputType = 'check';
} else if (col.dataIndex === 'remark') {
inputType = 'textarea';
} else if (col.dataIndex === 'datatype') {
inputType = 'datatype';
}
return {
...col,
onCell: (record) => ({
record,
dataIndex: col.dataIndex,
inputType,
inputType
: (col.dataIndex==='notNull' || col.dataIndex==='partOfDistributionKey' || col.dataIndex==='partOfPrimaryKeyLogically' || col.dataIndex==='needAttention' || col.dataIndex==='foreignKey') ? 'check' : 'text'
,
colTitle: col.title,
editing: isEditing(record),
datatypes: supportedDatatypes,
...
...
@@ -1175,7 +1174,7 @@ export const ImportActionTable = (props) => {
onChange && onChange(newData);
},
//eslint-disable-next-line react-hooks/exhaustive-deps
[moveRowRef.current
, onChange
],
[moveRowRef.current],
);
const onSearchInputChange = (value) => {
...
...
@@ -1199,15 +1198,15 @@ export const ImportActionTable = (props) => {
}
const displayMenu = (e) => {
show(e);
show({
event: e
})
}
const handleItemClick = ({ event, props, data, triggerEvent }) => {
const key = event.currentTarget.id;
if (key === 'up') {
const handleItemClick = ({ id, event, props }) => {
if (id === 'up') {
insertToFront(currentItem);
} else if (
key
=== 'down') {
} else if (
id
=== 'down') {
insertToBack(currentItem);
}
}
...
...
src/view/Manage/Model/Component/ImportExcel.jsx
View file @
82cac42b
...
...
@@ -79,7 +79,7 @@ class ImportExcel extends React.Component {
</
Col
>
<
Col
span=
{
6
}
>
<
Button
icon=
{
<
DownloadOutlined
/>
}
onClick=
{
this
.
downloadTemplate
}
>
模
版
下载
模
板
下载
</
Button
>
</
Col
>
</
Row
>
...
...
src/view/Manage/Model/Component/ImportMetadata.jsx
View file @
82cac42b
...
...
@@ -281,7 +281,6 @@ class ImportMetadata extends React.Component {
<
Pagination
showTotal=
{
total
=>
`共 ${total} 条`
}
showSizeChanger
size=
"small"
pageSize=
{
pageSizeDataTables
}
pageSizeOptions=
{
[
'20'
,
'60'
,
'100'
]
}
current=
{
pageNumDataTables
}
...
...
src/view/Manage/Model/Component/ImportServices.jsx
0 → 100644
View file @
82cac42b
import
React
from
'react'
import
{
Drawer
,
Form
,
Pagination
,
Divider
,
Upload
,
Button
,
Typography
,
Modal
,
Spin
}
from
'antd'
import
{
UploadOutlined
,
DownloadOutlined
}
from
'@ant-design/icons'
import
{
dispatch
}
from
'../../../../model'
import
{
AppContext
}
from
'../../../../App'
import
{
showMessage
}
from
'../../../../util'
import
Table
from
'../../ResizeableTable'
const
FC
=
(
props
)
=>
{
const
{
onCancel
,
onSuccess
,
visible
}
=
props
const
[
fileList
,
setFileList
]
=
React
.
useState
([])
const
[
confirmLoading
,
setConfirmLoading
]
=
React
.
useState
(
false
)
const
[
loading
,
setLoading
]
=
React
.
useState
(
false
)
const
[
logs
,
setLogs
]
=
React
.
useState
([])
const
[
pagination
,
setPagination
]
=
React
.
useState
({
pageNum
:
1
,
pageSize
:
20
})
const
[
total
,
setTotal
]
=
React
.
useState
(
0
)
const
[
users
,
setUsers
]
=
React
.
useState
([])
const
[
confirmParams
,
setConfirmParams
]
=
React
.
useState
({
visible
:
false
,
message
:
undefined
,
fileId
:
undefined
,
})
const
app
=
React
.
useContext
(
AppContext
)
const
columns
=
[
{
title
:
'序号'
,
dataIndex
:
'key'
,
render
:
(
text
,
record
,
index
)
=>
{
return
(
index
+
1
).
toString
();
},
width
:
60
,
},
{
title
:
'开始时间'
,
dataIndex
:
'startTime'
,
width
:
200
,
ellipsis
:
true
,
render
:
(
_
,
record
)
=>
record
.
startTime
?
new
Date
(
record
.
startTime
).
toLocaleString
()
:
''
},
{
title
:
'结束时间'
,
dataIndex
:
'endTime'
,
width
:
200
,
ellipsis
:
true
,
render
:
(
_
,
record
)
=>
record
.
endTime
?
new
Date
(
record
.
endTime
).
toLocaleString
()
:
''
},
{
title
:
'耗时'
,
dataIndex
:
'costTime'
,
width
:
100
,
ellipsis
:
true
,
render
:
(
_
,
record
,
__
)
=>
{
return
record
.
costTime
?
`
${
Number
(
record
.
costTime
/
1000
)}
秒`
:
''
;
}
},
{
title
:
'导入人'
,
dataIndex
:
'operator'
,
width
:
100
,
ellipsis
:
true
,
render
:
(
_
,
record
)
=>
{
const
temp
=
(
record
.
operator
??
''
).
split
(
':'
)
if
((
temp
??[]).
length
>=
3
)
{
const
user
=
(
users
??[]).
filter
((
user
)
=>
user
.
pernr
===
temp
[
2
])
if
(
user
&&
user
.
length
>
0
)
{
return
user
[
0
].
nachn
?
`
${
user
[
0
].
nachn
}
(
${
user
[
0
].
pernr
}
)`
:
user
[
0
].
pernr
}
return
temp
[
2
]
}
return
''
}
},
{
title
:
'导入状态'
,
dataIndex
:
'state'
,
ellipsis
:
true
,
},
]
React
.
useEffect
(()
=>
{
if
(
visible
)
{
getLogs
()
getUsers
()
}
},
[
visible
])
const
getUsers
=
()
=>
{
dispatch
({
type
:
'pds.getOwners'
,
callback
:
(
data
)
=>
{
setUsers
(
data
);
}
})
}
const
downloadTemplate
=
()
=>
{
window
.
open
(
'/api/pdataservice/pdsCURD/exportPDSDataServiceTemplate?model=DataService'
)
}
const
getLogs
=
()
=>
{
setLoading
(
true
)
setPagination
(
prev
=>
{
dispatch
({
type
:
'pds.getImportLogs'
,
payload
:
{
page
:
prev
.
pageNum
,
size
:
prev
.
pageSize
},
callback
:
data
=>
{
setLoading
(
false
)
setTotal
(
data
.
totalElements
)
setLogs
(
data
.
content
||
[])
},
error
:
()
=>
{
setLoading
(
false
)
}
})
return
prev
})
}
const
uploadProps
=
{
onRemove
:
file
=>
{
const
index
=
fileList
.
indexOf
(
file
);
const
newFileList
=
fileList
.
slice
();
newFileList
.
splice
(
index
,
1
);
setFileList
(
newFileList
);
},
beforeUpload
:
file
=>
{
const
isLt2OM
=
file
.
size
/
1024
/
1024
<
20
;
if
(
!
isLt2OM
)
{
showMessage
(
'error'
,
'上传文件必须小于20M'
);
setFileList
([]);
return
false
;
}
setFileList
([
file
]);
return
false
;
},
fileList
:
fileList
||
[],
accept
:
".xlsx"
,
};
const
handleOk
=
()
=>
{
if
((
fileList
||
[]).
length
===
0
)
{
showMessage
(
'info'
,
'请先选择文件上传'
)
return
}
setConfirmLoading
(
true
)
dispatch
({
type
:
'pds.addImportWithConfirm'
,
payload
:
{
fileList
:
fileList
,
params
:
{
namespace
:
app
?.
env
?.
domainId
},
},
callback
:
data
=>
{
setConfirmLoading
(
false
)
setFileList
([])
if
(
data
?.
fileId
)
{
setConfirmParams
({
visible
:
true
,
message
:
data
?.
message
,
fileId
:
data
?.
fileId
,
})
}
else
{
showMessage
(
'error'
,
'上传文件失败'
)
}
},
error
:
()
=>
{
setConfirmLoading
(
false
)
}
})
}
const
reset
=
()
=>
{
setConfirmLoading
(
false
)
setPagination
({
pageNum
:
1
,
pageSize
:
20
})
setFileList
([])
}
return
(
<
Drawer
visible=
{
visible
}
title=
'服务导入'
width=
{
900
}
placement=
"right"
closable
destroyOnClose
onClose=
{
()
=>
{
reset
()
onCancel
?.()
}
}
>
<
div
className=
'mt-3'
>
<
Form
layout=
'inline'
>
<
Form
.
Item
label=
'Excel导入:'
>
<
Button
className=
'mr-2'
icon=
{
<
DownloadOutlined
/>
}
onClick=
{
downloadTemplate
}
>
模板下载
</
Button
>
<
Upload
style=
{
{
display
:
'inline'
}
}
{
...
uploadProps
}
>
<
Button
icon=
{
<
UploadOutlined
/>
}
>
选择文件上传
</
Button
>
</
Upload
>
</
Form
.
Item
>
<
Form
.
Item
>
<
Button
type=
'primary'
onClick=
{
handleOk
}
loading=
{
confirmLoading
}
>
确定导入
</
Button
>
</
Form
.
Item
>
<
Button
onClick=
{
()
=>
getLogs
()
}
style=
{
{
marginLeft
:
'auto'
}
}
>
刷新日志
</
Button
>
</
Form
>
</
div
>
<
Divider
orientation=
"left"
>
导入日志
</
Divider
>
<
Table
className=
'mt-3'
columns=
{
columns
||
[]
}
rowKey=
{
'id'
}
dataSource=
{
logs
||
[]
}
pagination=
{
false
}
loading=
{
loading
}
expandable=
{
{
expandedRowRender
:
record
=>
<
React
.
Fragment
>
{
record
.
message
?.
split
(
'
\
n'
).
map
((
info
,
index
)
=>
{
return
<
Typography
.
Paragraph
key=
{
index
}
>
{
info
}
</
Typography
.
Paragraph
>
})
}
</
React
.
Fragment
>
}
}
sticky
/>
<
Pagination
className=
"text-center mt-3"
showSizeChanger
onChange=
{
(
_pageNum
,
_pageSize
)
=>
{
setPagination
({
pageNum
:
_pageNum
||
1
,
pageSize
:
_pageSize
||
20
});
getLogs
();
}
}
onShowSizeChange=
{
(
_pageNum
,
_pageSize
)
=>
{
setPagination
({
pageNum
:
_pageNum
||
1
,
pageSize
:
_pageSize
||
20
});
getLogs
();
}
}
current=
{
pagination
.
pageNum
}
pageSize=
{
pagination
.
pageSize
}
defaultCurrent=
{
1
}
total=
{
total
}
showTotal=
{
total
=>
`共 ${total} 条`
}
/>
<
Confirm
{
...
confirmParams
}
onCancel=
{
(
refresh
)
=>
{
setConfirmParams
({
visible
:
false
,
message
:
undefined
,
fileId
:
undefined
,
})
getLogs
()
refresh
&&
onSuccess
?.()
}
}
/>
</
Drawer
>
)
}
export
default
FC
const
Confirm
=
({
visible
,
message
,
fileId
,
onCancel
})
=>
{
const
[
waiting
,
setWaiting
]
=
React
.
useState
(
false
)
const
close
=
()
=>
{
setWaiting
(
true
)
dispatch
({
type
:
'pds.importConfirm'
,
payload
:
{
params
:
{
fileId
,
isContinued
:
false
,
},
},
callback
:
data
=>
{
showMessage
(
'success'
,
'取消导入成功'
)
setWaiting
(
false
)
onCancel
?.()
},
error
:
()
=>
{
setWaiting
(
false
)
}
})
}
const
save
=
()
=>
{
setWaiting
(
true
)
dispatch
({
type
:
'pds.importConfirm'
,
payload
:
{
params
:
{
fileId
,
isContinued
:
true
,
},
},
callback
:
data
=>
{
showMessage
(
'success'
,
'上传文件成功,正在导入。。。'
)
setWaiting
(
false
)
onCancel
?.(
true
)
},
error
:
()
=>
{
setWaiting
(
false
)
}
})
}
const
footer
=
React
.
useMemo
(()
=>
{
return
[
<
Button
key=
{
'cancel'
}
onClick=
{
()
=>
close
()
}
>
取消导入
</
Button
>,
<
Button
key=
{
'save'
}
type=
'primary'
disabled=
{
waiting
}
onClick=
{
()
=>
save
()
}
>
继续导入
</
Button
>
]
},
[
close
,
save
,
waiting
])
return
(
<
Modal
title=
'导入确认'
width=
{
600
}
visible=
{
visible
}
footer=
{
footer
}
destroyOnClose
maskClosable=
{
false
}
onCancel=
{
()
=>
{
close
()
}
}
bodyStyle=
{
{
height
:
400
,
overflow
:
'auto'
}
}
>
<
Spin
spinning=
{
waiting
}
>
{
(
message
??
''
).
split
(
'
\
n'
).
map
((
info
,
index
)
=>
{
return
<
Typography
.
Paragraph
key=
{
index
}
>
{
info
}
</
Typography
.
Paragraph
>
})
}
</
Spin
>
</
Modal
>
)
}
\ No newline at end of file
src/view/Manage/Model/Component/JDBCInformation.jsx
0 → 100644
View file @
82cac42b
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
Modal
,
Typography
,
Button
,
Space
,
Tooltip
,
Spin
}
from
'antd'
;
import
{
CopyOutlined
,
DownloadOutlined
}
from
'@ant-design/icons'
;
import
copy
from
'copy-to-clipboard'
;
import
{
dispatch
}
from
'../../../../model'
;
import
{
showMessage
}
from
'../../../../util'
;
const
FC
=
(
props
)
=>
{
const
{
visible
,
onCancel
}
=
props
;
const
[
information
,
setInformation
]
=
useState
(
undefined
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
useEffect
(()
=>
{
if
(
visible
)
{
getInformation
();
}
},
[
visible
])
const
getInformation
=
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'pds.getJdbcInformation'
,
callback
:
data
=>
{
setLoading
(
false
);
setInformation
(
data
);
},
error
:
()
=>
{
setLoading
(
false
);
}
})
}
return
(
<
Modal
title=
'JDBC信息'
width=
{
540
}
visible=
{
visible
}
onCancel=
{
onCancel
}
footer=
{
null
}
>
<
Spin
spinning=
{
loading
}
>
<
div
className=
'flex mb-3'
style=
{
{
justifyContent
:
'space-between'
,
alignItems
:
'baseline'
}
}
>
<
div
style=
{
{
width
:
400
}
}
>
<
Typography
.
Text
>
{
`impala JDBC地址: ${information?.impala?.url}`
}
</
Typography
.
Text
>
</
div
>
<
Space
>
<
Tooltip
title=
{
information
?.
impala
?.
urlTip
}
>
<
Button
type=
'link'
icon=
{
<
CopyOutlined
/>
}
onClick=
{
()
=>
{
if
(
information
?.
impala
?.
url
)
{
copy
(
information
?.
impala
?.
url
);
showMessage
(
'success'
,
'复制成功'
);
}
}
}
/>
</
Tooltip
>
<
Tooltip
title=
{
information
?.
impala
?.
downloadTip
}
>
<
Button
type=
'link'
icon=
{
<
DownloadOutlined
/>
}
onClick=
{
()
=>
{
if
(
information
?.
impala
?.
downloadUrl
)
{
copy
(
information
?.
impala
?.
downloadUrl
);
showMessage
(
'success'
,
'复制成功'
);
}
}
}
/>
</
Tooltip
>
</
Space
>
</
div
>
<
div
className=
'flex'
style=
{
{
justifyContent
:
'space-between'
,
alignItems
:
'baseline'
}
}
>
<
div
style=
{
{
width
:
400
}
}
>
<
Typography
.
Text
>
{
`Hana JDBC地址: ${information?.hana?.url}`
}
</
Typography
.
Text
>
</
div
>
<
Space
>
<
Tooltip
title=
{
information
?.
hana
?.
urlTip
}
>
<
Button
type=
'link'
icon=
{
<
CopyOutlined
/>
}
onClick=
{
()
=>
{
if
(
information
?.
hana
?.
url
)
{
copy
(
information
?.
hana
?.
url
);
showMessage
(
'success'
,
'复制成功'
);
}
}
}
/>
</
Tooltip
>
<
Tooltip
title=
{
information
?.
hana
?.
downloadTip
}
>
<
Button
type=
'link'
icon=
{
<
DownloadOutlined
/>
}
onClick=
{
()
=>
{
if
(
information
?.
hana
?.
downloadUrl
)
{
copy
(
information
?.
hana
?.
downloadUrl
);
showMessage
(
'success'
,
'复制成功'
);
}
}
}
/>
</
Tooltip
>
</
Space
>
</
div
>
</
Spin
>
</
Modal
>
)
}
export
default
FC
;
\ No newline at end of file
src/view/Manage/Model/Component/ModelSvg.jsx
View file @
82cac42b
...
...
@@ -43,7 +43,7 @@ export const AttentionSvg = (props) => (
</
defs
>
<
path
d=
"M826.027 34.133H197.973c-37.546 0-68.266 30.72-68.266 68.267v887.467L512 791.893l382.293 197.974V102.4c0-37.547-30.72-68.267-68.266-68.267zm-148.48 337.92L612.693 435.2c-3.413 3.413-5.12 10.24-5.12 15.36l15.36 87.04c1.707 13.653-11.946 23.893-23.893 17.067L520.533 512c-5.12-3.413-10.24-3.413-15.36 0l-78.506 42.667c-11.947 6.826-27.307-3.414-23.894-17.067l15.36-87.04c1.707-5.12 0-10.24-5.12-15.36l-64.853-63.147c-10.24-10.24-5.12-27.306 8.533-29.013l88.747-13.653c5.12 0 10.24-3.414 11.947-8.534l39.253-80.213c6.827-11.947 23.893-11.947 30.72 0l39.253 80.213c1.707 5.12 6.827 8.534 11.947 8.534l88.747 13.653c13.653 1.707 18.773 18.773 10.24 29.013z"
fill=
'#
196AD2
'
fill=
'#
c7000b
'
/>
</
svg
>
)
...
...
src/view/Manage/Model/Component/ModelTable.jsx
View file @
82cac42b
import
React
,
{
useState
,
useEffect
,
useRef
,
useMemo
}
from
"react"
;
import
{
Tooltip
,
Modal
,
Table
,
Typography
}
from
'antd'
;
import
LocalStorage
from
'local-storage'
;
import
React
,
{
useState
,
useEffect
,
useRef
,
useContext
,
useMemo
}
from
"react"
;
import
{
Tooltip
,
Modal
,
Pagination
,
Typography
,
Space
,
Menu
,
Dropdown
,
Row
,
Col
,
Divider
}
from
'antd'
;
import
{
DownOutlined
,
UpOutlined
,
UnorderedListOutlined
}
from
'@ant-design/icons'
;
import
copy
from
"copy-to-clipboard"
;
import
SmoothScroll
from
'smooth-scroll'
;
import
classnames
from
'classnames'
;
import
{
Resizable
}
from
'react-resizable'
;
import
{
useContextMenu
,
Menu
as
RcMenu
,
Item
as
RcItem
}
from
"react-contexify"
;
import
ResizeObserver
from
'rc-resize-observer'
;
import
ServiceDetail
from
'./ServiceDetailModal'
;
import
SampleModal
from
'./SampleModal'
;
import
ExchangeOwnerModal
from
'./ExchangeOwner'
;
import
Table
from
'../../ResizeableTable'
;
import
DataGrid
,
{
defaultPageSize
}
from
'../../VirtualTable'
;
import
{
dispatch
}
from
'../../../../model'
;
import
{
showMessage
,
getQueryParam
,
isSzseEnv
,
formatDate
,
getDataModelerRole
}
from
'../../../../util'
;
import
{
showMessage
,
getQueryParam
,
paginate
,
isSzseEnv
,
formatDate
,
getDataModelerRole
}
from
'../../../../util'
;
import
{
AnchorId
,
AnchorTimestamp
,
Action
,
CatalogId
,
ModelerId
,
DataModelerRoleReader
}
from
'../../../../util/constant'
;
import
ExpandedModelTable
from
"./ExpandedModelTable"
;
import
{
AppContext
}
from
"../../../../App"
;
import
SelectUser
from
"./SelectUsers"
;
// import Tag from "../../Tag";
import
{
useContextMenu
,
Menu
as
RcMenu
,
Item
as
RcItem
}
from
"react-contexify"
;
import
'./ModelTable.less'
;
import
'react-contexify/dist/ReactContexify.css'
;
const
{
Paragraph
,
Text
}
=
Typography
;
const
{
Text
}
=
Typography
;
const
{
Column
}
=
Table
;
const
actions
=
[
{
title
:
'编辑'
,
key
:
'edit'
},
{
title
:
'删除'
,
key
:
'delete'
},
{
title
:
'URI复制'
,
key
:
'copyUri'
},
{
title
:
'样本数据'
,
key
:
'sample'
},
{
title
:
'历史版本'
,
key
:
'history'
},
{
title
:
'授权'
,
key
:
'admit'
},
// { title: '申请', key: 'startFlow' },
// { title: '下载Tableau tds', key: 'downloadTds' },
// { title: '跳转至电子表格', key: 'smart' },
{
title
:
'更换管理'
,
key
:
'exchangeOwner'
},
{
title
:
'拖拉创建字段'
,
key
:
'dragAttribute'
},
{
title
:
'自定义sql创建字段'
,
key
:
'sqlAttribute'
}
]
const
ModelNameColumn
=
(
props
)
=>
{
const
{
text
,
record
,
detailItem
}
=
props
;
...
...
@@ -30,14 +55,14 @@ const ModelNameColumn = (props) => {
ellipsis
:
true
,
},
{
title
:
'
字段中文
名称'
,
title
:
'名称'
,
width
:
160
,
dataIndex
:
'cnName'
,
editable
:
true
,
ellipsis
:
true
,
},
{
title
:
'
字段英文名称
'
,
title
:
'
技术ID(英文名称)
'
,
width
:
160
,
dataIndex
:
'name'
,
editable
:
true
,
...
...
@@ -49,7 +74,6 @@ const ModelNameColumn = (props) => {
if
(
data
.
digest
)
{
_textComponent
=
<
div
style=
{
{
width
:
500
,
maxHeight
:
300
,
overflow
:
'auto'
}
}
>
<
Table
rowKey=
'name'
dataSource=
{
data
.
digest
.
attributeDigests
||
[]
}
columns=
{
cols
}
loading=
{
false
}
...
...
@@ -73,7 +97,7 @@ const ModelNameColumn = (props) => {
onVisibleChange=
{
(
visible
)
=>
{
if
(
visible
&&
!
record
.
digest
)
{
dispatch
({
type
:
'
datamodel.getDataModel
Digest'
,
type
:
'
pds.getService
Digest'
,
payload
:
{
id
:
record
.
id
},
...
...
@@ -92,219 +116,539 @@ const ModelNameColumn = (props) => {
);
}
const
ModelTable
=
(
props
)
=>
{
const
{
data
,
onChange
,
onItemAction
,
onSelect
,
onHistory
,
catalogId
,
keyword
,
onAutoCreateTable
,
offset
=
null
,
view
,
modelState
,
user
,
selectModelerIds
,
visibleColName
s
}
=
props
;
const
ResizeableHeaderCell
=
props
=>
{
const
{
onResize
,
width
,
onClick
,
...
restProp
s
}
=
props
;
const
[
selectedRowKeys
,
setSelectedRowKeys
]
=
useState
([]);
const
[
expandedSelectedRowKeys
,
setExpandedSelectedRowKeys
]
=
useState
([]);
const
[
currentItem
,
setCurrentItem
]
=
useState
(
null
);
const
[
scrollRowIndex
,
setScrollRowIndex
]
=
useState
();
if
(
!
width
)
{
return
<
th
{
...
restProps
}
/>;
}
const
expandedDataMapRef
=
useRef
(
new
Map
());
const
shouldScrollRef
=
useRef
(
false
);
return
(
<
Resizable
width=
{
width
}
height=
{
0
}
handle=
{
<
span
className=
"react-resizable-handle"
onClick=
{
(
e
)
=>
{
e
.
stopPropagation
();
}
}
/>
}
onResize=
{
onResize
}
draggableOpts=
{
{
enableUserSelectHack
:
false
}
}
>
<
th
onClick=
{
onClick
}
{
...
restProps
}
/>
</
Resizable
>
);
};
const
anchorId
=
getQueryParam
(
AnchorId
,
props
?.
location
?.
search
);
const
anchorTimestamp
=
getQueryParam
(
AnchorTimestamp
,
props
?.
location
?.
search
);
const
gridRef
=
useRef
();
const
ModelTable
=
(
props
)
=>
{
const
[
modal
,
contextHolder
]
=
Modal
.
useModal
()
;
const
{
data
,
onChange
,
onItemAction
,
onSelect
,
onHistory
,
catalogId
,
keyword
,
onAutoCreateTable
,
offset
=
null
,
modelId
=
null
,
modelPid
=
null
,
view
,
selectModelerIds
,
onSubSelect
,
modelState
,
user
,
isOnlyEnding
,
visibleColNames
}
=
props
;
const
MENU_ID
=
'model-table-contextmenu'
;
const
{
show
}
=
useContextMenu
({
const
MENU_ID
=
(((
modelId
||
''
)
!==
''
)
?
`model-table-contextmenu-
${
modelId
}
`
:
'model-table-contextmenu'
);
const
{
show
,
hideAll
}
=
useContextMenu
({
id
:
MENU_ID
,
});
const
cols
=
[
{
name
:
'序号'
,
key
:
'index'
,
width
:
60
,
sortable
:
false
,
resizable
:
true
,
},
{
name
:
'模型名称'
,
key
:
'name'
,
width
:
isSzseEnv
?
360
:
160
,
sortable
:
true
,
resizable
:
true
,
formatter
(
props
)
{
return
(<
ModelNameColumn
text=
{
props
.
row
.
name
}
record=
{
props
.
row
}
detailItem=
{
detailItem
}
/>);
}
},
{
name
:
'中文名称'
,
key
:
'cnName'
,
width
:
isSzseEnv
?
420
:
160
,
sortable
:
true
,
resizable
:
true
,
formatter
(
props
)
{
return
(
<
Tooltip
title=
{
props
.
row
.
cnName
||
''
}
>
<
Text
ellipsis=
{
true
}
>
{
props
.
row
.
cnName
||
''
}
</
Text
>
</
Tooltip
>
)
}
const
[
tableWidth
,
setTableWidth
]
=
useState
(
0
);
const
[
selectedRowKeys
,
setSelectedRowKeys
]
=
useState
([]);
const
[
subSelectedRowKeys
,
setSubSelectedRowKeys
]
=
useState
([]);
// const [ mouseEnterKey, setMouseEnterKey ] = useState(null);
const
[
sortRule
,
setSortRule
]
=
useState
(
null
);
const
[
filterData
,
setFilterData
]
=
useState
([]);
const
[
subData
,
setSubData
]
=
useState
([]);
const
[
serviceDetailParams
,
setServiceDetailParams
]
=
useState
({
visible
:
false
,
id
:
''
})
const
[
sampleParams
,
setSampleParams
]
=
useState
({
visible
:
false
,
service
:
undefined
});
const
[
exchangeOwnerParams
,
setExchangeOwnerParams
]
=
useState
({
visible
:
false
,
id
:
undefined
});
const
[
attrs
,
setAttrs
]
=
useState
(
undefined
);
const
app
=
useContext
(
AppContext
);
const
indexCol
=
{
title
:
'序号'
,
dataIndex
:
'key'
,
render
:
(
text
,
record
,
index
)
=>
{
return
(
index
+
1
).
toString
();
},
{
name
:
'路径'
,
key
:
'path'
,
width
:
120
,
sortable
:
true
,
resizable
:
true
,
formatter
(
props
)
{
return
(
<
Tooltip
title=
{
props
.
row
.
path
||
''
}
>
<
Text
ellipsis=
{
true
}
>
{
props
.
row
.
path
||
''
}
</
Text
>
</
Tooltip
>
)
width
:
60
,
ellipsis
:
true
,
filter
:
false
,
}
},
const
fixedCols
=
[
// {
// title: '路径',
// dataIndex: 'path',
// width: 120,
// ellipsis: true,
// render: (text, _, __) => {
// return (
// <Tooltip title={text||''}>
// <Text ellipsis={true}>{text||''}</Text>
// </Tooltip>
// )
// }
// },
{
nam
e
:
'状态'
,
key
:
'state'
,
titl
e
:
'状态'
,
dataIndex
:
'state'
,
width
:
100
,
sortable
:
true
,
re
sizable
:
true
,
formatter
(
props
)
{
ellipsis
:
true
,
re
nder
:
(
_
,
record
)
=>
{
let
color
=
''
;
if
(
props
.
row
.
state
?.
id
===
'1'
)
{
if
(
record
?
.
state
?.
id
===
'1'
)
{
color
=
'#DE7777'
;
}
else
if
(
props
.
row
.
state
?.
id
===
'2'
)
{
}
else
if
(
record
?
.
state
?.
id
===
'2'
)
{
color
=
'#779BDE'
;
}
else
if
(
props
.
row
.
state
?.
id
===
'4'
)
{
}
else
if
(
record
?
.
state
?.
id
===
'4'
)
{
color
=
'#77DEBF'
;
}
return
(
<
span
>
<
span
style=
{
{
display
:
'inline-block'
,
width
:
10
,
height
:
10
,
borderRadius
:
5
,
marginRight
:
5
,
backgroundColor
:
color
}
}
></
span
>
<
span
>
{
props
.
row
.
state
?.
cnName
||
''
}
</
span
>
<
span
>
{
record
?
.
state
?.
cnName
||
''
}
</
span
>
</
span
>
);
}
},
{
name
:
'创建
人'
,
key
:
'editor'
,
title
:
'管理
人'
,
dataIndex
:
'editor'
,
width
:
100
,
sortable
:
true
,
resizable
:
true
,
},
{
name
:
'版本号'
,
key
:
'modifiedTs'
,
width
:
170
,
sortable
:
true
,
resizable
:
true
,
formatter
(
props
)
{
return
`V_
${
formatDate
(
props
.
row
.
modifiedTs
)}
`
;
}
},
{
name
:
'模型描述'
,
key
:
'remark'
,
sortable
:
true
,
resizable
:
true
,
formatter
(
props
)
{
return
(
<
Tooltip
title=
{
props
.
row
.
remark
||
''
}
overlayClassName=
'tooltip-common'
>
<
Text
ellipsis=
{
true
}
>
{
props
.
row
.
remark
||
''
}
</
Text
>
ellipsis
:
true
,
render
:
(
editor
,
record
)
=>
{
const
user
=
users
?.
filter
((
user
)
=>
user
.
pernr
===
editor
);
if
(
user
&&
user
.
length
>
0
)
{
return
<
Tooltip
title=
{
user
[
0
].
nachn
?
`${user[0].nachn}(${user[0].pernr})`
:
user
[
0
].
pernr
}
>
<
Text
ellipsis=
{
true
}
>
{
user
[
0
].
nachn
?
`${user[0].nachn}(${user[0].pernr})`
:
user
[
0
].
pernr
}
</
Text
>
</
Tooltip
>
)
}
return
editor
;
}
},
]
;
]
const
columns
=
useMemo
(()
=>
{
let
newCols
=
[...
cols
];
if
((
visibleColNames
||
[]).
length
>
0
)
{
newCols
=
newCols
.
filter
(
col
=>
visibleColNames
.
indexOf
(
col
.
name
)
!==-
1
||
col
.
name
===
'序号'
);
const
actionCol
=
{
title
:
'操作'
,
dataIndex
:
'action'
,
width
:
240
,
fixed
:
'right'
,
filter
:
false
,
render
:
(
_
,
record
)
=>
{
const
authActionTitles
=
[];
if
((
getDataModelerRole
(
user
)
!==
DataModelerRoleReader
)
&&
view
!==
'grant'
&&
!
isOnlyEnding
&&
(
record
.
editable
||
record
.
permitCheckOut
))
{
authActionTitles
.
push
(
'编辑'
);
}
if
((
getDataModelerRole
(
user
)
!==
DataModelerRoleReader
)
&&
view
!==
'grant'
&&
!
isOnlyEnding
&&
record
.
deletable
)
{
authActionTitles
.
push
(
'删除'
);
}
if
(
visibleColNames
.
indexOf
(
'模型描述'
)
===
-
1
)
{
newCols
[
newCols
.
length
-
1
].
width
=
null
;
if
(
record
.
odata
)
{
authActionTitles
.
push
(
'URI复制'
)
;
}
authActionTitles
.
push
(
'样本数据'
);
authActionTitles
.
push
(
'历史版本'
);
if
(
getDataModelerRole
(
user
)
!==
DataModelerRoleReader
&&
view
!==
'grant'
&&
record
.
grantable
)
{
authActionTitles
.
push
(
'授权'
);
}
return
newCols
;
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
visibleColNames
])
// if (getDataModelerRole(user)!==DataModelerRoleReader && view!=='grant' && isOnlyEnding && !currentItem?.grantable) {
// authActionTitles.push('申请');
// }
const
summarySelectedCount
=
useMemo
(()
=>
{
let
newSelectedRowKeys
=
Array
.
from
(
new
Set
([...
selectedRowKeys
,
...
expandedSelectedRowKeys
]));
if
(
getDataModelerRole
(
user
)
!==
DataModelerRoleReader
&&
view
!==
'grant'
&&
record
.
supportChangeOwn
)
{
authActionTitles
.
push
(
'更换管理'
);
}
const
ids
=
[];
(
data
||
[]).
forEach
(
item
=>
{
ids
.
push
(
item
.
id
);
if
(
item
.
alreadyCheckedOut
)
{
ids
.
push
(
item
.
checkedOutId
);
if
(
getDataModelerRole
(
user
)
!==
DataModelerRoleReader
&&
view
!==
'grant'
&&
!
isOnlyEnding
&&
record
.
serviceDefinitionType
===
'empty'
)
{
authActionTitles
.
push
(
'拖拉创建字段'
);
authActionTitles
.
push
(
'自定义sql创建字段'
);
}
})
newSelectedRowKeys
=
(
newSelectedRowKeys
||
[]).
filter
(
key
=>
ids
.
indexOf
(
key
)
!==
-
1
);
// if (getDataModelerRole(user)!==DataModelerRoleReader && view!=='grant' && !isOnlyEnding && record.supportODataDisable) {
// authActionTitles.push('下载Tableau tds');
// }
return
(
newSelectedRowKeys
||
[]).
length
;
},
[
selectedRowKeys
,
expandedSelectedRowKeys
,
data
])
// if (getDataModelerRole(user)!==DataModelerRoleReader && view!=='grant' && record.supportSmartBIWebSpreadSheet) {
// authActionTitles.push('跳转至电子表格');
// }
useEffect
(()
=>
{
if
(
data
&&
gridRef
.
current
)
{
setTimeout
(()
=>
{
gridRef
.
current
?.
scrollToRow
(
0
);
},
100
)
const
authActions
=
actions
.
filter
(
item
=>
authActionTitles
.
indexOf
(
item
.
title
)
!==
-
1
);
if
(
getDataModelerRole
(
user
)
!==
DataModelerRoleReader
&&
view
!==
'grant'
)
{
record
.
state
?.
supportedActions
?.
forEach
((
item
,
index
)
=>
{
authActions
.
push
({
title
:
item
.
cnName
,
key
:
`action-
${
index
}
`
});
});
}
},
[
data
])
const
haveMore
=
authActions
.
length
>
3
;
const
showActions
=
authActions
.
slice
(
0
,
3
);
const
hiddenActions
=
authActions
.
slice
(
3
,
authActions
.
length
);
return
(
<
Space
size=
{
5
}
split=
{
<
Divider
type=
'vertical'
style=
{
{
margin
:
0
}
}
/>
}
>
{
showActions
.
map
((
item
,
index
)
=>
{
return
(
<
div
key=
{
index
}
style=
{
{
width
:
50
}
}
>
<
a
onClick=
{
()
=>
{
handleItemClick
(
item
.
key
,
record
)}
}
>
{
item
.
title
}
</
a
>
</
div
>
)
})
}
{
haveMore
&&
<
Dropdown
overlay=
{
<
Menu
onClick=
{
({
key
})
=>
{
handleItemClick
(
key
,
record
);
}
}
>
{
hiddenActions
.
map
((
item
,
index
)
=>
{
return
(
<
Menu
.
Item
key=
{
item
.
key
}
>
<
div
style=
{
{
textAlign
:
'center'
}
}
>
{
item
.
title
}
</
div
>
</
Menu
.
Item
>
)
})
}
</
Menu
>
}
placement=
"bottomLeft"
>
<
UnorderedListOutlined
className=
'default'
style=
{
{
fontSize
:
16
,
cursor
:
'pointer'
,
marginLeft
:
5
}
}
/>
</
Dropdown
>
}
</
Space
>
)
}
}
// const [ columns, setColumns ] = useState([]);
// const [ includePathColumns, setIncludePathColumns ] = useState([]);
const
[
pagination
,
setPagination
]
=
useState
(
{
pageNum
:
1
,
pageSize
:
20
}
);
const
[
currentItem
,
setCurrentItem
]
=
useState
(
null
);
const
{
pageNum
,
pageSize
}
=
pagination
;
const
[
users
,
setUsers
]
=
useState
([]);
const
[
modal
,
contextHolder
]
=
Modal
.
useModal
();
const
anchorId
=
getQueryParam
(
AnchorId
,
props
.
location
?.
search
);
const
anchorTimestamp
=
getQueryParam
(
AnchorTimestamp
,
props
.
location
?.
search
);
const
shouldScrollRef
=
useRef
(
false
);
useEffect
(()
=>
{
getUsers
();
getAttrs
();
if
((
modelId
||
''
)
!==
''
)
{
window
?.
addEventListener
(
"storage"
,
modelEventChange
);
return
()
=>
{
window
?.
removeEventListener
(
"storage"
,
modelEventChange
);
}
}
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[])
useEffect
(()
=>
{
setSelectedRowKeys
([]);
setExpandedSelectedRowKeys
([]);
if
((
modelId
||
''
)
===
''
)
{
onSelect
&&
onSelect
([]);
if
((
keyword
||
''
)
===
''
)
{
if
(
offset
!==
null
)
{
const
_pageNum
=
parseInt
(
offset
/
pageSize
+
((
offset
%
pageSize
===
0
)?
0
:
1
));
setPagination
({...
pagination
,
pageNum
:
_pageNum
});
}
else
{
setPagination
({...
pagination
,
pageNum
:
1
});
}
}
else
{
setPagination
({...
pagination
,
pageNum
:
1
});
}
}
else
{
getCheckoutDataModel
();
}
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
catalogId
,
keyword
,
offset
,
modelState
]);
useEffect
(()
=>
{
if
((
selectModelerIds
||
[]).
length
===
0
)
{
if
((
selectModelerIds
||
[]).
length
===
0
)
{
setSelectedRowKeys
([]);
set
Expanded
SelectedRowKeys
([]);
set
Sub
SelectedRowKeys
([]);
}
},
[
selectModelerIds
])
useEffect
(()
=>
{
if
((
anchorId
||
''
)
!==
''
)
{
shouldScrollRef
.
current
=
true
;
}
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
anchorTimestamp
])
useEffect
(()
=>
{
if
(
shouldScrollRef
.
current
&&
gridRef
.
current
&&
offset
!==
null
&&
(
data
||
[]).
length
>
0
)
{
setScrollRowIndex
(
offset
);
setTimeout
(()
=>
{
gridRef
.
current
?.
scrollToRow
((
offset
-
1
)
%
defaultPageSize
);
if
(
shouldScrollRef
.
current
)
{
SmoothScroll
(
'a[href*="#"]'
);
const
_id
=
getQueryParam
(
AnchorId
,
props
.
location
.
search
);
var
scroll
=
new
SmoothScroll
();
var
anchor
=
document
.
querySelector
(
`#data-model-
${
_id
}
`
);
if
(
anchor
)
{
scroll
.
animateScroll
(
anchor
);
shouldScrollRef
.
current
=
false
;
},
300
)
}
}
})
useEffect
(()
=>
{
const
newData
=
[...
data
];
if
(
sortRule
)
{
if
(
sortRule
.
order
===
'ascend'
)
{
newData
.
sort
((
item1
,
item2
)
=>
{
if
(
sortRule
.
field
===
'state'
)
{
return
(
item1
[
sortRule
.
field
]?.
cnName
||
''
).
localeCompare
(
item2
[
sortRule
.
field
]?.
cnName
||
''
);
}
else
if
(
sortRule
.
field
===
'modifiedTs'
)
{
return
formatDate
(
item1
[
sortRule
.
field
]).
localeCompare
(
formatDate
(
item2
[
sortRule
.
field
]));
}
return
item1
[
sortRule
.
field
].
localeCompare
(
item2
[
sortRule
.
field
]);
})
}
else
if
(
sortRule
.
order
===
'descend'
)
{
newData
.
sort
((
item1
,
item2
)
=>
{
if
(
sortRule
.
field
===
'state'
)
{
return
(
item2
[
sortRule
.
field
]?.
cnName
||
''
).
localeCompare
(
item1
[
sortRule
.
field
]?.
cnName
||
''
);
}
else
if
(
sortRule
.
field
===
'modifiedTs'
)
{
return
formatDate
(
item2
[
sortRule
.
field
]).
localeCompare
(
formatDate
(
item1
[
sortRule
.
field
]));
}
return
item2
[
sortRule
.
field
].
localeCompare
(
item1
[
sortRule
.
field
]);
})
}
}
const
_data
=
paginate
(
newData
||
[],
pageNum
,
pageSize
);
setFilterData
(
_data
);
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
data
,
pagination
,
sortRule
])
const
handleItemClick
=
(
id
,
record
)
=>
{
if
(
id
===
'edit'
)
{
if
(
record
?.
editable
)
{
editItem
(
record
);
}
else
if
(
record
?.
permitCheckOut
)
{
dispatch
({
type
:
'pds.checkoutService'
,
payload
:
{
params
:
{
id
:
record
?.
id
}
},
callback
:
data
=>
{
onChange
&&
onChange
();
editItem
(
data
);
}
})
}
}
else
if
(
id
===
'delete'
)
{
deleteItem
(
record
);
}
else
if
(
id
===
'sample'
)
{
setSampleParams
({
visible
:
true
,
service
:
record
})
}
else
if
(
id
===
'history'
)
{
historyItem
(
record
);
}
else
if
(
id
===
'copy'
)
{
window
.
open
(
`/data-govern/data-model-action?
${
Action
}
=add&
${
CatalogId
}
=
${(
view
===
'dir'
)?(
catalogId
||
''
):
''
}
&
${
ModelerId
}
=
${
record
.
id
}
`
);
}
else
if
(
id
===
'createTable'
)
{
deployAction
(
record
);
}
else
if
(
id
.
indexOf
(
'action'
)
!==
-
1
)
{
const
index
=
(
id
.
split
(
'-'
))[
1
];
const
action
=
record
?.
state
?.
supportedActions
[
index
];
stateAction
(
record
,
action
);
}
else
if
(
id
===
'admit'
)
{
app
.
openAdmit
?.({
dirId
:
catalogId
,
service
:
record
})
}
else
if
(
id
===
'enableOData'
)
{
startODataItem
(
record
);
}
else
if
(
id
===
'disableOData'
)
{
disableODataItem
(
record
);
}
else
if
(
id
===
'startFlow'
)
{
app
.
applyServer
?.({
service
:
record
});
}
else
if
(
id
===
'downloadTds'
)
{
window
.
open
(
`/api/pdataservice/pdsCURD/genTDS?id=
${
record
?.
id
}
`);
} else if (id === 'checkout') {
dispatch({
type: 'pds.checkoutService',
payload: {
params: {
id: record?.id
}
},
callback: () => {
showMessage('success', '检出成功');
onChange && onChange();
}
})
} else if (id === 'smart') {
dispatch({
type: 'pds.getSmartBiUrl',
payload: {
url: record?.smartBiWebSpreadSheetEntry
},
callback: (data) => {
window.open(data)
}
})
} else if (id === 'exchangeOwner') {
setExchangeOwnerParams({ visible: true, id: record?.id });
} else if (id === 'offline') {
offlineService(record);
} else if (id === 'copyUri') {
copy(record.odata);
showMessage('success', 'URI复制成功');
} else if (id === 'dragAttribute') {
app?.editServer?.({ service: record, dirId: catalogId, type: id });
} else if (id === 'sqlAttribute') {
app?.editServer?.({ service: record, dirId: catalogId, type: id });
}
}
const detailItem = (record) => {
// onItemAction && onItemAction(record, 'detail', getDataModelerRole(user)===DataModelerRoleReader);
app.openDetail?.({ service: record, isOnlyEnding })
// setServiceDetailParams({ visible: true, id: record.id })
}
const columns = useMemo(() => {
let newCols = [];
attrs?.forEach(item => {
let col = {
title: item.name,
dataIndex: item.key,
ellipsis: true,
width: 200,
render: (_, record) => {
return <Tooltip title={record.basicInfo ? record.basicInfo[item.key] : ''}>
<Text ellipsis={true}>{record.basicInfo ? record.basicInfo[item.key] : ''}</Text>
</Tooltip>
}
};
if (item.key === 'name') {
col.render = (text, record, index) => {
return (<ModelNameColumn text={record.basicInfo?record.basicInfo[item.key]:''} record={record} detailItem={detailItem} />);
};
}
if (item.userSelected === true) {
col.render = (_, record) => {
const user = users?.filter((user)=>(user.pernr===record.basicInfo?.[item.key]));
if (user && user.length > 0) {
return <Tooltip title={user[0].nachn?`
$
{
user
[
0
].
nachn
}(
$
{
user
[
0
].
pernr
})
`:user[0].pernr}>
<Text ellipsis={true}>{user[0].nachn?`
$
{
user
[
0
].
nachn
}(
$
{
user
[
0
].
pernr
})
`:user[0].pernr}</Text>
</Tooltip>
}
return record.basicInfo?.[item.key];
};
}
newCols.push(col);
});
if ((visibleColNames||[]).length > 0) {
newCols = newCols.filter(col => visibleColNames.indexOf(col.title)!==-1);
}
if (!modelId) {
newCols = [indexCol, ...newCols, ...fixedCols, actionCol];
} else {
newCols = [...newCols, ...fixedCols, actionCol];
}
return newCols;
}, [visibleColNames, attrs, indexCol, actionCol, modelId, detailItem, users])
const modelEventChange = (e) => {
if (e.key === 'modelChange') {
expandedDataMapRef
.
current
.
delete
(
LocalStorage
.
get
(
'modelId'
)
);
getCheckoutDataModel(
);
}
}
const
editItem
=
(
record
)
=>
{
onItemAction
&&
onItemAction
(
record
,
'edit'
);
const getAttrs = () => {
dispatch({
type: 'pds.getAttrs',
payload: {
modelName: 'DataService'
},
callback: data => {
setAttrs(data);
},
error: () => {
}
})
}
const
detailItem
=
(
record
)
=>
{
onItemAction
&&
onItemAction
(
record
,
'detail'
,
getDataModelerRole
(
user
)
===
DataModelerRoleReader
);
const getUsers = () => {
dispatch({
type: 'pds.getOwners',
callback: (data) => {
setUsers(data);
}
})
}
const getCheckoutDataModel = () => {
dispatch({
type: 'pds.getCheckoutService',
payload: {
id: modelPid
},
callback: data => {
setSubData(data?[data]:[]);
},
error: () => {
}
})
}
// const getDataModel = () => {
// dispatch({
// type: 'datamodel.getDataModel',
// payload: {
// id: modelId
// },
// callback: data => {
// setSubData(data?[data]:[]);
// },
// error: () => {
// }
// })
// }
const editItem = (record) => {
// onItemAction && onItemAction(record, 'edit');
app.editServer?.({ dirId: catalogId, service: record })
}
const deployAction = (record) => {
...
...
@@ -314,17 +658,18 @@ const ModelTable = (props) => {
const stateAction = (record, action) => {
modal.confirm({
title: '提示!',
content
:
`您确定要
${
action
.
cnName
||
''
}
该
模型
吗?`
,
content: `
您确定要
$
{
action
.
cnName
||
''
}
该
服务
吗
?
`,
onOk: () => {
dispatch({
type
:
'
datamodel
.nextState'
,
type: '
pds
.nextState',
payload: {
easyDataModelerDataModel
Id
:
record
.
id
,
pdsDataService
Id: record.id,
actionId: action.id
},
callback: () => {
showMessage
(
'success'
,
`
模型
${
action
.
cnName
||
''
}
成功`
);
showMessage('success', `
服务
$
{
action
.
cnName
||
''
}
成功
`);
if ((modelId||'') === '') {
onChange && onChange();
const index = selectedRowKeys.findIndex((rowKey) => rowKey === record.id);
...
...
@@ -334,6 +679,14 @@ const ModelTable = (props) => {
setSelectedRowKeys(newSelectedRowKeys);
onSelect && onSelect(newSelectedRowKeys);
}
} else {
if (action.id === '2') {
onChange && onChange();
} else {
getCheckoutDataModel();
}
}
}
})
}
...
...
@@ -341,21 +694,23 @@ const ModelTable = (props) => {
}
const deleteItem = (record) => {
modal.confirm({
title: '提示!',
content
:
'您确定要删除该
模型
吗?'
,
content: '您确定要删除该
服务
吗?',
onOk: () => {
dispatch({
type
:
'
datamodel.deleteDataModel
'
,
type: '
pds.deleteService
',
payload: {
params: {
id: record.id
}
},
callback: () => {
showMessage
(
'success'
,
'
模型
删除成功'
);
showMessage('success', '
服务
删除成功');
onChange && onChange();
if ((modelId||'') ==='') {
const index = selectedRowKeys.findIndex((rowKey) => rowKey === record.id);
if (index !== -1) {
const newSelectedRowKeys = [...selectedRowKeys];
...
...
@@ -364,6 +719,8 @@ const ModelTable = (props) => {
onSelect && onSelect(newSelectedRowKeys);
}
}
}
})
}
});
...
...
@@ -373,32 +730,113 @@ const ModelTable = (props) => {
onHistory && onHistory(record.id);
}
const startODataItem = (record) => {
modal.confirm({
title: '提示!',
content: '您确定要启动该服务的OData吗?',
onOk: () => {
dispatch({
type: 'pds.enableOData',
payload: {
params: {
pdsDataServiceId: record.id
}
},
callback: () => {
showMessage('success', '启动成功');
onChange && onChange();
}
})
}
});
}
const disableODataItem = (record) => {
modal.confirm({
title: '提示!',
content: '您确定要停用该服务的OData吗?',
onOk: () => {
dispatch({
type: 'pds.disableOData',
payload: {
params: {
pdsDataServiceId: record.id
}
},
callback: () => {
showMessage('success', '停用成功');
onChange && onChange();
}
})
}
});
}
const offlineService = (record) => {
modal.confirm({
title: '提示!',
content: '您确定要停用该服务吗?',
onOk: () => {
dispatch({
type: 'pds.offlineDataService',
payload: {
params: {
id: record.id
}
},
callback: () => {
showMessage('success', '停用成功');
onChange && onChange();
}
})
}
});
}
const onSelectChange = keys => {
setSelectedRowKeys(keys);
onSelect
&&
onSelect
([...
expandedSelectedRowKeys
,
...
keys
]);
if ((modelId||'') !== '') {
onSubSelect && onSubSelect(keys, subData[0].id);
} else {
onSelect && onSelect([...subSelectedRowKeys, ...keys]);
}
};
const
on
ExpandedTable
SelectChange
=
(
keys
,
id
)
=>
{
const on
Sub
SelectChange = (keys, id) => {
if ((keys||[]).length === 0) {
const
index
=
expanded
SelectedRowKeys
.
findIndex
((
rowKey
)
=>
rowKey
===
id
);
const
new
ExpandedSelectedRowKeys
=
[...
expanded
SelectedRowKeys
];
new
Expanded
SelectedRowKeys
.
splice
(
index
,
1
);
set
ExpandedSelectedRowKeys
(
newExpanded
SelectedRowKeys
);
onSelect
&&
onSelect
([...
new
Expanded
SelectedRowKeys
,
...
selectedRowKeys
]);
const index =
sub
SelectedRowKeys.findIndex((rowKey) => rowKey === id);
const new
SubSelectedRowKeys = [...sub
SelectedRowKeys];
new
Sub
SelectedRowKeys.splice(index, 1);
set
SubSelectedRowKeys(newSub
SelectedRowKeys);
onSelect && onSelect([...new
Sub
SelectedRowKeys, ...selectedRowKeys]);
} else {
const
newExpandedSelectedRowKeys
=
[...
expandedSelectedRowKeys
,
id
];
setExpandedSelectedRowKeys
(
newExpandedSelectedRowKeys
);
onSelect
&&
onSelect
([...
newExpandedSelectedRowKeys
,
...
selectedRowKeys
]);
const newSubSelectedRowKeys = [...subSelectedRowKeys, id];
onSelect && onSelect([...newSubSelectedRowKeys, ...selectedRowKeys]);
}
}
const
onExpandedDataMapChange
=
(
id
,
value
)
=>
{
expandedDataMapRef
.
current
.
set
(
id
,
value
);
const onTableChange = (pagination, filters, sorter, extra) => {
if (sorter) {
setSortRule(sorter);
}
}
const rowSelection = {
selectedRowKeys,
onChange: onSelectChange,
hideSelectAll: (modelId||'') !=='',
};
const classes = classnames('model-table', {
'model-table-sub': modelId
});
let expandable = undefined;
let needExpand = false;
(
data
||
[]).
forEach
(
record
=>
{
if (!modelId) {
(filterData||[]).forEach(record => {
if (record?.alreadyCheckedOut) {
needExpand = true;
}
...
...
@@ -406,57 +844,53 @@ const ModelTable = (props) => {
if (needExpand) {
expandable = {
expandedRowHeight
:
100
,
rowExpandable
:
(
row
)
=>
{
return
row
?.
alreadyCheckedOut
;
},
expandRowRender
:
(
row
)
=>
{
return
(
<
div
style=
{
{
padding
:
10
}
}
>
<
ExpandedModelTable
id=
{
row
?.
checkedOutId
}
pid=
{
row
?.
id
}
checked=
{
expandedSelectedRowKeys
.
indexOf
(
row
?.
checkedOutId
)
!==-
1
}
onContextMenu=
{
onExpandedTableContextMenu
}
dataMap=
{
expandedDataMapRef
.
current
}
visibleColNames=
{
visibleColNames
}
onExpandedSelect=
{
onExpandedTableSelectChange
}
onExpandedChange=
{
onExpandedDataMapChange
}
expandedRowRender: record => <ModelTable
view={view}
modelId={record?.checkedOutId}
modelPid={record?.id}
onSubSelect={onSubSelectChange}
{...props}
/>
</
div
>
)
/>,
expandIcon: ({ expanded, onExpand, record }) => {
if (!record?.alreadyCheckedOut) return null;
return expanded ? <UpOutlined style={{ fontSize: 10 }} onClick={e => onExpand(record, e)} /> : <DownOutlined style={{ fontSize: 10 }} onClick={e => onExpand(record, e)} />
},
rowExpandable: record => {
return record?.alreadyCheckedOut;
}
};
}
} else {
expandable = {
expandedRowRender: record => <></>,
expandIcon: ({ expanded, onExpand, record }) => {
return null;
},
rowExpandable: record => {
return false;
}
}
const
onExpandedTableContextMenu
=
(
e
,
item
)
=>
{
setCurrentItem
(
item
);
displayMenu
(
e
);
}
const displayMenu = (e) => {
show
(
e
);
show({
event: e
})
}
const
handleItemClick
=
({
event
,
props
,
data
,
triggerEvent
})
=>
{
const
key
=
event
.
currentTarget
.
id
;
const onServiceDetailClose = () => {
setServiceDetailParams({ visible: false, id: '' })
}
if
(
key
===
'edit'
)
{
editItem
(
currentItem
);
}
else
if
(
key
===
'delete'
)
{
deleteItem
(
currentItem
);
}
else
if
(
key
===
'history'
)
{
historyItem
(
currentItem
);
}
else
if
(
key
===
'copy'
)
{
window
.
open
(
`/data-govern/data-model-action?
${
Action
}
=add&
${
CatalogId
}
=
${(
view
===
'dir'
)?(
catalogId
||
''
):
''
}
&
${
ModelerId
}
=
${
currentItem
.
id
}
`
);
}
else
if
(
key
===
'createTable'
)
{
deployAction
(
currentItem
);
}
else
if
(
key
.
indexOf
(
'action'
)
!==
-
1
)
{
const
index
=
(
key
.
split
(
'-'
))[
1
];
const
action
=
currentItem
?.
state
?.
supportedActions
[
index
];
stateAction
(
currentItem
,
action
);
const onSampleClose = () => {
setSampleParams({ visible: false, service: undefined });
}
const onExchangeOwnerClose = (refresh = false) => {
setExchangeOwnerParams({ visible: false, id: undefined });
refresh && onChange?.();
}
let disableEdit = false, disableDelete = false, editTip = '', deleteTip = '', editMenuTitle = '编辑';
...
...
@@ -465,90 +899,89 @@ const ModelTable = (props) => {
disableEdit = true;
if (currentItem?.state?.id === '2') {
editTip
=
'待发布的
模型
不允许编辑'
;
editTip = '待发布的
服务
不允许编辑';
}
}
if
(
!
currentItem
?.
permitCheckOut
&&
currentItem
?.
state
?.
id
===
'4'
)
{
disableEdit
=
true
;
editTip
=
`
${
currentItem
.
holder
||
''
}
正在编辑中, 不允许再编辑`
;
editMenuTitle
=
`编辑(
${
currentItem
.
holder
||
''
}
正在编辑中)`
;
}
//
if (!currentItem?.permitCheckOut && currentItem?.state?.id==='4') {
//
disableEdit = true;
//
editTip = `
$
{
currentItem
.
holder
||
''
}
正在编辑中
,
不允许再编辑
`;
//
editMenuTitle = `
编辑
(
$
{
currentItem
.
holder
||
''
}
正在编辑中
)
`;
//
}
if (!currentItem?.deletable) {
disableDelete = true;
if (currentItem?.state?.id === '2') {
deleteTip
=
'待发布的
模型
不允许删除'
;
deleteTip = '待发布的
服务
不允许删除';
} else if (currentItem?.state?.id === '4') {
deleteTip
=
'已发布的
模型
不允许删除'
;
deleteTip = '已发布的
服务
不允许删除';
}
}
return (
<
div
>
<
div
className=
'flex'
style=
{
{
height
:
20
,
alignItems
:
'center'
,
marginBottom
:
12
}
}
>
<
Paragraph
style=
{
{
overflow
:
'hidden'
}
}
>
<
Text
className=
'title-color'
ellipsis=
{
true
}
>
总数:
<
Text
className=
'text-color'
>
{
(
data
||
[]).
length
}
</
Text
>
</
Text
>
</
Paragraph
>
<
Paragraph
style=
{
{
overflow
:
'hidden'
,
marginLeft
:
20
}
}
>
<
Text
className=
'title-color'
ellipsis=
{
true
}
>
已选数:
<
Text
className=
'text-color'
>
{
summarySelectedCount
}
</
Text
>
</
Text
>
</
Paragraph
>
</
div
>
<
DataGrid
gridRef=
{
gridRef
}
style=
{
{
blockSize
:
'calc(100vh - 94px - 37px - 57px - 24px - 32px)'
}
}
checkable
columns=
{
columns
}
// rows={Array.from({ length: 10000 }).map((_, i) => ({
// name: `test${i}`,
// }))}
rows=
{
data
||
[]
}
rowHeight=
{
51
}
rowClassName=
{
(
row
)
=>
{
return
(
row
.
id
===
anchorId
)?
'anchor'
:
''
<div className={classes}>
<Table
rowSelection={view!=='grant'?rowSelection:undefined}
rowKey={'id'}
extraColWidth={(modelId||needExpand)?85:32}
columns={columns||[]}
dataSource={modelId?(subData||[]):(filterData||[])}
pagination={false}
size={modelId?'small':'default'}
// rowClassName={(record, index) => 'cursor-contextmenu'}
onRow={(record, index) => {
return {
id: `
data
-
model
-
$
{
record
?.
id
}
`,
onContextMenu: event => {
setCurrentItem(record);
// displayMenu(event);
},
}
}}
rowClassName={(record, index) => (record?.id===anchorId)?'yy-table-select-row':''}
scroll={{ y: modelId?null:((filterData||[]).length===0?null:'calc(100vh - 121px - 57px - 24px - 38px - 44px)') }}
onChange={onTableChange}
expandable={!isOnlyEnding ? expandable : undefined}
/>
{
!modelId && (data||[]).length>0 && <Pagination
className="text-center mt-3"
showSizeChanger
onChange={(_pageNum, _pageSize) => {
setPagination({ pageNum: _pageNum, pageSize: _pageSize || 20 });
}}
scrollRowIndex=
{
scrollRowIndex
}
expandable=
{
expandable
}
onContextMenu=
{
(
e
,
row
)
=>
{
setCurrentItem
(
row
);
displayMenu
(
e
);
onShowSizeChange={(_pageNum, _pageSize) => {
setPagination({ pageNum: 1, pageSize: _pageSize });
}}
selectedRows=
{
selectedRowKeys
}
onSelectedRowsChange=
{
onSelectChange
}
getComparator=
{
getComparator
}
current={pageNum}
pageSize={pageSize}
defaultCurrent={1}
total={(data||[]).length}
showTotal={total => `
共
$
{
total
}
条
`}
/>
}
<RcMenu id={MENU_ID}>
{
(
getDataModelerRole
(
user
)
!==
DataModelerRoleReader
)
&&
<
RcItem
id=
"edit"
disabled=
{
disableEdit
}
onClick=
{
handleItemClick
}
>
<
Tooltip
title=
{
editTip
}
>
{
editMenuTitle
}
</
Tooltip
>
{/* {
(getDataModelerRole(user)!==DataModelerRoleReader) && view!=='grant' && !isOnlyEnding && <RcItem id="edit" disabled={!currentItem?.editable&&!currentItem?.permitCheckOut} onClick={handleItemClick}>
编辑
</RcItem>
}
{
(
getDataModelerRole
(
user
)
!==
DataModelerRoleReader
)
&&
<
RcItem
id=
"delete"
disabled=
{
disableDelet
e
}
onClick=
{
handleItemClick
}
>
(getDataModelerRole(user)!==DataModelerRoleReader) &&
view!=='grant'&& !isOnlyEnding && <RcItem id="delete" disabled={!currentItem?.deletabl
e} onClick={handleItemClick}>
<Tooltip title={deleteTip}>
删除
</Tooltip>
</RcItem>
}
<RcItem id="sample" onClick={handleItemClick}>
样本数据
</RcItem>
<RcItem id="history" onClick={handleItemClick}>
历史版本
</RcItem>
{
(
getDataModelerRole
(
user
)
!==
DataModelerRoleReader
)
&&
<
RcItem
id=
"copy"
onClick=
{
handleItemClick
}
>
复制模型
</
RcItem
>
}
{
getDataModelerRole
(
user
)
!==
DataModelerRoleReader
&&
(
currentItem
?.
state
?.
supportedActions
||
[]).
length
>
0
&&
currentItem
?.
state
?.
supportedActions
.
map
((
item
,
index
)
=>
{
getDataModelerRole(user)!==DataModelerRoleReader && view!=='grant' && (currentItem?.state?.supportedActions||[]).length>0 && currentItem?.state?.supportedActions.map((item, index) => {
return (
<RcItem id={`
action
-
$
{
index
}
`} onClick={handleItemClick}>
{item.cnName||''}
...
...
@@ -557,38 +990,49 @@ const ModelTable = (props) => {
})
}
{
getDataModelerRole
(
user
)
!==
DataModelerRoleReader
&&
currentItem
?.
deployable
&&
<
RcItem
id=
'createTable'
onClick=
{
handleItemClick
}
>
建表
getDataModelerRole(user)!==DataModelerRoleReader&& view!=='grant' && <RcItem id="admit" onClick={handleItemClick} disabled={!currentItem?.grantable}>
授权
</RcItem>
}
{
getDataModelerRole(user)!==DataModelerRoleReader && view!=='grant' && isOnlyEnding && <RcItem id="startFlow" onClick={handleItemClick} disabled={currentItem?.grantable}>
申请
</RcItem>
}
{
getDataModelerRole(user)!==DataModelerRoleReader && view!=='grant' && !isOnlyEnding && currentItem?.supportODataEnable && <RcItem id="enableOData" onClick={handleItemClick}>
启动OData
</RcItem>
}
{
getDataModelerRole(user)!==DataModelerRoleReader && view!=='grant' && !isOnlyEnding && currentItem?.supportODataDisable && <RcItem id="disableOData" onClick={handleItemClick}>
停用OData
</RcItem>
}
{
getDataModelerRole(user)!==DataModelerRoleReader && view!=='grant' && !isOnlyEnding && currentItem?.supportODataDisable && <RcItem id="downloadTds" onClick={handleItemClick}>
下载Tableau tds
</RcItem>
}
{
getDataModelerRole(user)!==DataModelerRoleReader && view!=='grant' && currentItem?.supportSmartBIWebSpreadSheet && <RcItem id="smart" onClick={handleItemClick}>
跳转至电子表格
</RcItem>
}
{
getDataModelerRole(user)!==DataModelerRoleReader && view!=='grant' && currentItem?.supportChangeOwn && <RcItem id="exchangeOwner" onClick={handleItemClick}>
更换管理
</RcItem>
} */}
</RcMenu>
<ServiceDetail visible={serviceDetailParams.visible} id={serviceDetailParams.id} onClose={onServiceDetailClose} />
<SampleModal visible={sampleParams.visible} service={sampleParams.service} onCancel={onSampleClose} />
<ExchangeOwnerModal visible={exchangeOwnerParams.visible} id={exchangeOwnerParams.id} onCancel={onExchangeOwnerClose} />
{ contextHolder }
</div>
);
}
export default ModelTable;
\ No newline at end of file
function
getComparator
(
sortColumn
)
{
switch
(
sortColumn
)
{
case
'name'
:
case
'cnName'
:
case
'editor'
:
case
'remark'
:
case
'path'
:
return
(
a
,
b
)
=>
{
return
a
[
sortColumn
].
localeCompare
(
b
[
sortColumn
]);
};
case
'state'
:
return
(
a
,
b
)
=>
{
return
a
[
sortColumn
].
id
.
localeCompare
(
b
[
sortColumn
].
id
);
};
case
'modifiedTs'
:
return
(
a
,
b
)
=>
{
return
a
[
sortColumn
]
-
b
[
sortColumn
];
};
default
:
throw
new
Error
(
`unsupported sortColumn: "
${
sortColumn
}
"`
);
}
}
src/view/Manage/Model/Component/ModelTree.jsx
View file @
82cac42b
import
React
,
{
useState
,
useEffect
,
useContext
}
from
"react"
;
import
React
,
{
useState
,
useEffect
,
useContext
,
useMemo
}
from
"react"
;
import
{
Tooltip
,
Tree
,
Modal
,
Spin
,
Dropdown
,
Menu
,
Button
,
AutoComplete
}
from
"antd"
;
import
{
PlusOutlined
,
S
ync
Outlined
,
ImportOutlined
,
UnorderedListOutlined
,
ReloadOutlined
}
from
'@ant-design/icons'
;
import
{
PlusOutlined
,
S
wap
Outlined
,
ImportOutlined
,
UnorderedListOutlined
,
ReloadOutlined
}
from
'@ant-design/icons'
;
import
classnames
from
'classnames'
;
import
{
useContextMenu
,
Menu
as
RcMenu
,
Item
as
RcItem
}
from
"react-contexify"
;
...
...
@@ -22,7 +22,7 @@ const viewModes = [
},
{
key
:
'state'
,
name
:
'
模型
状态视角'
name
:
'
服务
状态视角'
}
];
...
...
@@ -34,11 +34,12 @@ const ModelTree = (props) => {
id
:
MENU_ID
,
});
const
{
onSelect
,
onViewChange
,
refrence
=
''
,
importStockModel
,
keyword
}
=
props
;
const
{
onSelect
,
onViewChange
,
refrence
=
''
,
importStockModel
,
keyword
,
isOnlyEnding
=
false
}
=
props
;
const
{
user
}
=
useContext
(
AppContext
);
const
{
user
,
env
}
=
useContext
(
AppContext
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
treeData
,
setTreeData
]
=
useState
(
null
);
const
[
rootItem
,
setRootItem
]
=
useState
();
const
[
item
,
setItem
]
=
useState
(
null
);
const
[
prevItem
,
setPrevItem
]
=
useState
(
null
);
const
[
visible
,
setVisible
]
=
useState
(
false
);
...
...
@@ -56,16 +57,18 @@ const ModelTree = (props) => {
const
[
dataList
,
setDataList
]
=
useState
([]);
const
[
options
,
setOptions
]
=
useState
([]);
const
[
serviceCountMapping
,
setServiceCountMapping
]
=
useState
();
const
[
modal
,
contextHolder
]
=
Modal
.
useModal
();
const
timestamp
=
getQueryParam
(
AnchorTimestamp
,
props
.
location
?.
search
||
''
);
const
id
=
getQueryParam
(
AnchorId
,
props
.
location
?.
search
||
''
);
const
did
=
getQueryParam
(
AnchorDirId
,
props
.
location
?.
search
||
''
);
useEffect
(()
=>
{
getShowSyncAndDomains
();
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[])
//
useEffect(() => {
//
getShowSyncAndDomains();
//
//eslint-disable-next-line react-hooks/exhaustive-deps
//
}, [])
useEffect
(()
=>
{
if
(
refrence
===
'recatalog'
)
{
...
...
@@ -97,7 +100,7 @@ const ModelTree = (props) => {
}
else
{
if
(
prevItem
&&
!
item
)
{
setItem
(
prevItem
);
onSelect
&&
onSelect
(
prevItem
?.
key
||
''
);
onSelect
&&
onSelect
(
prevItem
?.
key
||
''
,
null
,
prevItem
?.
key
===
rootId
);
setPrevItem
(
null
);
}
}
...
...
@@ -105,20 +108,46 @@ const ModelTree = (props) => {
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
keyword
])
const
getShowSyncAndDomains
=
()
=>
{
useEffect
(()
=>
{
getServiceCount
()
},
[
viewSelectedKey
])
// const getShowSyncAndDomains = () => {
// dispatch({
// type: 'datamodel.isSetRootDomainId',
// callback: data => {
// if (data === 'false') {
// dispatch({
// type: 'user.getDomains',
// callback: _data => {
// setDomains(_data||[]);
// setIsSetRootId(false);
// }
// });
// } else {
// setIsSetRootId(true);
// }
// }
// });
// }
const
getServiceCount
=
()
=>
{
dispatch
({
type
:
'datamodel.isSetRootDomainId
'
,
type
:
(
viewSelectedKey
===
'dir'
)
?
'pds.loadDataServiceCatalogServiceCount'
:
'pds.loadDataServiceStateCatalogServiceCount
'
,
callback
:
data
=>
{
if
(
data
===
'false'
)
{
dispatch
({
type
:
'user.getDomains'
,
callback
:
_data
=>
{
setDomains
(
_data
||
[]);
setIsSetRootId
(
false
);
if
(
viewSelectedKey
===
'dir'
)
{
let
newData
=
{}
for
(
const
key
in
(
data
||
{}))
{
let
total
=
0
const
item
=
data
[
key
]
for
(
const
id
in
item
)
{
total
=
total
+
item
[
id
]??
0
}
});
newData
[
key
]
=
total
}
setServiceCountMapping
(
newData
)
}
else
{
set
IsSetRootId
(
true
);
set
ServiceCountMapping
(
data
)
}
}
});
...
...
@@ -127,12 +156,13 @@ const ModelTree = (props) => {
const
getDataModelLocationThenGetDirTreeData
=
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'
datamodel.getDataModel
Location'
,
type
:
'
pds.getDataService
Location'
,
payload
:
{
id
pdsDataServiceId
:
id
,
namespace
:
`
${
env
?.
domainId
}
`
},
callback: data => {
getDirTreeData
(
data
.
easyDataModelerDataModel
CatalogId
||
''
,
data
.
offset
);
getDirTreeData(data.
pdsDataService
CatalogId||'', data.offset);
},
error: () => {
setLoading(false);
...
...
@@ -145,7 +175,7 @@ const ModelTree = (props) => {
setLoading(true);
dispatch({
type
:
(
type
===
'refresh'
)?
'
datamodel.refreshDataModelCatalog'
:
'datamodel.loadDataModel
Catalog'
,
type: (type==='refresh')?'
pds.refreshCatalog':'pds.loadDataService
Catalog',
callback: data => {
data.key = data.id||'';
...
...
@@ -175,6 +205,7 @@ const ModelTree = (props) => {
setLoading(false);
setTreeData(data.subCatalogs||[]);
setRootId(data.id||'');
setRootItem(data);
const _dataList = [];
generateList(data.subCatalogs||[], _dataList);
...
...
@@ -198,14 +229,14 @@ const ModelTree = (props) => {
} else if (refrence === '') {
const
currentItem
=
(
data
.
subCatalogs
||
[]).
length
>
0
?
data
.
subCatalogs
[
0
]:
null
;
setItem
(
currentItem
);
if
(
currentItem
&&
currentItem
.
key
)
{
setExpandedKeys
([
currentItem
?.
key
]);
}
// const currentItem = (data.subCatalogs||[]).length>0?data.subCatalogs[0]: null;
onSelect
&&
onSelect
(
currentItem
?(
currentItem
.
key
||
''
):
''
);
// setItem(currentItem);
// if (currentItem && currentItem.key) {
// setExpandedKeys([currentItem?.key]);
// }
setItem(data);
onSelect && onSelect(data?.id, null, true);
}
},
...
...
@@ -218,7 +249,10 @@ const ModelTree = (props) => {
const getStateTreeData = () => {
setLoading(true);
dispatch({
type
:
'datamodel.loadDataModelStateCatalog'
,
type: 'pds.loadStateCatalog',
payload: {
isOnlyEnding
},
callback: data => {
setLoading(false);
let _treeData = data?.subCatalogs||[];
...
...
@@ -285,27 +319,32 @@ const ModelTree = (props) => {
}
}
const
onSyncMenuClick
=
({
key
})
=>
{
//
const onSyncMenuClick = ({ key }) => {
setDomainSelectedKey
(
key
);
dispatch
({
type
:
'datamodel.setRootDomainId'
,
payload
:
{
params
:
{
domainId
:
key
}
},
callback
:
()
=>
{
setIsSetRootId
(
true
);
getDirTreeData
(
''
,
null
,
'load'
);
}
});
//
setDomainSelectedKey(key);
//
dispatch({
//
type: 'datamodel.setRootDomainId',
//
payload: {
//
params: {
//
domainId: key
//
}
//
},
//
callback: () => {
//
setIsSetRootId(true);
//
getDirTreeData('', null, 'load');
//
}
//
});
}
//
}
const
onTreeSelect
=
(
keys
,
data
)
=>
{
if
((
keys
||
[]).
length
===
0
)
{
if
(
viewSelectedKey
===
'dir'
)
{
setItem
(
rootItem
);
onSelect
&&
onSelect
(
rootId
,
null
,
true
);
}
return
;
}
...
...
@@ -331,6 +370,8 @@ const ModelTree = (props) => {
}
else
{
getStateTreeData
(
item
?.
key
||
''
);
}
getServiceCount
();
}
const
sync
=
()
=>
{
...
...
@@ -340,9 +381,9 @@ const ModelTree = (props) => {
const
moveNode
=
(
steps
)
=>
{
setLoading
(
true
);
dispatch
({
type
:
'
datamodel.upDownModel
Catalog'
,
type
:
'
pds.upDown
Catalog'
,
payload
:
{
model
CatalogId
:
currentRightClickDir
.
id
,
pdsDataService
CatalogId
:
currentRightClickDir
.
id
,
steps
},
callback
:
()
=>
{
...
...
@@ -358,14 +399,14 @@ const ModelTree = (props) => {
const
deleteNode
=
()
=>
{
modal
.
confirm
({
title
:
'提示!'
,
content
:
'删除目录会删除相关的
模型
,您确定删除吗?'
,
content
:
'删除目录会删除相关的
服务
,您确定删除吗?'
,
onOk
:
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'
datamodel.deleteDataModel
Catalog'
,
type
:
'
pds.delete
Catalog'
,
payload
:
{
params
:
{
easyDataModeler
CatalogId
:
currentRightClickDir
.
id
pdsDataService
CatalogId
:
currentRightClickDir
.
id
}
},
callback
:
()
=>
{
...
...
@@ -453,7 +494,8 @@ const ModelTree = (props) => {
};
const
displayMenu
=
(
e
)
=>
{
show
(
e
,
{
show
({
event
:
e
,
position
:
{
x
:
e
.
clientX
+
30
,
y
:
e
.
clientY
-
10
...
...
@@ -477,17 +519,17 @@ const ModelTree = (props) => {
</
Menu
>
);
const
syncMenu
=
(
<
Menu
selectedKeys=
{
[
domainSelectedKey
]
}
onClick=
{
onSyncMenuClick
}
>
{
domains
&&
domains
.
map
(
domain
=>
{
return
(
<
Menu
.
Item
key=
{
domain
.
domainId
}
value=
{
domain
.
domainId
}
>
{
domain
.
domainName
}
</
Menu
.
Item
>
)
})
}
</
Menu
>
);
//
const syncMenu = (
//
<Menu selectedKeys={[domainSelectedKey]} onClick={onSyncMenuClick}>
//
{
//
domains && domains.map(domain => {
//
return (
//
<Menu.Item key={domain.domainId} value={domain.domainId} >{domain.domainName}</Menu.Item>
//
)
//
})
//
}
//
</Menu>
//
);
const
classes
=
classnames
(
'model-tree'
,
{
'model-tree-recatalog'
:
(
refrence
===
'recatalog'
)
...
...
@@ -503,7 +545,7 @@ const ModelTree = (props) => {
borderBottom
:
"1px solid #EFEFEF"
,
height
:
57
,
alignItems
:
'center'
,
justifyContent
:
(
viewSelectedKey
===
'dir'
&&
getDataModelerRole
(
user
)
===
DataModelerRoleAdmin
)?
'space-between'
:
''
,
//
justifyContent: (viewSelectedKey==='dir' && getDataModelerRole(user)===DataModelerRoleAdmin)?'space-between':'',
}
}
>
<
Dropdown
overlay=
{
exportMenu
}
placement=
"bottomLeft"
>
...
...
@@ -513,38 +555,38 @@ const ModelTree = (props) => {
</
Dropdown
>
{
(
viewSelectedKey
===
'dir'
&&
getDataModelerRole
(
user
)
===
DataModelerRoleAdmin
)
&&
(
<
Tooltip
title=
"新增目录"
className=
'ml-2
'
>
<
PlusOutlined
className=
'default'
onClick=
{
add
}
style=
{
{
fontSize
:
16
,
cursor
:
'pointer'
}
}
/>
</
Tooltip
>
)
// (viewSelectedKey==='dir' && getDataModelerRole(user)===DataModelerRoleAdmin && !isOnlyEnding
) && (
// <Tooltip title="新增目录" className='ml-6
'>
//
<PlusOutlined className='default' onClick=
{
add
}
style
=
{{
fontSize
:
16
,
cursor
:
'pointer'
}}
/
>
//
</Tooltip>
//
)
}
{
{
/* {
(viewSelectedKey==='dir' && getDataModelerRole(user)===DataModelerRoleAdmin) && (
<Tooltip title="存量模型导入" className='ml-2'>
<ImportOutlined className='default' onClick={() => { importStockModel && importStockModel() }} style={{ fontSize:16,cursor:'pointer' }} />
</Tooltip>
)
}
}
*/
}
<
Tooltip
title=
"刷新目录"
className=
'ml-
2
'
>
<
Tooltip
title=
"刷新目录"
className=
'ml-
6
'
>
<
Button
type=
'text'
icon=
{
<
ReloadOutlined
className=
'default'
/>
}
size=
'small'
onClick=
{
refresh
}
/>
</
Tooltip
>
{
{
/* {
(viewSelectedKey==='dir' && getDataModelerRole(user)===DataModelerRoleAdmin) && !isSetRootId && (
<Dropdown overlay={syncMenu} placement="bottomLeft">
<Tooltip title="同步目录">
<
S
yncOutlined
className=
'default ml-2'
style=
{
{
fontSize
:
16
,
cursor
:
'pointer'
}
}
/>
<S
wapOutlined className='default ml-2' style={{ fontSize:16,cursor:'pointer', transform: 'rotate(90deg)',
}} />
</Tooltip>
</Dropdown>
)
}
}
*/
}
{
(
viewSelectedKey
===
'dir'
&&
getDataModelerRole
(
user
)
===
DataModelerRoleAdmin
)
&&
isSetRootId
&&
(
<
Tooltip
title=
"同步目录"
className=
'ml-
2
'
>
<
Button
type=
'text'
icon=
{
<
S
yncOutlined
className=
'default'
/>
}
size=
'small'
onClick=
{
sync
}
/>
<
Tooltip
title=
"同步目录"
className=
'ml-
6
'
>
<
Button
type=
'text'
icon=
{
<
S
wapOutlined
className=
'default'
style=
{
{
transform
:
'rotate(90deg)'
}
}
/>
}
size=
'small'
onClick=
{
sync
}
/>
</
Tooltip
>
)
}
...
...
@@ -557,6 +599,7 @@ const ModelTree = (props) => {
allowClear
value=
{
searchKeyword
}
style=
{
{
marginBottom
:
10
,
width
:
'100%'
}
}
placeholder=
'搜索目录'
onSelect=
{
onAutoCompleteSelect
}
onSearch=
{
onAutoCompleteSearch
}
onChange=
{
onAutoCompleteChange
}
...
...
@@ -576,6 +619,7 @@ const ModelTree = (props) => {
</
AutoComplete
>
}
<
Tree
className=
'tree-contextmenu'
onExpand=
{
onExpand
}
expandedKeys=
{
expandedKeys
}
autoExpandParent=
{
autoExpandParent
}
...
...
@@ -585,10 +629,19 @@ const ModelTree = (props) => {
treeData=
{
treeData
}
selectedKeys=
{
[
item
?
item
.
key
:
''
]
}
titleRender=
{
(
nodeData
)
=>
{
return
<
span
title=
{
nodeData
?.
remark
||
''
}
>
{
nodeData
?.
name
||
''
}
</
span
>;
let
title
=
nodeData
?.
name
if
(
nodeData
.
status
===
-
1
)
{
title
=
`${title}_已停用`
}
if
(
serviceCountMapping
?.[
nodeData
.
id
]
!==
null
&&
serviceCountMapping
?.[
nodeData
.
id
]
!==
undefined
)
{
title
=
`${title} (${serviceCountMapping?.[nodeData.id]})`
}
return
<
span
title=
{
nodeData
?.
remark
||
''
}
className=
'cursor-pointer-contextmenu'
>
{
title
}
</
span
>;
}
}
onRightClick=
{
({
event
,
node
})
=>
{
if
(
viewSelectedKey
===
'dir'
&&
getDataModelerRole
(
user
)
===
DataModelerRoleAdmin
)
{
if
(
viewSelectedKey
===
'dir'
)
{
setCurrentRightClickDir
(
node
);
displayMenu
(
event
);
}
...
...
src/view/Manage/Model/Component/ODataConfigModal.jsx
0 → 100644
View file @
82cac42b
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
Modal
,
Button
,
Form
,
Input
}
from
'antd'
;
import
{
dispatch
}
from
'../../../../model'
;
const
FC
=
(
props
)
=>
{
const
{
visible
,
service
,
onCancel
}
=
props
;
const
[
confirmLoading
,
setConfirmLoading
]
=
useState
(
false
);
const
[
form
]
=
Form
.
useForm
();
useEffect
(()
=>
{
if
(
visible
)
{
form
?.
setFieldsValue
({
name
:
service
?.
odata
});
}
},
[
visible
])
const
onOk
=
async
()
=>
{
try
{
const
row
=
await
form
.
validateFields
();
setConfirmLoading
(
true
);
dispatch
({
type
:
'pds.enableOData'
,
payload
:
{
params
:
{
pdsDataServiceId
:
service
?.
id
,
name
:
row
.
name
,
}
},
callback
:
data
=>
{
setConfirmLoading
(
false
);
cancel
(
true
);
},
error
:
()
=>
{
setConfirmLoading
(
false
);
}
});
}
catch
(
errInfo
)
{
console
.
log
(
'Validate Failed:'
,
errInfo
);
}
}
const
reset
=
()
=>
{
form
.
resetFields
();
setConfirmLoading
(
false
);
}
const
cancel
=
(
refresh
=
false
)
=>
{
reset
();
onCancel
?.(
refresh
);
}
const
footer
=
[
<
Button
key=
"0"
onClick=
{
()
=>
{
cancel
()}
}
>
取消
</
Button
>,
<
Button
key=
"1"
type=
"primary"
loading=
{
confirmLoading
}
onClick=
{
onOk
}
>
确定
</
Button
>,
];
return
(
<
Modal
forceRender
visible=
{
visible
}
title=
{
`启用${service?.name}的OData`
}
width=
{
540
}
onCancel=
{
()
=>
{
cancel
()}
}
footer=
{
footer
}
>
<
Form
form=
{
form
}
>
<
Form
.
Item
name=
'name'
label=
'URI'
rules=
{
[
{
required
:
true
,
message
:
'请输入URI'
,
},
]
}
>
<
Input
placeholder=
'请输入URI'
/>
</
Form
.
Item
>
</
Form
>
</
Modal
>
)
}
export
default
FC
;
\ No newline at end of file
src/view/Manage/Model
Config/Component/UpdatePartitionModal
.jsx
→
src/view/Manage/Model
/Component/Offline
.jsx
View file @
82cac42b
import
React
,
{
use
Effect
,
use
State
}
from
'react'
;
import
React
,
{
useState
}
from
'react'
;
import
{
Modal
,
Form
,
Input
}
from
'antd'
;
import
LocalStorage
from
'local-storage'
;
import
{
dispatch
}
from
'../../../../model'
;
import
{
dispatchLatest
}
from
'../../../../model'
;
import
{
showMessage
,
showNotifaction
}
from
'../../../../util'
;
const
UpdatePartitionModal
=
(
props
)
=>
{
const
{
visible
,
onCancel
,
i
tem
,
action
=
'add'
}
=
props
;
const
FC
=
(
props
)
=>
{
const
{
visible
,
onCancel
,
i
ds
}
=
props
;
const
[
form
]
=
Form
.
useForm
();
const
[
confirmLoading
,
setConfirmLoading
]
=
useState
(
false
);
...
...
@@ -20,38 +22,25 @@ const UpdatePartitionModal = (props) => {
},
};
useEffect
(()
=>
{
if
(
visible
)
{
if
(
action
!==
'add'
)
{
form
.
setFieldsValue
({
name
:
item
?.
name
||
''
,
cnName
:
item
?.
cnName
||
''
,
partitionMethod
:
item
?.
partitionMethod
||
''
,
definition
:
item
?.
definition
||
''
,
remark
:
item
?.
remark
||
''
});
}
}
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
visible
])
const
handleOk
=
async
()
=>
{
try
{
const
values
=
await
form
.
validateFields
();
let
newItem
=
null
;
if
(
action
===
'add'
)
{
newItem
=
{...
values
};
}
else
{
newItem
=
{...
item
,
...
values
};
}
setConfirmLoading
(
true
);
dispatch
({
type
:
'datamodel.savePartitionType'
,
dispatchLatest
({
type
:
'pds.offline'
,
payload
:
{
data
:
newItem
params
:
{
reason
:
values
?.
desc
},
callback
:
data
=>
{
setConfirmLoading
(
false
);
data
:
ids
},
callback
:
()
=>
{
reset
();
showMessage
(
'success'
,
'停用成功'
)
onCancel
&&
onCancel
(
true
);
},
error
:
()
=>
{
...
...
@@ -73,7 +62,7 @@ const UpdatePartitionModal = (props) => {
<
Modal
forceRender
visible=
{
visible
}
title=
{
action
===
'add'
?
'新增分区'
:
'编辑分区'
}
title=
'服务停用'
width=
{
520
}
confirmLoading=
{
confirmLoading
}
onCancel=
{
()
=>
{
...
...
@@ -87,41 +76,15 @@ const UpdatePartitionModal = (props) => {
form=
{
form
}
>
<
Form
.
Item
label=
"名称"
name=
"name"
rules=
{
[{
required
:
true
,
message
:
'请输入分区名称'
}]
}
>
<
Input
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"中文名称"
name=
"cnName"
rules=
{
[{
required
:
true
,
message
:
'请输入分区中文名称'
}]
}
>
<
Input
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"分区方式"
name=
"partitionMethod"
rules=
{
[{
required
:
true
,
message
:
'请输入分区方式'
}]
}
>
<
Input
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"定义"
name=
"definition"
>
<
Input
.
TextArea
row=
{
4
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"描述"
name=
"remark"
label=
"停用原因"
name=
"desc"
// rules={[{ required: true, message: '请填写停用原因' }]}
>
<
Input
.
TextArea
row
=
{
4
}
/>
<
Input
.
TextArea
row
s=
{
6
}
/>
</
Form
.
Item
>
</
Form
>
</
Modal
>
);
}
export
default
UpdatePartitionModal
;
\ No newline at end of file
export
default
FC
;
\ No newline at end of file
src/view/Manage/Model/Component/RecatalogModal.jsx
View file @
82cac42b
...
...
@@ -17,17 +17,17 @@ const RecatalogModal = (props) => {
const
onOk
=
()
=>
{
if
((
catalogId
||
''
)
===
''
)
{
showMessage
(
'warn'
,
'请先选择
模型
目录'
);
showMessage
(
'warn'
,
'请先选择
服务
目录'
);
return
;
}
setConfirmLoading
(
true
);
dispatch
({
type
:
'
datamodel.recatalogDataModel
'
,
type
:
'
pds.recatalogService
'
,
payload
:
{
params
:
{
easyDataModel
CatalogId
:
catalogId
,
easyDataModelerDataModel
Ids
:
ids
.
join
(
','
)
pdsDataService
CatalogId
:
catalogId
,
pdsDataService
Ids
:
ids
.
join
(
','
)
},
},
callback
:
message
=>
{
...
...
src/view/Manage/Model/Component/SampleModal.jsx
0 → 100644
View file @
82cac42b
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
Modal
,
Button
,
Form
,
Input
,
Table
,
Tooltip
,
Typography
}
from
'antd'
;
import
{
dispatch
}
from
'../../../../model'
;
const
FC
=
(
props
)
=>
{
const
{
visible
,
service
,
onCancel
}
=
props
;
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
data
,
setData
]
=
useState
(
undefined
);
const
[
cols
,
setCols
]
=
useState
([]);
useEffect
(()
=>
{
if
(
visible
)
{
getSample
();
}
},
[
visible
])
const
getSample
=
()
=>
{
setLoading
(
true
)
dispatch
({
type
:
'pds.getSample'
,
payload
:
{
params
:
{
pdsDataServiceId
:
service
?.
id
,
}
},
callback
:
data
=>
{
setLoading
(
false
);
setData
(
data
?.
content
||
[]);
const
newCols
=
[];
data
?.
headers
?.
forEach
(
item
=>
{
if
(
item
)
{
newCols
.
push
({
title
:
item
,
dataIndex
:
item
,
width
:
150
,
ellipsis
:
true
,
render
:
(
value
,
record
)
=>
<
Tooltip
title=
{
value
}
>
<
Typography
.
Text
ellipsis=
{
true
}
>
{
value
}
</
Typography
.
Text
>
</
Tooltip
>
});
}
});
setCols
(
newCols
);
},
error
:
()
=>
{
setLoading
(
false
);
}
});
}
const
cancel
=
()
=>
{
setLoading
(
false
);
setData
(
undefined
);
onCancel
?.();
}
const
footer
=
[
<
Button
key=
"0"
onClick=
{
()
=>
{
cancel
()}
}
>
取消
</
Button
>,
];
return
(
<
Modal
forceRender
visible=
{
visible
}
title=
{
`${service?.name}的样本数据`
}
width=
{
650
}
onCancel=
{
()
=>
{
cancel
()}
}
footer=
{
footer
}
>
<
Table
loading=
{
loading
}
columns=
{
cols
}
dataSource=
{
data
||
[]
}
size=
'small'
scroll=
{
{
x
:
600
,
y
:
300
}
}
pagination=
{
false
}
/>
</
Modal
>
)
}
export
default
FC
;
\ No newline at end of file
src/view/Manage/Model/Component/SelectFilter.jsx
0 → 100644
View file @
82cac42b
import
React
,
{
useState
,
useMemo
,
useEffect
}
from
"react"
import
{
Select
}
from
"antd"
import
debounce
from
'lodash/debounce'
;
const
{
Option
}
=
Select
const
FC
=
({
value
,
onChange
,
data
,
...
restProps
})
=>
{
const
[
searchValue
,
setSearchValue
]
=
useState
(
undefined
)
const
debounceFetcher
=
useMemo
(()
=>
{
return
debounce
((
value
)
=>
{
setSearchValue
(
value
);
},
800
);
},
[]);
const
filterData
=
useMemo
(()
=>
{
if
(
searchValue
)
{
return
data
?.
filter
(
item
=>
item
.
includes
(
searchValue
));
}
return
data
||
[];
},
[
data
,
searchValue
])
const
change
=
(
value
)
=>
{
onChange
?.(
value
)
}
return
(
<
Select
style=
{
{
width
:
'100%'
}
}
showSearch
value=
{
value
}
onChange=
{
change
}
allowClear
filterOption=
{
false
}
onSearch=
{
debounceFetcher
}
{
...
restProps
}
>
{
filterData
?.
map
((
item
,
index
)
=>
{
return
(
<
Option
value=
{
item
}
key=
{
index
}
>
{
item
}
</
Option
>
)
})
}
</
Select
>
)
}
export
default
FC
\ No newline at end of file
src/view/Manage/Model/Component/SelectUsers.jsx
0 → 100755
View file @
82cac42b
import
React
,
{
useState
,
useMemo
,
useEffect
}
from
"react"
import
{
Select
,
Typography
}
from
"antd"
import
debounce
from
'lodash/debounce'
;
import
{
highlightSearchContentByTerms
}
from
'../../../../util'
;
const
{
Option
}
=
Select
const
SelectUser
:
React
.
FC
=
(
props
)
=>
{
const
{
value
,
onChange
,
users
,
type
,
loading
=
false
,
terms
,
publishedValue
}
=
props
const
[
searchValue
,
setSearchValue
]
=
useState
(
undefined
)
const
debounceFetcher
=
useMemo
(()
=>
{
return
debounce
((
value
)
=>
{
setSearchValue
(
value
);
},
800
);
},
[]);
const
filterUsers
=
useMemo
(()
=>
{
if
(
searchValue
)
{
return
users
?.
filter
(
item
=>
item
.
nachn
?.
includes
(
searchValue
)
||
item
.
pernr
?.
includes
(
searchValue
));
}
return
users
||
[];
},
[
users
,
searchValue
])
const
change
=
(
value
)
=>
{
onChange
&&
onChange
(
value
)
}
if
(
type
===
'edit'
){
return
(
<
Select
style=
{
{
width
:
'100%'
}
}
showSearch
value=
{
value
}
onChange=
{
change
}
loading=
{
loading
}
allowClear
filterOption=
{
false
}
onSearch=
{
debounceFetcher
}
>
{
filterUsers
?.
map
((
item
)
=>
{
return
(
<
Option
value=
{
item
.
pernr
}
key=
{
item
.
pernr
}
>
{
`${item.nachn}(${item.pernr})`
}
</
Option
>
)
})
}
</
Select
>
)
}
else
if
(
type
===
'detail'
){
return
<
span
>
<
Typography
.
Text
>
{
highlightSearchContentByTerms
(
value
,
terms
)
}
</
Typography
.
Text
>
{
publishedValue
&&
publishedValue
!==
value
&&
<
Typography
.
Text
className=
'ml-2'
type=
'danger'
><
del
>
{
publishedValue
}
</
del
></
Typography
.
Text
>
}
</
span
>
// try {
// const user = (users??[]).filter((item)=>(item.pernr===value))
// let publishedUser = null;
// if (publishedValue && publishedValue !== value) {
// publishedUser = (users??[]).filter((item)=>(item.pernr===publishedValue))
// }
// return <span>
// <Typography.Text>{highlightSearchContentByTerms(`${user[0].nachn}(${user[0].pernr})`, terms)}</Typography.Text>
// {
// publishedUser && <Typography.Text className='ml-2' type='danger'><del>{`${publishedUser[0].nachn}(${publishedUser[0].pernr})`}</del></Typography.Text>
// }
// </span>;
// } catch (error) {
// return <span>
// <Typography.Text>{highlightSearchContentByTerms(value, terms)}</Typography.Text>
// {
// publishedValue && publishedValue!==value && <Typography.Text className='ml-2' type='danger'><del>{publishedValue}</del></Typography.Text>
// }
// </span>
// }
}
else
{
return
null
}
}
export
default
SelectUser
\ No newline at end of file
src/view/Manage/Model/Component/ServiceDetail.jsx
0 → 100644
View file @
82cac42b
import
React
,
{
useState
,
useMemo
,
useEffect
}
from
'react'
import
{
Button
,
Modal
,
Spin
,
Popover
,
Table
,
Descriptions
,
Tooltip
}
from
'antd'
import
{
dispatch
}
from
'../../../../model'
import
{
highlightSearchContentByTerms
}
from
'../../../../util'
const
FC
=
(
props
)
=>
{
const
{
id
,
terms
}
=
props
const
[
data
,
setData
]
=
useState
()
const
[
loading
,
setLoading
]
=
useState
(
false
)
const
columns
=
[
{
title
:
'序号'
,
dataIndex
:
'key'
,
editable
:
false
,
width
:
60
,
fixed
:
'left'
,
render
:
(
text
,
record
,
index
)
=>
{
return
(
index
+
1
).
toString
();
}
},
{
title
:
'中文名称'
,
width
:
200
,
dataIndex
:
'cnName'
,
editable
:
true
,
ellipsis
:
true
,
require
:
true
,
fixed
:
'left'
,
render
:
(
text
,
_
,
__
)
=>
{
return
(
<
Tooltip
title=
{
text
||
''
}
>
<
span
>
{
highlightSearchContentByTerms
(
text
,
terms
)
}
</
span
>
</
Tooltip
>
)
}
},
{
title
:
'英文名称'
,
width
:
200
,
dataIndex
:
'name'
,
editable
:
true
,
ellipsis
:
true
,
require
:
true
,
render
:
(
text
,
record
,
index
)
=>
{
return
(
<
Tooltip
title=
{
text
||
''
}
>
<
span
style=
{
{
fontWeight
:
'bold'
}
}
>
{
highlightSearchContentByTerms
(
text
,
terms
)
}
</
span
>
</
Tooltip
>
)
}
},
{
title
:
'类型'
,
width
:
150
,
dataIndex
:
'datatype'
,
editable
:
true
,
ellipsis
:
true
,
require
:
true
,
render
:
(
_
,
record
,
__
)
=>
{
if
(
record
?.
datatype
)
{
if
((
record
?.
datatype
?.
name
===
'Char'
||
record
?.
datatype
?.
name
===
'Varchar'
)
&&
record
?.
datatype
?.
parameterValues
?.
length
>
0
)
{
return
`
${
record
?.
datatype
?.
name
||
''
}(
$
{(
record
?.
datatype
?.
parameterValues
[
0
]?
record
.
datatype
.
parameterValues
[
0
]:
0
)})
`;
} else if ((record?.datatype?.name==='Decimal'||record?.datatype?.name==='Numeric') && record?.datatype?.parameterValues?.length>1) {
return `
$
{
record
?.
datatype
?.
name
||
''
}(
$
{(
record
?.
datatype
?.
parameterValues
[
0
]?
record
.
datatype
.
parameterValues
[
0
]:
0
)},
$
{(
record
?.
datatype
?.
parameterValues
[
1
]?
record
.
datatype
.
parameterValues
[
1
]:
0
)})
`;
}
return record.datatype.name||'';
}
return '';
}
},
]
useEffect(() => {
getService()
}, [])
const getService = () => {
setLoading(true)
dispatch({
type: 'pds.getDataService',
payload: {
id
},
callback: (data) => {
setLoading(false)
setData(data||[])
},
error: () => {
setLoading(false)
}
})
}
return (
<Spin spinning={loading}>
<h3 className='mr-3' style={{ marginBottom: 0 }}>基本信息</h3>
<Descriptions className='mt-3' column={3}>
<Descriptions.Item label={<div style={{ textAlign: 'right', width: 85 }}>中文名称</div>} >{highlightSearchContentByTerms(data?.cnName||'', terms)}</Descriptions.Item>
<Descriptions.Item label={<div style={{ textAlign: 'right', width: 85 }}>英文名称</div>}>{highlightSearchContentByTerms(data?.name||'', terms)}</Descriptions.Item>
<Descriptions.Item label={<div style={{ textAlign: 'right', width: 85 }}>数据内容</div>}>{highlightSearchContentByTerms(data?.remark||'', terms)}</Descriptions.Item>
</Descriptions>
<h3 className='mr-3' style={{ marginBottom: 0 }}>字段列表</h3>
<Table
className='mt-3'
dataSource={data?.pdsdataServiceAttributes||[]}
columns={columns}
size='small'
rowKey='iid'
pagination={false}
sticky
/>
</Spin>
)
}
export default FC
src/view/Manage/Model/Component/ServiceDetailModal.jsx
0 → 100644
View file @
82cac42b
import
React
,
{
useState
,
useMemo
,
useEffect
}
from
'react'
import
{
Button
,
Modal
,
Spin
,
Popover
,
Table
,
Descriptions
,
Tooltip
}
from
'antd'
import
{
dispatch
}
from
'../../../../model'
import
{
highlightSearchContentByTerms
}
from
'../../../../util'
import
ServiceDetail
from
'./ServiceDetail'
const
FC
=
(
props
)
=>
{
const
{
visible
,
id
,
onClose
,
terms
}
=
props
const
close
=
()
=>
{
onClose
?.()
}
return
(
<
Modal
width=
{
1200
}
visible=
{
visible
}
destroyOnClose
title=
'服务详情'
bodyStyle=
{
{
minHeight
:
300
}
}
footer=
{
<>
<
Button
onClick=
{
close
}
>
取消
</
Button
>
</>
}
onCancel=
{
close
}
>
{
visible
&&
<
ServiceDetail
id=
{
id
}
terms=
{
terms
}
/>
}
</
Modal
>
)
}
export
default
FC
src/view/Manage/Model/Component/StartAuthorize.jsx
0 → 100644
View file @
82cac42b
import
React
,
{
useState
}
from
'react'
;
import
{
Modal
,
Form
,
Input
}
from
'antd'
;
import
LocalStorage
from
'local-storage'
;
import
{
dispatchLatest
}
from
'../../../../model'
;
import
{
showNotifaction
,
showMessage
}
from
'../../../../util'
;
const
FC
=
(
props
)
=>
{
const
{
visible
,
onCancel
,
services
}
=
props
;
const
[
form
]
=
Form
.
useForm
();
const
[
confirmLoading
,
setConfirmLoading
]
=
useState
(
false
);
const
formItemLayout
=
{
labelCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
4
},
},
wrapperCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
20
},
},
};
const
handleOk
=
async
()
=>
{
try
{
const
values
=
await
form
.
validateFields
();
setConfirmLoading
(
true
);
dispatchLatest
({
type
:
'pds.authorize'
,
payload
:
{
params
:
{
reason
:
values
?.
desc
},
data
:
services
},
callback
:
()
=>
{
reset
();
showMessage
(
'success'
,
'授权成功!'
);
onCancel
&&
onCancel
(
true
);
},
error
:
()
=>
{
setConfirmLoading
(
false
);
}
})
}
catch
(
errInfo
)
{
}
}
const
reset
=
()
=>
{
setConfirmLoading
(
false
);
form
.
resetFields
();
}
return
(
<
Modal
forceRender
visible=
{
visible
}
title=
'服务授权'
width=
{
520
}
confirmLoading=
{
confirmLoading
}
onCancel=
{
()
=>
{
reset
();
onCancel
&&
onCancel
();
}
}
onOk=
{
handleOk
}
>
<
Form
{
...
formItemLayout
}
form=
{
form
}
>
<
Form
.
Item
label=
"授权原因"
name=
"desc"
rules=
{
[{
required
:
true
,
message
:
'请填写授权原因'
}]
}
>
<
Input
.
TextArea
rows=
{
6
}
/>
</
Form
.
Item
>
</
Form
>
</
Modal
>
);
}
export
default
FC
;
\ No newline at end of file
src/view/Manage/Model/Component/StartRelease.jsx
0 → 100644
View file @
82cac42b
import
React
,
{
useState
}
from
'react'
;
import
{
Modal
,
Form
,
Input
}
from
'antd'
;
import
LocalStorage
from
'local-storage'
;
import
{
dispatchLatest
}
from
'../../../../model'
;
import
{
showMessage
,
showNotifaction
}
from
'../../../../util'
;
const
FC
=
(
props
)
=>
{
const
{
visible
,
onCancel
,
ids
}
=
props
;
const
[
form
]
=
Form
.
useForm
();
const
[
confirmLoading
,
setConfirmLoading
]
=
useState
(
false
);
const
formItemLayout
=
{
labelCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
4
},
},
wrapperCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
20
},
},
};
const
handleOk
=
async
()
=>
{
try
{
const
values
=
await
form
.
validateFields
();
setConfirmLoading
(
true
);
dispatchLatest
({
type
:
'pds.release'
,
payload
:
{
params
:
{
reason
:
values
?.
desc
},
data
:
ids
},
callback
:
()
=>
{
reset
();
showMessage
(
'success'
,
'发布成功!'
)
onCancel
&&
onCancel
(
true
);
},
error
:
()
=>
{
setConfirmLoading
(
false
);
}
})
}
catch
(
errInfo
)
{
}
}
const
reset
=
()
=>
{
setConfirmLoading
(
false
);
form
.
resetFields
();
}
return
(
<
Modal
forceRender
visible=
{
visible
}
title=
'服务发布'
width=
{
520
}
confirmLoading=
{
confirmLoading
}
onCancel=
{
()
=>
{
reset
();
onCancel
&&
onCancel
();
}
}
onOk=
{
handleOk
}
>
<
Form
{
...
formItemLayout
}
form=
{
form
}
>
<
Form
.
Item
label=
"发布原因"
name=
"desc"
rules=
{
[{
required
:
true
,
message
:
'请填写发布原因'
}]
}
>
<
Input
.
TextArea
rows=
{
6
}
/>
</
Form
.
Item
>
</
Form
>
</
Modal
>
);
}
export
default
FC
;
\ No newline at end of file
src/view/Manage/Model/Component/SuggestTable.jsx
View file @
82cac42b
import
React
,
{
useState
}
from
'react'
;
import
{
Table
,
Tooltip
,
Typography
}
from
'antd'
;
import
{
Table
,
Tooltip
}
from
'antd'
;
import
{
Resizable
}
from
'react-resizable'
;
import
ResizeObserver
from
'rc-resize-observer'
;
...
...
@@ -123,7 +123,7 @@ const SuggestTable = (props) => {
render
:
(
text
,
_
,
__
)
=>
{
return
(
<
Tooltip
title=
{
text
||
''
}
>
<
Typography
.
Text
ellipsis=
{
true
}
>
{
text
||
''
}
</
Typography
.
Text
>
<
span
>
{
text
||
''
}
</
span
>
</
Tooltip
>
)
}
...
...
src/view/Manage/Model/Component/UpdateTreeItemModal.jsx
View file @
82cac42b
...
...
@@ -70,6 +70,12 @@ class UpdateTreeItemForm extends React.Component {
>
<
Input
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"编码"
name=
"code"
>
<
Input
/>
</
Form
.
Item
>
</
Form
>
);
}
...
...
@@ -89,12 +95,12 @@ const UpdateTreeItemModal = (props) => {
_action
=
item
?
'sub'
:
'root'
;
}
form
.
setFields
([{
name
:
'name'
,
errors
:
[]
},
{
name
:
'remark'
,
errors
:
[]
}]);
form
.
setFields
([{
name
:
'name'
,
errors
:
[]
},
{
name
:
'remark'
,
errors
:
[]
}
,
{
name
:
'code'
,
errors
:
[]
}
]);
if
(
type
===
'add'
)
{
form
.
setFieldsValue
({
action
:
_action
,
name
:
''
,
remark
:
''
});
form
.
setFieldsValue
({
action
:
_action
,
name
:
''
,
remark
:
''
,
code
:
''
});
}
else
{
form
.
setFieldsValue
({
action
:
''
,
name
:
item
?
item
.
name
:
''
,
remark
:
item
?
item
.
remark
:
''
});
form
.
setFieldsValue
({
action
:
''
,
name
:
item
?
item
.
name
:
''
,
remark
:
item
?
item
.
remark
:
''
,
code
:
item
?.
code
});
}
}
//eslint-disable-next-line react-hooks/exhaustive-deps
...
...
@@ -112,12 +118,14 @@ const UpdateTreeItemModal = (props) => {
payload
=
{
name
:
values
.
name
||
''
,
remark
:
values
.
remark
||
''
,
code
:
values
.
code
||
''
,
parentId
:
rootId
};
}
else
if
(
type
===
'add'
)
{
payload
=
{
name
:
values
.
name
||
''
,
remark
:
values
.
remark
||
''
,
code
:
values
.
code
||
''
,
parentId
:
item
.
id
};
}
else
{
...
...
@@ -125,11 +133,12 @@ const UpdateTreeItemModal = (props) => {
...
item
,
name
:
values
.
name
||
''
,
remark
:
values
.
remark
||
''
,
code
:
values
.
code
||
''
,
}
}
dispatchLatest
({
type
:
'
datamodel.saveDataModel
Catalog'
,
type
:
'
pds.save
Catalog'
,
payload
:
{
data
:
payload
},
...
...
src/view/Manage/Model/Component/VersionHistory.jsx
View file @
82cac42b
...
...
@@ -22,7 +22,7 @@ const VersionHistory = (props) => {
const
getVersions
=
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'
datamodel
.getVersions'
,
type
:
'
pds
.getVersions'
,
payload
:
{
params
:
{
id
...
...
@@ -39,7 +39,7 @@ const VersionHistory = (props) => {
}
const
onVersionItemClick
=
(
version
)
=>
{
window
.
open
(
`/data-govern/data-model-action?
${
Action
}
=detail-version&
${
ModelerId
}
=
${
version
.
dataModelId
||
''
}
&
${
VersionId
}
=
${
version
.
id
||
''
}
`
);
//
window.open(`/data-govern/data-model-action?${Action}=detail-version&${ModelerId}=${version.dataModelId||''}&${VersionId}=${version.id||''}`);
}
return
(
...
...
src/view/Manage/Model/index.jsx
View file @
82cac42b
import
React
from
'react'
;
import
{
Button
,
Space
,
Spin
,
Input
,
Select
,
Tooltip
}
from
'antd'
;
import
{
Button
,
Space
,
Spin
,
Input
,
Select
,
Tooltip
,
Dropdown
,
Menu
,
Modal
}
from
'antd'
;
import
copy
from
"copy-to-clipboard"
;
import
{
CaretLeftOutlined
,
CaretRightOutlined
}
from
'@ant-design/icons'
;
import
{
ResizableBox
}
from
'react-resizable'
;
...
...
@@ -14,12 +14,18 @@ import ExportOtherModal from './Component/ExportOtherModal';
import
RecatalogModal
from
'./Component/RecatalogModal'
;
import
HistoryAndVersionDrawer
from
'./Component/HistoryAndVersionDrawer'
;
import
StartFlowModal
from
'./Component/StartFlowModal'
;
import
JDBCInformation
from
'./Component/JDBCInformation'
;
import
{
showMessage
,
showNotifaction
,
inputWidth
,
DeleteTipModal
,
getDataModelerRole
}
from
'../../../util'
;
import
{
dispatch
,
dispatchLatestHomepage
}
from
'../../../model'
;
import
{
Action
,
CatalogId
,
ModelerId
,
Hints
,
ModelerData
,
PermitCheckOut
,
Editable
,
StateId
,
Holder
,
DDL
,
DataModelerRoleReader
,
ReadOnly
}
from
'../../../util/constant'
;
import
{
AppContext
}
from
'../../../App'
;
import
DebounceInput
from
'./Component/DebounceInput'
;
import
ColSettingModal
from
'./Component/ColSettingModal'
;
import
StartAuthorize
from
'./Component/StartAuthorize'
;
import
StartRelease
from
'./Component/StartRelease'
;
import
Offline
from
'./Component/Offline'
;
import
ImportServices
from
'./Component/ImportServices'
;
import
download
from
'../../../util/download'
;
import
'./index.less'
;
...
...
@@ -29,8 +35,8 @@ const InputDebounce = DebounceInput(300)(Input);
class
Model
extends
React
.
Component
{
constructor
()
{
super
();
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
importModalVisible
:
false
,
importStockWordDrawerVisible
:
false
,
...
...
@@ -50,7 +56,8 @@ class Model extends React.Component {
hints
:
[],
loadingStates
:
false
,
modelStates
:
[],
currentModelState
:
''
,
currentModelState
:
props
.
isOnlyEnding
?
'4_0'
:
''
,
currentODataState
:
'0'
,
currentView
:
''
,
exportDDLModalReference
:
'exportDDL'
,
currentModel
:
{},
...
...
@@ -59,6 +66,15 @@ class Model extends React.Component {
showDeleteTip
:
false
,
colSettingModalVisible
:
false
,
visibleColNames
:
[],
startAuthorizeParams
:
{
visible
:
false
,
services
:
[]
},
startReleaseVisible
:
false
,
offlineVisible
:
false
,
jdbcInformationVisible
:
false
,
isRoot
:
false
,
importServicesVisible
:
false
,
}
}
...
...
@@ -82,11 +98,14 @@ class Model extends React.Component {
getModelStates
=
()
=>
{
this
.
setState
({
loadingStates
:
true
},
()
=>
{
dispatch
({
type
:
'datamodel.loadDataModelStateCatalog'
,
type
:
'pds.loadStateCatalog'
,
payload
:
{
isOnlyEnding
:
this
.
props
.
isOnlyEnding
},
callback
:
data
=>
{
this
.
setState
({
loadingStates
:
false
,
modelStates
:
[{
name
:
'all'
,
id
:
''
,
cnName
:
'所有状态'
},
...(
data
?.
subCatalogs
||
[])]
modelStates
:
this
.
props
.
isOnlyEnding
?
data
?.
subCatalogs
||
[]
:
[{
name
:
'all'
,
id
:
''
,
cnName
:
'所有状态'
},
...(
data
?.
subCatalogs
||
[])]
});
},
error
:
()
=>
{
...
...
@@ -98,14 +117,12 @@ class Model extends React.Component {
getPreference
=
()
=>
{
dispatch
({
type
:
'datamodel.getPreference'
,
type
:
'pds.getCols'
,
payload
:
{
modelName
:
'DataService'
},
callback
:
data
=>
{
this
.
setState
();
if
((
data
.
cols
||
''
)
===
''
)
{
this
.
setState
({
visibleColNames
:
[]});
}
else
{
this
.
setState
({
visibleColNames
:
data
.
cols
.
split
(
','
)});
}
this
.
setState
({
visibleColNames
:
data
?.
map
(
item
=>
item
.
titleCnName
)});
}
})
}
...
...
@@ -120,9 +137,14 @@ class Model extends React.Component {
})
}
onTreeSelect
=
(
key
,
offset
=
null
)
=>
{
onODataStateChange
=
(
value
)
=>
{
this
.
setState
({
currentODataState
:
value
,
offset
:
null
},
()
=>
{
this
.
onTableChange
();
})
}
this
.
setState
({
catalogId
:
key
,
keyword
:
''
,
offset
,
currentModelState
:
(
offset
!==
null
)?
''
:
this
.
state
.
currentModelState
},
()
=>
{
onTreeSelect
=
(
key
,
offset
=
null
,
isRoot
=
false
)
=>
{
this
.
setState
({
catalogId
:
key
,
keyword
:
''
,
offset
,
currentModelState
:
this
.
state
.
currentModelState
,
isRoot
},
()
=>
{
if
(
!
key
||
key
===
''
)
{
this
.
setState
({
tableData
:
[],
filterTableData
:
[]
});
}
else
{
...
...
@@ -132,14 +154,16 @@ class Model extends React.Component {
}
onTableChange
=
()
=>
{
const
{
currentView
,
catalogId
,
keyword
,
currentModelState
}
=
this
.
state
;
const
{
currentView
,
catalogId
,
keyword
,
currentModelState
,
currentODataState
}
=
this
.
state
;
this
.
setState
({
loadingTableData
:
true
},
()
=>
{
if
(
keyword
===
''
)
{
if
(
currentView
===
'dir'
)
{
const
params
=
{
easyDataModelerCatalogId
:
catalogId
,
pdsDataServiceCatalogId
:
catalogId
,
namespace
:
`
${
this
.
props
.
app
?.
env
?.
domainId
}
`,
isExcludeOtherOwner: !this.props.isOnlyEnding
};
if (currentModelState !== '') {
...
...
@@ -147,10 +171,19 @@ class Model extends React.Component {
}
dispatchLatestHomepage({
type
:
'
datamodel.getCurrentDataModelCatalog
'
,
type: '
pds.getServices
',
payload: params,
callback: data => {
this
.
setState
({
loadingTableData
:
false
,
tableData
:
data
.
easyDataModelerDataModels
||
[],
filterTableData
:
data
.
easyDataModelerDataModels
||
[]
});
const filterData = data.pdsdataServices?.filter(service => {
if (currentODataState === '0') return true;
if (currentODataState === '1') return service.supportODataDisable;
if (currentODataState === '2') return !service.supportODataDisable;
return false;
})
this.setState({ loadingTableData: false, tableData: data.pdsdataServices||[], filterTableData: filterData });
},
error: () => {
this.setState({ loadingTableData: false });
...
...
@@ -158,12 +191,22 @@ class Model extends React.Component {
})
} else {
dispatchLatestHomepage({
type
:
'
datamodel.getCurrentDataModelStateCatalog
'
,
type: '
pds.getStateServices
',
payload: {
easyDataModelerStateCatalogId
:
catalogId
pdsDataServiceStateCatalogId: catalogId,
namespace: `
$
{
this
.
props
.
app
?.
env
?.
domainId
}
`,
isExcludeOtherOwner: !this.props.isOnlyEnding
},
callback: data => {
this
.
setState
({
loadingTableData
:
false
,
tableData
:
data
.
easyDataModelerDataModels
||
[],
filterTableData
:
data
.
easyDataModelerDataModels
||
[]
});
const filterData = data.pdsdataServices?.filter(service => {
if (currentODataState === '0') return true;
if (currentODataState === '1') return service.supportODataDisable;
if (currentODataState === '2') return !service.supportODataDisable;
return false;
})
this.setState({ loadingTableData: false, tableData: data.pdsdataServices||[], filterTableData: filterData });
},
error: () => {
this.setState({ loadingTableData: false });
...
...
@@ -173,7 +216,9 @@ class Model extends React.Component {
} else {
const params = {
term
:
keyword
,
term: encodeURIComponent(keyword),
namespace: `
$
{
this
.
props
.
app
?.
env
?.
domainId
}
`,
isExcludeOtherOwner: !this.props.isOnlyEnding
};
if (currentModelState !== '') {
...
...
@@ -181,10 +226,18 @@ class Model extends React.Component {
}
dispatchLatestHomepage({
type
:
'
datamodel.searchModel
'
,
type: '
pds.searchService
',
payload: params,
callback: data => {
this
.
setState
({
loadingTableData
:
false
,
tableData
:
data
||
[],
filterTableData
:
data
||
[]
});
const filterData = data?.filter(service => {
if (currentODataState === '0') return true;
if (currentODataState === '1') return service.supportODataDisable;
if (currentODataState === '2') return !service.supportODataDisable;
return false;
})
this.setState({ loadingTableData: false, tableData: data||[], filterTableData: filterData });
},
error: () => {
this.setState({ loadingTableData: false });
...
...
@@ -212,7 +265,7 @@ class Model extends React.Component {
}
onSearchInputChange = (value) => {
this.setState({ keyword: value||'', catalogId: '' }, () => {
this.setState({ keyword: value||'', catalogId: ''
, isRoot: true
}, () => {
if (value !== '') {
this.onTableChange();
}
...
...
@@ -228,11 +281,11 @@ class Model extends React.Component {
onExportDDLBtnClick = () => {
const { selectModelerIds, tableData } = this.state;
if ((selectModelerIds||[]).length === 0) {
showMessage('info', '请先选择
模型
');
showMessage('info', '请先选择
服务
');
return;
}
//
模型
名称在导出ddl的时候有使用
//
服务
名称在导出ddl的时候有使用
const _selectModelerNames = [];
(selectModelerIds||[]).forEach(id => {
...
...
@@ -255,7 +308,7 @@ class Model extends React.Component {
startFlow = () => {
const { selectModelerIds } = this.state;
if ((selectModelerIds||[]).length === 0) {
showMessage('info', '请先选择
模型
');
showMessage('info', '请先选择
服务
');
return;
}
...
...
@@ -265,18 +318,111 @@ class Model extends React.Component {
onRecatalogBtnClick = () => {
const { selectModelerIds } = this.state;
if ((selectModelerIds||[]).length === 0) {
showMessage('info', '请先选择
模型
');
showMessage('info', '请先选择
服务
');
return;
}
this.setState({ recatalogModalVisible: true });
}
onAuthorizeBtnClick = () => {
const { selectModelerIds, tableData } = this.state;
if ((selectModelerIds||[]).length === 0) {
showMessage('info', '请先选择服务');
return;
}
const services = (tableData||[]).filter(item => selectModelerIds.indexOf(item.id) !== -1);
this.setState({ startAuthorizeParams: {
visible: true,
services
}})
}
onReleaseBtnClick = () => {
const { selectModelerIds } = this.state;
if ((selectModelerIds||[]).length === 0) {
showMessage('info', '请先选择服务');
return;
}
this.setState({ startReleaseVisible: true })
}
onImportClick = () => {
this.setState({ importServicesVisible: true });
}
onExportClick = () => {
const { modal } = this.props;
const { catalogId } = this.state;
modal?.confirm({
title: '提示',
content: '是否确认导表格中所有数据?',
onOk: () => {
dispatch({
type: 'pds.exportAll',
payload: {
responseType: 'blob',
params: {
pdsDataServiceCatalogId: catalogId,
namespace: this.props.app?.env?.domainId,
isExcludeOtherOwner: this.props.isOnlyEnding
}
},
callback: (res) => {
download(res)
}
})
},
});
}
onSubscribeBtnClick = () => {
const { selectModelerIds } = this.state;
const { modal } = this.props;
if ((selectModelerIds||[]).length === 0) {
showMessage('info', '请先选择服务');
return;
}
modal?.confirm({
title: '提示',
content: '是否确认收藏选中的服务?',
onOk: () => {
dispatch({
type: 'assetmanage.addSubscribe',
payload: {
params: {
appType: 'pDataService',
resourceIds: (selectModelerIds??[]).toString(),
env: this.props.app?.env?.domainId,
}
},
callback: () => {
showMessage('success', '收藏成功');
this.setState({ selectModelerIds: [] });
}
})
},
});
}
onOfflineBtnClick = () => {
const { selectModelerIds } = this.state;
if ((selectModelerIds||[]).length === 0) {
showMessage('info', '请先选择服务');
return;
}
this.setState({ offlineVisible: true })
}
onBatchDeleteBtnClick = () => {
const { selectModelerIds } = this.state;
if ((selectModelerIds||[]).length === 0) {
showMessage('info', '请先选择
模型
');
showMessage('info', '请先选择
服务
');
return;
}
...
...
@@ -404,6 +550,36 @@ class Model extends React.Component {
}
}
onStartAuthorizeCancel = (refresh = false) => {
this.setState({ startAuthorizeParams: {
visible: false,
services: []
}});
if (refresh) {
this.setState({ selectModelerIds: [] }, () => {
this.onTableChange();
});
}
}
onStartReleaseCancel = (refresh = false) => {
this.setState({ startReleaseVisible: false });
if (refresh) {
this.setState({ selectModelerIds: [] }, () => {
this.onTableChange();
});
}
}
onOfflineCancel = (refresh = false) => {
this.setState({ offlineVisible: false });
if (refresh) {
this.setState({ selectModelerIds: [] }, () => {
this.onTableChange();
});
}
}
onHistoryAndVersionDrawerCancel = () => {
this.setState({ historyAndVersionDrawerVisible: false });
}
...
...
@@ -421,7 +597,7 @@ class Model extends React.Component {
const { catalogId } = this.state;
if ((catalogId||'') === '') {
showMessage('info', '请先选择
模型
目录');
showMessage('info', '请先选择
服务
目录');
return;
}
...
...
@@ -464,7 +640,8 @@ class Model extends React.Component {
}
render() {
const { importModalVisible, catalogId, loadingTableData, selectModelerIds, keyword, filterTableData, selectModelerNames, exportDDLModalVisible, exportOtherModalVisible, importStockWordDrawerVisible , loadingStates, modelStates, currentModelState, currentView, recatalogModalVisible, exportDDLModalReference, currentModel, offset, historyAndVersionDrawerVisible, modelerId, startFlowModalVisible, expandTree, showDeleteTip, colSettingModalVisible, visibleColNames } = this.state;
const { app, isOnlyEnding } = this.props;
const { importModalVisible, catalogId, loadingTableData, selectModelerIds, keyword, filterTableData, selectModelerNames, exportDDLModalVisible, exportOtherModalVisible, importStockWordDrawerVisible , loadingStates, modelStates, currentModelState, currentView, recatalogModalVisible, exportDDLModalReference, currentModel, offset, historyAndVersionDrawerVisible, modelerId, startFlowModalVisible, expandTree, showDeleteTip, colSettingModalVisible, visibleColNames, currentODataState } = this.state;
const classes = classNames('data-model', {
'data-model-collapse': !expandTree
...
...
@@ -473,16 +650,14 @@ class Model extends React.Component {
let disableStartFlow = false, startFlowTip = '';
if ((currentView==='dir'&¤tModelState==='2')||(currentView!=='dir'&&catalogId==='2')) {
disableStartFlow = true;
startFlowTip = '只有草稿状态下的
模型
才能送审';
startFlowTip = '只有草稿状态下的
服务
才能送审';
} else if ((selectModelerIds||[]).length===0) {
disableStartFlow = true;
startFlowTip = '请先选择
模型
';
startFlowTip = '请先选择
服务
';
}
return (
<AppContext.Consumer>
{
value => <div className={classes}>
<div className={classes}>
<ResizableBox
className='left'
width={230}
...
...
@@ -508,44 +683,104 @@ class Model extends React.Component {
>
<Space>
{
(getDataModelerRole(value?.user)!==DataModelerRoleReader)
&& <React.Fragment>
currentView==='dir' && (getDataModelerRole(app?.user)!==DataModelerRoleReader) && !isOnlyEnding
&& <React.Fragment>
<Space>
<Button onClick={() => { this.setState({ importModalVisible: true }); }}>新建</Button>
<Dropdown
overlay={
<Menu>
<Menu.Item onClick={() => {
app?.editServer?.({ dirId: catalogId, type: 'register' });
}}>注册服务</Menu.Item>
<Menu.Item onClick={() => {
app?.editServer?.({ dirId: catalogId, type: 'drag' });
}}>拖拉创建服务</Menu.Item>
<Menu.Item onClick={() => {
app?.editServer?.({ dirId: catalogId, type: 'sql' });
}}>自定义sql创建服务</Menu.Item>
</Menu>
}
placement="bottomLeft"
trigger={['click']}
>
<Tooltip title={this.state.isRoot?'请先选择目录':''}>
<Button disabled={this.state.isRoot}>新建</Button>
</Tooltip>
</Dropdown>
</Space>
<Space>
<Tooltip title={(selectModelerIds||[]).length===0?'请先选择
模型
':''}>
{/*
<Space>
<Tooltip title={(selectModelerIds||[]).length===0?'请先选择
服务
':''}>
<Button onClick={this.onExportOtherBtnClick} disabled={(selectModelerIds||[]).length===0}>导出</Button>
</Tooltip>
</Space>
</Space>
*/}
<Space>
{/*
<Space>
<Tooltip title={startFlowTip}>
<Button onClick={this.startFlow} disabled={disableStartFlow}>送审</Button>
</Tooltip>
</Space>
</Space>
*/}
<Space>
<Tooltip title={(selectModelerIds||[]).length===0?'请先选择
模型
':''}>
{/*
<Space>
<Tooltip title={(selectModelerIds||[]).length===0?'请先选择
服务
':''}>
<Button onClick={this.onRecatalogBtnClick} disabled={(selectModelerIds||[]).length===0}>变更目录</Button>
</Tooltip>
</Space>
</Space>
*/}
<Space>
<Tooltip title={(selectModelerIds||[]).length===0?'请先选择模型':''}>
{/* <Space>
<Tooltip title={(selectModelerIds||[]).length===0?'请先选择服务':''}>
<Button onClick={this.onAuthorizeBtnClick} disabled={(selectModelerIds||[]).length===0}>授权</Button>
</Tooltip>
</Space> */}
{/* <Space>
<Tooltip title={(selectModelerIds||[]).length===0?'请先选择服务':''}>
<Button onClick={this.onReleaseBtnClick} disabled={(selectModelerIds||[]).length===0}>发布</Button>
</Tooltip>
</Space> */}
{/* <Space>
<Tooltip title={(selectModelerIds||[]).length===0?'请先选择服务':''}>
<Button onClick={this.onBatchDeleteBtnClick} disabled={(selectModelerIds||[]).length===0}>删除</Button>
</Tooltip>
</Space>
</Space> */}
{/* <Space>
<Button onClick={this.onVisibleColSettingClick}>可见列设置</Button>
</Space> */}
</React.Fragment>
}
<Space>
<Button onClick={this.onVisibleColSettingClick}>可见列设置</Button>
</Space>
</React.Fragment>
<Space>
<Button onClick={() => { this.setState({jdbcInformationVisible: true}); }}>JDBC信息</Button>
</Space>
{
(getDataModelerRole(app?.user)!==DataModelerRoleReader) && !isOnlyEnding && <Button onClick={this.onImportClick}>导入</Button>
}
{
(getDataModelerRole(app?.user)!==DataModelerRoleReader) && !isOnlyEnding && (currentView==='dir') &&
<Tooltip title={this.state.isRoot?'请先选择目录':''}>
<Button onClick={this.onExportClick} disabled={this.state.isRoot}>导出</Button>
</Tooltip>
}
{
(getDataModelerRole(app?.user)!==DataModelerRoleReader) && isOnlyEnding &&
<Tooltip title={(selectModelerIds||[]).length===0?'请先选择服务':''}>
<Button onClick={this.onSubscribeBtnClick} disabled={(selectModelerIds||[]).length===0}>收藏</Button>
</Tooltip>
}
{
(getDataModelerRole(app?.user)!==DataModelerRoleReader) && isOnlyEnding &&
<Tooltip title={(selectModelerIds||[]).length===0?'请先选择服务':''}>
<Button onClick={this.onOfflineBtnClick} disabled={(selectModelerIds||[]).length===0}>停用</Button>
</Tooltip>
}
</Space>
<Space>
{
(currentView==='dir'||keyword!=='') && <Space>
<span>发布状态:</span>
<Select
style={{ width: 120 }}
onChange={(value) => {
...
...
@@ -565,8 +800,22 @@ class Model extends React.Component {
</Space>
}
<Space>
{/* <span>OData状态:</span>
<Select
style={{ width: 120 }}
onChange={(value) => {
this.onODataStateChange(value);
}}
value={currentODataState}
>
<Option value='0'>所有状态</Option>
<Option value='1'>已启动</Option>
<Option value='2'>未启动</Option>
</Select> */}
</Space>
<Space>
<InputDebounce
placeholder="通过
模型
名称全文搜索"
placeholder="通过
服务
名称全文搜索"
allowClear
value={keyword}
onChange={(value) => { this.onSearchInputChange(value); }}
...
...
@@ -581,7 +830,8 @@ class Model extends React.Component {
<Spin spinning={loadingTableData}>
<ModelTable
loading={loadingTableData}
user={value?.user}
user={app?.user}
isOnlyEnding={isOnlyEnding}
catalogId={catalogId}
view={currentView}
data={filterTableData}
...
...
@@ -600,35 +850,6 @@ class Model extends React.Component {
</div>
</div>
<ImportModal
view={currentView}
catalogId={catalogId}
visible={importModalVisible}
onCancel={this.onImportModalCancel}
onCancelByWord={this.onImportModalCancelByWord}
onCancelByDDL={this.onImportModalCancelByDDL}
/>
<ImportStockWordDrawer
visible={importStockWordDrawerVisible}
onCancel={this.onImportStockWordDrawerCancel}
catalogId={catalogId}
onSuccess={this.onImportStockWordSuccess}
/>
<ExportDDLModal
visible={exportDDLModalVisible}
reference={exportDDLModalReference}
ids={(exportDDLModalReference==='exportDDL')?selectModelerIds:[currentModel.id]}
names={selectModelerNames}
env={value?.env}
onCancel={this.onExportDDLModalCancel}
/>
<ExportOtherModal
visible={exportOtherModalVisible}
onCancel={this.onExportOtherModalCancel}
/>
<RecatalogModal
visible={recatalogModalVisible}
...
...
@@ -642,28 +863,60 @@ class Model extends React.Component {
onCancel={this.onHistoryAndVersionDrawerCancel}
/>
<StartFlowModal
<StartAuthorize
visible={this.state.startAuthorizeParams.visible}
services={this.state.startAuthorizeParams.services}
onCancel={this.onStartAuthorizeCancel}
/>
<StartRelease
visible={this.state.startReleaseVisible}
ids={selectModelerIds}
visible={startFlowModalVisible}
onCancel={this.onStartFlowModalCancel}
onCancel={this.onStartReleaseCancel}
/>
<
DeleteTipModal
visible={
showDeleteTip
}
tip='您确定要删除这些模型吗?'
onCancel={this.on
DeleteTipModal
Cancel}
<
Offline
visible={
this.state.offlineVisible
}
ids={selectModelerIds}
onCancel={this.on
Offline
Cancel}
/>
<ColSettingModal
visible={colSettingModalVisible}
onCancel={this.onColSettingModalCancel}
/>
<JDBCInformation
visible={this.state.jdbcInformationVisible}
onCancel={() => { this.setState({ jdbcInformationVisible: false }) }}
/>
<ImportServices
visible={this.state.importServicesVisible}
onCancel={() => { this.setState({ importServicesVisible: false }) }}
onSuccess={() => {
this.onTableChange()
}}
/>
</div>
}
</AppContext.Consumer>
);
}
}
export default Model;
const WrapModel = (props) => {
const [modal, contextHolder] = Modal.useModal();
return (
<AppContext.Consumer>
{
value => <React.Fragment>
<Model app={value} modal={modal} {...props} />
{contextHolder}
</React.Fragment>
}
</AppContext.Consumer>
)
}
export default WrapModel;
src/view/Manage/ModelConfig/Component/ConstraintDetail.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
Input
,
Table
,
Tooltip
}
from
'antd'
;
import
{
inputWidth
}
from
'../../../../util'
;
import
{
dispatch
}
from
'../../../../model'
;
const
ConstraintDetail
=
(
props
)
=>
{
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
rules
,
setRules
]
=
useState
([]);
const
[
keyword
,
setKeyword
]
=
useState
(
''
);
useEffect
(()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'datamodel.getAllConstraints'
,
callback
:
data
=>
{
setLoading
(
false
);
const
_rules
=
[];
(
data
||
[]).
forEach
(
constraint
=>
{
(
constraint
.
allRules
||
[]).
forEach
(
rule
=>
{
_rules
.
push
({...
constraint
,
...{
ruleName
:
rule
.
name
||
''
,
ruleDesc
:
rule
.
desc
||
''
}});
});
});
setRules
(
_rules
);
},
error
:
()
=>
{
setLoading
(
false
);
}
})
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[])
const
columns
=
[
{
title
:
'序号'
,
dataIndex
:
'key'
,
editable
:
false
,
render
:
(
_
,
__
,
index
)
=>
{
return
(
index
+
1
).
toString
();
},
width
:
60
,
},
{
title
:
'规范名称'
,
dataIndex
:
'name'
,
width
:
180
,
ellipsis
:
true
,
render
:
(
text
,
_
,
__
)
=>
{
return
(
<
Tooltip
title=
{
text
||
''
}
>
<
span
>
{
text
||
''
}
</
span
>
</
Tooltip
>
)
}
},
{
title
:
'规范中文名称'
,
dataIndex
:
'cnName'
,
width
:
180
,
ellipsis
:
true
,
render
:
(
text
,
_
,
__
)
=>
{
return
(
<
Tooltip
title=
{
text
||
''
}
>
<
span
>
{
text
||
''
}
</
span
>
</
Tooltip
>
)
}
},
{
title
:
'前置依赖'
,
dataIndex
:
'ruleName'
,
width
:
180
,
ellipsis
:
true
,
render
:
(
text
,
_
,
__
)
=>
{
return
(
<
Tooltip
title=
{
text
||
''
}
>
<
span
>
{
text
||
''
}
</
span
>
</
Tooltip
>
)
}
},
{
title
:
'描述'
,
dataIndex
:
'ruleDesc'
,
ellipsis
:
true
,
render
:
(
text
,
_
,
__
)
=>
{
return
(
<
Tooltip
title=
{
text
||
''
}
>
<
span
>
{
text
||
''
}
</
span
>
</
Tooltip
>
)
}
}
]
const
onSearchInputChange
=
(
e
)
=>
{
setKeyword
(
e
.
target
.
value
||
''
);
}
return
(
<
div
>
<
div
className=
'd-flex mb-3'
style=
{
{
alignItems
:
'center'
}
}
>
<
Input
placeholder=
"请输入前置依赖名称"
allowClear
value=
{
keyword
}
onChange=
{
onSearchInputChange
}
style=
{
{
width
:
inputWidth
}
}
/>
</
div
>
<
Table
loading=
{
loading
}
columns=
{
columns
}
rowKey=
{
'ruleName'
}
dataSource=
{
(
rules
||
[]).
filter
(
item
=>
(
item
.
ruleName
||
''
).
indexOf
(
keyword
)
!==-
1
)
}
pagination=
{
false
}
sticky
/>
</
div
>
);
}
export
default
ConstraintDetail
;
\ No newline at end of file
src/view/Manage/ModelConfig/Component/EditTemplate.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
React
,
{
useState
,
useEffect
}
from
'react'
;
import
{
Form
,
Button
,
Space
}
from
'antd'
;
import
LocalStorage
from
'local-storage'
;
import
TemplateAction
from
'./TemplateAction'
;
import
{
dispatchLatest
}
from
'../../../../model'
;
import
{
getQueryParam
,
showMessage
}
from
'../../../../util'
;
import
{
Action
,
TemplateId
}
from
'../../../../util/constant'
;
import
'../../Model/Component/EditModel.less'
;
const
EditTemplate
=
(
props
)
=>
{
const
[
actionData
,
setActionData
]
=
useState
({
action
:
''
,
templateId
:
''
,
});
const
[
templateData
,
setTemplateData
]
=
useState
({});
const
[
confirmLoading
,
setConfirmLoading
]
=
useState
(
false
);
const
{
action
,
templateId
}
=
actionData
;
const
[
form
]
=
Form
.
useForm
();
useEffect
(()
=>
{
const
_action
=
getQueryParam
(
Action
,
props
.
location
.
search
);
const
_templateId
=
getQueryParam
(
TemplateId
,
props
.
location
.
search
);
setActionData
({
action
:
_action
,
templateId
:
_templateId
});
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[])
const
save
=
async
(
e
)
=>
{
try
{
const
row
=
await
form
.
validateFields
();
const
newTemplateData
=
{...
templateData
,
...
row
};
setConfirmLoading
(
true
);
dispatchLatest
({
type
:
'datamodel.saveTemplate'
,
payload
:
{
data
:
newTemplateData
},
callback
:
data
=>
{
setConfirmLoading
(
false
);
if
(
action
===
'add'
)
{
showMessage
(
"success"
,
'新增模型成功'
);
setActionData
({
...
actionData
,
...{
action
:
'detail'
,
templateId
:
data
.
id
}
});
}
else
{
showMessage
(
"success"
,
'保存模型成功'
);
setActionData
({
...
actionData
,
...{
action
:
'detail'
,
templateId
:
data
.
id
||
''
}
});
}
LocalStorage
.
set
(
'templateChange'
,
!
(
LocalStorage
.
get
(
'templateChange'
)
||
false
));
},
error
:
()
=>
{
setConfirmLoading
(
false
);
}
})
}
catch
(
errInfo
)
{
console
.
log
(
'Validate Failed:'
,
errInfo
);
}
}
const
edit
=
()
=>
{
setActionData
({
...
actionData
,
action
:
'edit'
});
}
const
cancelEdit
=
()
=>
{
setActionData
({
...
actionData
,
action
:
'detail'
});
}
const
onActionChange
=
(
data
)
=>
{
setTemplateData
(
data
);
}
let
title
=
''
;
if
(
action
===
'add'
)
{
title
=
'新增模版'
;
}
else
if
(
action
===
'edit'
)
{
title
=
'模版编辑'
;
}
else
if
(
action
===
'detail'
)
{
title
=
'模版详情'
;
}
let
actionsBtn
=
null
;
if
(
action
===
'add'
)
{
actionsBtn
=
(
<
Space
>
<
Button
type=
'primary'
onClick=
{
save
}
loading=
{
confirmLoading
}
danger
>
保存
</
Button
>
</
Space
>
)
}
else
if
(
action
===
'detail'
)
{
actionsBtn
=
(
<
Space
>
<
Button
type=
'primary'
onClick=
{
edit
}
danger
>
编辑
</
Button
>
</
Space
>
);
}
else
if
(
action
===
'edit'
)
{
actionsBtn
=
(
<
Space
>
<
Button
type=
'primary'
onClick=
{
save
}
loading=
{
confirmLoading
}
danger
>
保存
</
Button
>
<
Button
onClick=
{
cancelEdit
}
>
取消
</
Button
>
</
Space
>
)
}
return
(
<
div
className=
'edit-model position-relative'
>
<
div
className=
'edit-header'
>
<
span
style=
{
{
fontSize
:
16
,
fontWeight
:
'bold'
,
color
:
'#fff'
}
}
>
{
title
}
</
span
>
</
div
>
<
div
className=
'edit-container'
>
<
div
className=
'edit-container-card'
>
<
TemplateAction
onChange=
{
onActionChange
}
action=
{
action
}
id=
{
templateId
}
form=
{
form
}
/>
</
div
>
</
div
>
<
div
className=
'edit-footer'
>
{
actionsBtn
}
</
div
>
</
div
>
);
}
export
default
EditTemplate
;
\ No newline at end of file
src/view/Manage/ModelConfig/Component/PartitionCURD.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
Table
,
Button
,
Tooltip
,
Modal
,
Divider
}
from
'antd'
;
import
{
dispatch
}
from
'../../../../model'
;
import
{
showMessage
}
from
'../../../../util'
;
import
UpdatePartitionModal
from
'./UpdatePartitionModal'
;
const
PartitionCURD
=
(
props
)
=>
{
const
[
partitions
,
setPartitions
]
=
useState
([]);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
actionData
,
setActionData
]
=
useState
({
action
:
''
,
updataPartitionModalVisible
:
false
,
item
:
null
});
const
{
action
,
updataPartitionModalVisible
,
item
}
=
actionData
;
const
[
modal
,
contextHolder
]
=
Modal
.
useModal
();
useEffect
(()
=>
{
getPartitions
();
},
[])
const
columns
=
[
{
title
:
'序号'
,
dataIndex
:
'key'
,
editable
:
false
,
render
:
(
text
,
record
,
index
)
=>
{
return
(
index
+
1
).
toString
();
},
width
:
60
,
},
{
title
:
'分区名称'
,
dataIndex
:
'name'
,
width
:
180
,
ellipsis
:
true
,
render
:
(
text
,
_
,
__
)
=>
{
return
(
<
Tooltip
title=
{
text
||
''
}
>
<
span
>
{
text
||
''
}
</
span
>
</
Tooltip
>
)
}
},
{
title
:
'分区中文名称'
,
dataIndex
:
'cnName'
,
width
:
180
,
ellipsis
:
true
,
render
:
(
text
,
_
,
__
)
=>
{
return
(
<
Tooltip
title=
{
text
||
''
}
>
<
span
>
{
text
||
''
}
</
span
>
</
Tooltip
>
)
}
},
{
title
:
'分区方式'
,
dataIndex
:
'partitionMethod'
,
width
:
180
,
ellipsis
:
true
,
render
:
(
text
,
_
,
__
)
=>
{
return
(
<
Tooltip
title=
{
text
||
''
}
>
<
span
>
{
text
||
''
}
</
span
>
</
Tooltip
>
)
}
},
{
title
:
'定义'
,
dataIndex
:
'definition'
,
ellipsis
:
true
,
render
:
(
text
,
_
,
__
)
=>
{
return
(
<
Tooltip
placement=
'topLeft'
title=
{
<
div
style=
{
{
maxWidth
:
400
,
maxHeight
:
300
,
overflow
:
'auto'
}
}
>
{
text
||
''
}
</
div
>
}
overlayClassName=
'tooltip-common'
>
<
span
>
{
text
||
''
}
</
span
>
</
Tooltip
>
)
}
},
{
title
:
'描述'
,
dataIndex
:
'remark'
,
width
:
180
,
ellipsis
:
true
,
render
:
(
text
,
_
,
__
)
=>
{
return
(
<
Tooltip
title=
{
text
||
''
}
>
<
span
>
{
text
||
''
}
</
span
>
</
Tooltip
>
)
}
},
{
title
:
'操作'
,
key
:
'action'
,
width
:
120
,
render
:
(
text
,
record
)
=>
{
return
(
<
div
style=
{
{
display
:
'flex'
,
alignItems
:
'center'
}
}
>
<
Button
type=
'link'
size=
'small'
onClick=
{
()
=>
{
editItem
(
record
);
}
}
style=
{
{
padding
:
0
}
}
>
编辑
</
Button
>
<
div
style=
{
{
margin
:
'0 5px'
}
}
>
<
Divider
type=
'vertical'
/>
</
div
>
<
Button
type=
'link'
size=
'small'
onClick=
{
()
=>
{
deleteItem
(
record
);
}
}
style=
{
{
padding
:
0
}
}
>
删除
</
Button
>
</
div
>
)
}
}
];
const
getPartitions
=
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'datamodel.getSupportedPartitionTypes'
,
payload
:
{
excludeBuiltin
:
true
},
callback
:
data
=>
{
setPartitions
(
data
||
[]);
setLoading
(
false
);
},
error
:
()
=>
{
setLoading
(
false
);
}
})
}
const
editItem
=
(
record
)
=>
{
setActionData
({...
actionData
,
...{
action
:
'edit'
,
updataPartitionModalVisible
:
true
,
item
:
record
}});
}
const
deleteItem
=
(
record
)
=>
{
modal
.
confirm
({
title
:
'提示!'
,
content
:
'您确定要删除该分区吗?'
,
onOk
:
()
=>
{
dispatch
({
type
:
'datamodel.deletePartitionType'
,
payload
:
{
params
:
{
id
:
record
.
id
}
},
callback
:
()
=>
{
showMessage
(
'success'
,
'模版分区成功'
);
getPartitions
();
}
})
}
});
}
const
onAddClick
=
()
=>
{
setActionData
({...
actionData
,
...{
action
:
'add'
,
updataPartitionModalVisible
:
true
}});
}
const
onUpdatePartitionModalCancel
=
(
refresh
=
false
)
=>
{
setActionData
({...
actionData
,
updataPartitionModalVisible
:
false
}
);
refresh
&&
getPartitions
();
}
return
(
<
div
>
<
div
className=
'd-flex mb-3'
style=
{
{
alignItems
:
'center'
}
}
>
<
Button
onClick=
{
onAddClick
}
>
新建
</
Button
>
</
div
>
<
Table
loading=
{
loading
}
columns=
{
columns
}
rowKey=
{
'id'
}
dataSource=
{
partitions
||
[]
}
pagination=
{
false
}
sticky
/>
<
UpdatePartitionModal
visible=
{
updataPartitionModalVisible
}
action=
{
action
}
item=
{
item
}
onCancel=
{
onUpdatePartitionModalCancel
}
/>
{
contextHolder
}
</
div
>
);
}
export
default
PartitionCURD
;
\ No newline at end of file
src/view/Manage/ModelConfig/Component/TemplateAction.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
React
,
{
useState
,
useEffect
}
from
'react'
;
import
{
Spin
,
Tabs
,
Popover
,
Divider
,
Button
,
Space
}
from
'antd'
;
import
{
QuestionCircleOutlined
}
from
'@ant-design/icons'
;
import
TemplateActionHeader
from
'./TemplateActionHeader'
;
import
{
ImportActionTable
}
from
'../../Model/Component/ImportActionTable'
;
import
{
dispatchLatest
,
dispatch
}
from
'../../../../model'
;
const
{
TabPane
}
=
Tabs
;
const
TemplateAction
=
(
props
)
=>
{
const
{
action
,
onChange
,
form
,
id
}
=
props
;
const
[
templateData
,
setTemplateData
]
=
useState
(
null
);
const
[
supportedDatatypes
,
setSupportedDatatypes
]
=
useState
([]);
const
[
tabKey
,
setTabKey
]
=
useState
(
'1'
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
useEffect
(()
=>
{
//初始化form状态
if
(
action
===
'add'
||
action
===
'edit'
)
{
form
.
setFieldsValue
({
cnName
:
''
,
name
:
''
,
remark
:
''
,
});
}
if
(
action
===
'add'
)
{
getSupportedDatatypes
();
}
else
if
((
action
===
'edit'
||
action
===
'detail'
)
&&
id
)
{
getCurrentTemplate
();
}
//eslint-disable-next-line react-hooks/exhaustive-deps
},
[
action
,
id
]);
const
getCurrentTemplate
=
()
=>
{
setLoading
(
true
);
dispatchLatest
({
type
:
'datamodel.getTemplate'
,
payload
:
{
params
:
{
id
}
},
callback
:
data
=>
{
setTemplateData
(
data
||
{});
onChange
&&
onChange
(
data
||
{});
getSupportedDatatypes
();
if
(
action
===
'edit'
)
{
form
.
setFieldsValue
({
cnName
:
data
.
cnName
||
''
,
name
:
data
.
name
||
''
,
remark
:
data
.
remark
||
''
,
});
}
},
error
:
()
=>
{
setLoading
(
false
);
}
})
}
const
getSupportedDatatypes
=
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'datamodel.getSupportedDatatypes'
,
callback
:
data
=>
{
setLoading
(
false
);
setSupportedDatatypes
(
data
||
[]);
},
error
:
()
=>
{
setLoading
(
false
);
}
});
}
//模版不需要对字段进行校验
const
onTableChange
=
(
data
)
=>
{
let
newTemplateData
=
{...
templateData
,
...{
easyDataModelerDataModelAttributes
:
data
}};
setTemplateData
(
newTemplateData
);
onChange
&&
onChange
(
newTemplateData
);
}
const
onTabChange
=
(
key
)
=>
{
setTabKey
(
key
);
}
const
prevStep
=
()
=>
{
setTabKey
(
`
${
Number
(
tabKey
)
-
1
}
`
);
}
const
nextStep
=
()
=>
{
setTabKey
(
`
${
Number
(
tabKey
)
+
1
}
`
);
}
return
(
<
Spin
spinning=
{
loading
}
>
<
Tabs
activeKey=
{
tabKey
}
onChange=
{
onTabChange
}
>
<
TabPane
tab=
'基本信息'
key=
'1'
>
<
TemplateActionHeader
form=
{
form
}
editable=
{
action
!==
'detail'
}
templateData=
{
templateData
||
{}
}
/>
</
TabPane
>
<
TabPane
tab=
{
<
span
>
<
span
>
数据表结构
</
span
>
{
(
action
!==
'detail'
&&
action
!==
'flow'
&&
action
!==
'detail-version'
)
&&
(
<
Popover
content=
'表格可以通过拖拽来排序'
>
<
QuestionCircleOutlined
className=
'ml-1 pointer'
/>
</
Popover
>
)
}
</
span
>
}
key=
'2'
>
<
ImportActionTable
type=
'template'
modelerData=
{
templateData
||
{}
}
supportedDatatypes=
{
supportedDatatypes
}
onChange=
{
onTableChange
}
editable=
{
action
!==
'detail'
}
/>
</
TabPane
>
</
Tabs
>
{
action
!==
'detail'
&&
(
<
React
.
Fragment
>
<
Divider
style=
{
{
margin
:
0
}
}
/>
<
div
className=
'flex'
style=
{
{
justifyContent
:
'flex-end'
,
height
:
64
,
alignItems
:
'center'
}
}
>
<
Space
size=
'small'
>
<
Button
type=
'primary'
onClick=
{
prevStep
}
disabled=
{
tabKey
===
'1'
}
danger
>
上一步
</
Button
>
<
Button
type=
'primary'
onClick=
{
nextStep
}
disabled=
{
tabKey
===
'2'
}
danger
>
下一步
</
Button
>
</
Space
>
</
div
>
</
React
.
Fragment
>
)
}
</
Spin
>
);
};
export
default
TemplateAction
;
\ No newline at end of file
src/view/Manage/ModelConfig/Component/TemplateActionHeader.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
React
from
'react'
;
import
{
Form
,
Input
,
Row
,
Col
,
Descriptions
}
from
'antd'
;
const
{
TextArea
}
=
Input
;
const
TemplateActionHeader
=
(
props
)
=>
{
const
{
editable
,
form
,
templateData
}
=
props
;
const
formItemLayout
=
{
labelCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
5
},
},
wrapperCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
19
},
},
};
return
(
editable
?
(
<
Form
form=
{
form
}
{
...
formItemLayout
}
>
<
Row
>
<
Col
span=
{
12
}
>
<
Form
.
Item
label=
"中文名称"
name=
"cnName"
labelAlign=
"left"
rules=
{
[{
required
:
true
,
message
:
'请输入中文名称!'
}]
}
>
<
Input
/>
</
Form
.
Item
>
</
Col
>
<
Col
span=
{
12
}
>
<
Form
.
Item
label=
"英文名称"
name=
"name"
labelAlign=
"left"
rules=
{
[{
required
:
true
,
message
:
'请输入英文名称!'
}]
}
>
<
Input
/>
</
Form
.
Item
>
</
Col
>
</
Row
>
<
Row
>
<
Col
span=
{
12
}
>
<
Form
.
Item
label=
"描述"
name=
"remark"
labelAlign=
"left"
rules=
{
[{
required
:
true
,
message
:
'请输入描述!'
}]
}
>
<
TextArea
row=
{
4
}
/>
</
Form
.
Item
>
</
Col
>
</
Row
>
</
Form
>
)
:
(
<
Descriptions
column=
{
2
}
>
<
Descriptions
.
Item
label=
"中文名称"
>
{
templateData
.
cnName
||
''
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
"英文名称"
>
{
templateData
.
name
||
''
}
</
Descriptions
.
Item
>
<
Descriptions
.
Item
label=
"描述"
>
{
templateData
.
remark
||
''
}
</
Descriptions
.
Item
>
</
Descriptions
>
)
)
}
export
default
TemplateActionHeader
;
\ No newline at end of file
src/view/Manage/ModelConfig/Component/TemplateCURD.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
Table
,
Button
,
Tooltip
,
Modal
,
Divider
}
from
'antd'
;
import
{
Action
,
TemplateId
}
from
'../../../../util/constant'
;
import
{
dispatch
}
from
'../../../../model'
;
import
{
showMessage
}
from
'../../../../util'
;
const
TemplateCURD
=
(
props
)
=>
{
const
[
templates
,
setTemplates
]
=
useState
([]);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
modal
,
contextHolder
]
=
Modal
.
useModal
();
useEffect
(()
=>
{
getTemplates
();
window
?.
addEventListener
(
"storage"
,
(
e
)
=>
{
if
(
e
.
key
===
'templateChange'
)
{
getTemplates
();
}
});
},
[])
const
columns
=
[
{
title
:
'序号'
,
dataIndex
:
'key'
,
editable
:
false
,
render
:
(
text
,
record
,
index
)
=>
{
return
(
index
+
1
).
toString
();
},
width
:
60
,
},
{
title
:
'模版名称'
,
dataIndex
:
'name'
,
width
:
180
,
ellipsis
:
true
,
render
:
(
text
,
record
,
_
)
=>
{
return
(
<
Tooltip
title=
{
text
||
''
}
>
<
a
onClick=
{
()
=>
{
detailItem
(
record
);}
}
>
{
text
||
''
}
</
a
>
</
Tooltip
>
);
}
},
{
title
:
'中文名称'
,
dataIndex
:
'cnName'
,
width
:
180
,
ellipsis
:
true
,
},
{
title
:
'模版描述'
,
dataIndex
:
'remark'
,
ellipsis
:
true
,
},
{
title
:
'更新时间'
,
dataIndex
:
'modifiedTs'
,
width
:
120
,
ellipsis
:
true
,
},
{
title
:
'操作'
,
key
:
'action'
,
width
:
120
,
render
:
(
text
,
record
)
=>
{
return
(
<
div
style=
{
{
display
:
'flex'
,
alignItems
:
'center'
}
}
>
<
Button
type=
'link'
size=
'small'
onClick=
{
()
=>
{
editItem
(
record
);
}
}
style=
{
{
padding
:
0
}
}
>
编辑
</
Button
>
<
div
style=
{
{
margin
:
'0 5px'
}
}
>
<
Divider
type=
'vertical'
/>
</
div
>
<
Button
type=
'link'
size=
'small'
onClick=
{
()
=>
{
deleteItem
(
record
);
}
}
style=
{
{
padding
:
0
}
}
>
删除
</
Button
>
</
div
>
)
}
}
];
const
getTemplates
=
()
=>
{
setLoading
(
true
);
dispatch
({
type
:
'datamodel.getAllTemplates'
,
callback
:
data
=>
{
setTemplates
(
data
||
[]);
setLoading
(
false
);
},
error
:
()
=>
{
setLoading
(
false
);
}
})
}
const
editItem
=
(
record
)
=>
{
window
.
open
(
`/data-govern/model-template-action?
${
Action
}
=edit&
${
TemplateId
}
=
${
record
.
id
}
`
);
}
const
detailItem
=
(
record
)
=>
{
window
.
open
(
`/data-govern/model-template-action?
${
Action
}
=detail&
${
TemplateId
}
=
${
record
.
id
}
`
);
}
const
deleteItem
=
(
record
)
=>
{
modal
.
confirm
({
title
:
'提示!'
,
content
:
'您确定要删除该模版吗?'
,
onOk
:
()
=>
{
dispatch
({
type
:
'datamodel.deleteTemplate'
,
payload
:
{
params
:
{
id
:
record
.
id
}
},
callback
:
()
=>
{
showMessage
(
'success'
,
'模版删除成功'
);
getTemplates
();
}
})
}
});
}
const
onAddClick
=
()
=>
{
window
.
open
(
`/data-govern/model-template-action?
${
Action
}
=add`
);
}
return
(
<
div
>
<
div
className=
'd-flex mb-3'
style=
{
{
alignItems
:
'center'
}
}
>
<
Button
onClick=
{
onAddClick
}
>
新建
</
Button
>
</
div
>
<
Table
loading=
{
loading
}
columns=
{
columns
}
rowKey=
{
'id'
}
dataSource=
{
templates
||
[]
}
pagination=
{
false
}
sticky
/>
{
contextHolder
}
</
div
>
);
}
export
default
TemplateCURD
;
\ No newline at end of file
src/view/Manage/ModelConfig/Component/WordTemplate.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
React
,
{
useState
}
from
'react'
;
import
{
Button
,
Upload
,
Form
,
Row
,
Col
}
from
'antd'
;
import
{
DownloadOutlined
,
UploadOutlined
}
from
'@ant-design/icons'
;
import
{
dispatchLatest
}
from
'../../../../model'
;
const
WordTemplate
=
(
props
)
=>
{
const
[
fileList
,
setFileList
]
=
useState
([]);
const
[
confirmLoading
,
setConfirmLoading
]
=
useState
(
false
);
const
[
form
]
=
Form
.
useForm
();
const
downloadTemplate
=
()
=>
{
window
.
open
(
"/api/datamodeler/easyDataModelerExport/word/downloadTemplate"
);
}
const
uploadProps
=
{
onRemove
:
file
=>
{
const
index
=
fileList
.
indexOf
(
file
);
const
newFileList
=
fileList
.
slice
();
newFileList
.
splice
(
index
,
1
);
setFileList
(
newFileList
);
},
beforeUpload
:
file
=>
{
setFileList
([
file
]);
return
false
;
},
fileList
:
fileList
||
[],
accept
:
".doc,.docx"
,
};
const
normFile
=
(
e
)
=>
{
return
fileList
;
};
const
handleOk
=
async
()
=>
{
try
{
const
row
=
await
form
.
validateFields
();
setConfirmLoading
(
true
);
dispatchLatest
({
type
:
'datamodel.uploadWordTemplate'
,
payload
:
{
fileList
:
row
.
upload
},
callback
:
data
=>
{
setConfirmLoading
(
false
);
reset
();
},
error
:
()
=>
{
setConfirmLoading
(
false
);
}
})
}
catch
(
errInfo
)
{
console
.
log
(
'Validate Failed:'
,
errInfo
);
}
}
const
reset
=
()
=>
{
setConfirmLoading
(
false
);
form
.
resetFields
();
setFileList
([]);
}
const
layout
=
{
labelCol
:
{
span
:
8
},
wrapperCol
:
{
span
:
16
},
};
const
tailLayout
=
{
wrapperCol
:
{
offset
:
8
,
span
:
16
},
};
return
(
<
Form
form=
{
form
}
{
...
layout
}
onFinish=
{
handleOk
}
>
<
Form
.
Item
label=
'最新模版上传'
required=
{
true
}
>
<
Row
>
<
Col
>
<
Form
.
Item
name=
'upload'
valuePropName=
"fileList"
getValueFromEvent=
{
normFile
}
noStyle
rules=
{
[
{
required
:
true
,
message
:
'请选择文件上传'
,
},
]
}
>
<
Upload
{
...
uploadProps
}
>
<
Button
icon=
{
<
UploadOutlined
/>
}
>
选择文件上传
</
Button
>
</
Upload
>
</
Form
.
Item
>
</
Col
>
<
Col
>
<
Button
className=
'ml-3'
icon=
{
<
DownloadOutlined
/>
}
onClick=
{
downloadTemplate
}
>
模版下载
</
Button
>
</
Col
>
</
Row
>
</
Form
.
Item
>
<
Form
.
Item
{
...
tailLayout
}
>
<
Button
type=
"primary"
htmlType=
"submit"
loading=
{
confirmLoading
}
>
确定
</
Button
>
</
Form
.
Item
>
</
Form
>
)
}
export
default
WordTemplate
;
\ No newline at end of file
src/view/Manage/ModelConfig/index.jsx
deleted
100644 → 0
View file @
ee27b8a2
import
React
,
{
useState
}
from
'react'
;
import
{
Tabs
}
from
'antd'
;
import
WordTemplate
from
'./Component/WordTemplate'
;
import
TemplateCURD
from
'./Component/TemplateCURD'
;
import
ConstraintDetail
from
'./Component/ConstraintDetail'
;
import
PartitionCURD
from
'./Component/PartitionCURD'
;
import
'./index.less'
;
const
{
TabPane
}
=
Tabs
;
const
ModelConfig
=
()
=>
{
const
[
tabKey
,
setTabKey
]
=
useState
(
'1'
);
const
onTabChange
=
(
key
)
=>
{
setTabKey
(
key
);
}
return
(
<
div
className=
'model-config'
>
<
Tabs
activeKey=
{
tabKey
}
onChange=
{
onTabChange
}
>
<
TabPane
tab=
'Word模版配置'
key=
'1'
>
<
WordTemplate
/>
</
TabPane
>
<
TabPane
tab=
'生成表类型配置'
key=
'2'
>
<
TemplateCURD
/>
</
TabPane
>
<
TabPane
tab=
'规范配置'
key=
'3'
>
<
ConstraintDetail
/>
</
TabPane
>
<
TabPane
tab=
'分区配置'
key=
'4'
>
<
PartitionCURD
/>
</
TabPane
>
</
Tabs
>
</
div
>
)
}
export
default
ModelConfig
;
\ No newline at end of file
src/view/Manage/ModelConfig/index.less
deleted
100644 → 0
View file @
ee27b8a2
.model-config {
height: calc(100vh - 64px - 30px);
padding: 20px;
background: #fff;
overflow: auto;
}
\ No newline at end of file
src/view/Manage/index.jsx
View file @
82cac42b
...
...
@@ -6,14 +6,11 @@ import { GetSession } from "../../util";
import
{
ManageLayout
}
from
"../../layout"
;
import
DatasourceManage
from
'./DatasourceManage'
;
import
Model
from
'./Model'
;
import
ModelConfig
from
'./ModelConfig'
;
import
AssetManage
from
'./AssetManage'
;
import
AssetResourceBrowse
from
'./AssetResourceBrowse'
;
import
AssetBrowse
from
'./AssetBrowse'
;
import
AssetRecycle
from
'./AssetRecycle'
;
import
DataMasterDefine
from
"./DataMaster/Define"
;
import
DataMasterManage
from
"./DataMaster/Manage"
;
import
DataService
from
'./Model'
;
class
Manage
extends
Component
{
...
...
@@ -29,14 +26,11 @@ class Manage extends Component {
session
&&
session
.
userId
?
(
<
Switch
>
<
Route
path=
{
`${match.path}/datasource-manage`
}
component=
{
DatasourceManage
}
/>
<
Route
path=
{
`${match.path}/data-model`
}
component=
{
Model
}
/>
<
Route
path=
{
`${match.path}/model-config`
}
component=
{
ModelConfig
}
/>
<
Route
path=
{
`${match.path}/asset-manage`
}
component=
{
AssetManage
}
/>
<
Route
path=
{
`${match.path}/asset-resource-browse`
}
component=
{
AssetResourceBrowse
}
/>
<
Route
path=
{
`${match.path}/asset-browse`
}
component=
{
AssetBrowse
}
/>
<
Route
path=
{
`${match.path}/asset-recycle`
}
component=
{
AssetRecycle
}
/>
<
Route
path=
{
`${match.path}/msd-define`
}
component=
{
DataMasterDefine
}
/>
<
Route
path=
{
`${match.path}/msd-manage`
}
component=
{
DataMasterManage
}
/>
<
Route
path=
{
`${match.path}/data-service`
}
component=
{
DataService
}
/>
</
Switch
>
)
:
(
<
GetSession
{
...
this
.
props
}
/>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment