敏感数据识别
Showing
13 changed files
with
1227 additions
and
33 deletions
| ... | @@ -112,8 +112,8 @@ export const saveSensitiveDataTask = (params) => request({ | ... | @@ -112,8 +112,8 @@ export const saveSensitiveDataTask = (params) => request({ |
| 112 | /** 编辑修改敏感数据识别任务 */ | 112 | /** 编辑修改敏感数据识别任务 */ |
| 113 | export const updateSensitiveDataTask = (params) => request({ | 113 | export const updateSensitiveDataTask = (params) => request({ |
| 114 | url: `${import.meta.env.VITE_APP_ANONYMIZATION_BASEURL}/sensitive-data-task/update`, | 114 | url: `${import.meta.env.VITE_APP_ANONYMIZATION_BASEURL}/sensitive-data-task/update`, |
| 115 | method: 'post', | 115 | method: 'put', |
| 116 | params | 116 | data: params |
| 117 | }) | 117 | }) |
| 118 | 118 | ||
| 119 | /** 删除敏感数据识别任务 */ | 119 | /** 删除敏感数据识别任务 */ |
| ... | @@ -123,5 +123,72 @@ export const deleteSensitiveDataTask = (data) => request({ | ... | @@ -123,5 +123,72 @@ export const deleteSensitiveDataTask = (data) => request({ |
| 123 | data | 123 | data |
| 124 | }) | 124 | }) |
| 125 | 125 | ||
| 126 | /** 手动执行敏感任务 */ | ||
| 127 | export const execSensitiveDataTask = (guid) => request({ | ||
| 128 | url: `${import.meta.env.VITE_APP_ANONYMIZATION_BASEURL}/sensitive-data-task/exec-task?taskGuid=${guid}`, | ||
| 129 | method: 'get' | ||
| 130 | }) | ||
| 131 | |||
| 126 | /** 数据来源类型 */ | 132 | /** 数据来源类型 */ |
| 127 | //export const | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 133 | export const dataSourceTypeList = [{ | ||
| 134 | value: 1, | ||
| 135 | label: '数据源' | ||
| 136 | }, { | ||
| 137 | value: 2, | ||
| 138 | label: '文件导入' | ||
| 139 | }]; | ||
| 140 | |||
| 141 | /** 获取数据库选择列表 */ | ||
| 142 | export const getDatabase = (params) => request({ | ||
| 143 | url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/get-source-list`, | ||
| 144 | method: 'post', | ||
| 145 | data: params | ||
| 146 | }) | ||
| 147 | |||
| 148 | /** 获取敏感数据任务执行的数据表列表 */ | ||
| 149 | export const getExecSensitiveTable = (execGuid) => request({ | ||
| 150 | url: `${import.meta.env.VITE_APP_ANONYMIZATION_BASEURL}/sensitive-data-task/get-exec-sensitive-table?execGuid=${execGuid}`, | ||
| 151 | method: 'get' | ||
| 152 | }) | ||
| 153 | |||
| 154 | /** 根据数据源或表获取敏感数据任务执行的字段列表 */ | ||
| 155 | export const getExecSensitiveFieldTable = (params) => request({ | ||
| 156 | url: `${import.meta.env.VITE_APP_ANONYMIZATION_BASEURL}/sensitive-data-task/get-exec-sensitive-field`, | ||
| 157 | method: 'post', | ||
| 158 | data: params | ||
| 159 | }) | ||
| 160 | |||
| 161 | /** 获取当前数据表下的执行字段 */ | ||
| 162 | export const getExecSensitiveFieldLabel = (params) => request({ | ||
| 163 | url: `${import.meta.env.VITE_APP_ANONYMIZATION_BASEURL}/sensitive-data-task/get-exec-sensitive-label`, | ||
| 164 | method: 'post', | ||
| 165 | data: params | ||
| 166 | }) | ||
| 167 | |||
| 168 | /** 获取敏感数据识别任务执行后的统计结果 */ | ||
| 169 | export const getStatisticsNum = (params) => request({ | ||
| 170 | url: `${import.meta.env.VITE_APP_ANONYMIZATION_BASEURL}/sensitive-data-task/statistics-num`, | ||
| 171 | method: 'get', | ||
| 172 | params | ||
| 173 | }) | ||
| 174 | |||
| 175 | /** 修改敏感数据识别字段标签 */ | ||
| 176 | export const updateSensitiveDataTaskFieldLabel = (params) => request({ | ||
| 177 | url: `${import.meta.env.VITE_APP_ANONYMIZATION_BASEURL}/sensitive-data-task/batch-update-label`, | ||
| 178 | method: 'put', | ||
| 179 | data: params | ||
| 180 | }) | ||
| 181 | |||
| 182 | /** 批量修改确认状态 */ | ||
| 183 | export const batchUpdateSensitiveDataTaskFieldStatus = (params) => request({ | ||
| 184 | url: `${import.meta.env.VITE_APP_ANONYMIZATION_BASEURL}/sensitive-data-task/batch-change-status`, | ||
| 185 | method: 'post', | ||
| 186 | data: params | ||
| 187 | }) | ||
| 188 | |||
| 189 | /** 获取敏感数据识别任务执行日志 */ | ||
| 190 | export const getSensitiveDataTaskExecLog = (params) => request({ | ||
| 191 | url: `${import.meta.env.VITE_APP_ANONYMIZATION_BASEURL}/sensitive-data-task/get-exec-sensitive-exec-log`, | ||
| 192 | method: 'post', | ||
| 193 | data: params | ||
| 194 | }) | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
src/assets/icons/filter-mobile-select.svg
0 → 100644
| 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1755825941248" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1233" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M102.784 179.648A32 32 0 0 1 128.064 128H768a32 32 0 0 1 25.28 51.648L576 458.944v468.992a32 32 0 0 1-49.728 26.624l-192-128a32 32 0 0 1-14.24-26.592V458.944L102.784 179.648z m274.528 248.672A32 32 0 0 1 384 448v334.848l128 85.344V448a32 32 0 0 1 6.72-19.68L702.624 192H193.472l183.84 236.32zM735.968 512h128a32 32 0 1 1 0 64h-128a32 32 0 1 1 0-64z m0 128h128a32 32 0 1 1 0 64h-128a32 32 0 1 1 0-64z m0 128h128a32 32 0 1 1 0 64h-128a32 32 0 1 1 0-64z" fill="#4fa1a4" p-id="1234"></path></svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M102.784 179.648A32 32 0 0 1 128.064 128H768a32 32 0 0 1 25.28 51.648L576 458.944v468.992a32 32 0 0 1-49.728 26.624l-192-128a32 32 0 0 1-14.24-26.592V458.944L102.784 179.648z m274.528 248.672A32 32 0 0 1 384 448v334.848l128 85.344V448a32 32 0 0 1 6.72-19.68L702.624 192H193.472l183.84 236.32zM735.968 512h128a32 32 0 1 1 0 64h-128a32 32 0 1 1 0-64z m0 128h128a32 32 0 1 1 0 64h-128a32 32 0 1 1 0-64z m0 128h128a32 32 0 1 1 0 64h-128a32 32 0 1 1 0-64z" fill="#999999" p-id="1519"></path></svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | <svg t="1755766425695" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1233" width="200" height="200"><path d="M102.784 179.648A32 32 0 0 1 128.064 128H768a32 32 0 0 1 25.28 51.648L576 458.944v468.992a32 32 0 0 1-49.728 26.624l-192-128a32 32 0 0 1-14.24-26.592V458.944L102.784 179.648z m274.528 248.672A32 32 0 0 1 384 448v334.848l128 85.344V448a32 32 0 0 1 6.72-19.68L702.624 192H193.472l183.84 236.32zM735.968 512h128a32 32 0 1 1 0 64h-128a32 32 0 1 1 0-64z m0 128h128a32 32 0 1 1 0 64h-128a32 32 0 1 1 0-64z m0 128h128a32 32 0 1 1 0 64h-128a32 32 0 1 1 0-64z" fill="#999999" p-id="1234"></path></svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -43,18 +43,23 @@ const btn = computed(() => { | ... | @@ -43,18 +43,23 @@ const btn = computed(() => { |
| 43 | return props.popoverInfo.btn ?? {}; | 43 | return props.popoverInfo.btn ?? {}; |
| 44 | }); | 44 | }); |
| 45 | 45 | ||
| 46 | const dataProps = computed(() => { | ||
| 47 | return <any>(props.popoverInfo.props || {}); | ||
| 48 | }); | ||
| 49 | |||
| 46 | const initAttr = () => { | 50 | const initAttr = () => { |
| 47 | const data = props.popoverInfo.data ?? [] | 51 | const data = props.popoverInfo.data ?? [] |
| 48 | const check = props.popoverInfo.checked ?? [] | 52 | const check = props.popoverInfo.checked ?? [] |
| 49 | checkedVal.value = check | 53 | checkedVal.value = check |
| 50 | isIndeterminate.value = data.length > 0 && data.length == check.length | 54 | checkAll.value = data.length > 0 && data.length == check.length; |
| 55 | isIndeterminate.value = check.length > 0 && data.length > check.length | ||
| 51 | authorities.value = data | 56 | authorities.value = data |
| 52 | } | 57 | } |
| 53 | 58 | ||
| 54 | const filterPopover = (val) => { | 59 | const filterPopover = (val) => { |
| 55 | let data = props.popoverInfo.data ?? [] | 60 | let data = props.popoverInfo.data ?? [] |
| 56 | if (val) { | 61 | if (val) { |
| 57 | authorities.value = data.filter(item => item.dataPermissionName.indexOf(val) > -1) | 62 | authorities.value = data.filter(item => item[dataProps.value.label || 'dataPermissionName'].indexOf(val) > -1) |
| 58 | } else { | 63 | } else { |
| 59 | authorities.value = data | 64 | authorities.value = data |
| 60 | } | 65 | } |
| ... | @@ -70,7 +75,8 @@ const handleCheckedCitiesChange = (val) => { | ... | @@ -70,7 +75,8 @@ const handleCheckedCitiesChange = (val) => { |
| 70 | isIndeterminate.value = checkedCount > 0 && checkedCount < authorities.value.length; | 75 | isIndeterminate.value = checkedCount > 0 && checkedCount < authorities.value.length; |
| 71 | }; | 76 | }; |
| 72 | const showPopver = () => { | 77 | const showPopver = () => { |
| 73 | inputValue.value = '' | 78 | inputValue.value = ''; |
| 79 | initAttr(); | ||
| 74 | emits('showPopver', props.popoverInfo.scope, btn.value) | 80 | emits('showPopver', props.popoverInfo.scope, btn.value) |
| 75 | } | 81 | } |
| 76 | const btnClick = () => { | 82 | const btnClick = () => { |
| ... | @@ -98,10 +104,10 @@ watch(() => props.popoverInfo, async (val) => { | ... | @@ -98,10 +104,10 @@ watch(() => props.popoverInfo, async (val) => { |
| 98 | </template> | 104 | </template> |
| 99 | <template v-else-if="type == 'checkbox-list-btns'"> | 105 | <template v-else-if="type == 'checkbox-list-btns'"> |
| 100 | <div class="content_body"> | 106 | <div class="content_body"> |
| 101 | <el-input v-model.trim="inputValue" placeholder="请输入权限名称" :prefix-icon="Search" clearable | 107 | <el-input v-model.trim="inputValue" v-show="popoverInfo.data?.length > 5" :placeholder="props.popoverInfo.placeholder ?? '请输入权限名称'" :prefix-icon="Search" clearable |
| 102 | @change="filterPopover" /> | 108 | @input="filterPopover" /> |
| 103 | <el-checkbox-group v-model="checkedVal" @change="handleCheckedCitiesChange"> | 109 | <el-checkbox-group v-model="checkedVal" @change="handleCheckedCitiesChange"> |
| 104 | <el-checkbox v-for="auth in authorities" :key="auth.guid" :label="auth.guid">{{ auth.dataPermissionName | 110 | <el-checkbox v-for="auth in authorities" :key="auth.guid" :value="auth.guid">{{ auth[dataProps.label || 'dataPermissionName'] |
| 105 | }}</el-checkbox> | 111 | }}</el-checkbox> |
| 106 | </el-checkbox-group> | 112 | </el-checkbox-group> |
| 107 | </div> | 113 | </div> |
| ... | @@ -118,6 +124,9 @@ watch(() => props.popoverInfo, async (val) => { | ... | @@ -118,6 +124,9 @@ watch(() => props.popoverInfo, async (val) => { |
| 118 | </div> | 124 | </div> |
| 119 | <template #reference> | 125 | <template #reference> |
| 120 | <span v-if="btn.value == 'authority'" @click="showPopver" v-preReClick>{{ btn.label }}</span> | 126 | <span v-if="btn.value == 'authority'" @click="showPopver" v-preReClick>{{ btn.label }}</span> |
| 127 | <el-icon class="filter-icon" v-else-if="btn.value == 'filter'" @click="showPopver"> | ||
| 128 | <svg-icon :name="checkedVal.length ? 'filter-mobile-select' : 'filter-mobile'" /> | ||
| 129 | </el-icon> | ||
| 121 | <el-icon v-else-if="btn.value == 'QuestionFilled'"> | 130 | <el-icon v-else-if="btn.value == 'QuestionFilled'"> |
| 122 | <QuestionFilled /> | 131 | <QuestionFilled /> |
| 123 | </el-icon> | 132 | </el-icon> |
| ... | @@ -138,8 +147,8 @@ watch(() => props.popoverInfo, async (val) => { | ... | @@ -138,8 +147,8 @@ watch(() => props.popoverInfo, async (val) => { |
| 138 | } | 147 | } |
| 139 | 148 | ||
| 140 | .el-checkbox-group { | 149 | .el-checkbox-group { |
| 141 | margin: 8px -8px 0; | 150 | margin: 0px -8px 0; |
| 142 | max-height: 276px; | 151 | max-height: 256px; |
| 143 | overflow: hidden auto; | 152 | overflow: hidden auto; |
| 144 | 153 | ||
| 145 | .el-checkbox { | 154 | .el-checkbox { | ... | ... |
| ... | @@ -328,7 +328,7 @@ onMounted(() => { | ... | @@ -328,7 +328,7 @@ onMounted(() => { |
| 328 | <span v-if="item.unit">{{ item.unit }}</span> | 328 | <span v-if="item.unit">{{ item.unit }}</span> |
| 329 | </template> | 329 | </template> |
| 330 | <template #default="scope" v-else-if="item.type == 'switch'"> | 330 | <template #default="scope" v-else-if="item.type == 'switch'"> |
| 331 | <el-switch v-model="scope.row[item.field]" inline-prompt :key="scope.row.guid" | 331 | <el-switch v-model="scope.row[item.field]" inline-prompt :key="scope.row[rowKey || 'guid']" |
| 332 | :disabled="!item.isDisabled ? false : item.isDisabled(scope)" :active-value="item.activeValue" | 332 | :disabled="!item.isDisabled ? false : item.isDisabled(scope)" :active-value="item.activeValue" |
| 333 | :inactive-value="item.inactiveValue" :width="item.switchWidth" :active-text="item.activeText" | 333 | :inactive-value="item.inactiveValue" :width="item.switchWidth" :active-text="item.activeText" |
| 334 | :inactive-text="item.inactiveText" :before-change="() => beforeChange(scope, item)" | 334 | :inactive-text="item.inactiveText" :before-change="() => beforeChange(scope, item)" | ... | ... |
| ... | @@ -85,6 +85,42 @@ const routes: RouteRecordRaw[] = [ | ... | @@ -85,6 +85,42 @@ const routes: RouteRecordRaw[] = [ |
| 85 | cache: true | 85 | cache: true |
| 86 | }, | 86 | }, |
| 87 | }, | 87 | }, |
| 88 | { | ||
| 89 | path: 'sensitive-identify-config', | ||
| 90 | name: 'sensitiveIdentifyConfig', | ||
| 91 | component: () => import('@/views/data_anonymization/sensitiveIdentifyConfig.vue'), | ||
| 92 | meta: { | ||
| 93 | title: '敏感数据识别查看', | ||
| 94 | sidebar: false, | ||
| 95 | breadcrumb: false, | ||
| 96 | cache: true, | ||
| 97 | reuse: true, | ||
| 98 | editPage: false, | ||
| 99 | activeMenu: '/data-anonymization/sensitive-identify' | ||
| 100 | }, | ||
| 101 | beforeEnter: (to, from) => { | ||
| 102 | if (to.query.taskName) { | ||
| 103 | to.meta.title = `敏感数据识别查看-${to.query.taskName}`; | ||
| 104 | } | ||
| 105 | } | ||
| 106 | }, | ||
| 107 | { | ||
| 108 | path: 'sensitive-identify-task-exec-log', | ||
| 109 | name: 'sensitiveIdentifyTaskExecLog', | ||
| 110 | component: () => import('@/views/data_anonymization/sensitiveIdentifyTaskExecLog.vue'), | ||
| 111 | meta: { | ||
| 112 | title: '执行日志', | ||
| 113 | sidebar: false, | ||
| 114 | breadcrumb: false, | ||
| 115 | cache: true, | ||
| 116 | reuse: true | ||
| 117 | }, | ||
| 118 | beforeEnter: (to, from) => { | ||
| 119 | if (to.query.guid) { | ||
| 120 | to.meta.title = `日志-${to.query.name}`; | ||
| 121 | } | ||
| 122 | } | ||
| 123 | } | ||
| 88 | ], | 124 | ], |
| 89 | }, | 125 | }, |
| 90 | { | 126 | { | ... | ... |
| ... | @@ -495,6 +495,16 @@ export const tagType = (row, type) => { | ... | @@ -495,6 +495,16 @@ export const tagType = (row, type) => { |
| 495 | } else { | 495 | } else { |
| 496 | state = 'info'; | 496 | state = 'info'; |
| 497 | } | 497 | } |
| 498 | } else if (type == 'sensitiveIdentifyTaskStatus') { | ||
| 499 | if (row[type] == 'Y') { | ||
| 500 | state = 'success' | ||
| 501 | } else if (row[type] == 'N') { | ||
| 502 | state = 'info'; | ||
| 503 | } else if (row[type] == 'E') { | ||
| 504 | state = 'danger'; | ||
| 505 | } else if (row[type] == 'R') { | ||
| 506 | state = 'warning'; | ||
| 507 | } | ||
| 498 | } else if (type == 'state' || type == 'documentState') { | 508 | } else if (type == 'state' || type == 'documentState') { |
| 499 | switch (row[type]) { | 509 | switch (row[type]) { |
| 500 | case 'N': | 510 | case 'N': |
| ... | @@ -805,6 +815,16 @@ export const tagMethod = (row, type) => { | ... | @@ -805,6 +815,16 @@ export const tagMethod = (row, type) => { |
| 805 | }else if (row[type] == 'R') { //部分通过 | 815 | }else if (row[type] == 'R') { //部分通过 |
| 806 | tag = '执行中'; | 816 | tag = '执行中'; |
| 807 | } | 817 | } |
| 818 | } else if (type == 'sensitiveIdentifyTaskStatus') { | ||
| 819 | if (row[type] == 'Y') { | ||
| 820 | tag = '成功' | ||
| 821 | } else if (row[type] == 'N') { | ||
| 822 | tag = '未执行'; | ||
| 823 | } else if (row[type] == 'E') { //部分通过 | ||
| 824 | tag = '失败'; | ||
| 825 | }else if (row[type] == 'R') { //部分通过 | ||
| 826 | tag = '执行中'; | ||
| 827 | } | ||
| 808 | } else if (type == 'execState') { | 828 | } else if (type == 'execState') { |
| 809 | if (row[type] == 0 || row[type] == null) { | 829 | if (row[type] == 0 || row[type] == null) { |
| 810 | tag = '未执行' | 830 | tag = '未执行' | ... | ... |
| ... | @@ -82,7 +82,7 @@ const tableInfo = ref({ | ... | @@ -82,7 +82,7 @@ const tableInfo = ref({ |
| 82 | proxy.$openMessageBox("此操作将永久删除, 是否继续?", () => { | 82 | proxy.$openMessageBox("此操作将永久删除, 是否继续?", () => { |
| 83 | let guids = [scope.row.guid]; | 83 | let guids = [scope.row.guid]; |
| 84 | deleteGeneralizeFile(guids).then((res: any) => { | 84 | deleteGeneralizeFile(guids).then((res: any) => { |
| 85 | if (res.code == proxy.$passCode) { | 85 | if (res?.code == proxy.$passCode) { |
| 86 | getTableData(); | 86 | getTableData(); |
| 87 | proxy.$ElMessage({ | 87 | proxy.$ElMessage({ |
| 88 | type: "success", | 88 | type: "success", |
| ... | @@ -122,7 +122,7 @@ const getTableData = () => { | ... | @@ -122,7 +122,7 @@ const getTableData = () => { |
| 122 | generalizeFileName: page.value.generalizeFileName, | 122 | generalizeFileName: page.value.generalizeFileName, |
| 123 | fieldType: page.value.fieldType | 123 | fieldType: page.value.fieldType |
| 124 | }).then((res: any) => { | 124 | }).then((res: any) => { |
| 125 | if (res.code == proxy.$passCode) { | 125 | if (res?.code == proxy.$passCode) { |
| 126 | const data = res.data || {} | 126 | const data = res.data || {} |
| 127 | tableInfo.value.data = data.records || [] | 127 | tableInfo.value.data = data.records || [] |
| 128 | tableInfo.value.page.limit = data.pageSize | 128 | tableInfo.value.page.limit = data.pageSize | ... | ... |
| ... | @@ -268,7 +268,7 @@ const saveUpdate = async () => { | ... | @@ -268,7 +268,7 @@ const saveUpdate = async () => { |
| 268 | if (!guid.value) { | 268 | if (!guid.value) { |
| 269 | saveLoading.value = true; | 269 | saveLoading.value = true; |
| 270 | saveGeneralizeFile(params).then((res: any) => { | 270 | saveGeneralizeFile(params).then((res: any) => { |
| 271 | if (res.code == proxy.$passCode) { | 271 | if (res?.code == proxy.$passCode) { |
| 272 | proxy.$ElMessage.success('泛化文件新建成功'); | 272 | proxy.$ElMessage.success('泛化文件新建成功'); |
| 273 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | 273 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); |
| 274 | anonymizationStore.setIsRefresh(true); | 274 | anonymizationStore.setIsRefresh(true); |
| ... | @@ -285,7 +285,7 @@ const saveUpdate = async () => { | ... | @@ -285,7 +285,7 @@ const saveUpdate = async () => { |
| 285 | params.guid = guid.value; | 285 | params.guid = guid.value; |
| 286 | saveLoading.value = true; | 286 | saveLoading.value = true; |
| 287 | updateGeneralizeFile(params).then((res: any) => { | 287 | updateGeneralizeFile(params).then((res: any) => { |
| 288 | if (res.code == proxy.$passCode) { | 288 | if (res?.code == proxy.$passCode) { |
| 289 | proxy.$ElMessage.success('泛化文件编辑成功'); | 289 | proxy.$ElMessage.success('泛化文件编辑成功'); |
| 290 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | 290 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); |
| 291 | anonymizationStore.setIsRefresh(true); | 291 | anonymizationStore.setIsRefresh(true); |
| ... | @@ -310,7 +310,7 @@ onBeforeMount(() => { | ... | @@ -310,7 +310,7 @@ onBeforeMount(() => { |
| 310 | if (guid.value) { | 310 | if (guid.value) { |
| 311 | fullscreenLoading.value = true; | 311 | fullscreenLoading.value = true; |
| 312 | getGeneralizeFileDetail(guid.value).then(async (res: any) => { | 312 | getGeneralizeFileDetail(guid.value).then(async (res: any) => { |
| 313 | if (res.code == proxy.$passCode) { | 313 | if (res?.code == proxy.$passCode) { |
| 314 | let detail = res.data || {}; | 314 | let detail = res.data || {}; |
| 315 | baseInfoItems.value.forEach(item => { | 315 | baseInfoItems.value.forEach(item => { |
| 316 | item.default = detail[item.field]; | 316 | item.default = detail[item.field]; | ... | ... |
| ... | @@ -73,7 +73,7 @@ const tableInfo = ref({ | ... | @@ -73,7 +73,7 @@ const tableInfo = ref({ |
| 73 | label: "编辑", value: "edit", click: (scope) => { | 73 | label: "编辑", value: "edit", click: (scope) => { |
| 74 | currTableData.value = scope.row; | 74 | currTableData.value = scope.row; |
| 75 | getLabelDetail(scope.row.guid).then((res: any) => { | 75 | getLabelDetail(scope.row.guid).then((res: any) => { |
| 76 | if (res.code == proxy.$passCode) { | 76 | if (res?.code == proxy.$passCode) { |
| 77 | const detail = res.data || {}; | 77 | const detail = res.data || {}; |
| 78 | currTableData.value = Object.assign({}, currTableData.value, detail); | 78 | currTableData.value = Object.assign({}, currTableData.value, detail); |
| 79 | newCreateLabelFormItems.value.forEach(item => { | 79 | newCreateLabelFormItems.value.forEach(item => { |
| ... | @@ -120,7 +120,7 @@ const tableInfo = ref({ | ... | @@ -120,7 +120,7 @@ const tableInfo = ref({ |
| 120 | proxy.$openMessageBox("此操作将永久删除, 是否继续?", () => { | 120 | proxy.$openMessageBox("此操作将永久删除, 是否继续?", () => { |
| 121 | let guids = [scope.row.guid]; | 121 | let guids = [scope.row.guid]; |
| 122 | deleteLabel(guids).then((res: any) => { | 122 | deleteLabel(guids).then((res: any) => { |
| 123 | if (res.code == proxy.$passCode) { | 123 | if (res?.code == proxy.$passCode) { |
| 124 | getTableData(); | 124 | getTableData(); |
| 125 | proxy.$ElMessage({ | 125 | proxy.$ElMessage({ |
| 126 | type: "success", | 126 | type: "success", |
| ... | @@ -159,7 +159,7 @@ const getTableData = () => { | ... | @@ -159,7 +159,7 @@ const getTableData = () => { |
| 159 | pageSize: page.value.limit, | 159 | pageSize: page.value.limit, |
| 160 | labelName: page.value.labelName | 160 | labelName: page.value.labelName |
| 161 | }).then((res: any) => { | 161 | }).then((res: any) => { |
| 162 | if (res.code == proxy.$passCode) { | 162 | if (res?.code == proxy.$passCode) { |
| 163 | const data = res.data || {} | 163 | const data = res.data || {} |
| 164 | tableInfo.value.data = data.records || [] | 164 | tableInfo.value.data = data.records || [] |
| 165 | tableInfo.value.page.limit = data.pageSize | 165 | tableInfo.value.page.limit = data.pageSize |
| ... | @@ -193,7 +193,7 @@ const tableSwitchChange = (val, scope, field) => { | ... | @@ -193,7 +193,7 @@ const tableSwitchChange = (val, scope, field) => { |
| 193 | bizState: val | 193 | bizState: val |
| 194 | } | 194 | } |
| 195 | updateLabelState(params).then((res: any) => { | 195 | updateLabelState(params).then((res: any) => { |
| 196 | if (res.code == proxy.$passCode && res.data) { | 196 | if (res?.code == proxy.$passCode && res.data) { |
| 197 | getTableData(); | 197 | getTableData(); |
| 198 | proxy.$ElMessage({ | 198 | proxy.$ElMessage({ |
| 199 | type: "success", | 199 | type: "success", |
| ... | @@ -331,7 +331,7 @@ const newCreateLabelDialogInfo = ref({ | ... | @@ -331,7 +331,7 @@ const newCreateLabelDialogInfo = ref({ |
| 331 | newCreateLabelDialogInfo.value.submitBtnLoading = true; | 331 | newCreateLabelDialogInfo.value.submitBtnLoading = true; |
| 332 | if (newCreateLabelDialogInfo.value.type == 'add') { | 332 | if (newCreateLabelDialogInfo.value.type == 'add') { |
| 333 | saveLabel(params).then((res: any) => { | 333 | saveLabel(params).then((res: any) => { |
| 334 | if (res.code == proxy.$passCode) { | 334 | if (res?.code == proxy.$passCode) { |
| 335 | proxy.$ElMessage.success('标签新建成功'); | 335 | proxy.$ElMessage.success('标签新建成功'); |
| 336 | newCreateLabelDialogInfo.value.visible = false; | 336 | newCreateLabelDialogInfo.value.visible = false; |
| 337 | newCreateLabelDialogInfo.value.submitBtnLoading = false; | 337 | newCreateLabelDialogInfo.value.submitBtnLoading = false; |
| ... | @@ -350,7 +350,7 @@ const newCreateLabelDialogInfo = ref({ | ... | @@ -350,7 +350,7 @@ const newCreateLabelDialogInfo = ref({ |
| 350 | params.labelRuleContent.guid = currTableData.value.labelRuleContent?.guid; | 350 | params.labelRuleContent.guid = currTableData.value.labelRuleContent?.guid; |
| 351 | params.labelRuleField.guid = currTableData.value.labelRuleField?.guid; | 351 | params.labelRuleField.guid = currTableData.value.labelRuleField?.guid; |
| 352 | updateLabel(params).then((res: any) => { | 352 | updateLabel(params).then((res: any) => { |
| 353 | if (res.code == proxy.$passCode) { | 353 | if (res?.code == proxy.$passCode) { |
| 354 | proxy.$ElMessage.success('标签编辑成功'); | 354 | proxy.$ElMessage.success('标签编辑成功'); |
| 355 | newCreateLabelDialogInfo.value.visible = false; | 355 | newCreateLabelDialogInfo.value.visible = false; |
| 356 | newCreateLabelDialogInfo.value.submitBtnLoading = false; | 356 | newCreateLabelDialogInfo.value.submitBtnLoading = false; |
| ... | @@ -654,7 +654,7 @@ onBeforeMount(() => { | ... | @@ -654,7 +654,7 @@ onBeforeMount(() => { |
| 654 | getParamsList({ | 654 | getParamsList({ |
| 655 | dictType: "标签类型", | 655 | dictType: "标签类型", |
| 656 | }).then((res: any) => { | 656 | }).then((res: any) => { |
| 657 | if (res.code == proxy.$passCode) { | 657 | if (res?.code == proxy.$passCode) { |
| 658 | labelTypeList.value = res.data || []; | 658 | labelTypeList.value = res.data || []; |
| 659 | let item = newCreateLabelFormItems.value.find(item => item.field == 'labelgroup'); | 659 | let item = newCreateLabelFormItems.value.find(item => item.field == 'labelgroup'); |
| 660 | item && (item.children[0].options = labelTypeList.value); | 660 | item && (item.children[0].options = labelTypeList.value); |
| ... | @@ -665,7 +665,7 @@ onBeforeMount(() => { | ... | @@ -665,7 +665,7 @@ onBeforeMount(() => { |
| 665 | getParamsList({ | 665 | getParamsList({ |
| 666 | dictType: "内置规则", | 666 | dictType: "内置规则", |
| 667 | }).then((res: any) => { | 667 | }).then((res: any) => { |
| 668 | if (res.code == proxy.$passCode) { | 668 | if (res?.code == proxy.$passCode) { |
| 669 | builtInRuleList.value = res.data || []; | 669 | builtInRuleList.value = res.data || []; |
| 670 | ruleContentFormItems.value[1].options = builtInRuleList.value; | 670 | ruleContentFormItems.value[1].options = builtInRuleList.value; |
| 671 | } else { | 671 | } else { | ... | ... |
| ... | @@ -8,10 +8,18 @@ import { commonPageConfig } from '@/components/PageNav/index'; | ... | @@ -8,10 +8,18 @@ import { commonPageConfig } from '@/components/PageNav/index'; |
| 8 | import { TableColumnWidth } from "@/utils/enum"; | 8 | import { TableColumnWidth } from "@/utils/enum"; |
| 9 | import { | 9 | import { |
| 10 | getSensitiveDataTaskList, | 10 | getSensitiveDataTaskList, |
| 11 | dataSourceTypeList, | ||
| 12 | deleteSensitiveDataTask, | ||
| 13 | saveSensitiveDataTask, | ||
| 14 | updateSensitiveDataTask, | ||
| 15 | getDatabase, | ||
| 16 | execSensitiveDataTask, | ||
| 11 | } from '@/api/modules/dataAnonymization'; | 17 | } from '@/api/modules/dataAnonymization'; |
| 18 | import { useValidator } from '@/hooks/useValidator'; | ||
| 12 | 19 | ||
| 13 | const router = useRouter() | 20 | const router = useRouter() |
| 14 | const { proxy } = getCurrentInstance() as any; | 21 | const { proxy } = getCurrentInstance() as any; |
| 22 | const { required } = useValidator(); | ||
| 15 | 23 | ||
| 16 | const searchItemList = ref([{ | 24 | const searchItemList = ref([{ |
| 17 | type: "input", | 25 | type: "input", |
| ... | @@ -23,9 +31,9 @@ const searchItemList = ref([{ | ... | @@ -23,9 +31,9 @@ const searchItemList = ref([{ |
| 23 | }, { | 31 | }, { |
| 24 | type: "select", | 32 | type: "select", |
| 25 | label: "", | 33 | label: "", |
| 26 | field: "fieldType", | 34 | field: "dataSource", |
| 27 | default: null, | 35 | default: null, |
| 28 | options: [], | 36 | options: dataSourceTypeList, |
| 29 | placeholder: "数据来源", | 37 | placeholder: "数据来源", |
| 30 | clearable: true, | 38 | clearable: true, |
| 31 | filterable: true, | 39 | filterable: true, |
| ... | @@ -34,25 +42,342 @@ const searchItemList = ref([{ | ... | @@ -34,25 +42,342 @@ const searchItemList = ref([{ |
| 34 | /** 分页及搜索传参信息配置。 */ | 42 | /** 分页及搜索传参信息配置。 */ |
| 35 | const page = ref({ | 43 | const page = ref({ |
| 36 | ...commonPageConfig, | 44 | ...commonPageConfig, |
| 37 | generalizeFileName: '', | 45 | taskName: '', |
| 38 | fieldType: '' | 46 | dataSource: null |
| 39 | }); | 47 | }); |
| 40 | 48 | ||
| 49 | const currTableData = ref(); | ||
| 50 | |||
| 51 | const tableInfo = ref({ | ||
| 52 | id: 'data-file-table', | ||
| 53 | fields: [ | ||
| 54 | { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" }, | ||
| 55 | { label: "任务名称", field: "taskName", width: 160 }, | ||
| 56 | { | ||
| 57 | label: "数据来源", field: "dataSource", width: 120, getName: (scope) => { | ||
| 58 | return scope.row.dataSource && dataSourceTypeList.find(f => f.value == scope.row.dataSource)?.label || '--'; | ||
| 59 | } | ||
| 60 | }, | ||
| 61 | { label: "任务状态", field: "sensitiveIdentifyTaskStatus", width: TableColumnWidth.STATE, align: 'center', type: "tag" }, | ||
| 62 | { label: "执行人", field: "execUserName", width: TableColumnWidth.USERNAME }, | ||
| 63 | { label: "执行时间", field: "execTime", width: TableColumnWidth.DATETIME }, | ||
| 64 | { label: "修改人", field: "updateUserName", width: TableColumnWidth.USERNAME }, | ||
| 65 | { label: "修改时间", field: "updateTime", width: TableColumnWidth.DATETIME }, | ||
| 66 | ], | ||
| 67 | data: [], | ||
| 68 | page: { | ||
| 69 | type: "normal", | ||
| 70 | rows: 0, | ||
| 71 | ...page.value, | ||
| 72 | }, | ||
| 73 | loading: false, | ||
| 74 | actionInfo: { | ||
| 75 | label: "操作", | ||
| 76 | type: "btn", | ||
| 77 | width: 304, | ||
| 78 | fixed: 'right', | ||
| 79 | btns: (scope) => { | ||
| 80 | return [{ | ||
| 81 | label: '敏感数据查看', value: 'view', disabled: scope.row.status != 'Y', click: (scope) => { | ||
| 82 | router.push({ | ||
| 83 | name: 'sensitiveIdentifyConfig', | ||
| 84 | query: { | ||
| 85 | guid: scope.row.guid, | ||
| 86 | execGuid: scope.row.execGuid, | ||
| 87 | taskName: scope.row.taskName | ||
| 88 | } | ||
| 89 | }); | ||
| 90 | } | ||
| 91 | }, { | ||
| 92 | label: '手动执行', value: 'execute', disabled: scope.row.status == 'R', click: (scope) => { | ||
| 93 | execSensitiveDataTask(scope.row.guid).then((res: any) => { | ||
| 94 | if (res?.code == proxy.$passCode) { | ||
| 95 | getTableData(); | ||
| 96 | proxy.$ElMessage.success('该任务手动执行提交成功'); | ||
| 97 | } else { | ||
| 98 | proxy.$ElMessage.error(res.msg); | ||
| 99 | } | ||
| 100 | }) | ||
| 101 | } | ||
| 102 | }, { | ||
| 103 | label: "编辑", value: "edit", disabled: scope.row.status == 'R', click: (scope) => { | ||
| 104 | let row = scope.row; | ||
| 105 | currTableData.value = row; | ||
| 106 | newCreateTaskDialogInfo.value.visible = true; | ||
| 107 | newCreateTaskDialogInfo.value.title = '编辑数据敏感识别任务'; | ||
| 108 | newCreateTaskDialogInfo.value.type = 'edit'; | ||
| 109 | newCreateTaskFormItems.value[0].default = row.taskName; | ||
| 110 | newCreateTaskFormItems.value[1].default = row.dataSource; | ||
| 111 | newCreateTaskFormItems.value[2].default = row.dataSourceGuid || ''; | ||
| 112 | newCreateTaskFormItems.value[2].visible = row.dataSource == 1; | ||
| 113 | newCreateTaskFormItems.value[3].default = row.filePath || []; | ||
| 114 | newCreateTaskFormItems.value[3].visible = row.dataSource == 2; | ||
| 115 | } | ||
| 116 | }, { | ||
| 117 | label: "删除", value: "delete", disabled: scope.row.status == 'R', click: (scope) => { | ||
| 118 | proxy.$openMessageBox("此操作将永久删除, 是否继续?", () => { | ||
| 119 | let guids = [scope.row.guid]; | ||
| 120 | deleteSensitiveDataTask(guids).then((res: any) => { | ||
| 121 | if (res?.code == proxy.$passCode) { | ||
| 122 | getTableData(); | ||
| 123 | proxy.$ElMessage({ | ||
| 124 | type: "success", | ||
| 125 | message: "删除成功", | ||
| 126 | }); | ||
| 127 | } else { | ||
| 128 | proxy.$ElMessage({ | ||
| 129 | type: "error", | ||
| 130 | message: res.msg, | ||
| 131 | }); | ||
| 132 | } | ||
| 133 | }); | ||
| 134 | }) | ||
| 135 | } | ||
| 136 | }, { | ||
| 137 | label: '日志', value: 'log', click: (scope) => { | ||
| 138 | router.push({ | ||
| 139 | name: 'sensitiveIdentifyTaskExecLog', | ||
| 140 | query: { | ||
| 141 | guid: scope.row.guid, | ||
| 142 | name: scope.row.taskName, | ||
| 143 | } | ||
| 144 | }); | ||
| 145 | } | ||
| 146 | }] | ||
| 147 | } | ||
| 148 | } | ||
| 149 | }) | ||
| 150 | |||
| 151 | const toSearch = (val: any, clear: boolean = false) => { | ||
| 152 | if (clear) { | ||
| 153 | searchItemList.value.map((item) => (item.default = "")); | ||
| 154 | page.value.taskName = ''; | ||
| 155 | page.value.dataSource = null; | ||
| 156 | } else { | ||
| 157 | page.value.taskName = val.taskName; | ||
| 158 | page.value.dataSource = val.dataSource; | ||
| 159 | } | ||
| 160 | getTableData(); | ||
| 161 | }; | ||
| 162 | |||
| 163 | const getTableData = () => { | ||
| 164 | tableInfo.value.loading = true | ||
| 165 | getSensitiveDataTaskList({ | ||
| 166 | pageIndex: page.value.curr, | ||
| 167 | pageSize: page.value.limit, | ||
| 168 | taskName: page.value.taskName, | ||
| 169 | dataSource: page.value.dataSource | ||
| 170 | }).then((res: any) => { | ||
| 171 | if (res?.code == proxy.$passCode) { | ||
| 172 | const data = res.data || {}; | ||
| 173 | tableInfo.value.data = data.records?.map(d => { | ||
| 174 | d.sensitiveIdentifyTaskStatus = d.status; | ||
| 175 | return d; | ||
| 176 | }) || [] | ||
| 177 | tableInfo.value.page.limit = data.pageSize | ||
| 178 | tableInfo.value.page.curr = data.pageIndex | ||
| 179 | tableInfo.value.page.rows = data.totalRows | ||
| 180 | } else { | ||
| 181 | proxy.$ElMessage({ | ||
| 182 | type: 'error', | ||
| 183 | message: res.msg, | ||
| 184 | }) | ||
| 185 | } | ||
| 186 | tableInfo.value.loading = false | ||
| 187 | }) | ||
| 188 | }; | ||
| 189 | |||
| 190 | const tablePageChange = (info) => { | ||
| 191 | page.value.curr = Number(info.curr); | ||
| 192 | page.value.limit = Number(info.limit); | ||
| 193 | getTableData(); | ||
| 194 | }; | ||
| 195 | |||
| 196 | const dataSourceList = ref([]); | ||
| 197 | |||
| 198 | const newCreateTaskFormItems = ref([{ | ||
| 199 | label: '任务名称', | ||
| 200 | type: 'input', | ||
| 201 | placeholder: '请选择', | ||
| 202 | field: 'taskName', | ||
| 203 | default: '', | ||
| 204 | required: true, | ||
| 205 | filterable: true, | ||
| 206 | clearable: true, | ||
| 207 | visible: true, | ||
| 208 | }, | ||
| 209 | { | ||
| 210 | label: '数据来源', | ||
| 211 | type: 'select', | ||
| 212 | placeholder: '请选择', | ||
| 213 | field: 'dataSource', | ||
| 214 | default: 1, | ||
| 215 | options: dataSourceTypeList, | ||
| 216 | props: { | ||
| 217 | label: "label", | ||
| 218 | value: "value", | ||
| 219 | }, | ||
| 220 | required: true, | ||
| 221 | filterable: true, | ||
| 222 | clearable: true, | ||
| 223 | visible: true, | ||
| 224 | }, { | ||
| 225 | label: '数据源', | ||
| 226 | type: 'select', | ||
| 227 | placeholder: '请选择', | ||
| 228 | field: 'dataSourceGuid', | ||
| 229 | default: '', | ||
| 230 | options: dataSourceList.value, | ||
| 231 | props: { | ||
| 232 | label: 'databaseNameZh', | ||
| 233 | value: 'guid' | ||
| 234 | }, | ||
| 235 | filterable: true, | ||
| 236 | visible: true, | ||
| 237 | required: true | ||
| 238 | }, { | ||
| 239 | label: '文件上传', | ||
| 240 | tip: '支持扩展名:xlsx、xls、csv,文件大小不超过10MB', | ||
| 241 | type: 'upload-file', | ||
| 242 | accept: '.xlsx, .xls, .csv', | ||
| 243 | limitSize: 10, | ||
| 244 | isExcel: true, | ||
| 245 | required: true, | ||
| 246 | default: <any>[], | ||
| 247 | block: true, | ||
| 248 | visible: false, | ||
| 249 | field: 'file', | ||
| 250 | }]); | ||
| 251 | |||
| 252 | const newCreateTaskFormRules = ref({ | ||
| 253 | taskName: [required('请输入任务名称')], | ||
| 254 | dataSource: [required('请选择数据来源')], | ||
| 255 | dataSourceGuid: [required('请选择数据源')], | ||
| 256 | file: [{ | ||
| 257 | validator: (rule: any, value: any, callback: any) => { | ||
| 258 | if (!value?.length) { | ||
| 259 | callback(new Error('请上传文件')) | ||
| 260 | } else { | ||
| 261 | callback(); | ||
| 262 | } | ||
| 263 | }, trigger: 'change' | ||
| 264 | }] | ||
| 265 | }); | ||
| 266 | |||
| 267 | const newCreateTaskDialogInfo = ref({ | ||
| 268 | visible: false, | ||
| 269 | size: 550, | ||
| 270 | title: "添加数据敏感识别任务", | ||
| 271 | type: "", | ||
| 272 | formInfo: { | ||
| 273 | id: "label-form", | ||
| 274 | items: newCreateTaskFormItems.value, | ||
| 275 | rules: newCreateTaskFormRules.value, | ||
| 276 | }, | ||
| 277 | submitBtnLoading: false, | ||
| 278 | btns: { | ||
| 279 | cancel: () => { | ||
| 280 | newCreateTaskDialogInfo.value.visible = false; | ||
| 281 | newCreateTaskDialogInfo.value.submitBtnLoading = false; | ||
| 282 | }, | ||
| 283 | submit: (btn, info) => { | ||
| 284 | let params = Object.assign({}, info, { | ||
| 285 | filePath: info.file?.map(f => { | ||
| 286 | return { | ||
| 287 | name: f.name, | ||
| 288 | url: f.url | ||
| 289 | } | ||
| 290 | }) || [] | ||
| 291 | }); | ||
| 292 | delete params.file; | ||
| 293 | newCreateTaskDialogInfo.value.submitBtnLoading = true; | ||
| 294 | if (newCreateTaskDialogInfo.value.type == 'add') { | ||
| 295 | saveSensitiveDataTask(params).then((res: any) => { | ||
| 296 | if (res?.code == proxy.$passCode) { | ||
| 297 | proxy.$ElMessage.success('标签新建成功'); | ||
| 298 | newCreateTaskDialogInfo.value.visible = false; | ||
| 299 | newCreateTaskDialogInfo.value.submitBtnLoading = false; | ||
| 300 | page.value.curr = 1; | ||
| 301 | getTableData(); | ||
| 302 | } else { | ||
| 303 | newCreateTaskDialogInfo.value.submitBtnLoading = false; | ||
| 304 | proxy.$ElMessage.error(res.msg); | ||
| 305 | } | ||
| 306 | }); | ||
| 307 | } else { | ||
| 308 | newCreateTaskDialogInfo.value.submitBtnLoading = true; | ||
| 309 | params.guid = currTableData.value.guid; | ||
| 310 | updateSensitiveDataTask(params).then((res: any) => { | ||
| 311 | if (res?.code == proxy.$passCode) { | ||
| 312 | proxy.$ElMessage.success('标签编辑成功'); | ||
| 313 | newCreateTaskDialogInfo.value.visible = false; | ||
| 314 | newCreateTaskDialogInfo.value.submitBtnLoading = false; | ||
| 315 | getTableData(); | ||
| 316 | } else { | ||
| 317 | newCreateTaskDialogInfo.value.submitBtnLoading = false; | ||
| 318 | proxy.$ElMessage.error(res.msg); | ||
| 319 | } | ||
| 320 | }); | ||
| 321 | } | ||
| 322 | } | ||
| 323 | } | ||
| 324 | }); | ||
| 325 | |||
| 326 | const handleTaskSelectChange = (val, row, item) => { | ||
| 327 | if (item.field == 'dataSource') { | ||
| 328 | newCreateTaskFormItems.value[0].default = row.taskName; | ||
| 329 | newCreateTaskFormItems.value[1].default = val; | ||
| 330 | newCreateTaskFormItems.value[2].default = row.dataSourceGuid || ''; | ||
| 331 | newCreateTaskFormItems.value[2].visible = val == 1; | ||
| 332 | newCreateTaskFormItems.value[3].default = row.file || []; | ||
| 333 | newCreateTaskFormItems.value[3].visible = val == 2; | ||
| 334 | } | ||
| 335 | } | ||
| 336 | |||
| 337 | const handleCreate = () => { | ||
| 338 | newCreateTaskDialogInfo.value.visible = true; | ||
| 339 | newCreateTaskDialogInfo.value.title = '添加数据敏感识别任务'; | ||
| 340 | newCreateTaskDialogInfo.value.type = 'add'; | ||
| 341 | newCreateTaskFormItems.value[0].default = ''; | ||
| 342 | newCreateTaskFormItems.value[1].default = 1; | ||
| 343 | newCreateTaskFormItems.value[2].default = ''; | ||
| 344 | newCreateTaskFormItems.value[2].visible = true; | ||
| 345 | newCreateTaskFormItems.value[3].default = []; | ||
| 346 | newCreateTaskFormItems.value[3].visible = false; | ||
| 347 | } | ||
| 348 | |||
| 349 | onBeforeMount(() => { | ||
| 350 | toSearch({}); | ||
| 351 | getDatabase({ connectStatus: 1 }).then((res: any) => { | ||
| 352 | if (res?.code == proxy.$passCode) { | ||
| 353 | dataSourceList.value = res.data || []; | ||
| 354 | newCreateTaskFormItems.value[2].options = dataSourceList.value; | ||
| 355 | } else { | ||
| 356 | proxy.$ElMessage({ | ||
| 357 | type: "error", | ||
| 358 | message: res.msg, | ||
| 359 | }); | ||
| 360 | } | ||
| 361 | }) | ||
| 362 | }) | ||
| 363 | |||
| 41 | </script> | 364 | </script> |
| 42 | 365 | ||
| 43 | <template> | 366 | <template> |
| 44 | <div class="container_wrap"> | 367 | <div class="container_wrap"> |
| 45 | <div class="table_tool_wrap"> | 368 | <div class="table_tool_wrap"> |
| 46 | <!-- 头部搜索 --> | 369 | <!-- 头部搜索 --> |
| 47 | <!-- <TableTools :searchItems="searchItemList" :searchId="'data-label-search'" @search="toSearch" :init="false" /> | 370 | <TableTools :searchItems="searchItemList" :searchId="'data-label-search'" @search="toSearch" :init="false" /> |
| 48 | <div class="tools_btns"> | 371 | <div class="tools_btns"> |
| 49 | <el-button type="primary" @click="handleCreate">新建</el-button> | 372 | <el-button type="primary" @click="handleCreate">新建</el-button> |
| 50 | </div> --> | 373 | </div> |
| 51 | </div> | 374 | </div> |
| 52 | <div class="table_panel_wrap"> | 375 | <div class="table_panel_wrap"> |
| 53 | <!-- 右侧标签管理表格 --> | 376 | <!-- 右侧标签管理表格 --> |
| 54 | <!-- <Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" /> --> | 377 | <Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" /> |
| 55 | </div> | 378 | </div> |
| 379 | <Dialog_form ref="dialogTaskFormRef" :dialogConfigInfo="newCreateTaskDialogInfo" | ||
| 380 | @formDialogSelectChange="handleTaskSelectChange"></Dialog_form> | ||
| 56 | </div> | 381 | </div> |
| 57 | </template> | 382 | </template> |
| 58 | 383 | ... | ... |
| 1 | <route lang="yaml"> | ||
| 2 | name: sensitiveIdentifyConfig | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="sensitiveIdentifyConfig"> | ||
| 6 | import { | ||
| 7 | getExecSensitiveTable, | ||
| 8 | getExecSensitiveFieldTable, | ||
| 9 | getExecSensitiveFieldLabel, | ||
| 10 | getDataLabelList, | ||
| 11 | getStatisticsNum, | ||
| 12 | getParamsList, | ||
| 13 | updateSensitiveDataTaskFieldLabel, | ||
| 14 | batchUpdateSensitiveDataTaskFieldStatus, | ||
| 15 | } from '@/api/modules/dataAnonymization'; | ||
| 16 | import PageNav from "@/components/PageNav/index.vue"; | ||
| 17 | import { commonPageConfig } from '@/components/PageNav/index'; | ||
| 18 | import { ElMessageBox } from 'element-plus'; | ||
| 19 | import { changeNum } from "@/utils/common"; | ||
| 20 | import BtnPopover from "@/components/Popover/index.vue"; | ||
| 21 | |||
| 22 | const route = useRoute(); | ||
| 23 | const { proxy } = getCurrentInstance() as any; | ||
| 24 | const isLook = ref(!!route.query.isLook); | ||
| 25 | |||
| 26 | const treeInfo = ref({ | ||
| 27 | id: "data-list-tree", | ||
| 28 | filter: true, | ||
| 29 | queryValue: "", | ||
| 30 | queryPlaceholder: "请输入关键字搜索", | ||
| 31 | props: { | ||
| 32 | label: "label", | ||
| 33 | value: "value", | ||
| 34 | isLeaf: "isLeaf", | ||
| 35 | children: 'tableList' | ||
| 36 | }, | ||
| 37 | nodeKey: 'value', | ||
| 38 | expandedKey: <any>[], | ||
| 39 | currentNodeKey: '', | ||
| 40 | data: [], | ||
| 41 | expandOnNodeClick: false, | ||
| 42 | loading: false, | ||
| 43 | currentObj: <any>{} | ||
| 44 | }); | ||
| 45 | |||
| 46 | const treeRef = ref(); | ||
| 47 | |||
| 48 | const nodeClick = (data, node) => { | ||
| 49 | let exec = () => { | ||
| 50 | pageInfo.value.labelGuids = []; | ||
| 51 | pageInfo.value.labelTypeCodes = []; | ||
| 52 | pageInfo.value.confirmStatus = ''; | ||
| 53 | treeInfo.value.currentNodeKey = data.value; | ||
| 54 | treeInfo.value.currentObj = data; | ||
| 55 | if (data.parent) { | ||
| 56 | pageInfo.value.databaseName = data.parent; | ||
| 57 | pageInfo.value.tableName = data.tableName; | ||
| 58 | } else { | ||
| 59 | pageInfo.value.databaseName = data.databaseName; | ||
| 60 | pageInfo.value.tableName = ''; | ||
| 61 | } | ||
| 62 | getSensitiveTableFieldData(); | ||
| 63 | getCntSumInfo(); | ||
| 64 | getSensitiveFieldLabelData(); | ||
| 65 | } | ||
| 66 | if (checkTableSave()) { | ||
| 67 | ElMessageBox.confirm( | ||
| 68 | '存在未保存的数据,切换后会丢失,是否确定切换', | ||
| 69 | '提示', | ||
| 70 | { | ||
| 71 | confirmButtonText: '确定', | ||
| 72 | cancelButtonText: '取消', | ||
| 73 | type: 'warning', | ||
| 74 | } | ||
| 75 | ).then(() => { | ||
| 76 | exec(); | ||
| 77 | }).catch(() => { | ||
| 78 | treeRef.value.setCurrentKey(treeInfo.value.currentObj.value); | ||
| 79 | }) | ||
| 80 | } else { | ||
| 81 | exec(); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | const batchConfirm = () => { | ||
| 86 | if (!selectTableFieldRows.value.length) { | ||
| 87 | proxy.$ElMessage.error('请先勾选待确认的字段'); | ||
| 88 | return; | ||
| 89 | } | ||
| 90 | batchUpdateSensitiveDataTaskFieldStatus(selectTableFieldRows.value.map(s => s.guid)).then((res: any) => { | ||
| 91 | if (res?.code == proxy.$passCode) { | ||
| 92 | proxy.$ElMessage.success('批量确认字段成功'); | ||
| 93 | getSensitiveTableFieldData(); | ||
| 94 | } else { | ||
| 95 | proxy.$ElMessage.error(res.msg); | ||
| 96 | } | ||
| 97 | }) | ||
| 98 | } | ||
| 99 | |||
| 100 | /** 数量统计信息 */ | ||
| 101 | const cntSumInfo: any = ref({}); | ||
| 102 | |||
| 103 | const getCntSumInfo = () => { | ||
| 104 | getStatisticsNum({ | ||
| 105 | execGuid: route.query.execGuid, | ||
| 106 | databaseName: pageInfo.value.databaseName, | ||
| 107 | tableName: pageInfo.value.tableName | ||
| 108 | }).then((res: any) => { | ||
| 109 | if (res?.code == proxy.$passCode) { | ||
| 110 | cntSumInfo.value = res.data || {}; | ||
| 111 | } else { | ||
| 112 | proxy.$ElMessage.error(res.msg); | ||
| 113 | } | ||
| 114 | }) | ||
| 115 | } | ||
| 116 | |||
| 117 | const getExecSensitiveTableData = () => { | ||
| 118 | treeInfo.value.loading = true; | ||
| 119 | getExecSensitiveTable(route.query.execGuid).then((res: any) => { | ||
| 120 | treeInfo.value.loading = false; | ||
| 121 | if (res?.code == proxy.$passCode) { | ||
| 122 | treeInfo.value.data = res.data?.map(d => { | ||
| 123 | d.value = d.databaseName; | ||
| 124 | d.label = d.databaseChName; | ||
| 125 | d.tableList = d.tableList?.map(t => { | ||
| 126 | t.value = t.tableName; | ||
| 127 | t.label = t.tableChName; | ||
| 128 | t.parent = d.databaseName; | ||
| 129 | return t; | ||
| 130 | }) || [] | ||
| 131 | return d; | ||
| 132 | }) || []; | ||
| 133 | let treeData: any = treeInfo.value.data || []; | ||
| 134 | if (treeData.length) { | ||
| 135 | treeInfo.value.expandedKey = [treeData[0].value]; | ||
| 136 | treeInfo.value.currentNodeKey = treeData[0]?.value; | ||
| 137 | treeInfo.value.currentObj = treeData[0]; | ||
| 138 | treeData[0].tableList?.[0] && nodeClick(treeData[0], {}); | ||
| 139 | } | ||
| 140 | } else { | ||
| 141 | proxy.$ElMessage.error(res.msg); | ||
| 142 | } | ||
| 143 | }) | ||
| 144 | } | ||
| 145 | |||
| 146 | /** 所有的标签列表供编辑下拉显示 */ | ||
| 147 | const allDataLabelList: any = ref([]); | ||
| 148 | |||
| 149 | onBeforeMount(() => { | ||
| 150 | getExecSensitiveTableData(); | ||
| 151 | getDataLabelList({ | ||
| 152 | pageSize: -1, | ||
| 153 | bizState: 'Y' | ||
| 154 | }).then((res: any) => { | ||
| 155 | if (res?.code == proxy.$passCode) { | ||
| 156 | allDataLabelList.value = res.data?.records || []; | ||
| 157 | } else { | ||
| 158 | proxy.$ElMessage.error(res.msg); | ||
| 159 | } | ||
| 160 | }) | ||
| 161 | getParamsList({ | ||
| 162 | dictType: "标签类型", | ||
| 163 | }).then((res: any) => { | ||
| 164 | if (res?.code == proxy.$passCode) { | ||
| 165 | labelTypeList.value = res.data?.map(d => { | ||
| 166 | d.guid = d.value; | ||
| 167 | return d; | ||
| 168 | }) || []; | ||
| 169 | } else { | ||
| 170 | proxy.$ElMessage.error(res.msg); | ||
| 171 | } | ||
| 172 | }); | ||
| 173 | }) | ||
| 174 | |||
| 175 | /** ------------------------- 敏感数据识别字段列表操作 --------------------------------- */ | ||
| 176 | |||
| 177 | const labelList = ref([]); | ||
| 178 | |||
| 179 | /** 标签类型的字典列表 */ | ||
| 180 | const labelTypeList: any = ref([]); | ||
| 181 | |||
| 182 | /** 分页设置 */ | ||
| 183 | const pageInfo = ref({ | ||
| 184 | ...commonPageConfig, | ||
| 185 | taskExecGuid: route.query.execGuid, | ||
| 186 | databaseName: '', | ||
| 187 | tableName: '', | ||
| 188 | rows: 0, | ||
| 189 | labelGuids: [], //列头筛选 | ||
| 190 | labelTypeCodes: [], | ||
| 191 | confirmStatus: '' | ||
| 192 | }); | ||
| 193 | |||
| 194 | /** 敏感数据 */ | ||
| 195 | const sensitiveTableData: any = ref([]); | ||
| 196 | |||
| 197 | const sensitiveTableDataLoading = ref(false); | ||
| 198 | |||
| 199 | const getSensitiveTableFieldData = () => { | ||
| 200 | sensitiveTableDataLoading.value = true; | ||
| 201 | let confirmStatus: any = []; | ||
| 202 | getExecSensitiveFieldTable({ | ||
| 203 | pageIndex: pageInfo.value.curr, | ||
| 204 | pageSize: pageInfo.value.limit, | ||
| 205 | taskExecGuid: pageInfo.value.taskExecGuid, | ||
| 206 | databaseName: pageInfo.value.databaseName, | ||
| 207 | tableName: pageInfo.value.tableName, | ||
| 208 | labelGuids: pageInfo.value.labelGuids, | ||
| 209 | labelTypeCodes: pageInfo.value.labelTypeCodes, | ||
| 210 | confirmStatus: confirmStatus?.length > 1 ? null : confirmStatus[0] | ||
| 211 | }).then((res: any) => { | ||
| 212 | sensitiveTableDataLoading.value = false; | ||
| 213 | if (res?.code == proxy.$passCode) { | ||
| 214 | const data = res.data || {}; | ||
| 215 | sensitiveTableData.value = data.records || []; | ||
| 216 | pageInfo.value.limit = data.pageSize | ||
| 217 | pageInfo.value.curr = data.pageIndex | ||
| 218 | pageInfo.value.rows = data.totalRows | ||
| 219 | } else { | ||
| 220 | proxy.$ElMessage({ | ||
| 221 | type: 'error', | ||
| 222 | message: res.msg, | ||
| 223 | }) | ||
| 224 | } | ||
| 225 | }) | ||
| 226 | } | ||
| 227 | |||
| 228 | /** 获取当前选中的左侧库表下对应的数据标签数组,做列头筛选时使用。 */ | ||
| 229 | const getSensitiveFieldLabelData = () => { | ||
| 230 | getExecSensitiveFieldLabel({ | ||
| 231 | pageSize: -1, | ||
| 232 | taskExecGuid: pageInfo.value.taskExecGuid, | ||
| 233 | databaseName: pageInfo.value.databaseName, | ||
| 234 | tableName: pageInfo.value.tableName | ||
| 235 | }).then((res: any) => { | ||
| 236 | if (res?.code == proxy.$passCode) { | ||
| 237 | labelList.value = res.data?.map(d => { | ||
| 238 | d.guid = d.labelGuid; | ||
| 239 | return d; | ||
| 240 | }) || []; | ||
| 241 | } else { | ||
| 242 | proxy.$ElMessage({ | ||
| 243 | type: 'error', | ||
| 244 | message: res.msg, | ||
| 245 | }) | ||
| 246 | } | ||
| 247 | }) | ||
| 248 | } | ||
| 249 | |||
| 250 | const popoverLabelListInfo = computed(() => { | ||
| 251 | return { | ||
| 252 | type: 'checkbox-list-btns', | ||
| 253 | data: labelList.value, | ||
| 254 | placeholder: '请输入关键字搜索', | ||
| 255 | scope: { | ||
| 256 | row: {} | ||
| 257 | }, | ||
| 258 | placement: 'right-start', | ||
| 259 | props: { | ||
| 260 | value: 'guid', | ||
| 261 | label: 'labelName' | ||
| 262 | }, | ||
| 263 | checked: pageInfo.value.labelGuids, | ||
| 264 | btn: { | ||
| 265 | value: 'filter' | ||
| 266 | } | ||
| 267 | } | ||
| 268 | }); | ||
| 269 | |||
| 270 | const handleLabelPopoverClick = (scope) => { | ||
| 271 | if (checkTableSave()) { | ||
| 272 | ElMessageBox.confirm( | ||
| 273 | '存在未保存的数据,切换后会丢失,是否确定切换', | ||
| 274 | '提示', | ||
| 275 | { | ||
| 276 | confirmButtonText: '确定', | ||
| 277 | cancelButtonText: '取消', | ||
| 278 | type: 'warning', | ||
| 279 | } | ||
| 280 | ).then(() => { | ||
| 281 | pageInfo.value.labelGuids = scope.row.selectedData || []; | ||
| 282 | pageInfo.value.curr = 1; | ||
| 283 | getSensitiveTableFieldData(); | ||
| 284 | }) | ||
| 285 | } else { | ||
| 286 | pageInfo.value.labelGuids = scope.row.selectedData || []; | ||
| 287 | pageInfo.value.curr = 1; | ||
| 288 | getSensitiveTableFieldData(); | ||
| 289 | } | ||
| 290 | } | ||
| 291 | |||
| 292 | const popoverLabelTypeListInfo = computed(() => { | ||
| 293 | return { | ||
| 294 | type: 'checkbox-list-btns', | ||
| 295 | data: labelTypeList.value, | ||
| 296 | placeholder: '请输入关键字搜索', | ||
| 297 | scope: { | ||
| 298 | row: {} | ||
| 299 | }, | ||
| 300 | placement: 'right-start', | ||
| 301 | props: { | ||
| 302 | value: 'guid', | ||
| 303 | label: 'label' | ||
| 304 | }, | ||
| 305 | checked: pageInfo.value.labelTypeCodes, | ||
| 306 | btn: { | ||
| 307 | value: 'filter' | ||
| 308 | } | ||
| 309 | } | ||
| 310 | }); | ||
| 311 | |||
| 312 | const handleLabelTypePopoverClick = (scope) => { | ||
| 313 | if (checkTableSave()) { | ||
| 314 | ElMessageBox.confirm( | ||
| 315 | '存在未保存的数据,切换后会丢失,是否确定切换', | ||
| 316 | '提示', | ||
| 317 | { | ||
| 318 | confirmButtonText: '确定', | ||
| 319 | cancelButtonText: '取消', | ||
| 320 | type: 'warning', | ||
| 321 | } | ||
| 322 | ).then(() => { | ||
| 323 | pageInfo.value.labelTypeCodes = scope.row.selectedData || []; | ||
| 324 | pageInfo.value.curr = 1; | ||
| 325 | getSensitiveTableFieldData(); | ||
| 326 | }) | ||
| 327 | } else { | ||
| 328 | pageInfo.value.labelTypeCodes = scope.row.selectedData || []; | ||
| 329 | pageInfo.value.curr = 1; | ||
| 330 | getSensitiveTableFieldData(); | ||
| 331 | } | ||
| 332 | } | ||
| 333 | |||
| 334 | const popoverStatusListInfo = computed(() => { | ||
| 335 | return { | ||
| 336 | type: 'checkbox-list-btns', | ||
| 337 | data: [{ | ||
| 338 | guid: 'N', | ||
| 339 | label: '待确认' | ||
| 340 | }, { | ||
| 341 | guid: 'Y', | ||
| 342 | label: '已确认' | ||
| 343 | }], | ||
| 344 | placeholder: '请输入关键字搜索', | ||
| 345 | scope: { | ||
| 346 | row: {} | ||
| 347 | }, | ||
| 348 | placement: 'right-start', | ||
| 349 | props: { | ||
| 350 | value: 'guid', | ||
| 351 | label: 'label' | ||
| 352 | }, | ||
| 353 | checked: pageInfo.value.confirmStatus, | ||
| 354 | btn: { | ||
| 355 | value: 'filter' | ||
| 356 | } | ||
| 357 | } | ||
| 358 | }); | ||
| 359 | |||
| 360 | const handleStatusPopoverClick = (scope) => { | ||
| 361 | if (checkTableSave()) { | ||
| 362 | ElMessageBox.confirm( | ||
| 363 | '存在未保存的数据,切换后会丢失,是否确定切换', | ||
| 364 | '提示', | ||
| 365 | { | ||
| 366 | confirmButtonText: '确定', | ||
| 367 | cancelButtonText: '取消', | ||
| 368 | type: 'warning', | ||
| 369 | } | ||
| 370 | ).then(() => { | ||
| 371 | pageInfo.value.confirmStatus = scope.row.selectedData || []; | ||
| 372 | pageInfo.value.curr = 1; | ||
| 373 | getSensitiveTableFieldData(); | ||
| 374 | }) | ||
| 375 | } else { | ||
| 376 | pageInfo.value.confirmStatus = scope.row.selectedData || []; | ||
| 377 | pageInfo.value.curr = 1; | ||
| 378 | getSensitiveTableFieldData(); | ||
| 379 | } | ||
| 380 | } | ||
| 381 | |||
| 382 | /** 标签选择的值改变,标签类型跟着变化。 */ | ||
| 383 | const handleSelectChange = (val) => { | ||
| 384 | //暂时不处理,因为未保存会出现清空的场景,需要先存下之前的值。 | ||
| 385 | } | ||
| 386 | |||
| 387 | const sensitiveTableSelectable = (row, index) => { | ||
| 388 | return row.confirmStatus == 'N'; | ||
| 389 | } | ||
| 390 | |||
| 391 | const selectTableFieldRows: any = ref([]); | ||
| 392 | |||
| 393 | /** 勾选字段标准选中变化。 */ | ||
| 394 | const selectionDataChange = (val) => { | ||
| 395 | selectTableFieldRows.value = val; | ||
| 396 | }; | ||
| 397 | |||
| 398 | const handleFieldClickEdit = (scope) => { | ||
| 399 | scope.row.isEdit = true; | ||
| 400 | } | ||
| 401 | |||
| 402 | const handleFieldClickSave = (scope) => { | ||
| 403 | let labelName = ''; | ||
| 404 | let labelTypeCode = ''; | ||
| 405 | if (scope.row.labelGuid) { | ||
| 406 | let label = allDataLabelList.value.find(label => label.guid == scope.row.labelGuid); | ||
| 407 | if (label) { | ||
| 408 | labelName = label.labelName; | ||
| 409 | labelTypeCode = label.labelTypeCode; | ||
| 410 | } | ||
| 411 | } | ||
| 412 | sensitiveTableDataLoading.value = true; | ||
| 413 | updateSensitiveDataTaskFieldLabel([{ | ||
| 414 | guid: scope.row.guid, | ||
| 415 | labelGuid: scope.row.labelGuid, | ||
| 416 | labelName: labelName, | ||
| 417 | labelTypeCode: labelTypeCode | ||
| 418 | }]).then((res: any) => { | ||
| 419 | sensitiveTableDataLoading.value = false; | ||
| 420 | if (res?.code == proxy.$passCode) { | ||
| 421 | getSensitiveTableFieldData(); | ||
| 422 | getSensitiveFieldLabelData(); | ||
| 423 | getCntSumInfo(); | ||
| 424 | proxy.$ElMessage.success('标签修改成功'); | ||
| 425 | } else { | ||
| 426 | proxy.$ElMessage.error(res.msg); | ||
| 427 | } | ||
| 428 | }); | ||
| 429 | } | ||
| 430 | |||
| 431 | const checkTableSave = () => { | ||
| 432 | return sensitiveTableData.value.some(s => s.isEdit == true); | ||
| 433 | } | ||
| 434 | |||
| 435 | const pageChange = (info) => { | ||
| 436 | const toChange = checkTableSave() | ||
| 437 | const changeCont = () => { | ||
| 438 | pageInfo.value.curr = Number(info.curr) | ||
| 439 | pageInfo.value.limit = Number(info.limit) | ||
| 440 | getSensitiveTableFieldData(); | ||
| 441 | } | ||
| 442 | if (toChange) { | ||
| 443 | ElMessageBox.confirm( | ||
| 444 | '存在未保存的数据,切换后会丢失,是否确定切换', | ||
| 445 | '提示', | ||
| 446 | { | ||
| 447 | confirmButtonText: '确定', | ||
| 448 | cancelButtonText: '取消', | ||
| 449 | type: 'warning', | ||
| 450 | } | ||
| 451 | ).then(() => { | ||
| 452 | changeCont(); | ||
| 453 | }) | ||
| 454 | } else { | ||
| 455 | changeCont(); | ||
| 456 | } | ||
| 457 | } | ||
| 458 | |||
| 459 | </script> | ||
| 460 | |||
| 461 | <template> | ||
| 462 | <div class="container_wrap full flex"> | ||
| 463 | <div class="aside_wrap"> | ||
| 464 | <div class="aside_title">数据表列表</div> | ||
| 465 | <Tree ref="treeRef" :treeInfo="treeInfo" @nodeClick="nodeClick" /> | ||
| 466 | </div> | ||
| 467 | <div class="main_wrap"> | ||
| 468 | <div class="table_tool_wrap"> | ||
| 469 | <div class="tools_btns"> | ||
| 470 | <el-button v-if="!isLook" type="primary" @click="batchConfirm">批量确认</el-button> | ||
| 471 | <div class="cnt-desc">{{ '表总数:' + changeNum(cntSumInfo.tableNum || 0, 0) + '张 敏感表总数:' + | ||
| 472 | changeNum(cntSumInfo.sensitiveTableNum || 0, 0) + '张 字段总数:' | ||
| 473 | + changeNum(cntSumInfo.fieldNum || 0, 0) + '个 敏感字段总数:' + changeNum(cntSumInfo.sensitiveFieldNum || 0, 0) + | ||
| 474 | '个,其中直接标识:' + | ||
| 475 | changeNum(cntSumInfo.directIdentifierNum || 0, 0) + '个 准标识:' + changeNum(cntSumInfo.standardIdentifierNum || | ||
| 476 | 0, 0) + '个 敏感:' + | ||
| 477 | changeNum(cntSumInfo.sensitiveNum || 0, 0) + '个 非敏感:' + changeNum(cntSumInfo.nonSensitiveNum || 0, 0) + '个' | ||
| 478 | }}</div> | ||
| 479 | </div> | ||
| 480 | </div> | ||
| 481 | <div class="table_panel_wrap"> | ||
| 482 | <!-- 右侧表字段标签匹配管理表格 --> | ||
| 483 | <el-table ref="sensitiveTableRef" :data="sensitiveTableData" v-loading="sensitiveTableDataLoading" | ||
| 484 | :highlight-current-row="true" stripe border height="100%" row-key="guid" | ||
| 485 | @selection-change="selectionDataChange" tooltip-effect="light" :style="{ | ||
| 486 | width: '100%', | ||
| 487 | 'max-height': 'calc(100% - 16px)', | ||
| 488 | display: 'inline-block', | ||
| 489 | }"> | ||
| 490 | <el-table-column type="selection" v-if="!isLook" :selectable="sensitiveTableSelectable" :width="32" align="center" /> | ||
| 491 | <el-table-column label="序号" type="index" width="56px" align="center" show-overflow-tooltip> | ||
| 492 | </el-table-column> | ||
| 493 | <el-table-column label="字段中文名" prop="fieldChName" width="140" align="left" show-overflow-tooltip> | ||
| 494 | <template #default="scope"> | ||
| 495 | <span>{{ scope.row.fieldChName || '--' }}</span> | ||
| 496 | </template> | ||
| 497 | </el-table-column> | ||
| 498 | <el-table-column label="字段英文名" prop="fieldName" width="140" align="left" show-overflow-tooltip> | ||
| 499 | <template #default="scope"> | ||
| 500 | <span>{{ scope.row.fieldName || '--' }}</span> | ||
| 501 | </template> | ||
| 502 | </el-table-column> | ||
| 503 | <el-table-column label="标签" prop="labelGuid" class-name="filter-cell" width="140" align="left" | ||
| 504 | show-overflow-tooltip> | ||
| 505 | <template #header> | ||
| 506 | <span>标签</span> | ||
| 507 | <BtnPopover v-if="labelList.length" :popoverInfo="popoverLabelListInfo" | ||
| 508 | @popverBtnClick="handleLabelPopoverClick" /> | ||
| 509 | </template> | ||
| 510 | <template #default="scope"> | ||
| 511 | <el-select-v2 v-if="scope.row['isEdit']" v-model="scope.row['labelGuid']" filterable | ||
| 512 | :options="allDataLabelList" placeholder="请选择" clearable :props="{ value: 'guid', label: 'labelName' }" | ||
| 513 | @change="handleSelectChange" /> | ||
| 514 | <span v-else>{{ scope.row["labelName"] || '--' }}</span> | ||
| 515 | </template> | ||
| 516 | </el-table-column> | ||
| 517 | <el-table-column label="标签类型" prop="labelTypeName" class-name="filter-cell" width="120" align="left" | ||
| 518 | show-overflow-tooltip> | ||
| 519 | <template #header> | ||
| 520 | <span>标签类型</span> | ||
| 521 | <BtnPopover v-if="labelTypeList.length" :popoverInfo="popoverLabelTypeListInfo" | ||
| 522 | @popverBtnClick="handleLabelTypePopoverClick" /> | ||
| 523 | </template> | ||
| 524 | <template #default="scope"> | ||
| 525 | <span>{{ scope.row.labelTypeName || '--' }}</span> | ||
| 526 | </template> | ||
| 527 | </el-table-column> | ||
| 528 | <el-table-column label="所属表名" prop="tableChName" width="140" align="left" show-overflow-tooltip> | ||
| 529 | </el-table-column> | ||
| 530 | <el-table-column label="确认状态" prop="confirmStatus" class-name="filter-cell" width="120" align="center" | ||
| 531 | show-overflow-tooltip> | ||
| 532 | <template #header> | ||
| 533 | <span>确认状态</span> | ||
| 534 | <BtnPopover :popoverInfo="popoverStatusListInfo" @popverBtnClick="handleStatusPopoverClick" /> | ||
| 535 | </template> | ||
| 536 | <template #default="scope"> | ||
| 537 | <el-tag v-if="scope.row.confirmStatus != null" | ||
| 538 | :type="scope.row.confirmStatus == 'Y' ? 'success' : 'warning'">{{ | ||
| 539 | scope.row.confirmStatus == 'Y' ? '已确认' : '未确认' | ||
| 540 | }}</el-tag> | ||
| 541 | <span v-else>{{ '--' }}</span> | ||
| 542 | </template> | ||
| 543 | </el-table-column> | ||
| 544 | <el-table-column v-if="!isLook" label="操作" width="100px" align="left" fixed="right" show-overflow-tooltip> | ||
| 545 | <template #default="scope"> | ||
| 546 | <span class="text_btn" v-if="!scope.row['isEdit']" @click="handleFieldClickEdit(scope)" | ||
| 547 | v-preReClick>编辑</span> | ||
| 548 | <span class="text_btn" v-else @click="handleFieldClickSave(scope)" v-preReClick>保存</span> | ||
| 549 | </template> | ||
| 550 | </el-table-column> | ||
| 551 | </el-table> | ||
| 552 | <PageNav :pageInfo="pageInfo" @pageChange="pageChange" /> | ||
| 553 | </div> | ||
| 554 | </div> | ||
| 555 | </div> | ||
| 556 | </template> | ||
| 557 | |||
| 558 | <style lang="scss" scoped> | ||
| 559 | .container_wrap { | ||
| 560 | .aside_wrap { | ||
| 561 | width: 200px; | ||
| 562 | } | ||
| 563 | |||
| 564 | .table_tool_wrap { | ||
| 565 | display: flex; | ||
| 566 | } | ||
| 567 | |||
| 568 | .table_panel_wrap { | ||
| 569 | height: calc(100% - 70px); | ||
| 570 | } | ||
| 571 | } | ||
| 572 | |||
| 573 | .tree_panel { | ||
| 574 | height: 100%; | ||
| 575 | padding-top: 0; | ||
| 576 | |||
| 577 | :deep(.el-tree) { | ||
| 578 | margin: 0; | ||
| 579 | height: calc(100% - 68px); | ||
| 580 | overflow: hidden auto; | ||
| 581 | } | ||
| 582 | } | ||
| 583 | |||
| 584 | :deep(.el-table) { | ||
| 585 | & td.el-table__cell { | ||
| 586 | .cell { | ||
| 587 | padding: 0px 10px; | ||
| 588 | } | ||
| 589 | |||
| 590 | padding: 2px 0px; | ||
| 591 | height: 36px; | ||
| 592 | } | ||
| 593 | } | ||
| 594 | |||
| 595 | .tools_btns { | ||
| 596 | display: flex; | ||
| 597 | align-items: center; | ||
| 598 | |||
| 599 | .el-button { | ||
| 600 | margin-right: 8px; | ||
| 601 | } | ||
| 602 | } | ||
| 603 | |||
| 604 | :deep(.filter-cell) { | ||
| 605 | .cell { | ||
| 606 | position: relative; | ||
| 607 | |||
| 608 | .el-icon.filter-icon { | ||
| 609 | position: absolute; | ||
| 610 | right: 6px; | ||
| 611 | top: 2px; | ||
| 612 | width: 18px; | ||
| 613 | height: 18px; | ||
| 614 | |||
| 615 | svg { | ||
| 616 | width: 18px; | ||
| 617 | height: 18px; | ||
| 618 | } | ||
| 619 | } | ||
| 620 | } | ||
| 621 | } | ||
| 622 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | <route lang="yaml"> | ||
| 2 | name: sensitiveIdentifyTaskExecLog | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="sensitiveIdentifyTaskExecLog"> | ||
| 6 | import { ref } from "vue"; | ||
| 7 | import { useRouter, useRoute } from "vue-router"; | ||
| 8 | import Table from "@/components/Table/index.vue"; | ||
| 9 | import { ElMessage } from "element-plus"; | ||
| 10 | import { commonPageConfig } from '@/components/PageNav/index'; | ||
| 11 | import { | ||
| 12 | getSensitiveDataTaskExecLog, | ||
| 13 | } from '@/api/modules/dataAnonymization'; | ||
| 14 | |||
| 15 | |||
| 16 | const { proxy } = getCurrentInstance() as any; | ||
| 17 | |||
| 18 | const router = useRouter(); | ||
| 19 | const route = useRoute(); | ||
| 20 | const guid = route.query.guid; | ||
| 21 | const wordName = route.query.name | ||
| 22 | |||
| 23 | const page = ref({ | ||
| 24 | ...commonPageConfig | ||
| 25 | }); | ||
| 26 | |||
| 27 | const tableInfo = ref({ | ||
| 28 | id: "word-log-table", | ||
| 29 | loading: false, | ||
| 30 | fields: [ | ||
| 31 | { label: "报告名称", field: "analysisReportName", width: 230 }, | ||
| 32 | { | ||
| 33 | label: "方案类型", field: "analysisReportType", width: 100, getName: (scope) => { | ||
| 34 | let planType = scope.row.analysisReportType; | ||
| 35 | return planType == 1 ? '表' : (planType == 2 ? '数据库' : (planType == 4 ? '数据同步' : '分组')); | ||
| 36 | } | ||
| 37 | }, | ||
| 38 | { label: "报告对象", field: "qualityModelName", width: 180, }, | ||
| 39 | { label: "质量评分", field: "qualityScore", width: 100, align: "right" }, | ||
| 40 | { label: "最后执行时间", field: "execTime", width: 180, }, | ||
| 41 | { label: "执行状态", field: "execResult", type: "tag", width: 120, align: "center" }, | ||
| 42 | ], | ||
| 43 | data: [], | ||
| 44 | page: { | ||
| 45 | type: "normal", | ||
| 46 | rows: 0, | ||
| 47 | ...page.value, | ||
| 48 | }, | ||
| 49 | actionInfo: { | ||
| 50 | label: "操作", | ||
| 51 | type: "btn", | ||
| 52 | width: 100, | ||
| 53 | fixed: 'right', | ||
| 54 | btns: (scope) => { | ||
| 55 | return [{ label: "查看报告", value: "reportView", disabled: scope.row['execResult'] != 'Y' }]; | ||
| 56 | } | ||
| 57 | } | ||
| 58 | }); | ||
| 59 | |||
| 60 | const getTableData = () => { | ||
| 61 | tableInfo.value.loading = true; | ||
| 62 | getSensitiveDataTaskExecLog({ pageIndex: page.value.curr, pageSize: page.value.limit, taskGuid: guid }).then((res: any) => { | ||
| 63 | tableInfo.value.loading = false; | ||
| 64 | if (res?.code == proxy.$passCode) { | ||
| 65 | const data = res.data || {} | ||
| 66 | tableInfo.value.data = data.records || [] | ||
| 67 | tableInfo.value.page.limit = data.pageSize | ||
| 68 | tableInfo.value.page.curr = data.pageIndex | ||
| 69 | tableInfo.value.page.rows = data.totalRows | ||
| 70 | } else { | ||
| 71 | ElMessage.error(res.msg); | ||
| 72 | } | ||
| 73 | }) | ||
| 74 | }; | ||
| 75 | |||
| 76 | const tableBtnClick = (scope, btn) => { | ||
| 77 | const type = btn.value; | ||
| 78 | const row = scope.row; | ||
| 79 | if (type == 'reportView') { | ||
| 80 | router.push({ | ||
| 81 | name: 'analysisReport', | ||
| 82 | query: { | ||
| 83 | planGuid: row.planGuid, | ||
| 84 | reportExecGuid: row.guid, | ||
| 85 | name: wordName | ||
| 86 | } | ||
| 87 | }); | ||
| 88 | } | ||
| 89 | }; | ||
| 90 | |||
| 91 | onBeforeMount(() => { | ||
| 92 | getTableData(); | ||
| 93 | }); | ||
| 94 | |||
| 95 | </script> | ||
| 96 | |||
| 97 | <template> | ||
| 98 | <div class="container_wrap"> | ||
| 99 | <div class="table_panel_wrap"> | ||
| 100 | <Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" /> | ||
| 101 | </div> | ||
| 102 | </div> | ||
| 103 | </template> | ||
| 104 | |||
| 105 | <style lang="scss" scoped> | ||
| 106 | .container_wrap { | ||
| 107 | padding: 0; | ||
| 108 | |||
| 109 | .table_panel_wrap { | ||
| 110 | height: 100%; | ||
| 111 | padding: 16px 16px 0; | ||
| 112 | } | ||
| 113 | } | ||
| 114 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or sign in to post a comment