Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
N
nse-ui
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Members
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
吴超
nse-ui
Commits
2373db28
Commit
2373db28
authored
Sep 08, 2025
by
ningjihai
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
发现梳理
parent
6bc00674
显示空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
1724 行增加
和
522 行删除
+1724
-522
src/api/discover/index.js
+93
-35
src/views/discover/Discover/discoverProcess.vue
+138
-67
src/views/discover/Discover/discoverResult.vue
+782
-158
src/views/discover/Discover/list.vue
+154
-22
src/views/discover/Discover/modules/DomainRuleDialog.vue
+213
-175
src/views/discover/Discover/modules/MatchPreviewDialog.vue
+116
-48
src/views/discover/Discover/modules/SaveVersionDialog.vue
+214
-0
src/views/project/Project/list.vue
+14
-17
没有找到文件。
src/api/discover/index.js
View file @
2373db28
...
...
@@ -69,44 +69,102 @@ export function initEdit(taskid) {
})
}
// export function getdatascopeprojectlist(data) {
// return request({
// url: '/core/datascopeproject/getdatascopeprojectlist',
// method: 'post',
// data: data
// })
// }
// export function checkDatasystemName(data) {
// return request({
// url: '/core/tdataproject/checkDatasystemName',
// method: 'post',
// data: data
// })
// }
export
function
delDiscoverTask
(
data
)
{
return
request
({
url
:
'/core/tdatadiscovery/del'
,
method
:
'post'
,
data
:
data
})
}
export
function
executetask
(
data
)
{
return
request
({
url
:
'/core/discoverytask/executetask'
,
method
:
'post'
,
data
:
data
})
}
export
function
tdataMonitorQuery
(
query
)
{
return
request
({
url
:
'/core/tdataMonitor/query'
,
method
:
'get'
,
params
:
query
})
}
export
function
getdiscoverresultreport
(
query
)
{
return
request
({
url
:
'/core/tdiscoverresult/getdiscoverresultreport'
,
method
:
'get'
,
params
:
query
})
}
export
function
getarearule
(
query
)
{
return
request
({
url
:
'/core/tdiscoverresult/getarearule'
,
method
:
'get'
,
params
:
query
})
}
export
function
initExecute
(
query
)
{
return
request
({
url
:
'/core/tdatadiscovery/initExecute'
,
method
:
'get'
,
params
:
query
})
}
export
function
tdiscoverresultQuery
(
data
)
{
return
request
({
url
:
'/core/tdiscoverresult/query'
,
method
:
'post'
,
data
:
data
})
}
export
function
discoverresultsure
(
data
)
{
return
request
({
url
:
'/core/tdiscoverresult/discoverresultsure'
,
method
:
'post'
,
data
:
data
})
}
export
function
discoverchangerule
(
data
)
{
return
request
({
url
:
'/core/tdiscoverresult/discoverchangerule'
,
method
:
'post'
,
data
:
data
})
}
export
function
showmatchrate
(
data
)
{
return
request
({
url
:
'/core/tdiscoverresult/showmatchrate'
,
method
:
'post'
,
data
:
data
})
}
export
function
saveedition
(
data
)
{
return
request
({
url
:
'/core/tdiscoverresult/saveedition'
,
method
:
'post'
,
data
:
data
})
}
export
function
download
(
query
)
{
return
request
({
url
:
'/core/tdiscoverresult/download'
,
method
:
'get'
,
params
:
query
,
responseType
:
'blob'
//
})
}
// export function checkDatasystem(data) {
// return request({
// url: '/core/tdataproject/checkDatasystem',
// method: 'post',
// data: data
// })
// }
// export function queryByEditSort(data) {
// return request({
// url: '/core/tdatasource/queryByEditSort',
// method: 'post',
// data: data
// })
// }
// export function selectProDataSource(data) {
// return request({
// url: '/core/tdatasource/selectProDataSource',
// method: 'post',
// data: data
// })
// }
// export function queryShemas(data) {
// return request({
...
...
src/views/discover/Discover/discoverProcess.vue
View file @
2373db28
<
script
setup
name=
"DiscoverProcess"
>
import
{
getCurrentInstance
,
reactive
,
ref
,
toRefs
}
from
'vue'
import
{
getCurrentInstance
,
reactive
,
ref
,
toRefs
,
onMounted
,
onBeforeUnmount
}
from
'vue'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
import
{
useRouter
}
from
'vue-router'
import
useAppStore
from
'@/store/modules/app'
import
usePermissionStore
from
'@/store/modules/permission'
import
{
changeRoute
}
from
'@/utils/switchRoute'
import
WaterWaveChart
from
'./modules/WaterWaveChart.vue'
// import AddDiscoveryDialog from './modules/AddDiscoveryDialog.vue' // 引入新增发现任务弹窗
import
useAppStore
from
'@/store/modules/app'
import
{
tdataMonitorQuery
}
from
'@/api/discover'
const
appStore
=
useAppStore
()
const
ajaxFlag
=
ref
(
true
)
const
permissionStore
=
usePermissionStore
()
const
router
=
useRouter
()
const
emit
=
defineEmits
([
'page'
])
...
...
@@ -22,78 +30,142 @@ const props = defineProps({
default
:
()
=>
({})
}
})
function
pageProjectManage
()
{
changeRoute
()
function
pageList
()
{
emit
(
'page'
,
'list'
)
// changeRoute()
router
.
push
({
path
:
'/project/Project'
})
//
router.push({
//
path: '/project/Project'
//
})
}
// 进度数据
const
progress
=
ref
(
10
0
)
// 100% 进度
const
completedCount
=
ref
(
2
0
)
// 已完成表数量
const
progress
=
ref
(
0
)
// 100% 进度
const
tableSum
=
ref
(
0
)
// 已完成表数量
const
totalCount
=
ref
(
20
)
// 总表数量
// 执行失败数据
const
failureData
=
ref
([
{
category
:
'数据连接'
,
severity
:
'高'
,
executeTime
:
'2025-08-23 10:30'
},
{
category
:
'权限验证'
,
severity
:
'中'
,
executeTime
:
'2025-08-23 10:25'
},
{
category
:
'资源限制'
,
severity
:
'低'
,
executeTime
:
'2025-08-23 10:20'
}
//
{
//
category: '数据连接',
//
severity: '高',
//
executeTime: '2025-08-23 10:30'
//
},
//
{
//
category: '权限验证',
//
severity: '中',
//
executeTime: '2025-08-23 10:25'
//
},
//
{
//
category: '资源限制',
//
severity: '低',
//
executeTime: '2025-08-23 10:20'
//
}
])
// 已完成数据
const
completedData
=
ref
([
{
discoveryNo
:
1
,
tableName
:
'gen_table'
,
schema
:
'ry'
,
discoveryTime
:
'2025-08-23 04:15:23'
},
{
discoveryNo
:
2
,
tableName
:
'gen_table_column'
,
schema
:
'ry'
,
discoveryTime
:
'2025-08-23 04:15:24'
},
{
discoveryNo
:
3
,
tableName
:
'sys_config'
,
schema
:
'ry'
,
discoveryTime
:
'2025-08-23 04:15:25'
},
{
discoveryNo
:
4
,
tableName
:
'sys_dept'
,
schema
:
'ry'
,
discoveryTime
:
'2025-08-23 04:15:26'
},
{
discoveryNo
:
5
,
tableName
:
'sys_dict_data'
,
schema
:
'ry'
,
discoveryTime
:
'2025-08-23 04:15:27'
},
{
discoveryNo
:
6
,
tableName
:
'sys_dict_type'
,
schema
:
'ry'
,
discoveryTime
:
'2025-08-23 04:15:28'
},
{
discoveryNo
:
7
,
tableName
:
'sys_job'
,
schema
:
'ry'
,
discoveryTime
:
'2025-08-23 04:15:29'
},
{
discoveryNo
:
8
,
tableName
:
'sys_job_log'
,
schema
:
'ry'
,
discoveryTime
:
'2025-08-23 04:15:30'
},
{
discoveryNo
:
9
,
tableName
:
'sys_logininfor'
,
schema
:
'ry'
,
discoveryTime
:
'2025-08-23 04:15:31'
},
{
discoveryNo
:
10
,
tableName
:
'sys_menu'
,
schema
:
'ry'
,
discoveryTime
:
'2025-08-23 04:15:32'
},
{
discoveryNo
:
11
,
tableName
:
'sys_notice'
,
schema
:
'ry'
,
discoveryTime
:
'2025-08-23 04:15:33'
},
{
discoveryNo
:
12
,
tableName
:
'sys_oper_log'
,
schema
:
'ry'
,
discoveryTime
:
'2025-08-23 04:15:34'
},
{
discoveryNo
:
13
,
tableName
:
'sys_post'
,
schema
:
'ry'
,
discoveryTime
:
'2025-08-23 04:15:35'
},
{
discoveryNo
:
14
,
tableName
:
'sys_role'
,
schema
:
'ry'
,
discoveryTime
:
'2025-08-23 04:15:36'
}
//
{ discoveryNo: 1, tableName: 'gen_table', schema: 'ry', discoveryTime: '2025-08-23 04:15:23' },
//
{ discoveryNo: 2, tableName: 'gen_table_column', schema: 'ry', discoveryTime: '2025-08-23 04:15:24' },
//
{ discoveryNo: 3, tableName: 'sys_config', schema: 'ry', discoveryTime: '2025-08-23 04:15:25' },
//
{ discoveryNo: 4, tableName: 'sys_dept', schema: 'ry', discoveryTime: '2025-08-23 04:15:26' },
//
{ discoveryNo: 5, tableName: 'sys_dict_data', schema: 'ry', discoveryTime: '2025-08-23 04:15:27' },
//
{ discoveryNo: 6, tableName: 'sys_dict_type', schema: 'ry', discoveryTime: '2025-08-23 04:15:28' },
//
{ discoveryNo: 7, tableName: 'sys_job', schema: 'ry', discoveryTime: '2025-08-23 04:15:29' },
//
{ discoveryNo: 8, tableName: 'sys_job_log', schema: 'ry', discoveryTime: '2025-08-23 04:15:30' },
//
{ discoveryNo: 9, tableName: 'sys_logininfor', schema: 'ry', discoveryTime: '2025-08-23 04:15:31' },
//
{ discoveryNo: 10, tableName: 'sys_menu', schema: 'ry', discoveryTime: '2025-08-23 04:15:32' },
//
{ discoveryNo: 11, tableName: 'sys_notice', schema: 'ry', discoveryTime: '2025-08-23 04:15:33' },
//
{ discoveryNo: 12, tableName: 'sys_oper_log', schema: 'ry', discoveryTime: '2025-08-23 04:15:34' },
//
{ discoveryNo: 13, tableName: 'sys_post', schema: 'ry', discoveryTime: '2025-08-23 04:15:35' },
//
{ discoveryNo: 14, tableName: 'sys_role', schema: 'ry', discoveryTime: '2025-08-23 04:15:36' }
])
// 严重性标签类型
const
getSeverityType
=
(
severity
)
=>
{
const
types
=
{
'高'
:
'danger'
,
'中'
:
'warning'
,
'低'
:
'info'
}
return
types
[
severity
]
||
'info'
}
// 查看结果处理
const
handleCatResult
=
()
=>
{
console
.
log
(
'查看详细结果'
)
emit
(
'page'
,
'discoverResult'
)
appStore
.
setQueryData
({
taskid
:
appStore
.
queryData
.
taskid
,
resultid
:
appStore
.
queryData
.
resultid
,
datasystemid
:
appStore
.
queryData
.
datasystemid
,
discoverTaskName
:
appStore
.
queryData
.
discoverTaskName
,
icon
:
appStore
.
queryData
.
icon
,
breadPathData
:
[
{
path
:
appStore
.
queryData
.
breadPathData
[
0
].
path
,
label
:
appStore
.
queryData
.
breadPathData
[
0
].
label
},
{
label
:
"查看结果"
}
]
});
emit
(
'page'
,
'discoverResult'
,
{
listItem
:
props
.
listItem
})
}
onMounted
(()
=>
{
getMonitorDataRequest
()
})
const
timeOutId
=
ref
(
null
)
onBeforeUnmount
(()
=>
{
if
(
timeOutId
.
value
)
{
clearTimeout
(
timeOutId
.
value
);
ajaxFlag
.
value
=
false
}
})
const
getMonitorDataRequest
=
()
=>
{
tdataMonitorQuery
({
taskid
:
appStore
.
queryData
.
taskid
||
props
.
listItem
.
id
,
projectid
:
sessionStorage
.
getItem
(
'projectId'
)
}).
then
(
res
=>
{
const
{
statistics
,
errorlist
,
dbdatainfo
}
=
res
.
data
failureData
.
value
=
errorlist
.
map
(
item
=>
(({
...
item
,
category
:
item
.
errorType
,
severity
:
item
.
seriousness
,
executeTime
:
item
.
excutionTime
})))
tableSum
.
value
=
statistics
.
tableSum
if
(
statistics
.
count
===
0
){
progress
.
value
=
0
}
else
{
progress
.
value
=
((
statistics
.
tableSum
/
statistics
.
count
)
*
100
).
toFixed
(
2
)
}
completedData
.
value
=
JSON
.
parse
(
dbdatainfo
.
message
);
console
.
log
(
'completedData.value'
,
completedData
.
value
)
if
(
ajaxFlag
&&
(
progress
.
value
<
100
))
{
timeOutId
.
value
=
setTimeout
(()
=>
{
getMonitorDataRequest
();
},
1000
)
}
})
}
</
script
>
<
template
>
<div
class=
"app-container scroller"
>
<PageTitle
:back=
"true"
@
back=
"page
ProjectManage
"
>
<PageTitle
:back=
"true"
@
back=
"page
List
"
>
<template
#
title
>
返回项目管理
发现进度
</
template
>
</PageTitle>
...
...
@@ -110,7 +182,7 @@ const handleCatResult = () => {
<WaterWaveChart
:usage=
"progress"
color=
"#1890ff"
/>
</div>
<div
>
完成表数:{{ completedCount
}}
</div>
<div
class=
"complete"
>
完成表数:{{ tableSum
}}
</div>
</div>
<!-- 执行失败表格 -->
...
...
@@ -125,14 +197,8 @@ const handleCatResult = () => {
empty-text=
"暂无数据"
:header-cell-style=
"{ background: '#f5f7fa', color: '#606266' }"
>
<el-table-column
prop=
"category"
label=
"类别"
min-width=
"120"
/>
<el-table-column
prop=
"severity"
label=
"严重性"
min-width=
"100"
>
<
template
#
default=
"{ row }"
>
<el-tag
:type=
"getSeverityType(row.severity)"
size=
"small"
>
{{
row
.
severity
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"category"
label=
"类别"
min-width=
"120"
fixed=
"left"
/>
<el-table-column
prop=
"severity"
label=
"严重性"
min-width=
"100"
/>
<el-table-column
prop=
"executeTime"
label=
"执行时间"
min-width=
"140"
/>
</el-table>
</div>
...
...
@@ -142,23 +208,26 @@ const handleCatResult = () => {
<div
class=
"right-panel"
>
<div
class=
"completed-table-section"
>
<div
class=
"section-header"
>
<span
class=
"title"
>
已完成
</span>
<span
class=
"title"
>
已完成
</span>
<el-button
v-show=
"progress > 100.00 || progress == 100.00"
type=
"primary"
@
click=
"handleCatResult"
>
查看结果
</el-button>
</div>
<el-table
:data=
"completedData"
height=
"6
00
px"
height=
"6
12
px"
style=
"width: 100%"
:header-cell-style=
"{ background: '#f5f7fa', color: '#606266' }"
empty-text=
"暂无数据"
>
<el-table-column
prop=
"discoveryNo"
label=
"发现序号"
width=
"100"
align=
"center"
/>
<el-table-column
prop=
"tableName"
label=
"发现表名"
min-width=
"150"
/>
<el-table-column
prop=
"schema"
label=
"SCHEMA"
width=
"100"
/>
<el-table-column
prop=
"discoveryTime"
label=
"发现时间"
width=
"160"
/>
<el-table-column
label=
"发现序号"
width=
"100"
align=
"center"
fixed
>
<
template
#
default=
"scope"
>
{{
scope
.
$index
+
1
}}
</
template
>
</el-table-column>
<el-table-column
prop=
"dbType"
label=
"发现表名"
min-width=
"150"
/>
<el-table-column
prop=
"dbName"
label=
"SCHEMA"
width=
"100"
/>
<el-table-column
prop=
"createTime"
label=
"发现时间"
width=
"160"
fixed=
"right"
/>
</el-table>
</div>
</div>
...
...
@@ -211,7 +280,9 @@ const handleCatResult = () => {
flex-direction
:
column
;
gap
:
20px
;
}
.complete
{
width
:
100px
;
}
.right-panel
{
flex
:
1
;
min-width
:
0
;
...
...
src/views/discover/Discover/discoverResult.vue
View file @
2373db28
<
script
setup
name=
"DiscoverResult"
>
import
{
getCurrentInstance
,
reactive
,
ref
,
toRefs
}
from
'vue'
import
{
getCurrentInstance
,
reactive
,
ref
,
toRefs
,
onMounted
}
from
'vue'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
import
{
useRouter
}
from
'vue-router'
import
useAppStore
from
'@/store/modules/app'
import
usePermissionStore
from
'@/store/modules/permission'
import
{
changeRoute
}
from
'@/utils/switchRoute'
import
{
getToken
,
removeToken
}
from
'@/utils/auth'
import
DomainRuleDialog
from
'./modules/DomainRuleDialog.vue'
import
MatchPreviewDialog
from
'./modules/MatchPreviewDialog.vue'
import
SaveVersionDialog
from
'./modules/SaveVersionDialog.vue'
import
{
tdiscoverresultQuery
,
getdiscoverresultreport
,
getarearule
,
initExecute
,
discoverresultsure
,
discoverchangerule
,
showmatchrate
,
saveedition
,
download
}
from
'@/api/discover/index'
import
{
Loading
}
from
'@element-plus/icons-vue'
import
{
version
}
from
'nprogress'
const
appStore
=
useAppStore
()
const
permissionStore
=
usePermissionStore
()
...
...
@@ -22,46 +38,343 @@ const props = defineProps({
default
:
()
=>
({})
}
})
function
pageProjectManage
()
{
changeRoute
()
router
.
push
({
path
:
'/project/Project'
const
requestParams
=
ref
({
taskid
:
''
,
page
:
1
,
rows
:
10
,
resultid
:
''
,
filter
:
{
tablename
:
''
,
// 结果表名(resultid)
nschema
:
''
,
// schema名称
ntable
:
''
,
// 表名
nfield
:
''
,
// 字段名
checksure
:
'2'
,
// 是否确认(0:未确认 1:已确认 2:全部
issensitive
:
'0'
,
// 显示模式(0:显示全部 1:显示敏感)
}
})
const
requestParamsCopy
=
ref
({
taskid
:
''
,
page
:
1
,
rows
:
10
,
resultid
:
''
,
filter
:
{
tablename
:
''
,
// 结果表名(resultid)
nschema
:
''
,
// schema名称
ntable
:
''
,
// 表名
nfield
:
''
,
// 字段名
checksure
:
'2'
,
// 是否确认(0:未确认 1:已确认 2:全部
issensitive
:
'0'
,
// 显示模式(0:显示全部 1:显示敏感)
}
})
onMounted
(()
=>
{
requestParams
.
value
.
taskid
=
appStore
.
queryData
.
taskid
;
requestParams
.
value
.
resultid
=
appStore
.
queryData
.
resultid
;
requestParams
.
value
.
filter
.
tablename
=
appStore
.
queryData
.
resultid
;
requestParamsCopy
.
value
=
JSON
.
parse
(
JSON
.
stringify
(
requestParams
.
value
));
saveVersionDialog
.
value
.
params
.
taskid
=
appStore
.
queryData
.
taskid
;
saveVersionDialog
.
value
.
params
.
resultid
=
appStore
.
queryData
.
resultid
;
getResultListRequest
();
displayTableAndFields
();
getDiscoverRuleListRequest
();
getVersionHistoryListRequest
();
})
const
totalCount
=
ref
(
0
);
const
collapseDataList
=
ref
([]);
const
listLoading
=
ref
(
false
);
/**
* 请求敏感类型列表
*/
const
getResultListRequest
=
()
=>
{
listLoading
.
value
=
true
tdiscoverresultQuery
(
requestParams
.
value
).
then
(
response
=>
{
const
{
list
,
total
}
=
response
.
data
list
.
map
(
item
=>
{
item
.
children
.
map
(
child
=>
{
child
.
icon
=
[
{
label
:
'匹配预览'
,
name
:
"matchingPercent"
,
color
:
"rgb(50,176,115)"
,
icon
:
''
,
key
:
"actStatus"
}
];
if
(
child
.
dataarea_id
)
{
child
.
icon
.
push
({
label
:
child
.
dataarea_name
,
icon
:
""
,
color
:
"rgb(83,144,213)"
,
name
:
"setDataarea"
,
key
:
"dataarea_name"
})
}
else
{
child
.
icon
.
push
({
label
:
'设置'
,
icon
:
""
,
color
:
"rgb(83,144,213)"
,
name
:
"setDataarea"
,
// fontStyle: {color: 'red'},
key
:
"dataarea_name"
})
}
if
(
child
.
correlation
)
{
child
.
icon
.
push
({
label
:
'疑似敏感'
,
name
:
"maybeKey"
,
color
:
"rgb(250, 114, 86)"
,
icon
:
''
,
key
:
"actStatus"
})
}
child
.
button
=
child
.
issure
===
'1'
?
[
{
label
:
'已确认'
,
name
:
'confirm'
,
type
:
'success'
,
key
:
'confirm'
}
]
:
[
{
label
:
'未确认'
,
name
:
'unconfirmed'
,
type
:
'default'
,
key
:
'confirm'
},
];
child
.
discoverInfo
=
`
${
child
.
tsampling
}
/
${
child
.
teffe_sampling
}
/
${
child
.
tmatching
}
`
})
})
collapseDataList
.
value
=
list
;
totalCount
.
value
=
total
;
listLoading
.
value
=
false
})
}
const
reportData
=
ref
([])
const
displayTableAndFields
=
()
=>
{
getdiscoverresultreport
({
taskid
:
appStore
.
queryData
.
taskid
}).
then
(
response
=>
{
const
{
tasktime
,
tablecount
,
fieldcount
,
sensitivetable
,
sensitivefield
}
=
response
.
data
reportData
.
value
=
[
{
label
:
"任务运行时间"
,
content
:
tasktime
,
color
:
"rgb(50,179,115)"
},
{
label
:
"任务总对象数(表/文件)"
,
content
:
tablecount
,
color
:
"rgb(250,114,86)"
},
{
label
:
"发现敏感对象数(表/文件)"
,
content
:
String
(
sensitivetable
),
color
:
"rgb(255,189,91)"
},
{
label
:
"任务总列数"
,
content
:
String
(
fieldcount
),
color
:
"rgb(83,144,213)"
},
{
label
:
"发现敏感列数"
,
content
:
String
(
sensitivefield
),
color
:
"rgb(157,90,178)"
}
];
})
}
const
searchregexParams
=
ref
({
dataarea
:
''
,
rulename
:
''
})
const
dataAreaInfo
=
ref
({
dataArea
:
''
,
rule
:
''
,
dataAreaList
:
[],
ruleList
:
[]
})
const
getDiscoverRuleListRequest
=
()
=>
{
getarearule
({
project_id
:
sessionStorage
.
getItem
(
"projectId"
),
rulename
:
searchregexParams
.
value
.
dataarea
}).
then
(
response
=>
{
let
data
=
response
.
data
;
console
.
log
(
data
)
if
(
data
&&
data
.
length
>
0
)
{
const
newData
=
data
.
map
(
item
=>
{
return
{
dataarea
:
{
dataarea
:
item
.
dataareaname
,
id
:
item
.
dataarea_id
,
// areatype: item.areatype,
// ceatetime: item.createtime,
// createuser: item.createuser,
// flag: item.flag,
// hasarea: item.hasarea,
// note: item.note,
// remark: item.remark,
// updatetime: item.updatetime,
// updateuser: item.updateuser
},
data
:
item
.
regexlist
.
length
>
0
?
item
.
regexlist
.
map
(
rule
=>
{
return
{
createtime
:
rule
.
createTime
,
createuser
:
rule
.
createUser
,
dataarea
:
item
.
dataarea
,
datafile
:
null
,
defaulttype
:
String
(
rule
.
defaulttype
),
dictionaryClass
:
''
,
discoverway
:
''
,
name
:
rule
.
name
,
note
:
null
,
ruleid
:
String
(
rule
.
id
),
tid
:
item
.
tid
}
})
:
[]
}
})
dataAreaInfo
.
value
.
dataAreaList
=
newData
;
console
.
log
(
'123123'
,
dataAreaInfo
.
value
.
dataAreaList
)
}
})
}
const
all_version_data
=
ref
({})
const
project_version_data
=
ref
({})
const
task_version_data
=
ref
([])
const
getVersionHistoryListRequest
=
()
=>
{
initExecute
({
taskid
:
appStore
.
queryData
.
taskid
,
projectid
:
sessionStorage
.
getItem
(
"projectId"
)
}).
then
(
response
=>
{
const
{
data
}
=
response
.
data
;
let
{
all_version
,
project_version
,
task_version
}
=
data
;
task_version
.
sort
((
a
,
b
)
=>
new
Date
(
b
.
datetime
).
getTime
()
-
new
Date
(
a
.
datetime
).
getTime
());
all_version_data
.
value
=
all_version
project_version_data
.
value
=
project_version
task_version_data
.
value
=
task_version
})
}
const
tableColumns
=
ref
([
{
title
:
"序号"
,
align
:
"center"
,
width
:
70
,
key
:
"index"
},
{
title
:
"字段"
,
align
:
"center"
,
key
:
"tfields"
,
ellipsis
:
true
,
tooltip
:
true
,
width
:
150
},
{
title
:
"字段说明"
,
align
:
"center"
,
key
:
"tfieldremark"
,
tooltip
:
true
,
ellipsis
:
true
,
},
{
title
:
"采样数/有效采样数/匹配率"
,
align
:
"center"
,
key
:
"discoverInfo"
,
},
{
title
:
"数据域"
,
align
:
"center"
,
key
:
"dataarea_name"
,
slot
:
"action"
,
},
{
title
:
"数据发现规则"
,
align
:
"center"
,
key
:
"sensitive_name"
},
{
title
:
"梳理"
,
align
:
"center"
,
key
:
"confirm"
,
slot
:
"button"
},
{
title
:
"操作"
,
align
:
"center"
,
key
:
"actStatus"
,
width
:
260
,
slot
:
"action"
}
])
function
pageProjectManage
()
{
emit
(
'page'
,
'discoverProcess'
,
{
listItem
:
props
.
listItem
})
}
// 折叠面板激活项
const
activeNames
=
ref
(
'gen_table'
)
// gen_table 数据
const
genTableData
=
ref
([
{
index
:
1
,
field
:
'business_name'
,
fieldDesc
:
''
,
samplingInfo
:
'0/0/0%'
,
dataDomain
:
'设置'
,
discoveryRule
:
''
,
status
:
'未确认'
},
{
index
:
2
,
field
:
'business_name...'
,
fieldDesc
:
''
,
samplingInfo
:
'0/0/0%'
,
dataDomain
:
'设置'
,
discoveryRule
:
''
,
status
:
'未确认'
},
{
index
:
3
,
field
:
'class_name'
,
fieldDesc
:
''
,
samplingInfo
:
'0/0/0%'
,
dataDomain
:
'设置'
,
discoveryRule
:
''
,
status
:
'未确认'
},
{
index
:
4
,
field
:
'create_by'
,
fieldDesc
:
''
,
samplingInfo
:
'0/0/0%'
,
dataDomain
:
'设置'
,
discoveryRule
:
''
,
status
:
'未确认'
},
{
index
:
5
,
field
:
'create_time'
,
fieldDesc
:
''
,
samplingInfo
:
'0/0/0%'
,
dataDomain
:
'设置'
,
discoveryRule
:
''
,
status
:
'未确认'
},
{
index
:
6
,
field
:
'function_author'
,
fieldDesc
:
''
,
samplingInfo
:
'0/0/0%'
,
dataDomain
:
'设置'
,
discoveryRule
:
''
,
status
:
'未确认'
}
])
//
const genTableData = ref([
//
{ index: 1, field: 'business_name', fieldDesc: '', samplingInfo: '0/0/0%', dataDomain: '设置', discoveryRule: '', status: '未确认' },
//
{ index: 2, field: 'business_name...', fieldDesc: '', samplingInfo: '0/0/0%', dataDomain: '设置', discoveryRule: '', status: '未确认' },
//
{ index: 3, field: 'class_name', fieldDesc: '', samplingInfo: '0/0/0%', dataDomain: '设置', discoveryRule: '', status: '未确认' },
//
{ index: 4, field: 'create_by', fieldDesc: '', samplingInfo: '0/0/0%', dataDomain: '设置', discoveryRule: '', status: '未确认' },
//
{ index: 5, field: 'create_time', fieldDesc: '', samplingInfo: '0/0/0%', dataDomain: '设置', discoveryRule: '', status: '未确认' },
//
{ index: 6, field: 'function_author', fieldDesc: '', samplingInfo: '0/0/0%', dataDomain: '设置', discoveryRule: '', status: '未确认' }
//
])
// 其他表格数据
const
allTableNames
=
ref
([
{
name
:
'gen_table'
,
sensitiveCount
:
1
},
{
name
:
'ry.gen_table_column'
,
sensitiveCount
:
0
},
{
name
:
'ry.sys_config'
,
sensitiveCount
:
0
},
{
name
:
'ry.sys_dept'
,
sensitiveCount
:
1
},
{
name
:
'ry.sys_dict_data'
,
sensitiveCount
:
0
},
{
name
:
'ry.sys_dict_type'
,
sensitiveCount
:
0
},
{
name
:
'ry.sys_job'
,
sensitiveCount
:
0
},
{
name
:
'ry.sys_job_log'
,
sensitiveCount
:
0
},
{
name
:
'ry.sys_logininfor'
,
sensitiveCount
:
0
},
{
name
:
'ry.sys_menu'
,
sensitiveCount
:
0
}
])
//
const allTableNames = ref([
//
{ name: 'gen_table', sensitiveCount: 1 },
//
{ name: 'ry.gen_table_column', sensitiveCount: 0 },
//
{ name: 'ry.sys_config', sensitiveCount: 0 },
//
{ name: 'ry.sys_dept', sensitiveCount: 1 },
//
{ name: 'ry.sys_dict_data', sensitiveCount: 0 },
//
{ name: 'ry.sys_dict_type', sensitiveCount: 0 },
//
{ name: 'ry.sys_job', sensitiveCount: 0 },
//
{ name: 'ry.sys_job_log', sensitiveCount: 0 },
//
{ name: 'ry.sys_logininfor', sensitiveCount: 0 },
//
{ name: 'ry.sys_menu', sensitiveCount: 0 }
//
])
const
selectAll
=
ref
(
false
)
/**
* 显示敏感字段切换
*/
const
displaySensitive
=
()
=>
{
console
.
log
(
'显示敏感字段切换'
)
console
.
log
(
'显示敏感字段切换'
,
selectAll
.
value
)
requestParams
.
value
.
filter
.
issensitive
=
selectAll
.
value
===
true
?
'1'
:
'0'
getResultListRequest
()
// console.log(requestParams.value.filter.issensitive)
}
/**
...
...
@@ -70,24 +383,150 @@ const displaySensitive = ()=>{
const
batchSettingRules
=
()
=>
{
console
.
log
(
'批量设置规则'
)
}
const
confirmAllLoading
=
ref
(
false
)
/**
* 确认所有
*/
const
confirmAll
=
()
=>
{
console
.
log
(
'确认所有'
)
confirmAllLoading
.
value
=
true
discoverresultsure
({
resultid
:
appStore
.
queryData
.
resultid
,
filter
:
{
...
requestParams
.
value
.
filter
,
issure
:
'1'
}
}).
then
((
res
)
=>
{
if
(
res
.
flag
){
ElMessage
.
success
(
res
.
msg
)
confirmAllLoading
.
value
=
false
getResultListRequest
()
}
else
{
confirmAllLoading
.
value
=
false
ElMessage
.
error
(
res
.
msg
)
}
})
}
const
cancelAllLoading
=
ref
(
false
)
/**
* 取消所有
*/
const
cancelAll
=
()
=>
{
console
.
log
(
'取消所有'
)
ElMessageBox
.
confirm
(
`确认取消所有么?`
,
'警告'
,
{
confirmButtonText
:
'确认'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
,
}
).
then
(()
=>
{
cancelAllLoading
.
value
=
true
discoverresultsure
({
resultid
:
appStore
.
queryData
.
resultid
,
filter
:
{
...
requestParams
.
value
.
filter
,
issure
:
'0'
}
}).
then
((
res
)
=>
{
if
(
res
.
flag
){
ElMessage
.
success
(
res
.
msg
)
cancelAllLoading
.
value
=
false
getResultListRequest
()
}
else
{
cancelAllLoading
.
value
=
false
ElMessage
.
error
(
res
.
msg
)
}
})
})
}
const
saveVersionDialog
=
ref
({
status
:
false
,
params
:
{
versionname
:
''
,
taskid
:
''
,
flag
:
'1'
,
resultid
:
''
,
projectid
:
''
,
},
dataList
:
[]
})
/**
* 打开版本弹窗
*/
const
openSaveDialog
=
()
=>
{
saveVersionDialog
.
value
.
status
=
true
}
/**
* 保存
*/
const
handleSave
=
()
=>
{
console
.
log
(
'保存'
)
// 处理保存
const
handleSave
=
async
(
versionName
)
=>
{
if
(
!
versionName
.
trim
())
{
ElMessage
.
warning
(
'请输入版本名称'
)
return
}
try
{
const
params
=
{
...
saveVersionDialog
.
value
.
params
,
versionname
:
versionName
,
version
:
'task_version'
,
projectid
:
sessionStorage
.
getItem
(
'projectId'
)
}
// 检查版本名是否重复
const
isDuplicate
=
task_version_data
.
value
.
some
(
item
=>
item
.
versionname
===
versionName
.
trim
()
)
if
(
isDuplicate
)
{
await
ElMessageBox
.
confirm
(
'版本名重复,是否需要覆盖?'
,
'提示'
,
{
confirmButtonText
:
'确认覆盖'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
})
// 覆盖保存
await
saveedition
({
...
params
,
flag
:
'2'
})
}
else
{
// 新增保存
await
saveedition
({
...
params
,
flag
:
'0'
})
}
ElMessage
.
success
(
'保存成功!'
)
saveVersionDialog
.
value
.
status
=
false
saveVersionDialog
.
value
.
params
.
versionname
=
''
getVersionHistoryListRequest
()
}
catch
(
error
)
{
console
.
log
(
error
)
if
(
error
!==
'cancel'
)
{
ElMessage
.
error
(
'保存失败'
)
console
.
error
(
'Save error:'
,
error
)
}
}
}
// 关闭弹窗时的处理
const
handleSaveDialogClose
=
()
=>
{
saveVersionDialog
.
value
.
params
.
versionname
=
''
}
/**
* 后退
*/
...
...
@@ -99,80 +538,246 @@ const handleChangeTableByCollapse = ()=>{
console
.
log
(
'切换表格显示方式'
)
}
const
domainRuleDialogRef
=
ref
()
const
domainRuleDialogVisible
=
ref
(
false
)
const
currentRowData
=
ref
(
null
)
// 打开设置弹窗
const
openSettingDialog
=
(
row
)
=>
{
currentRowData
.
value
=
row
// 方法1:使用ref调用子组件方法
// domainRuleDialogRef.value?.openDialog()
// 方法2:或者直接控制visible
domainRuleDialogVisible
.
value
=
true
const
confirmKey
=
(
row
)
=>
{
discoverresultsure
({
resultid
:
appStore
.
queryData
.
resultid
,
tableid
:
row
.
id
,
filter
:
{
...
requestParams
.
value
.
filter
,
issure
:
row
.
issure
===
'0'
?
'1'
:
'0'
}
}).
then
(()
=>
{
getResultListRequest
();
})
}
const
setDataareaDialog
=
ref
({
title
:
''
,
status
:
false
,
cacheData
:
{}
})
const
setDataarea
=
(
row
)
=>
{
console
.
log
(
'row'
,
row
)
setDataareaDialog
.
value
.
status
=
true
;
setDataareaDialog
.
value
.
cacheData
=
row
;
if
(
searchregexParams
.
value
.
dataarea
.
trim
().
length
>
0
)
{
searchregexParams
.
value
.
dataarea
=
''
;
getDiscoverRuleListRequest
();
}
if
(
row
.
dataarea_id
)
{
dataAreaInfo
.
value
.
dataArea
=
row
.
dataarea_id
;
}
else
{
dataAreaInfo
.
value
.
dataArea
=
''
;
}
if
(
row
.
sensitive_id
)
{
console
.
log
(
'dataAreaInfo.value.dataAreaList'
,
dataAreaInfo
.
value
.
dataAreaList
)
dataAreaInfo
.
value
.
ruleList
=
dataAreaInfo
.
value
.
dataAreaList
.
filter
(
item
=>
item
.
dataarea
.
id
===
row
.
dataarea_id
)[
0
].
data
;
console
.
log
(
' dataAreaInfo.value.ruleList'
,
dataAreaInfo
.
value
.
ruleList
)
dataAreaInfo
.
value
.
rule
=
row
.
sensitive_id
;
}
else
{
dataAreaInfo
.
value
.
rule
=
''
;
dataAreaInfo
.
value
.
ruleList
=
[]
console
.
log
(
'123'
)
}
}
const
selectRule
=
ref
({
})
// 处理规则确认
const
handleRuleConfirm
=
(
ruleData
)
=>
{
console
.
log
(
'选择的规则:'
,
ruleData
)
if
(
currentRowData
.
value
)
{
currentRowData
.
value
.
discoveryRule
=
ruleData
.
ruleLabel
currentRowData
.
value
.
dataDomain
=
ruleData
.
domainLabel
// 同时保存value值用于下次打开时回显
currentRowData
.
value
.
discoveryRuleValue
=
ruleData
.
rule
currentRowData
.
value
.
dataDomainValue
=
ruleData
.
domain
selectRule
.
value
=
ruleData
handlerSubmitRule
()
}
const
handlerSubmitRule
=
()
=>
{
console
.
log
(
'setDataareaDialog.value.cacheData'
,
setDataareaDialog
.
value
.
cacheData
)
discoverchangerule
({
resultid
:
appStore
.
queryData
.
resultid
,
tableid
:
setDataareaDialog
.
value
.
cacheData
.
id
,
filter
:
{
...
requestParams
.
value
.
filter
,
nareaid
:
selectRule
.
value
.
domainValue
,
nareaname
:
selectRule
.
value
.
domain
.
dataarea
,
ntruleid
:
selectRule
.
value
.
ruleValue
,
ntrulename
:
selectRule
.
value
.
rule
}
}).
then
(()
=>
{
getResultListRequest
();
setDataareaDialog
.
value
.
status
=
false
;
})
}
const
resetRule
=
()
=>
{
discoverchangerule
({
resultid
:
appStore
.
queryData
.
resultid
,
tableid
:
setDataareaDialog
.
value
.
cacheData
.
id
,
filter
:
{
...
requestParams
.
value
.
filter
,
nareaid
:
''
,
nareaname
:
''
,
ntruleid
:
''
,
ntrulename
:
''
}
}).
then
(()
=>
{
getResultListRequest
();
setDataareaDialog
.
value
.
status
=
false
;
const
{
cacheData
}
=
JSON
.
parse
(
JSON
.
stringify
(
setDataareaDialog
.
value
));
ElMessageBox
.
confirm
(
JSON
.
stringify
(
cacheData
.
value
)
===
'{}'
?
"撤销重置数据域操作!"
:
`撤销
${
cacheData
.
value
.
ttables
}
.
${
cacheData
.
value
.
tfields
}
的重置数据域操作!`
,
'警告'
,
{
confirmButtonText
:
'确认'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
,
}
).
then
(()
=>
{
discoverchangerule
({
resultid
:
appStore
.
queryData
.
resultid
,
tableid
:
cacheData
.
value
.
id
,
filter
:
{
...
requestParams
.
value
.
filter
,
nareaid
:
cacheData
.
value
.
dataarea_id
,
nareaname
:
cacheData
.
value
.
dataarea_name
,
ntruleid
:
String
(
cacheData
.
value
.
sensitive_id
),
ntrulename
:
cacheData
.
value
.
sensitive_name
}
}).
then
(()
=>
{
getResultListRequest
()
})
})
const
matchPreviewDialogRef
=
ref
()
const
matchPreviewDialogVisible
=
ref
(
false
)
const
currentRowDataPreview
=
ref
(
null
)
// 模拟匹配数据
const
matchedData
=
ref
([
{
value
:
'15888888888'
},
{
value
:
'15888888888'
},
{
value
:
'15888888888'
},
{
value
:
'15888888888'
},
{
value
:
'15888888888'
},
{
value
:
'15888888888'
},
{
value
:
'15888888888'
},
{
value
:
'15888888888'
},
{
value
:
'15888888888'
},
{
value
:
'15888888888'
}
])
})
}
const
unmatchedData
=
ref
([])
// 空数组,显示"暂无数据"
const
closeDomainRuleDialog
=
()
=>
{
dataAreaInfo
.
value
.
rule
=
''
;
dataAreaInfo
.
value
.
ruleList
=
[]
dataAreaInfo
.
value
.
dataArea
=
''
;
searchregexParams
.
value
.
dataarea
=
''
;
setDataareaDialog
.
value
.
status
=
false
console
.
log
(
1234
)
}
const
matchingDiscoverDialog
=
ref
({
status
:
false
,
sampleViewList
:
[],
unmatchDataList
:
[]
})
/**
* 匹配预览
* @param row
*/
const
matchingPercent
=
(
row
)
=>
{
showmatchrate
({
projectid
:
sessionStorage
.
getItem
(
'projectId'
),
taskid
:
appStore
.
queryData
.
taskid
,
ttables
:
row
.
ttables
,
tfields
:
row
.
tfields
,
dataarea_name
:
row
.
dataarea_name
}).
then
(
response
=>
{
const
{
matchurl
,
unmatchurl
}
=
response
.
data
;
matchingDiscoverDialog
.
value
.
status
=
true
;
matchingDiscoverDialog
.
value
.
sampleViewList
=
matchurl
.
map
(
item
=>
({
label
:
item
}));
matchingDiscoverDialog
.
value
.
unmatchDataList
=
unmatchurl
.
map
(
item
=>
({
label
:
item
}));
})
}
// 关闭弹窗时清空数据
const
handleMatchDialogClose
=
()
=>
{
matchingDiscoverDialog
.
value
.
sampleViewList
=
[]
matchingDiscoverDialog
.
value
.
unmatchDataList
=
[]
}
// 打开匹配预览弹窗
const
handleMatch
=
(
row
)
=>
{
console
.
log
(
'匹配预览:'
,
row
)
currentRowDataPreview
.
value
=
row
// 根据行数据获取匹配结果(这里需要根据实际业务逻辑实现)
// const matchResult = getMatchResult(row)
// matchedData.value = matchResult.matched
// unmatchedData.value = matchResult.unmatched
// 打开弹窗
matchPreviewDialogVisible
.
value
=
true
/**
* 导出当前查询结果信息文件
*/
const
exportData
=
()
=>
{
download
({
resultid
:
appStore
.
queryData
.
resultid
}).
then
(
res
=>
{
let
blob
=
new
Blob
([
res
],
{
type
:
'application/vnd.ms-excel,charset=utf-8'
})
let
elink
=
document
.
createElement
(
'a'
);
elink
.
href
=
URL
.
createObjectURL
(
blob
);
elink
.
download
=
appStore
.
queryData
.
discoverTaskName
+
"发现结果.xlsx"
document
.
body
.
appendChild
(
elink
);
elink
.
click
();
document
.
body
.
removeChild
(
elink
);
})
}
// 获取匹配结果的方法(需要根据实际业务实现)
const
getMatchResult
=
(
row
)
=>
{
// 这里应该是您的业务逻辑,返回匹配和不匹配的数据
return
{
matched
:
matchedData
.
value
,
unmatched
:
unmatchedData
.
value
}
const
handleImport
=
()
=>
{
uploadRef
.
value
?.
$el
.
querySelector
(
'input[type="file"]'
)?.
click
()
}
const
uploadRef
=
ref
(
null
)
const
uploadHeaders
=
ref
({
Token
:
getToken
()
})
const
uploadAction
=
computed
(()
=>
import
.
meta
.
env
.
VITE_APP_BASE_API
+
'/core/tdiscoverresult/importdata'
)
const
uploadData
=
ref
({
resultid
:
appStore
.
queryData
.
resultid
})
/**
* 上传前的验证
*/
const
beforeUpload
=
(
file
)
=>
{
console
.
log
(
file
)
const
isExcel
=
file
.
type
===
'application/vnd.ms-excel'
||
file
.
type
===
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
||
file
.
name
.
endsWith
(
'.xlsx'
)
||
file
.
name
.
endsWith
(
'.xls'
)
if
(
!
isExcel
)
{
ElMessage
.
error
(
'只能上传 Excel 文件!'
)
return
false
}
const
isLt10M
=
file
.
size
/
1024
/
1024
<
10
if
(
!
isLt10M
)
{
ElMessage
.
error
(
'文件大小不能超过 10MB!'
)
return
false
}
// 显示加载中
ElMessage
.
info
(
'文件上传中...'
)
return
true
}
/**
* 上传成功处理
*/
const
handleSuccess
=
(
response
,
file
,
fileList
)
=>
{
if
(
response
.
flag
)
{
ElMessage
.
success
(
'导入成功!'
)
// 刷新数据列表
getResultListRequest
()
}
else
{
ElMessage
.
error
(
response
.
msg
||
'导入失败'
)
}
}
/**
* 上传失败处理
*/
const
handleError
=
(
error
,
file
,
fileList
)
=>
{
console
.
error
(
'Upload error:'
,
error
)
ElMessage
.
error
(
'文件上传失败,请重试'
)
}
</
script
>
...
...
@@ -180,41 +785,44 @@ const getMatchResult = (row) => {
<div
class=
"app-container scroller"
>
<PageTitle
:back=
"true"
@
back=
"pageProjectManage"
>
<template
#
title
>
返回项目管理
查看结果
</
template
>
<
template
#
buttons
>
<el-button
type=
"success"
@
click=
"batchSettingRules"
>
批量设置规则
</el-button>
<el-checkbox
style=
"margin-right: 10px;"
v-model=
"selectAll"
@
change=
"displaySensitive"
class=
"select-all-checkbox"
>
仅显示敏感字段
</el-checkbox>
<el-button
type=
"primary"
:Loading=
"confirmAllLoading"
@
click=
"confirmAll"
>
确认所有
</el-button>
<el-button
type=
"danger"
:loading=
"cancelAllLoading"
@
click=
"cancelAll"
>
取消所有
</el-button>
<el-button
type=
"success"
@
click=
"
handleSave
"
@
click=
"
openSaveDialog
"
>
保存
保存
版本
</el-button>
<el-button
type=
"
info
"
@
click=
"
handleBack
"
type=
"
primary
"
@
click=
"
exportData
"
>
后退
导出
</el-button>
<el-button
type=
"success"
@
click=
"handleImport"
>
导入
</el-button>
<el-checkbox
style=
"margin-left: 10px;"
v-model=
"selectAll"
@
change=
"displaySensitive"
class=
"select-all-checkbox"
>
仅显示敏感字段
</el-checkbox>
</
template
>
</PageTitle>
...
...
@@ -227,100 +835,116 @@ const getMatchResult = (row) => {
<h2
class=
"report-title"
>
发现任务执行报告
</h2>
<div
class=
"overview-cards"
>
<el-descriptions
:column=
"4"
border
>
<el-descriptions-item
label=
"任务运行时间"
>
<span
class=
"highlight-text"
>
911毫秒
</span>
</el-descriptions-item>
<el-descriptions-item
label=
"任务总对象数"
>
<span
class=
"highlight-text"
>
20
</span>
</el-descriptions-item>
<el-descriptions-item
label=
"发现敏感对象数(表/文件)"
>
<span
class=
"highlight-text"
>
2
</span>
</el-descriptions-item>
<el-descriptions-item
label=
"任务总列数"
>
<span
class=
"highlight-text"
>
225
</span>
</el-descriptions-item>
<el-descriptions-item
label=
"发现敏感列数"
>
<span
class=
"highlight-text"
>
2
</span>
<el-descriptions-item
:label=
"item.label"
v-for=
"(item,index) in reportData"
:key=
"index"
>
<span
class=
"highlight-text"
>
{{item.content}}
</span>
</el-descriptions-item>
</el-descriptions>
</div>
</div>
<!-- 下方:详细数据表格 -->
<div
class=
"detailed-data"
>
<el-collapse
v-model=
"activeNames"
accordion
@
change=
"handleChangeTableByCollapse"
>
<el-collapse
v-model=
"activeNames"
v-if=
"collapseDataList.length > 0"
v-loading=
"listLoading"
accordion
@
change=
"handleChangeTableByCollapse"
>
<!-- 第一个表格 -->
<el-collapse-item
:name=
"item.
name"
v-for=
"(item, index) in allTableNames
"
:key=
"index"
>
<el-collapse-item
:name=
"item.
tfields"
v-for=
"(item, index) in collapseDataList
"
:key=
"index"
>
<
template
#
title
>
<span
class=
"collapse-title"
>
{{
item
.
name
}}
</span>
<span
class=
"sensitive-count"
>
{{
item
.
sensitiveCount
}}
个敏感数据
</span>
</
template
>
<el-table
:data=
"genTableData"
height=
"300px"
style=
"width: 100%;"
>
<el-table-column
prop=
"index"
label=
"序号"
width=
"60"
align=
"center"
fixed
/>
<el-table-column
prop=
"field"
label=
"字段"
min-width=
"120"
/>
<el-table-column
prop=
"fieldDesc"
label=
"字段说明"
min-width=
"150"
/>
<el-table-column
label=
"采样数/有效采样数/匹配率"
min-width=
"180"
>
<
template
#
default=
"{ row }"
>
{{
row
.
samplingInfo
}}
<span
class=
"collapse-title"
>
{{
item
.
tfields
}}
</span>
<span
class=
"sensitive-count"
>
{{
item
.
dataarea_name
}}
</span>
</
template
>
</el-table-column>
<el-table-column
prop=
"dataDomain"
label=
"数据域"
min-width=
"100"
>
<
template
#
default=
"scope"
>
<el-button
v-if=
"scope.row.discoveryRule"
type=
"primary"
plain
size=
"small"
@
click=
"openSettingDialog(scope.row)"
>
{{
scope
.
row
.
discoveryRule
}}
</el-button>
<el-button
v-else
plain
type=
"primary"
size=
"small"
@
click=
"openSettingDialog(scope.row)"
<el-table
:data=
"item.children"
height=
"300px"
style=
"width: 100%;"
>
<el-table-column
v-for=
"(tableItem,tableIndex) in tableColumns"
:fixed=
"tableIndex === tableColumns.length - 1 ? 'right' : ''"
:key=
"tableIndex"
:prop=
"tableItem.key"
:label=
"tableItem.title"
:width=
"tableItem.width"
:align=
"tableItem.align"
:show-overflow-tooltip=
"tableItem.tooltip"
>
设置
</el-button>
</
template
>
</el-table-column>
<el-table-column
prop=
"discoveryRule"
label=
"数据发现规则"
min-width=
"150"
/>
<el-table-column
prop=
"status"
label=
"梳理"
min-width=
"100"
>
<
template
#
default
>
<el-tag
size=
"small"
>
未确认
</el-tag>
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
min-width=
"120"
align=
"center"
fixed=
"right"
>
<
template
#
default=
"scope"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"handleMatch(scope.row)"
>
匹配预览
</el-button>
<div
v-if=
"tableItem.key === 'index'"
>
{{
scope
.
$index
+
1
}}
</div>
<el-button
type=
"primary"
link
v-if=
"tableItem.key === 'dataarea_name'"
@
click=
"setDataarea(scope.row)"
>
{{
scope
.
row
.
icon
.
find
(
x
=>
x
.
key
===
'dataarea_name'
).
label
}}
</el-button>
<el-button
type=
"primary"
plain
v-if=
"tableItem.key === 'confirm'"
size=
"small"
@
click=
"confirmKey(scope.row)"
>
{{
scope
.
row
.
button
[
0
].
label
}}
</el-button>
<el-button
type=
"success"
plain
v-if=
"tableItem.key === 'actStatus'"
size=
"small"
@
click=
"matchingPercent(scope.row)"
>
{{
scope
.
row
.
icon
.
find
(
x
=>
x
.
key
===
'actStatus'
).
label
}}
</el-button>
</
template
>
</el-table-column>
</el-table>
</el-collapse-item>
</el-collapse>
<el-empty
description=
"暂无数据"
v-else
/>
</div>
<pagination
v-show=
"totalCount > 0"
:total=
"totalCount"
v-model:page=
"requestParams.page"
v-model:limit=
"requestParams.rows"
@
pagination=
"getResultListRequest"
/>
</div>
</div>
<DomainRuleDialog
v-model=
"domainRuleDialogVisible"
:selected-data=
"currentRowData ? {
domain: currentRowData.dataDomainValue,
rule: currentRowData.discoveryRuleValue
} : {}"
v-model=
"setDataareaDialog.status"
:title=
"setDataareaDialog.title || '设置数据域与字段发现规则'"
:data-area-list=
"dataAreaInfo.dataAreaList"
:selected-data-area=
"dataAreaInfo.dataArea"
:selected-rule=
"dataAreaInfo.rule"
:ruleList=
"dataAreaInfo.ruleList"
@
update:selectedDataArea=
"(value) => dataAreaInfo.dataArea = value"
@
update:selectedRule=
"(value) => dataAreaInfo.rule = value"
@
confirm=
"handleRuleConfirm"
@
handleReset=
"resetRule"
@
closeDialog=
"closeDomainRuleDialog"
/>
<!-- 匹配预览弹窗 -->
<MatchPreviewDialog
v-model=
"matchPreviewDialogVisible"
:matched-data=
"matchedData"
:unmatched-data=
"unmatchedData"
v-model=
"matchingDiscoverDialog.status"
:matched-data=
"matchingDiscoverDialog.sampleViewList"
:unmatched-data=
"matchingDiscoverDialog.unmatchDataList"
@
close=
"handleMatchDialogClose"
/>
<SaveVersionDialog
v-model=
"saveVersionDialog.status"
title=
"保存发现模板"
:history-list=
"task_version_data"
:version-name=
"saveVersionDialog.params.versionname"
@
update:versionName=
"(value) => saveVersionDialog.params.versionname = value"
@
save=
"handleSave"
@
close=
"handleSaveDialogClose"
/>
<el-upload
ref=
"uploadRef"
class=
"hidden-upload"
:action=
"uploadAction"
:headers=
"uploadHeaders"
:data=
"uploadData"
:before-upload=
"beforeUpload"
:on-success=
"handleSuccess"
:on-error=
"handleError"
:show-file-list=
"false"
accept=
".xlsx,.xls"
/>
</div>
</template>
...
...
@@ -351,7 +975,7 @@ const getMatchResult = (row) => {
.discovery-report-container
{
padding
:
20px
;
background
:
#f5f7fa
;
min-height
:
100vh
;
//
min-height
:
100vh
;
}
.report-overview
{
...
...
src/views/discover/Discover/list.vue
View file @
2373db28
...
...
@@ -13,8 +13,10 @@ import SmartDiscoveryDialog from './modules/SmartDiscoveryDialog.vue'
import
{
queryDiscoverList
queryDiscoverList
,
delDiscoverTask
,
executetask
,
initExecute
}
from
'@/api/discover/index'
const
route
=
useRoute
()
...
...
@@ -166,25 +168,71 @@ const handleEdit = (row) => {
const
handleDiscover
=
(
row
)
=>
{
console
.
log
(
'发现:'
,
row
)
ElMessage
.
success
(
`开始发现任务:
${
row
.
taskName
}
`
)
emit
(
'page'
,
'discoverProcess'
,
{
listItem
:
row
})
// router.push({
// path: '/user/discoverProcess',
// query: {
// taskid: row.id,
// resultid: row.resultid,
// datasystemid: row.datasystemid,
// discoverTaskName: row.tname,
// btnStatus: '1'
// }
// })
}
ElMessageBox
.
confirm
(
'确认执行发现任务吗?'
+
`[
${
row
.
taskName
}
]`
,
'确认'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
}).
then
(
async
()
=>
{
executetask
({
taskid
:
row
.
id
,
version
:
''
,
datasystemid
:
row
.
datasystemid
,
taskname
:
row
.
tname
,
projectid
:
sessionStorage
.
getItem
(
'projectId'
),
project
:
sessionStorage
.
getItem
(
'projectName'
)
}).
then
(
res
=>
{
if
(
res
.
flag
){
appStore
.
setQueryData
({
taskid
:
row
.
id
,
btnStatus
:
'1'
,
resultid
:
row
.
resultid
,
datasystemid
:
row
.
datasystemid
,
discoverTaskName
:
row
.
tname
,
icon
:
route
.
meta
.
icon
,
breadPathData
:
[
{
path
:
route
.
path
,
label
:
route
.
meta
.
title
},
{
label
:
"发现进度"
}
]
});
emit
(
'page'
,
'discoverProcess'
,
{
listItem
:
row
})
}
else
{
ElMessage
.
error
(
res
.
msg
)
}
})
})
}
/**
* 监控
* @param row
*/
const
handleMonitor
=
(
row
)
=>
{
console
.
log
(
'监控:'
,
row
)
ElMessage
.
warning
(
`监控任务:
${
row
.
taskName
}
`
)
appStore
.
setQueryData
({
taskid
:
row
.
id
,
btnStatus
:
row
.
taskstatus
,
resultid
:
row
.
resultid
,
datasystemid
:
row
.
datasystemid
,
discoverTaskName
:
row
.
tname
,
icon
:
route
.
meta
.
icon
,
breadPathData
:
[
{
path
:
route
.
path
,
label
:
route
.
meta
.
title
},
{
label
:
"发现进度"
}
]
});
emit
(
'page'
,
'discoverProcess'
,
{
listItem
:
row
})
}
const
smartDiscoveryDialogRef
=
ref
()
const
smartData
=
ref
(
null
)
...
...
@@ -193,7 +241,6 @@ const handleMoreCommand = (command, row) => {
case
'smartDiscover'
:
smartData
.
value
=
row
handleSmartDiscover
(
row
)
ElMessage
.
info
(
`智能发现:
${
row
.
taskName
}
`
)
break
case
'viewHistory'
:
ElMessage
.
info
(
`查看历史:
${
row
.
taskName
}
`
)
...
...
@@ -206,18 +253,103 @@ const handleMoreCommand = (command, row) => {
emit
(
'page'
,
'discoverResult'
)
break
case
'delete'
:
ElMessage
.
error
(
`删除任务:
${
row
.
taskName
}
`
)
ElMessageBox
.
confirm
(
'删除后无法恢复,是否确认删除?'
,
'确认'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
}).
then
(
async
()
=>
{
delDiscoverTask
({
dataSystemName
:
'orcl202'
,
taskid
:
row
.
id
}).
then
(
res
=>
{
if
(
res
.
flag
){
ElMessage
.
success
(
res
.
msg
)
handleQuery
()
}
else
{
ElMessage
.
error
(
res
.
msg
)
}
})
})
break
}
}
const
smartDiscoveryDialogVisible
=
ref
(
false
)
const
AIDIscoverVersionListDialog
=
ref
({
status
:
false
,
cacheData
:
{},
columnsData
:
[
{
title
:
'发现版本'
,
key
:
'name'
,
align
:
'left'
},
{
title
:
"操作"
,
slot
:
"action"
,
key
:
"action"
,
align
:
"center"
,
width
:
150
}
],
tableData
:
[]
})
// 打开智能发现弹窗
const
handleSmartDiscover
=
(
row
)
=>
{
// 可以传入特定的发现版本数据
const
discoveryData
=
[
{
version
:
row
.
resultid
||
'12123'
}
// 使用任务的结果ID或默认值
initExecute
({
taskid
:
row
.
id
,
projectid
:
sessionStorage
.
getItem
(
'projectId'
)
}).
then
(
res
=>
{
const
{
task_version
,
project_version
,
all_version
}
=
res
.
data
const
allVersionList
=
[];
AIDIscoverVersionListDialog
.
value
.
status
=
true
AIDIscoverVersionListDialog
.
value
.
cacheData
=
row
if
(
JSON
.
stringify
(
all_version
)
!==
'{}'
)
{
allVersionList
.
push
({
...
project_version
,
version
:
all_version
.
versionname
,
type
:
'all_version'
,
versionname
:
`全局版本:
${
all_version
.
versionname
}
`
})
}
if
(
JSON
.
stringify
(
project_version
)
!==
'{}'
)
{
allVersionList
.
push
({
...
project_version
,
version
:
project_version
.
versionname
,
type
:
'project_version'
,
versionname
:
`项目版本:
${
project_version
.
versionname
}
`
})
}
task_version
.
map
(
item
=>
{
item
.
version
=
item
.
versionname
;
item
.
type
=
item
.
filename
;
item
.
versionname
=
`任务版本:
${
item
.
versionname
}
`
;
allVersionList
.
push
(
item
);
})
AIDIscoverVersionListDialog
.
value
.
tableData
=
allVersionList
.
map
(
item
=>
{
return
{
...
item
,
name
:
item
.
versionname
,
icon
:
[
{
...
appStore
.
tableButtonIcons
.
discover
,
key
:
'action'
,
name
:
'handleDiscover'
,
label
:
'智能发现'
,
}
]
}
})
})
// 优先使用ref方式
if
(
smartDiscoveryDialogRef
.
value
?.
openDialog
)
{
...
...
src/views/discover/Discover/modules/DomainRuleDialog.vue
View file @
2373db28
<
template
>
<el-dialog
v-model=
"dialogVisible"
title=
"设置数据域与字段发现规则"
width=
"700px"
:title=
"title"
width=
"800px"
destroy-on-close
:before-close=
"handleClose"
>
<div
class=
"domain-rule-dialog"
>
<!-- 搜索区域 -->
<div
class=
"search-section"
>
<el-input
v-model=
"
domainSearch
"
v-model=
"
searchText
"
placeholder=
"请输入数据域名称"
size=
"small"
prefix-icon=
"Search"
clearable
class=
"search-input"
/>
</div>
<div
class=
"content-section"
>
<!-- 左侧数据域列表 -->
<div
class=
"domain-list"
>
<div
class=
"section-title"
>
选择数据域
</div>
<div
class=
"content-container"
>
<!-- 左侧:选择数据域 -->
<div
class=
"left-panel"
>
<div
class=
"panel-header"
>
<h4>
选择数据域
</h4>
</div>
<div
class=
"list-container"
>
<el-radio-group
v-model=
"selectedDomain"
@
change=
"handleDomainChange"
>
<div
v-for=
"domain in filteredDomains"
:key=
"domain.value"
class=
"domain-item"
v-for=
"item in filteredDataAreaList"
:key=
"item.dataarea.id"
class=
"list-item"
:class=
"
{ 'item-selected': selectedDataArea === item.dataarea.id }"
@click="selectDataArea(item)"
>
<el-radio
:label=
"domain.value
"
>
{{
domain
.
label
}}
</el-radio
>
<div
class=
"item-content
"
>
<span
class=
"item-text"
>
{{
item
.
dataarea
.
dataarea
}}
</span>
</div
>
</div>
</el-radio-group>
</div>
</div>
<!-- 右侧字段发现规则 -->
<div
class=
"rule-list"
>
<div
class=
"section-title"
>
选择字段发现规则
</div>
<!-- 右侧:选择字段发现规则 -->
<div
class=
"right-panel"
>
<div
class=
"panel-header"
>
<h4>
选择字段发现规则
</h4>
</div>
<div
class=
"list-container"
>
<el-radio-group
v-model=
"selectedRule"
>
<div
v-for=
"rule in currentRules"
:key=
"rule.value"
class=
"rule-item"
v-for=
"rule in combinedRuleList"
:key=
"rule.ruleid"
class=
"list-item"
:class=
"
{ 'item-selected': selectedRule === rule.ruleid }"
@click="selectRule(rule)"
>
<el-radio
:label=
"rule.value"
>
{{
rule
.
label
}}
</el-radio>
<div
class=
"item-content"
>
<span
class=
"item-text"
>
{{
rule
.
name
}}
</span>
<span
class=
"item-desc"
v-if=
"rule.note"
>
{{
rule
.
note
}}
</span>
</div>
</div>
<div
v-if=
"combinedRuleList.length === 0"
class=
"empty-tip"
>
<el-empty
description=
"暂无数据"
/>
</
极速
>
</div>
</el-radio-group>
</div>
</div>
</div>
<!-- 底部按钮 -->
<div
class=
"dialog-footer"
>
<el-button
@
click=
"handleReset"
>
重置规则
</el-button>
...
...
@@ -69,149 +81,110 @@ import { ref, computed, watch } from 'vue'
import
{
ElMessage
}
from
'element-plus'
const
props
=
defineProps
({
// 已选择的规则数据 { domain: '', rule: '' }
selectedData
:
{
type
:
Object
,
default
:
()
=>
({})
modelValue
:
{
type
:
Boolean
,
default
:
false
},
title
:
{
type
:
String
,
default
:
'设置数据域与字段发现规则'
},
dataAreaList
:
{
type
:
Array
,
default
:
()
=>
[]
},
ruleList
:
{
type
:
Array
,
default
:
()
=>
[]
},
selectedDataArea
:
{
type
:
String
,
default
:
''
},
selectedRule
:
{
type
:
String
,
// 明确为字符串类型
default
:
''
}
})
const
emit
=
defineEmits
([
'update:modelValue'
,
'confirm'
])
const
emit
=
defineEmits
([
'update:modelValue'
,
'confirm'
,
'update:selectedDataArea'
,
'update:selectedRule'
,
'closeDialog'
,
'handleReset'
])
const
dialogVisible
=
computed
({
get
:
()
=>
props
.
modelValue
,
set
:
(
value
)
=>
emit
(
'update:modelValue'
,
value
)
})
const
domainSearch
=
ref
(
''
)
const
selectedDomain
=
ref
(
''
)
const
selectedRule
=
ref
(
''
)
// 数据域选项(根据图片内容)
const
domains
=
ref
([
{
value
:
'general'
,
label
:
'通用规则'
},
{
value
:
'decrypt'
,
label
:
'解密数据'
},
{
value
:
'mixed_id'
,
label
:
'混合证件号'
},
{
value
:
'email'
,
label
:
'电子邮件'
},
{
value
:
'social_security'
,
label
:
'社保卡号'
},
{
value
:
'business_license'
,
label
:
'营业执照'
},
{
value
:
'postal_code'
,
label
:
'邮政编码'
},
{
value
:
'chinese_address'
,
label
:
'中文地址'
},
{
value
:
'mixed_phone'
,
label
:
'混合电话号码'
},
{
value
:
'name'
,
label
:
'姓名'
},
{
value
:
'bank_card'
,
label
:
'银行卡号'
},
{
value
:
'ip_address'
,
label
:
'IP地址'
}
])
// 字段发现规则映射
const
rulesMapping
=
{
general
:
[
{
value
:
'general_rule_1'
,
label
:
'通用规则查询'
},
{
value
:
'general_rule_2'
,
label
:
'通用数据发现'
}
],
decrypt
:
[
{
value
:
'decrypt_rule_1'
,
label
:
'解密数据查询'
},
{
value
:
'decrypt_rule_2'
,
label
:
'数据解密规则'
}
],
mixed_id
:
[
{
value
:
'mixed_id_rule_1'
,
label
:
'按混合证件号字段查询'
}
],
email
:
[
{
value
:
'email_rule_1'
,
label
:
'邮箱字段查询'
},
{
value
:
'email_rule_2'
,
label
:
'电子邮件规则'
}
],
social_security
:
[
{
value
:
'ss_rule_1'
,
label
:
'社保卡号查询'
}
],
business_license
:
[
{
value
:
'bl_rule_1'
,
label
:
'营业执照查询'
}
],
postal_code
:
[
{
value
:
'pc_rule_1'
,
label
:
'邮政编码查询'
}
],
chinese_address
:
[
{
value
:
'address_rule_1'
,
label
:
'中文地址查询'
}
],
mixed_phone
:
[
{
value
:
'phone_rule_1'
,
label
:
'混合电话查询'
}
],
name
:
[
{
value
:
'name_rule_1'
,
label
:
'姓名字段查询'
}
],
bank_card
:
[
{
value
:
'bank_rule_1'
,
label
:
'银行卡号查询'
}
],
ip_address
:
[
{
value
:
'ip_rule_1'
,
label
:
'IP地址查询'
}
]
}
const
searchText
=
ref
(
''
)
const
localSelectedDataArea
=
ref
(
props
.
selectedDataArea
)
const
localSelectedRule
=
ref
(
props
.
selectedRule
)
const
internalRuleList
=
ref
([])
// 合并的规则列表:优先使用父组件传入的 ruleList,如果没有则使用内部生成的规则列表
const
combinedRuleList
=
computed
(()
=>
{
return
props
.
ruleList
.
length
>
0
?
props
.
ruleList
:
internalRuleList
.
value
})
// 过滤后的数据域列表
const
filteredD
omains
=
computed
(()
=>
{
if
(
!
domainSearch
.
value
)
return
domains
.
value
return
domains
.
value
.
filter
(
domain
=>
domain
.
label
.
toLowerCase
().
includes
(
domainSearch
.
value
.
toLowerCase
())
const
filteredD
ataAreaList
=
computed
(()
=>
{
if
(
!
searchText
.
value
)
return
props
.
dataAreaList
return
props
.
dataAreaList
.
filter
(
item
=>
item
.
dataarea
.
dataarea
.
toLowerCase
().
includes
(
searchText
.
value
.
toLowerCase
())
)
})
//
当前选中的数据域对应的规则
const
currentRules
=
computed
((
)
=>
{
return
rulesMapping
[
selectedDomain
.
value
]
||
[]
})
//
选择数据域
const
selectDataArea
=
(
item
)
=>
{
localSelectedDataArea
.
value
=
item
.
dataarea
.
id
localSelectedRule
.
value
=
''
// 打开弹窗时初始化
const
initDialog
=
()
=>
{
if
(
props
.
selectedData
.
domain
)
{
selectedDomain
.
value
=
props
.
selectedData
.
domain
selectedRule
.
value
=
props
.
selectedData
.
rule
||
''
}
else
{
// 默认选择第一个数据域和第一个规则
selectedDomain
.
value
=
domains
.
value
[
0
]?.
value
||
''
if
(
selectedDomain
.
value
&&
currentRules
.
value
.
length
>
0
)
{
selectedRule
.
value
=
currentRules
.
value
[
0
].
value
}
}
// 更新内部规则列表(如果父组件没有传入 ruleList)
internalRuleList
.
value
=
item
.
data
||
[]
emit
(
'update:selectedDataArea'
,
item
.
dataarea
.
id
)
emit
(
'update:selectedRule'
,
''
)
}
// 处理数据域变化
const
handleDomainChange
=
(
domainValue
)
=>
{
if
(
rulesMapping
[
domainValue
]
&&
rulesMapping
[
domainValue
].
length
>
0
)
{
selectedRule
.
value
=
rulesMapping
[
domainValue
][
0
].
value
}
else
{
selectedRule
.
value
=
''
}
// 选择规则
const
selectRule
=
(
rule
)
=>
{
localSelectedRule
.
value
=
rule
.
ruleid
// 存储完整规则对象
emit
(
'update:selectedRule'
,
rule
.
ruleid
)
}
// 重置规则
const
handleReset
=
()
=>
{
selectedDomain
.
value
=
domains
.
value
[
0
]?.
value
||
''
if
(
selectedDomain
.
value
&&
currentRules
.
value
.
length
>
0
)
{
selectedRule
.
value
=
currentRules
.
value
[
0
].
value
}
domainSearch
.
value
=
''
localSelectedDataArea
.
value
=
''
localSelectedRule
.
value
=
''
internalRuleList
.
value
=
[]
emit
(
'update:selectedDataArea'
,
''
)
emit
(
'update:selectedRule'
,
''
)
emit
(
'handleReset'
)
// ElMessage.info('规则已重置')
}
// 确
定
规则
// 确
认
规则
const
handleConfirm
=
()
=>
{
if
(
!
selectedDomain
.
value
)
{
if
(
!
localSelectedDataArea
.
value
)
{
ElMessage
.
warning
(
'请选择数据域'
)
return
}
if
(
!
s
electedRule
.
value
)
{
if
(
!
localS
electedRule
.
value
)
{
ElMessage
.
warning
(
'请选择字段发现规则'
)
return
}
const
selectedDomainObj
=
domains
.
value
.
find
(
d
=>
d
.
value
===
selectedDomain
.
value
)
const
selectedRuleObj
=
currentRules
.
value
.
find
(
r
=>
r
.
value
===
selectedRule
.
value
)
const
selectedDataArea
=
props
.
dataAreaList
.
find
(
item
=>
item
.
dataarea
.
id
===
localSelectedDataArea
.
value
)
// 从合并的规则列表中查找选中的规则
const
selectedRule
=
combinedRuleList
.
value
.
find
(
rule
=>
rule
.
ruleid
===
localSelectedRule
.
value
)
console
.
log
(
'selectedRule'
,
selectedRule
)
emit
(
'confirm'
,
{
domain
:
selectedD
omain
.
value
,
domain
Label
:
selectedDomainObj
?.
label
||
''
,
rule
:
selectedRule
.
valu
e
,
rule
Label
:
selectedRuleObj
?.
label
||
''
domain
:
selectedD
ataArea
.
dataarea
,
domain
Value
:
selectedDataArea
.
dataarea
.
id
,
rule
:
selectedRule
.
nam
e
,
rule
Value
:
selectedRule
.
ruleid
})
dialogVisible
.
value
=
false
...
...
@@ -219,24 +192,37 @@ const handleConfirm = () => {
// 关闭弹窗
const
handleClose
=
()
=>
{
console
.
log
(
'关闭'
)
internalRuleList
.
value
=
[]
dialogVisible
.
value
=
false
emit
(
'closeDialog'
)
}
// 监听弹窗显示状态
watch
(
dialogVisible
,
(
newVal
)
=>
{
if
(
newVal
)
{
initDialog
()
}
// 监听外部传入的选中值变化
watch
(()
=>
props
.
selectedDataArea
,
(
newVal
)
=>
{
localSelectedDataArea
.
value
=
newVal
})
const
openDialog
=
()
=>
{
initDialog
()
dialogVisible
.
value
=
true
}
// 暴露方法
defineExpose
({
openDialog
watch
(()
=>
props
.
selectedRule
,
(
newVal
)
=>
{
localSelectedRule
.
value
=
newVal
})
// 监听数据域列表变化,初始化选中状态
watch
(()
=>
props
.
dataAreaList
,
(
newList
)
=>
{
console
.
log
(
'传入子组件的 左侧数组'
,
newList
)
if
(
newList
.
length
>
0
&&
localSelectedDataArea
.
value
)
{
const
selectedItem
=
newList
.
find
(
item
=>
item
.
dataarea
.
id
===
localSelectedDataArea
.
value
)
if
(
selectedItem
)
{
internalRuleList
.
value
=
selectedItem
.
data
||
[]
}
}
},
{
immediate
:
true
})
// 监听父组件传入的 ruleList 变化
watch
(()
=>
props
.
ruleList
,
(
newRuleList
)
=>
{
console
.
log
(
'父组件传入的 ruleList:'
,
newRuleList
)
},
{
immediate
:
true
})
</
script
>
<
style
scoped
lang=
"scss"
>
...
...
@@ -244,65 +230,103 @@ defineExpose({
.search-section
{
margin-bottom
:
16px
;
.search-input
{
width
:
100%
;
:deep(.el-input__inner)
{
height
:
32px
;
}
}
}
.content-
section
{
.content-
container
{
display
:
flex
;
gap
:
20px
;
height
:
400px
;
border
:
1px
solid
#dcdfe6
;
border-radius
:
4px
;
overflow
:
hidden
;
}
.
domain-list
,
.r
ule-list
{
.
left-panel
,
.r
ight-panel
{
flex
:
1
;
display
:
flex
;
flex-direction
:
column
;
min-width
:
0
;
}
.section-title
{
.panel-header
{
padding
:
12px
16px
;
background
:
#f0f7ff
;
border-bottom
:
1px
solid
#dcdfe6
;
h4
{
margin
:
0
;
font-size
:
14px
;
font-weight
:
600
;
color
:
#303133
;
margin-bottom
:
12px
;
padding-left
:
4px
;
}
}
.list-container
{
flex
:
1
;
border
:
1px
solid
#dcdfe6
;
border-radius
:
4px
;
padding
:
12px
;
overflow-y
:
auto
;
padding
:
8px
;
}
.domain-item
,
.rule-item
{
padding
:
8px
0
;
.list-item
{
padding
:
10px
12px
;
margin-bottom
:
4px
;
border-radius
:
4px
;
cursor
:
pointer
;
transition
:
all
0.2s
ease
;
border
:
1px
solid
transparent
;
:deep(.el-radio)
{
width
:
100%
;
&:hover
{
background-color
:
#f5f7fa
;
border-color
:
#dcdfe6
;
}
.el-radio__label
{
font-size
:
13px
;
&
.item-selected
{
background-color
:
#e6f7ff
;
border-color
:
#1890ff
;
.item-text
{
color
:
#1890ff
;
font-weight
:
500
;
}
}
}
.
domain-item
{
&:hover
{
background-color
:
#f5f7fa
;
border-radius
:
4px
;
.
item-content
{
display
:
flex
;
flex-direction
:
column
;
gap
:
4px
;
}
.item-text
{
font-size
:
13px
;
color
:
#606266
;
font-weight
:
500
;
}
.rule-item
{
&:hover
{
background-color
:
#f5f7fa
;
border-radius
:
4px
;
.item-count
{
font-size
:
12px
;
color
:
#909399
;
}
.item-desc
{
font-size
:
12px
;
color
:
#909399
;
font-style
:
italic
;
}
.empty-tip
{
padding
:
20px
;
text-align
:
center
;
color
:
#909399
;
font-size
:
13px
;
}
.dialog-footer
{
...
...
@@ -314,7 +338,20 @@ defineExpose({
border-top
:
1px
solid
#e0e0e0
;
}
}
:deep
(
.el-radio-group
)
{
display
:
block
;
//
响应式设计
@media
(
max-width
:
768px
)
{
.domain-rule-dialog
{
.content-container
{
flex-direction
:
column
;
height
:
500px
;
}
.left-panel
,
.right-panel
{
flex
:
none
;
height
:
200px
;
}
}
}
</
style
>
\ No newline at end of file
src/views/discover/Discover/modules/MatchPreviewDialog.vue
View file @
2373db28
...
...
@@ -6,47 +6,76 @@
:before-close=
"handleClose"
>
<div
class=
"match-preview-dialog"
>
<div
class=
"
match-content
"
>
<div
class=
"
content-container
"
>
<!-- 左侧:匹配的数据 -->
<div
class=
"match-section"
>
<div
class=
"section-header"
>
<span
class=
"section-title"
>
匹配的数据
</span>
<div
class=
"left-panel"
>
<div
class=
"panel-header"
>
<h4>
匹配的数据
</h4>
<span
class=
"count-badge"
>
{{
matchedData
.
length
}}
</span>
</div>
<div
class=
"table-container"
>
<el-table
:data=
"matchedData"
style=
"width: 100%"
height=
"400"
:header-cell-style=
"
{ background: '#f0f7ff', color: '#606266', fontWeight: 'bold' }"
empty-text=
"暂无匹配数据"
:header-cell-style=
"
{ background: '#f0f7ff', color: '#606266' }"
>
<el-table-column
type=
"index"
label=
"序号"
width=
"60"
align=
"center"
/>
<el-table-column
prop=
"label"
label=
"数据值"
min-width=
"150"
show-overflow-tooltip
>
<el-table-column
prop=
"value"
label=
"匹配的数据"
align=
"center"
>
<template
#
default=
"
{ row }">
<span
class=
"match-value"
>
{{
row
.
value
}}
</span>
<span
class=
"data-value"
>
{{
row
.
label
}}
</span>
</
template
>
</el-table-column>
</el-table>
</div>
</div>
<!-- 分隔线 -->
<div
class=
"divider"
></div>
<!-- 右侧:不匹配的数据 -->
<div
class=
"match-section"
>
<div
class=
"section-header"
>
<span
class=
"section-title"
>
不匹配的数据
</span>
<div
class=
"right-panel"
>
<div
class=
"panel-header"
>
<h4>
不匹配的数据
</h4>
<span
class=
"count-badge"
>
{{ unmatchedData.length }}
</span>
</div>
<div
class=
"table-container"
>
<el-table
:data=
"unmatchedData"
style=
"width: 100%"
height=
"400"
:header-cell-style=
"{ background: '#f0f7ff', color: '#606266', fontWeight: 'bold' }"
empty-text=
"暂无数据"
:header-cell-style=
"{ background: '#f0f7ff', color: '#606266' }"
>
<el-table-column
type=
"index"
label=
"序号"
width=
"60"
align=
"center"
/>
<el-table-column
prop=
"label"
label=
"数据值"
min-width=
"150"
show-overflow-tooltip
>
<el-table-column
prop=
"value"
label=
"不匹配的数据"
align=
"center"
>
<
template
#
default=
"{ row }"
>
<span
class=
"unmatch-value"
>
{{
row
.
value
}}
</span>
<span
class=
"data-value"
>
{{
row
.
label
}}
</span>
</
template
>
</el-table-column>
</el-table>
</div>
</div>
</div>
<!-- 底部按钮 -->
<div
class=
"dialog-footer"
>
...
...
@@ -57,78 +86,117 @@
</template>
<
script
setup
>
import
{
ref
,
computed
}
from
'vue'
import
{
ref
,
watch
}
from
'vue'
import
{
ElMessage
}
from
'element-plus'
const
props
=
defineProps
({
modelValue
:
{
type
:
Boolean
,
default
:
false
},
// 匹配的数据
matchedData
:
{
type
:
Array
,
default
:
()
=>
[]
},
// 不匹配的数据
unmatchedData
:
{
type
:
Array
,
default
:
()
=>
[]
}
})
const
emit
=
defineEmits
([
'update:modelValue'
])
const
emit
=
defineEmits
([
'update:modelValue'
,
'close'
])
const
dialogVisible
=
computed
({
get
:
()
=>
props
.
modelValue
,
set
:
(
value
)
=>
emit
(
'update:modelValue'
,
value
)
})
//
关闭弹窗
//
处理关闭
const
handleClose
=
()
=>
{
dialogVisible
.
value
=
false
emit
(
'close'
)
}
// 暴露方法
defineExpose
({
openDialog
:
()
=>
{
dialogVisible
.
value
=
true
// 监听对话框关闭,清空数据
watch
(
dialogVisible
,
(
newVal
)
=>
{
if
(
!
newVal
)
{
// 对话框关闭时,可以通过父组件清空数据
emit
(
'close'
)
}
})
</
script
>
<
style
scoped
lang=
"scss"
>
.match-preview-dialog
{
.
match-content
{
.
content-container
{
display
:
flex
;
gap
:
20px
;
margin-bottom
:
2
0px
;
gap
:
0
;
height
:
45
0px
;
}
.match-section
{
.left-panel
,
.right-panel
{
flex
:
1
;
background
:
#fafafa
;
border-radius
:
6px
;
overflow
:
hidden
;
display
:
flex
;
flex-direction
:
column
;
min-width
:
0
;
}
.section-header
{
background
:
#f0f7ff
;
.panel-header
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
padding
:
12px
16px
;
background
:
#f0f7ff
;
border-bottom
:
1px
solid
#dcdfe6
;
.section-title
{
h4
{
margin
:
0
;
font-size
:
14px
;
font-weight
:
600
;
color
:
#303133
;
}
.count-badge
{
background
:
#1890ff
;
color
:
white
;
padding
:
2px
8px
;
border-radius
:
10px
;
font-size
:
12px
;
font-weight
:
500
;
}
}
.table-container
{
flex
:
1
;
border
:
1px
solid
#dcdfe6
;
border-top
:
none
;
border-radius
:
0
0
4px
4px
;
overflow
:
hidden
;
}
.divider
{
width
:
1px
;
background
:
#dcdfe6
;
margin
:
0
10px
;
}
.data-value
{
font-family
:
'Monaco'
,
'Consolas'
,
monospace
;
font-size
:
13px
;
color
:
#303133
;
}
:deep
(
.el-table
)
{
border
-radius
:
0
;
border
:
none
;
.el-table__header-wrapper
{
th
{
background
:
#f0f7ff
!important
;
.cell
{
font-weight
:
600
;
}
}
}
...
...
@@ -145,19 +213,10 @@ defineExpose({
}
}
.match-value
{
color
:
#52c41a
;
font-weight
:
500
;
}
.unmatch-value
{
color
:
#ff4d4f
;
font-weight
:
500
;
}
.dialog-footer
{
display
:
flex
;
justify-content
:
center
;
margin-top
:
20px
;
padding-top
:
16px
;
border-top
:
1px
solid
#e0e0e0
;
}
...
...
@@ -166,12 +225,21 @@ defineExpose({
//
响应式设计
@media
(
max-width
:
768px
)
{
.match-preview-dialog
{
.
match-content
{
.
content-container
{
flex-direction
:
column
;
height
:
600px
;
}
.left-panel
,
.right-panel
{
flex
:
none
;
height
:
250px
;
}
.match-section
{
min-height
:
200px
;
.divider
{
width
:
100%
;
height
:
1px
;
margin
:
10px
0
;
}
}
}
...
...
src/views/discover/Discover/modules/SaveVersionDialog.vue
0 → 100644
View file @
2373db28
<
template
>
<el-dialog
v-model=
"dialogVisible"
:title=
"title"
width=
"600px"
:before-close=
"handleClose"
>
<div
class=
"save-version-dialog"
>
<!-- 历史版本表格 -->
<div
class=
"history-section"
>
<h4
class=
"section-title"
>
历史版本
</h4>
<el-table
:data=
"historyList"
height=
"200"
empty-text=
"暂无历史版本"
:header-cell-style=
"
{ background: '#f0f7ff', color: '#606266' }"
>
<el-table-column
prop=
"versionname"
label=
"版本名称"
min-width=
"120"
show-overflow-tooltip
/>
<el-table-column
prop=
"operator"
label=
"操作人"
width=
"100"
align=
"center"
/>
<el-table-column
prop=
"savetime"
label=
"保存时间"
width=
"160"
align=
"center"
/>
</el-table>
</div>
<!-- 保存版本区域 -->
<div
class=
"save-section"
>
<h4
class=
"section-title"
>
保存版本
</h4>
<div
class=
"save-input-container"
>
<el-input
v-model=
"versionName"
placeholder=
"请输入版本名称"
clearable
class=
"version-input"
@
keyup
.
enter=
"handleSave"
/>
<el-button
type=
"primary"
@
click=
"handleSave"
:loading=
"saving"
class=
"save-btn"
>
保存
</el-button>
</div>
</div>
</div>
</el-dialog>
</
template
>
<
script
setup
>
import
{
ref
,
computed
,
watch
}
from
'vue'
import
{
ElMessage
}
from
'element-plus'
const
props
=
defineProps
({
modelValue
:
{
type
:
Boolean
,
default
:
false
},
title
:
{
type
:
String
,
default
:
'保存发现模板'
},
historyList
:
{
type
:
Array
,
default
:
()
=>
[]
},
versionName
:
{
type
:
String
,
default
:
''
}
})
const
emit
=
defineEmits
([
'update:modelValue'
,
'update:versionName'
,
'save'
,
'close'
])
const
dialogVisible
=
computed
({
get
:
()
=>
props
.
modelValue
,
set
:
(
value
)
=>
emit
(
'update:modelValue'
,
value
)
})
const
versionName
=
computed
({
get
:
()
=>
props
.
versionName
,
set
:
(
value
)
=>
emit
(
'update:versionName'
,
value
)
})
const
saving
=
ref
(
false
)
// 处理保存
const
handleSave
=
async
()
=>
{
if
(
!
versionName
.
value
.
trim
())
{
ElMessage
.
warning
(
'请输入版本名称'
)
return
}
saving
.
value
=
true
try
{
emit
(
'save'
,
versionName
.
value
.
trim
())
}
catch
(
error
)
{
console
.
error
(
'Save error:'
,
error
)
}
finally
{
saving
.
value
=
false
}
}
// 关闭弹窗
const
handleClose
=
()
=>
{
dialogVisible
.
value
=
false
emit
(
'close'
)
}
// 监听对话框显示状态,重置状态
watch
(
dialogVisible
,
(
newVal
)
=>
{
if
(
!
newVal
)
{
saving
.
value
=
false
}
})
</
script
>
<
style
scoped
lang=
"scss"
>
.save-version-dialog
{
.section-title
{
margin
:
0
0
12px
0
;
font-size
:
14px
;
font-weight
:
600
;
color
:
#303133
;
}
.history-section
{
margin-bottom
:
20px
;
:deep(.el-table)
{
border
:
1px
solid
#dcdfe6
;
border-radius
:
4px
;
.el-table__header-wrapper
{
th
{
background
:
#f0f7ff
;
font-weight
:
600
;
.cell
{
font-weight
:
600
;
}
}
}
.el-table__body-wrapper
{
.el-table__row
{
&:nth-child(even)
{
background-color
:
#fafafa
;
}
&
:hover
{
background-color
:
#f5f7fa
;
}
}
}
}
}
.save-section
{
.save-input-container
{
display
:
flex
;
gap
:
12px
;
align-items
:
center
;
.version-input
{
flex
:
1
;
:deep(.el-input__inner)
{
height
:
36px
;
}
}
.save-btn
{
height
:
36px
;
min-width
:
80px
;
}
}
}
}
//
响应式设计
@media
(
max-width
:
640px
)
{
.save-version-dialog
{
.save-input-container
{
flex-direction
:
column
;
align-items
:
stretch
;
.save-btn
{
width
:
100%
;
}
}
}
}
</
style
>
\ No newline at end of file
src/views/project/Project/list.vue
View file @
2373db28
...
...
@@ -150,28 +150,25 @@ const addLoading = ref(false)
const
showAddDialog
=
()
=>
{
addLoading
.
value
=
true
checkProjectNum
().
then
(
res
=>
{
console
.
log
(
'checkProjectNum'
,
res
)
if
(
res
.
flag
){
currentProject
.
value
=
null
dialogVisible
.
value
=
true
// getdatascopeprojectlist().then(res=>{
// addLoading.value = true
// checkProjectNum().then(res=>{
// console.log('checkProjectNum',res)
// if(res.flag){
// currentProject.value = null
// dialogVisible.value = true
// })
addLoading
.
value
=
false
}
else
{
addLoading
.
value
=
false
}
}).
catch
(
err
=>
{
addLoading
.
value
=
false
})
//
// addLoading.value = false
// }else{
// addLoading.value = false
// }
// }).catch(err=>{
// addLoading.value = false
// })
currentProject
.
value
=
null
dialogVisible
.
value
=
true
addLoading
.
value
=
false
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论