Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
csbr-daop
/
fe-data-trusted-space
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
a13d7955
authored
2026-03-05 17:58:36 +0800
by
lihua
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
代码评审内容修改
1 parent
663d5f54
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
411 additions
and
250 deletions
components.d.ts
src/api/apiHander.ts
src/api/modules/dataAnonymization.ts
src/components/CommonTable/index.ts
src/components/CommonTable/src/CommonTable.vue
src/router/modules/dataAnonymization.ts
src/types/components.d.ts
src/views/data_anonymization/resultProcess.vue → src/views/data_anonymization/anonResultProcessManage.vue
src/views/data_anonymization/anonResultReportView.vue
src/views/data_anonymization/anonResultView.vue
src/views/data_anonymization/anonTaskCreate.vue
src/views/data_anonymization/components/anonResultAnalysis.vue
components.d.ts
View file @
a13d795
...
...
@@ -13,6 +13,7 @@ declare module '@vue/runtime-core' {
Auth
:
typeof
import
(
'./src/components/Auth/index.vue'
)[
'default'
]
AuthAll
:
typeof
import
(
'./src/components/AuthAll/index.vue'
)[
'default'
]
CarouselPanel
:
typeof
import
(
'./src/components/CarouselPanel/src/CarouselPanel.vue'
)[
'default'
]
CommonTable
:
typeof
import
(
'./src/components/CommonTable/src/CommonTable.vue'
)[
'default'
]
ContentWrap
:
typeof
import
(
'./src/components/ContentWrap/src/ContentWrap.vue'
)[
'default'
]
Copyright
:
typeof
import
(
'./src/components/Copyright/index.vue'
)[
'default'
]
Day
:
typeof
import
(
'./src/components/Schedule/component/day.vue'
)[
'default'
]
...
...
src/api/apiHander.ts
0 → 100644
View file @
a13d795
/**
* API响应处理工具函数
* 统一处理API请求的成功/失败逻辑
*/
interface
ApiResponse
{
code
:
number
;
data
?:
any
;
msg
?:
string
;
}
export
interface
ApiHandlerOptions
{
/* 当前实例的proxy对象(用于获取$passCode和$ElMessage)*/
proxy
:
any
/** 加载状态ref */
loadingRef
?:
Ref
<
boolean
>
;
/** 成功回调函数 */
onSuccess
?:
(
res
:
any
)
=>
void
;
/** 失败回调函数 */
onError
?:
(
res
:
any
)
=>
void
;
/** 是否显示错误消息,默认true */
showError
?:
boolean
;
}
/**
* 统一处理API响应的工具函数
* @param apiPromise API请求Promise
* @param options 配置选项
*/
export
const
handleApiResponse
=
async
(
apiPromise
:
Promise
<
ApiResponse
>
,
options
:
ApiHandlerOptions
,
)
=>
{
const
{
loadingRef
,
onSuccess
,
onError
,
showError
=
true
,
proxy
}
=
options
;
try
{
// 设置加载状态
if
(
loadingRef
)
{
loadingRef
.
value
=
true
;
}
// 执行API请求
const
res
=
await
apiPromise
;
// 设置加载状态
if
(
loadingRef
)
{
loadingRef
.
value
=
false
;
}
// 判断请求是否成功
if
(
res
?.
code
==
proxy
.
$passCode
)
{
// 成功回调
onSuccess
&&
onSuccess
(
res
);
}
else
{
// 失败处理
const
errorMsg
=
res
?.
msg
||
''
;
if
(
showError
)
{
proxy
.
$ElMessage
.
error
(
errorMsg
);
}
onError
&&
onError
(
res
);
}
}
catch
(
error
:
any
)
{
// 异常处理
if
(
loadingRef
)
{
loadingRef
.
value
=
false
;
}
}
};
src/api/modules/dataAnonymization.ts
View file @
a13d795
...
...
@@ -2,6 +2,7 @@
* 匿名化管理的接口api文件
*/
import
request
from
"@/utils/request"
;
import
{
handleApiResponse
,
ApiHandlerOptions
}
from
'../apiHander'
;
// 导入公共处理方法
/** 获取标签列表。 */
export
const
getDataLabelList
=
(
params
)
=>
request
({
...
...
@@ -246,6 +247,12 @@ export const updateAnonTask = (params) => request({
})
/** 获取匿名化任务详情 */
// export const getAnonTaskDetail = (guid, defaultOptions: ApiHandlerOptions) => handleApiResponse(request({
// url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/detail?guid=${guid}`,
// method: 'get'
// }), defaultOptions)
/** 获取匿名化任务详情 */
export
const
getAnonTaskDetail
=
(
guid
)
=>
request
({
url
:
`
${
import
.
meta
.
env
.
VITE_APP_DIGITAL_CONTRACT_URL
}
/anon-task/detail?guid=
${
guid
}
`
,
method
:
'get'
...
...
@@ -265,12 +272,18 @@ export const anonTaskCheck = (params) => request({
})
/** 获取匿名化任务分析结果数据 */
export
const
getAnonAnalyzeResult
=
(
execGuid
)
=>
request
({
export
const
getAnonAnalyzeResult
1
=
(
execGuid
)
=>
request
({
url
:
`
${
import
.
meta
.
env
.
VITE_APP_DIGITAL_CONTRACT_URL
}
/anon-task/get-anon-analyze?taskExecGuid=
${
execGuid
}
`
,
method
:
'get'
})
/** 获取匿名化任务分析结果数据 */
export
const
getAnonAnalyzeResult
=
(
execGuid
,
defaultOptions
:
ApiHandlerOptions
)
=>
handleApiResponse
(
request
({
url
:
`
${
import
.
meta
.
env
.
VITE_APP_DIGITAL_CONTRACT_URL
}
/anon-task/get-anon-analyze?taskExecGuid=
${
execGuid
}
`
,
method
:
'get'
}),
defaultOptions
)
/** 获取匿名化任务分析结果数据 */
export
const
getLastAnonAnalyzeResult
=
(
execGuid
)
=>
request
({
url
:
`
${
import
.
meta
.
env
.
VITE_APP_DIGITAL_CONTRACT_URL
}
/anon-task/get-anon-analyze?isResult=true&taskExecGuid=
${
execGuid
}
`
,
method
:
'get'
...
...
src/components/CommonTable/index.ts
0 → 100644
View file @
a13d795
import
CommonTable
from
'./src/CommonTable.vue'
export
{
CommonTable
}
export
default
CommonTable
\ No newline at end of file
src/components/CommonTable/src/CommonTable.vue
0 → 100644
View file @
a13d795
<
script
lang=
"ts"
setup
name=
"CommonTable"
>
import
{
ref
,
watch
,
computed
}
from
"vue"
;
import
{
TableColumnWidth
}
from
"@/utils/enum"
;
import
{
calcColumnWidth
}
from
"@/utils/index"
;
import
Moment
from
'moment'
;
const
props
=
defineProps
({
data
:
{
type
:
Array
,
default
:
()
=>
[]
},
fields
:
{
type
:
Array
,
default
:
()
=>
[]
},
loading
:
{
type
:
Boolean
,
default
:
false
},
height
:
{
type
:
String
,
default
:
'100%'
},
showIndex
:
{
type
:
Boolean
,
default
:
false
},
rowKey
:
{
type
:
String
,
default
:
'guid'
},
style
:
{
type
:
Object
,
default
:
()
=>
({})
}
});
const
originTableFieldColumn
=
ref
({});
const
getTextAlign
=
(
field
)
=>
{
if
(
field
.
dataType
===
'decimal'
||
field
.
dataType
===
'int'
||
field
.
dataType
==
'bit'
||
field
.
dataType
==
'tinyint'
)
{
return
'right'
;
}
return
'left'
};
const
formatterPreviewDate
=
(
row
,
info
)
=>
{
let
enName
=
info
.
enName
;
let
v
=
row
[
enName
];
if
(
v
===
0
)
{
return
v
;
}
if
(
!
v
||
v
==
'null'
)
{
return
'--'
;
}
if
(
info
.
dataType
===
'datetime'
)
{
return
Moment
(
v
).
format
(
'YYYY-MM-DD HH:mm:ss'
);
}
if
(
info
.
dataType
===
'date'
)
{
if
(
isNaN
(
<
any
>
(
new
Date
(
v
))))
{
return
Moment
(
parseInt
(
v
)).
format
(
'YYYY-MM-DD'
);
}
else
{
return
Moment
(
v
).
format
(
'YYYY-MM-DD'
);
}
}
return
v
;
};
const
calcTableColumnWidth
=
(
data
:
any
[],
prop
,
title
,
otherWidth
=
0
)
=>
{
let
d
:
any
[]
=
[];
data
.
forEach
((
dt
)
=>
d
.
push
(
dt
[
prop
]));
return
calcColumnWidth
(
d
,
title
,
{
fontSize
:
14
,
fontFamily
:
"SimSun"
,
},
{
fontSize
:
14
,
fontFamily
:
"SimSun"
,
},
otherWidth
);
};
watch
(
()
=>
props
.
data
,
(
val
:
any
[],
oldVal
)
=>
{
if
(
!
props
.
fields
?.
length
)
{
originTableFieldColumn
.
value
=
{};
return
;
}
originTableFieldColumn
.
value
=
{};
props
.
fields
.
forEach
((
field
,
index
)
=>
{
originTableFieldColumn
.
value
[
field
.
enName
]
=
calcTableColumnWidth
(
val
?.
slice
(
0
,
20
)
||
[],
field
.
enName
,
field
.
chName
,
24
);
});
},
{
deep
:
true
,
}
);
</
script
>
<
template
>
<div
class=
"common-table"
v-loading=
"loading"
>
<el-table
:data=
"data"
:highlight-current-row=
"true"
stripe
border
tooltip-effect=
"light"
:height=
"height"
:row-key=
"rowKey"
:style=
"style"
>
<el-table-column
v-if=
"showIndex"
label=
"序号"
type=
"index"
width=
"56px"
align=
"center"
show-overflow-tooltip
></el-table-column>
<template
v-for=
"(item, index) in (fields || [])"
:key=
"index"
>
<el-table-column
:label=
"item.chName"
:width=
"item.dataType === 'datetime'
? TableColumnWidth.DATETIME
: item.dataType === 'date'
? TableColumnWidth.DATE
: originTableFieldColumn[item.enName]
"
:align=
"getTextAlign(item)"
:header-align=
"getTextAlign(item)"
:formatter=
"(row) => formatterPreviewDate(row, item)"
:show-overflow-tooltip=
"true"
>
</el-table-column>
</
template
>
</el-table>
<div
v-show=
"!fields.length"
class=
"empty-content"
>
<img
src=
"@/assets/images/empty-data.png"
:style=
"{ width: '168px', height: '96px' }"
/>
<div
class=
"empty-text"
>
暂无数据
</div>
</div>
</div>
</template>
<
style
lang=
"scss"
scoped
>
.common-table
{
width
:
100%
;
height
:
100%
;
.el-table
{
display
:
inline-block
;
}
.empty-content
{
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
height
:
100%
;
width
:
100%
;
flex-direction
:
column
;
.empty-text
{
font-size
:
14px
;
color
:
#b2b2b2
;
}
}
}
</
style
>
\ No newline at end of file
src/router/modules/dataAnonymization.ts
View file @
a13d795
...
...
@@ -133,8 +133,8 @@ const routes: RouteRecordRaw[] = [
children
:
[
{
path
:
''
,
name
:
'
resultProcess
'
,
component
:
()
=>
import
(
'@/views/data_anonymization/
resultProcess
.vue'
),
name
:
'
anonResultProcessManage
'
,
component
:
()
=>
import
(
'@/views/data_anonymization/
anonResultProcessManage
.vue'
),
meta
:
{
title
:
'匿名化处理'
,
sidebar
:
false
,
...
...
src/types/components.d.ts
View file @
a13d795
...
...
@@ -13,6 +13,7 @@ declare module '@vue/runtime-core' {
Auth
:
typeof
import
(
'./../components/Auth/index.vue'
)[
'default'
]
AuthAll
:
typeof
import
(
'./../components/AuthAll/index.vue'
)[
'default'
]
CarouselPanel
:
typeof
import
(
'./../components/CarouselPanel/src/CarouselPanel.vue'
)[
'default'
]
CommonTable
:
typeof
import
(
'./../components/CommonTable/src/CommonTable.vue'
)[
'default'
]
ContentWrap
:
typeof
import
(
'./../components/ContentWrap/src/ContentWrap.vue'
)[
'default'
]
Copyright
:
typeof
import
(
'./../components/Copyright/index.vue'
)[
'default'
]
Day
:
typeof
import
(
'./../components/Schedule/component/day.vue'
)[
'default'
]
...
...
src/views/data_anonymization/
resultProcess
.vue
→
src/views/data_anonymization/
anonResultProcessManage
.vue
View file @
a13d795
<route
lang=
"yaml"
>
name:
resultProcess
name:
anonResultProcessManage
</route>
<
script
lang=
"ts"
setup
name=
"
resultProcess
"
>
<
script
lang=
"ts"
setup
name=
"
anonResultProcessManage
"
>
import
TableTools
from
"@/components/Tools/table_tools.vue"
;
import
{
commonPageConfig
}
from
'@/components/PageNav/index'
;
import
{
TableColumnWidth
}
from
"@/utils/enum"
;
...
...
@@ -11,14 +11,13 @@ import {
getAnonTaskList
,
deleteAnonTask
,
}
from
'@/api/modules/dataAnonymization'
;
import
{
useValidator
}
from
'@/hooks/useValidator'
;
import
useDataAnonymizationStore
from
"@/store/modules/dataAnonymization"
;
const
anonymizationStore
=
useDataAnonymizationStore
();
const
router
=
useRouter
()
const
{
proxy
}
=
getCurrentInstance
()
as
any
;
const
{
required
}
=
useValidator
();
/** -------------- 搜索栏输入框配置 ------------------------ */
const
searchItemList
=
ref
([{
type
:
"input"
,
label
:
""
,
...
...
@@ -44,6 +43,7 @@ const page = ref({
dataSource
:
null
});
/** ----------------- 表格展示配置信息,及查询数据处理 ----------------- */
const
tableInfo
=
ref
({
id
:
'data-file-table'
,
fields
:
[
...
...
@@ -72,64 +72,18 @@ const tableInfo = ref({
width
:
230
,
fixed
:
'right'
,
btns
:
(
scope
)
=>
{
return
[{
label
:
"编辑"
,
value
:
"edit"
,
disabled
:
scope
.
row
.
isConfirm
==
'Y'
||
scope
.
row
.
dataSource
==
4
,
click
:
(
scope
)
=>
{
router
.
push
({
name
:
'anonTaskCreate'
,
query
:
{
guid
:
scope
.
row
.
guid
,
taskName
:
scope
.
row
.
taskName
}
});
}
},
{
label
:
'查看报告'
,
value
:
'report'
,
disabled
:
scope
.
row
.
status
!=
'Y'
,
click
:
(
scope
)
=>
{
router
.
push
({
name
:
'anonResultReportView'
,
query
:
{
guid
:
scope
.
row
.
guid
,
execGuid
:
scope
.
row
.
lastExecGuid
,
taskName
:
scope
.
row
.
taskName
}
});
}
return
[{
label
:
"编辑"
,
value
:
"edit"
,
disabled
:
scope
.
row
.
isConfirm
==
'Y'
||
scope
.
row
.
dataSource
==
4
,
click
:
tableBtnHandles
[
'edit'
]
},
{
label
:
'查看报告'
,
value
:
'report'
,
disabled
:
scope
.
row
.
status
!=
'Y'
,
click
:
tableBtnHandles
[
'report'
]
},
{
label
:
'查看数据'
,
value
:
'view'
,
disabled
:
scope
.
row
.
status
!=
'Y'
||
scope
.
row
.
handleType
==
'02'
,
click
:
(
scope
)
=>
{
router
.
push
({
name
:
'anonResultView'
,
query
:
{
guid
:
scope
.
row
.
guid
,
execGuid
:
scope
.
row
.
lastExecGuid
,
taskName
:
scope
.
row
.
taskName
}
});
}
label
:
'查看数据'
,
value
:
'view'
,
disabled
:
scope
.
row
.
status
!=
'Y'
||
scope
.
row
.
handleType
==
'02'
,
click
:
tableBtnHandles
[
'view'
]
},
{
label
:
"删除"
,
value
:
"delete"
,
disabled
:
scope
.
row
.
isConfirm
==
'Y'
,
click
:
(
scope
)
=>
{
proxy
.
$openMessageBox
(
"此操作将永久删除, 是否继续?"
,
()
=>
{
let
guids
=
[
scope
.
row
.
guid
];
deleteAnonTask
(
guids
).
then
((
res
:
any
)
=>
{
if
(
res
?.
code
==
proxy
.
$passCode
)
{
page
.
value
.
curr
=
1
;
getTableData
();
proxy
.
$ElMessage
({
type
:
"success"
,
message
:
"删除成功"
,
});
}
else
{
proxy
.
$ElMessage
({
type
:
"error"
,
message
:
res
.
msg
,
});
}
});
})
}
label
:
"删除"
,
value
:
"delete"
,
click
:
tableBtnHandles
[
'delete'
]
}]
}
}
})
/** 搜索栏触发搜索 */
const
toSearch
=
(
val
:
any
,
clear
:
boolean
=
false
)
=>
{
if
(
clear
)
{
searchItemList
.
value
.
map
((
item
)
=>
(
item
.
default
=
""
));
...
...
@@ -175,6 +129,58 @@ const tablePageChange = (info) => {
getTableData
();
};
const
tableBtnHandles
=
{
edit
:
(
scope
)
=>
{
router
.
push
({
name
:
'anonTaskCreate'
,
query
:
{
guid
:
scope
.
row
.
guid
,
taskName
:
scope
.
row
.
taskName
}
});
},
report
:
(
scope
)
=>
{
router
.
push
({
name
:
'anonResultReportView'
,
query
:
{
guid
:
scope
.
row
.
guid
,
execGuid
:
scope
.
row
.
lastExecGuid
,
taskName
:
scope
.
row
.
taskName
}
});
},
view
:
(
scope
)
=>
{
router
.
push
({
name
:
'anonResultView'
,
query
:
{
guid
:
scope
.
row
.
guid
,
execGuid
:
scope
.
row
.
lastExecGuid
,
taskName
:
scope
.
row
.
taskName
}
});
},
delete
:
(
scope
)
=>
{
proxy
.
$openMessageBox
(
"此操作将永久删除, 是否继续?"
,
()
=>
{
let
guids
=
[
scope
.
row
.
guid
];
deleteAnonTask
(
guids
).
then
((
res
:
any
)
=>
{
if
(
res
?.
code
==
proxy
.
$passCode
)
{
page
.
value
.
curr
=
1
;
getTableData
();
proxy
.
$ElMessage
({
type
:
"success"
,
message
:
"删除成功"
,
});
}
else
{
proxy
.
$ElMessage
({
type
:
"error"
,
message
:
res
.
msg
,
});
}
});
})
}
}
const
handleCreate
=
()
=>
{
router
.
push
({
name
:
'anonTaskCreate'
...
...
src/views/data_anonymization/anonResultReportView.vue
View file @
a13d795
...
...
@@ -228,17 +228,16 @@ onMounted(() => {
onBeforeMount
(()
=>
{
resultDataLoading
.
value
=
true
;
getAnonAnalyzeResult
(
taskExecGuid
.
value
).
then
((
res
:
any
)
=>
{
resultDataLoading
.
value
=
false
;
if
(
res
?.
code
==
proxy
.
$passCode
)
{
analysisResultInfo
.
value
=
res
.
data
||
{};
getAnonAnalyzeResult
(
taskExecGuid
.
value
,
{
proxy
:
proxy
,
loadingRef
:
resultDataLoading
,
onSuccess
:
(
res
:
any
)
=>
{
analysisResultInfo
.
value
=
res
?.
data
||
{};
analysisResultTableFields
.
value
=
res
.
data
?.
column
||
[];
pageInfo
.
value
.
curr
=
1
;
getAnalysisResultPageData
(
true
);
}
else
{
res
?.
msg
&&
proxy
.
$ElMessage
.
error
(
res
.
msg
);
}
})
;
})
getAnonTaskDetail
(
taskGuid
.
value
).
then
((
res
:
any
)
=>
{
if
(
res
?.
code
==
proxy
.
$passCode
)
{
oldAnonTaskValueInfo
.
value
=
res
.
data
||
{};
...
...
src/views/data_anonymization/anonResultView.vue
View file @
a13d795
...
...
@@ -9,9 +9,6 @@ import {
getLastAnonAnalyzeResult
,
exportAnonExecData
,
}
from
"@/api/modules/dataAnonymization"
;
import
{
calcColumnWidth
}
from
"@/utils/index"
;
import
Moment
from
'moment'
;
import
{
TableColumnWidth
}
from
"@/utils/enum"
;
import
{
ElMessage
}
from
"element-plus"
;
import
{
commonPageConfig
}
from
'@/components/PageNav/index'
;
import
{
download
}
from
"@/utils/common"
;
...
...
@@ -69,56 +66,7 @@ const getData = () => {
});
}
const
getTextAlign
=
(
field
)
=>
{
if
(
field
.
dataType
===
'decimal'
||
field
.
dataType
===
'int'
||
field
.
dataType
==
'bit'
||
field
.
dataType
==
'tinyint'
)
{
return
'right'
;
}
return
'left'
}
/** otherWidth表示使用标题宽度时添加标题排序图标等宽度 */
const
calcTableColumnWidth
=
(
data
:
any
[],
prop
,
title
,
otherWidth
=
0
)
=>
{
let
d
:
any
[]
=
[];
data
.
forEach
((
dt
)
=>
d
.
push
(
dt
[
prop
]));
return
calcColumnWidth
(
d
,
title
,
{
fontSize
:
14
,
fontFamily
:
"SimSun"
,
},
{
fontSize
:
14
,
fontFamily
:
"SimSun"
,
},
otherWidth
);
};
/** 每列字段对应的列宽计算结果。 */
const
originTableFieldColumn
=
ref
({});
watch
(
tableData
,
(
val
:
any
[],
oldVal
)
=>
{
if
(
!
tableFields
.
value
?.
length
)
{
originTableFieldColumn
.
value
=
{};
return
;
}
originTableFieldColumn
.
value
=
{};
tableFields
.
value
.
forEach
((
field
,
index
)
=>
{
originTableFieldColumn
.
value
[
field
.
enName
]
=
calcTableColumnWidth
(
val
?.
slice
(
0
,
20
)
||
[],
field
.
enName
,
field
.
chName
,
24
);
});
},
{
deep
:
true
,
}
);
watch
(()
=>
props
.
execGuid
,
(
val
)
=>
{
if
(
!
val
)
{
...
...
@@ -157,27 +105,7 @@ onBeforeMount(() => {
});
});
const
formatterPreviewDate
=
(
row
,
info
)
=>
{
let
enName
=
info
.
enName
;
let
v
=
row
[
enName
];
if
(
v
===
0
)
{
return
v
;
}
if
(
!
v
||
v
==
'null'
)
{
return
'--'
;
}
if
(
info
.
dataType
===
'datetime'
)
{
return
Moment
(
v
).
format
(
'YYYY-MM-DD HH:mm:ss'
);
}
if
(
info
.
dataType
===
'date'
)
{
if
(
isNaN
(
<
any
>
(
new
Date
(
v
))))
{
return
Moment
(
parseInt
(
v
)).
format
(
'YYYY-MM-DD'
);
}
else
{
return
Moment
(
v
).
format
(
'YYYY-MM-DD'
);
}
}
return
v
;
};
const
pageChange
=
(
info
)
=>
{
pageInfo
.
value
.
curr
=
Number
(
info
.
curr
);
...
...
@@ -212,19 +140,14 @@ const exportData = () => {
<div
class=
"table_tool_wrap"
v-loading=
"tableDataLoading"
>
<el-button
v-show=
"props.isPage"
style=
"margin-bottom: 8px;"
type=
"primary"
@
click=
"exportData"
v-preReClick
>
导出数据
</el-button>
<el-table
ref=
"tableRef"
v-show=
"tableFields.length"
:data=
"tableData"
:highlight-current-row=
"true"
stripe
border
tooltip-effect=
"light"
height=
"100%"
row-key=
"guid"
:style=
"
{ width: '100%', height: !props.isPage ? 'calc(100% - 34px)' : 'calc(100% - 64px)' }">
<template
v-for=
"(item, index) in (tableFields || [])"
>
<el-table-column
:label=
"item.chName"
:width=
"item.dataType === 'datetime'
? TableColumnWidth.DATETIME
: item.dataType === 'date'
? TableColumnWidth.DATE
: originTableFieldColumn[item.enName]
"
:align=
"getTextAlign(item)"
:header-align=
"getTextAlign(item)"
:formatter=
"(row) => formatterPreviewDate(row, item)"
:show-overflow-tooltip=
"true"
>
</el-table-column>
</
template
>
</el-table>
<CommonTable
v-show=
"tableFields.length"
:data=
"tableData"
:fields=
"tableFields"
:loading=
"tableDataLoading"
:height=
"'100%'"
:style=
"
{ width: '100%', height: !props.isPage ? 'calc(100% - 34px)' : 'calc(100% - 64px)' }"
/>
<div
v-show=
"!tableFields.length"
class=
"empty-content"
>
<img
src=
"../../assets/images/empty-data.png"
:style=
"
{ width: '168px', height: '96px' }" />
<div
class=
"empty-text"
>
暂无数据
</div>
...
...
src/views/data_anonymization/anonTaskCreate.vue
View file @
a13d795
...
...
@@ -5,7 +5,7 @@
<
template
>
<div
class=
"container_wrap full"
v-loading=
"fullscreenLoading"
ref=
"containerRef"
>
<div
class=
"content_main"
>
<!-- 顶部步骤条 -->
<!-- 顶部步骤条
, 需根据不同的条件显示不同的步骤
-->
<div
class=
"top_tool_wrap"
>
<StepBar
:steps-info=
"stepsInfo"
:style=
"
{ width: stepsInfo.list.length == 2 ? '30%' : '60%' }" />
</div>
...
...
@@ -17,6 +17,7 @@
formId=
"model-select-edit"
col=
"col3 custom-form"
@
select-change=
"handleDataSelectFormSelectChange"
@
uploadFileChange=
"uploadFileChange"
@
checkboxChange=
"handleDataSelectFormCheckboxChange"
/>
</ContentWrap>
<!-- 抽样预览的表单填写配置,及表格展示 -->
<ContentWrap
v-show=
"formRef?.formInline?.dataSource != 3"
id=
"id-previewData"
title=
"数据抽样预览"
description=
""
style=
"margin-top: 16px;"
>
<!-- 选择抽样预览的表单设置 -->
...
...
@@ -26,33 +27,29 @@
<!-- 抽样预览的数据表格设置 -->
<div
class=
"table-v2-main"
v-show=
"dataSimpleFormRef?.formInline?.enableSamplingRate == 'Y'"
v-loading=
"sampleTableDataLoading"
>
<el-table
ref=
"tableRef"
v-show=
"sampleTableFields.length"
:data=
"sampleTableData"
:highlight-current-row=
"true"
stripe
border
tooltip-effect=
"light"
height=
"100%"
row-key=
"guid"
:style=
"
{ width: '100%', height: '240px' }">
<el-table-column
label=
"序号"
type=
"index"
width=
"56px"
align=
"center"
show-overflow-tooltip
></el-table-column>
<template
v-for=
"(item, index) in (sampleTableFields || [])"
>
<el-table-column
:label=
"item.chName"
:width=
"item.dataType === 'datetime'
? TableColumnWidth.DATETIME
: item.dataType === 'date'
? TableColumnWidth.DATE
: originTableFieldColumn[item.enName]
"
:align=
"getTextAlign(item)"
:header-align=
"getTextAlign(item)"
:formatter=
"(row) => formatterPreviewDate(row, item)"
:show-overflow-tooltip=
"true"
>
</el-table-column>
</
template
>
</el-table>
<CommonTable
v-show=
"sampleTableFields.length"
:data=
"sampleTableData"
:fields=
"sampleTableFields"
:loading=
"sampleTableDataLoading"
:height=
"'100%'"
:show-index=
"true"
:style=
"
{ width: '100%', height: '240px' }"
/>
<!-- 无抽样数据时显示占位图片信息 -->
<div
v-show=
"!sampleTableFields.length"
class=
"main-placeholder"
>
<img
src=
"../../assets/images/no-data.png"
:style=
"
{ width: '96px', height: '96px' }" />
<div
class=
"empty-text"
>
暂无抽样数据
</div>
</div>
</div>
</ContentWrap>
<!-- 数据来源为文件夹时显示提取文件进度及结果分析 -->
<ContentWrap
v-show=
"formRef?.formInline?.dataSource == 3"
id=
"id-folder"
title=
"提取文件"
description=
""
style=
"margin-top: 16px;"
>
<div
class=
"folder-main"
>
<el-button
v-show=
"!clickSelectNode.path && !Object.keys(dicomStatisticsData)?.length"
:icon=
"Upload"
class=
"mr8"
@
click=
uploadFolder
>
上传文件
</el-button>
<!-- 弹框展示服务器文件夹目录,并选择 -->
<Dialog
ref=
"dialogRef"
:dialog-info=
"uploadFileDialogInfo"
@
btnClick=
"dialogBtnClick"
>
<template
#
extra-content
>
<div
class=
"folder-main-content"
v-loading=
"uploadFileDialogInfo.contentLoading"
>
...
...
@@ -128,6 +125,7 @@
</div>
</div>
</div>
<!-- 解析成功之后需要显示预览文件,和删除重新上传文件按钮 -->
<div
v-show=
"clickSelectNode.path && folderFileTableInfo.data?.length"
class=
"preview-title"
>
预览文件仅展示5条数据
</div>
<Table
v-show=
"clickSelectNode.path && folderFileTableInfo.data?.length"
:tableInfo=
"folderFileTableInfo"
>
...
...
@@ -150,6 +148,7 @@
<div
class=
"desc"
>
正在进行匿名化处理,请稍候...
</div>
<el-button
:icon=
"RefreshRight"
link
@
click=
"refreshQueryData"
v-preReClick
>
刷新查看结果
</el-button>
</div>
<!-- 展示执行失败页面 -->
<div
class=
"wait-result-div"
v-show=
"isExecEnd && analysisResultInfo.status == 'E'"
>
<el-icon
class=
"failed"
>
<CircleCloseFilled
/>
...
...
@@ -158,6 +157,7 @@
<div
v-show=
"analysisResultInfo.errorMsg"
class=
"error-desc"
>
{{ '【' + analysisResultInfo.errorMsg + '】' }}
</div>
</div>
<!-- 执行成功的报告结果查看页面 -->
<anonResultAnalysis
v-show=
"isExecEnd && analysisResultInfo.status == 'Y'"
ref=
"resultReportRef"
v-loading=
"downloadLoading"
:analysis-result-info=
"analysisResultInfo"
:is-word-style=
"isWordStyle"
:element-loading-text=
"loadingText"
:analysis-result-loading=
"analysisResultLoading"
...
...
@@ -190,25 +190,26 @@
<div
class=
"bottom_tool_wrap"
>
<
template
v-if=
"step == 0"
>
<el-button
@
click=
"cancelTask"
>
取消
</el-button>
<!-- 匿名化评测情况下只有2个步骤条,根据传参选择对应的处理函数 -->
<el-button
type=
"primary"
:disabled=
"formRef?.formInline?.handleType == '02' && formRef?.formInline?.dataSource == 3 && dicomStatisticsData?.state != 'Y'"
@
click=
"changeStep
(formRef?.formInline?.handleType == '02' ? 3 : 2
)"
>
下一步
</el-button>
@
click=
"changeStep
Handlers[formRef?.formInline?.handleType == '02' ? 3 : 2](
)"
>
下一步
</el-button>
</
template
>
<
template
v-else-if=
"step == 1"
>
<el-button
@
click=
"changeStep(1)"
>
上一步
</el-button>
<el-button
type=
"primary"
@
click=
"changeStep
(3
)"
>
下一步
</el-button>
<el-button
@
click=
"changeStep
Handlers['lastStep']
(1)"
>
上一步
</el-button>
<el-button
type=
"primary"
@
click=
"changeStep
Handlers['3'](
)"
>
下一步
</el-button>
</
template
>
<
template
v-else-if=
"step == 2"
>
<el-button
@
click=
"changeStep(formRef?.formInline?.handleType == '02' ? 1 : 2)"
>
上一步
</el-button>
<el-button
@
click=
"changeStep
Handlers.lastStep
(formRef?.formInline?.handleType == '02' ? 1 : 2)"
>
上一步
</el-button>
<el-button
v-show=
"formRef?.formInline?.handleType != '02'"
type=
"primary"
:disabled=
"analysisResultInfo.status == 'R' || (isExecEnd && analysisResultInfo.status == 'E')"
@
click=
"changeStep
(4
)"
>
下一步
</el-button>
@
click=
"changeStep
Handlers['4'](
)"
>
下一步
</el-button>
<el-button
type=
"primary"
v-show=
"formRef?.formInline?.handleType == '02'"
:disabled=
"analysisResultInfo.status == 'R' || (isExecEnd && analysisResultInfo.status == 'E')"
v-preReClick
@
click=
"closeTask"
>
关闭
</el-button>
</
template
>
<
template
v-else
>
<el-button
@
click=
"changeStep(3)"
>
上一步
</el-button>
<el-button
@
click=
"changeStep
Handlers.lastStep
(3)"
>
上一步
</el-button>
<el-button
type=
"primary"
v-preReClick
@
click=
"exportResult"
>
导出
</el-button>
</
template
>
</div>
...
...
@@ -221,7 +222,7 @@ import {
getAnonTaskDetail
,
getParamsList
,
chTransformEn
,
getAnonAnalyzeResult
,
getAnonAnalyzeResult
1
,
getAnonAnalyzePageData
,
getDatabase
,
getDsTableByDs
,
...
...
@@ -247,8 +248,6 @@ import {
import
useUserStore
from
"@/store/modules/user"
;
import
{
useValidator
}
from
'@/hooks/useValidator'
;
import
{
TableColumnWidth
}
from
'@/utils/enum'
;
import
{
calcColumnWidth
}
from
"@/utils/index"
;
import
Moment
from
'moment'
;
import
anonTaskStepTwo
from
'./anonTaskStepTwo.vue'
;
import
*
as
XLSX
from
'xlsx'
;
import
{
ElMessage
}
from
'element-plus'
;
...
...
@@ -261,6 +260,7 @@ import { commonPageConfig } from '@/components/PageNav';
import
{
Upload
}
from
"@element-plus/icons-vue"
;
import
anonResultAnalysis
from
'./components/anonResultAnalysis.vue'
;
import
html2canvas
from
'html2canvas'
;
import
{
calcColumnWidth
}
from
'@/utils'
;
const
anonymizationStore
=
useDataAnonymizationStore
();
const
{
proxy
}
=
getCurrentInstance
()
as
any
;
...
...
@@ -580,11 +580,12 @@ const dataSelectInfoFormRules = ref({
}]
});
/** 最新选中的 */
/** 最新选中的
数据源
*/
const
currDatasourceSelect
:
any
=
ref
({});
const
handleDataSelectFormSelectChange
=
async
(
val
,
row
,
formInfo
)
=>
{
if
(
row
.
field
==
'dataSource'
)
{
/** 数据基本信息选择表单下拉变化对应的处理函数 */
const
dataSelectFormSelectChangeHandlers
=
{
dataSource
:
(
val
,
row
,
formInfo
)
=>
{
dataSelectInfoItems
.
value
[
5
].
visible
=
val
==
1
;
dataSelectInfoItems
.
value
[
6
].
visible
=
val
==
1
;
dataSelectInfoItems
.
value
[
8
].
visible
=
val
==
2
;
...
...
@@ -592,7 +593,8 @@ const handleDataSelectFormSelectChange = async (val, row, formInfo) => {
sampleTableFields
.
value
=
[];
parseFileDataSum
.
value
=
[];
sampleTableData
.
value
=
[];
}
else
if
(
row
.
field
==
'dataSourceGuid'
)
{
},
dataSourceGuid
:
async
(
val
,
row
,
formInfo
)
=>
{
if
(
!
val
)
{
currDatasourceSelect
.
value
=
[];
sampleTableFields
.
value
=
[];
...
...
@@ -625,7 +627,8 @@ const handleDataSelectFormSelectChange = async (val, row, formInfo) => {
sampleTableFields
.
value
=
[];
parseFileDataSum
.
value
=
[];
sampleTableData
.
value
=
[];
}
else
if
(
row
.
field
==
'tableName'
)
{
},
tableName
:
(
val
,
row
,
formInfo
)
=>
{
if
(
!
val
)
{
sampleTableFields
.
value
=
[];
sampleTableData
.
value
=
[];
...
...
@@ -652,11 +655,16 @@ const handleDataSelectFormSelectChange = async (val, row, formInfo) => {
ElMessage
.
error
(
res
.
msg
);
}
});
}
else
if
(
row
.
field
==
'handleType'
)
{
},
handleType
:
(
val
,
row
,
formInfo
)
=>
{
setDataSelectFormItems
(
formInfo
);
}
}
const
handleDataSelectFormSelectChange
=
async
(
val
,
row
,
formInfo
)
=>
{
dataSelectFormSelectChangeHandlers
[
row
.
field
]?.(
val
,
row
,
formInfo
);
}
const
setDataSelectFormItems
=
(
info
,
isDetail
=
false
)
=>
{
dataSelectInfoItems
.
value
.
forEach
(
item
=>
{
item
.
default
=
info
[
item
.
field
];
...
...
@@ -785,38 +793,6 @@ const calcTableColumnWidth = (data: any[], prop, title, otherWidth = 0) => {
);
};
/** 每列字段对应的列宽计算结果。 */
const
originTableFieldColumn
=
ref
({});
const
getTextAlign
=
(
field
)
=>
{
if
(
field
.
dataType
===
'decimal'
||
field
.
dataType
===
'int'
)
{
return
'right'
;
}
return
'left'
}
watch
(
sampleTableData
,
(
val
:
any
[],
oldVal
)
=>
{
if
(
!
sampleTableFields
.
value
?.
length
)
{
originTableFieldColumn
.
value
=
{};
return
;
}
originTableFieldColumn
.
value
=
{};
sampleTableFields
.
value
.
forEach
((
field
,
index
)
=>
{
originTableFieldColumn
.
value
[
field
.
enName
]
=
calcTableColumnWidth
(
val
?.
slice
(
0
,
20
)
||
[],
field
.
enName
,
field
.
chName
,
24
);
});
},
{
deep
:
true
,
}
);
watch
(()
=>
sampleTableFields
.
value
,
(
val
)
=>
{
let
formInfo
=
formRef
.
value
.
formInline
;
if
(
formInfo
.
dataSource
==
3
)
{
...
...
@@ -831,27 +807,7 @@ watch(() => sampleTableFields.value, (val) => {
deep
:
true
})
const
formatterPreviewDate
=
(
row
,
info
)
=>
{
let
enName
=
info
.
enName
;
let
v
=
row
[
enName
];
if
(
v
===
0
)
{
return
v
;
}
if
(
!
v
||
v
==
'null'
)
{
return
'--'
;
}
if
(
info
.
dataType
===
'datetime'
)
{
return
Moment
(
v
).
format
(
'YYYY-MM-DD HH:mm:ss'
);
}
if
(
info
.
dataType
===
'date'
)
{
if
(
isNaN
(
<
any
>
(
new
Date
(
v
))))
{
return
Moment
(
parseInt
(
v
)).
format
(
'YYYY-MM-DD'
);
}
else
{
return
Moment
(
v
).
format
(
'YYYY-MM-DD'
);
}
}
return
v
;
};
/** 解析的总的表格数据,方便后面修改抽样比例时使用 */
const
parseFileDataSum
:
any
=
ref
([]);
...
...
@@ -1354,11 +1310,14 @@ const calculateElapsedTime = (parsingTime, parsingCompletedTime) => {
/** 第二步的配置组件引用。 */
const
anonTaskStepTwoRef
=
ref
();
const
changeStep
=
async
(
val
)
=>
{
if
(
val
<=
step
.
value
)
{
/** 步骤条对应的不同步骤下一步,上一步的处理函数。 */
const
changeStepHandlers
=
{
'lastStep'
:
(
val
)
=>
{
step
.
value
=
val
-
1
;
stepsInfo
.
value
.
step
=
val
-
1
;
}
else
if
(
val
==
2
)
{
},
'2'
:
()
=>
{
let
val
=
2
;
formRef
.
value
?.
ruleFormRef
?.
validate
((
valid
)
=>
{
if
(
valid
)
{
if
(
formRef
.
value
?.
formInline
?.
dataSource
==
2
&&
!
sampleTableFields
.
value
?.
length
)
{
...
...
@@ -1375,7 +1334,9 @@ const changeStep = async (val) => {
});
}
});
}
else
if
(
val
==
3
)
{
},
'3'
:
async
()
=>
{
let
val
=
3
;
let
exec
=
(
saveParams
)
=>
{
if
(
saveParams
.
coverageArea
?.
length
)
{
saveParams
.
coverageArea
=
[
saveParams
.
coverageArea
];
...
...
@@ -1514,8 +1475,10 @@ const changeStep = async (val) => {
}
})
}
}
else
if
(
val
==
4
)
{
//下一步之后,设置执行结束, 查看结果。
},
'4'
:
()
=>
{
let
val
=
4
;
//下一步之后,设置执行结束, 查看结果。
step
.
value
=
val
-
1
;
stepsInfo
.
value
.
step
=
val
-
1
;
}
...
...
@@ -1757,7 +1720,7 @@ const cancelTask = () => {
proxy
.
$openMessageBox
(
"当前页面尚未保存,确定放弃修改吗?"
,
()
=>
{
userStore
.
setTabbar
(
userStore
.
tabbar
.
filter
((
tab
:
any
)
=>
tab
.
fullPath
!==
fullPath
));
router
.
push
({
name
:
'
resultProcess
'
name
:
'
anonResultProcessManage
'
});
},
()
=>
{
proxy
.
$ElMessage
.
info
(
"已取消"
);
...
...
@@ -1768,7 +1731,7 @@ const cancelTask = () => {
const
closeTask
=
()
=>
{
userStore
.
setTabbar
(
userStore
.
tabbar
.
filter
((
tab
:
any
)
=>
tab
.
fullPath
!==
fullPath
));
router
.
push
({
name
:
'
resultProcess
'
name
:
'
anonResultProcessManage
'
});
}
...
...
@@ -1786,7 +1749,7 @@ const processStepThreeResultView = (isRefresh = false) => {
return
;
}
let
process
=
(
isRefresh
)
=>
{
getResultPromise
.
value
=
getAnonAnalyzeResult
(
taskExecGuid
.
value
).
then
((
res
:
any
)
=>
{
getResultPromise
.
value
=
getAnonAnalyzeResult
1
(
taskExecGuid
.
value
).
then
((
res
:
any
)
=>
{
getResultPromise
.
value
=
null
;
if
(
res
?.
code
==
proxy
.
$passCode
)
{
analysisResultInfo
.
value
=
res
.
data
||
{};
...
...
src/views/data_anonymization/components/anonResultAnalysis.vue
View file @
a13d795
...
...
@@ -98,7 +98,7 @@
<
/div
>
<
/div
>
<
div
class
=
"result-title"
>
重标识风险表
<
/div
>
<
el
-
table
ref
=
"tableRef"
v
-
show
=
"analysisResultTableFields.length"
:
data
=
"resultData"
<
el
-
table
ref
=
"tableRef"
v
-
show
=
"analysisResultTableFields
?
.length"
:
data
=
"resultData"
v
-
loading
=
"analysisResultLoading"
:
highlight
-
current
-
row
=
"true"
stripe
border
tooltip
-
effect
=
"light"
height
=
"100%"
row
-
key
=
"guid"
:
style
=
"
{
width
:
'100%'
,
height
:
'280px'
}
">
<el-table-column label="
等价类
" type="
index
" width="
68
px
" align="
center
" show-overflow-tooltip>
...
...
@@ -127,14 +127,14 @@
<
el
-
table
-
column
label
=
"判断重风险是否大于门限阈值"
prop
=
"isGtThreshold"
width
=
"130"
align
=
"left"
fixed
=
"right"
show
-
overflow
-
tooltip
><
/el-table-column
>
<
/el-table
>
<
div
v
-
show
=
"!analysisResultTableFields.length"
class
=
"empty-content"
>
<
div
v
-
show
=
"!analysisResultTableFields
?
.length"
class
=
"empty-content"
>
<
img
src
=
"../../../assets/images/empty-data.png"
:
style
=
"
{
width
:
'168px'
,
height
:
'96px'
}
" />
<div class="
empty
-
text
">暂无数据</div>
</div>
<div v-show="
analysisResultTableFields
.
length
" class="
result
-
table
-
desc
">门限阈值的取值:完全公开共享数据发布,取值
<div v-show="
analysisResultTableFields
?
.
length
" class="
result
-
table
-
desc
">门限阈值的取值:完全公开共享数据发布,取值
1/20;受控公开共享数据发布,取值
1/5;领地公开共享数据发布,取值 1/3</div>
<PageNav v-show="
analysisResultTableFields
.
length
" :class="
[
pageInfo
.
type
]
" :pageInfo="
pageInfo
"
<PageNav v-show="
analysisResultTableFields
?
.
length
" :class="
[
pageInfo
.
type
]
" :pageInfo="
pageInfo
"
@pageChange="
pageChange
" />
<div class="
row
-
two
-
main
" style="
margin
-
top
:
12
px
;
">
<div class="
table
-
one
">
...
...
@@ -394,7 +394,7 @@ const props = defineProps({
}
,
analysisResultTableFields
:
{
type
:
Array
,
default
:
[],
default
:
<
any
>
[],
}
,
originResultTableFieldColumn
:
{
type
:
Object
,
...
...
Write
Preview
Styling with
Markdown
is supported
Attach a file
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 post a comment