1416702f by lihua

迁移数据匿名化代码

1 parent bb72749e
......@@ -3,6 +3,51 @@
*/
import request from "@/utils/request";
/** 获取标签列表。 */
export const getDataLabelList = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/label/page-list`,
method: 'post',
data: params
})
/** 修改标签启用禁用状态 */
export const updateLabelState = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/label/update-state`,
method: 'put',
params
})
export const saveLabel = (data) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/label/save`,
method: 'post',
data
})
export const deleteLabel = (data) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/label/delete`,
method: 'delete',
data
})
export const updateLabel = (data) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/label/update`,
method: 'put',
data
})
/** 获取标签详情 */
export const getLabelDetail = (guid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/label/detail?guid=${guid}`,
method: 'get'
})
/** 获取数据字典配置 */
export const getParamsList = (params) => request({
url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-by-dictType`,
method: 'get',
params
})
/** 字段类型 */
export const fieldTypeList = [{
value: '1',
......@@ -58,4 +103,241 @@ export const parseGeneralizeFileData = (data) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/generalize-file/parse-file`,
method: 'post',
data
})
/** --------- 敏感数据识别接口 ------------------- */
/** 获取敏感数据识别任务列表 */
export const getSensitiveDataTaskList = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/sensitive-data-task/page-list`,
method: 'post',
data: params
})
/** 新增敏感数据识别任务 */
export const saveSensitiveDataTask = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/sensitive-data-task/save`,
method: 'post',
data: params
})
/** 编辑修改敏感数据识别任务 */
export const updateSensitiveDataTask = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/sensitive-data-task/update`,
method: 'put',
data: params
})
/** 删除敏感数据识别任务 */
export const deleteSensitiveDataTask = (data) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/sensitive-data-task/delete`,
method: 'delete',
data
})
/** 手动执行敏感任务 */
export const execSensitiveDataTask = (guid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/sensitive-data-task/exec-task?taskGuid=${guid}`,
method: 'get'
})
/** 数据来源类型 */
export const dataSourceTypeList = [{
value: 1,
label: '数据库'
}, {
value: 2,
label: '文件导入'
}];
/** 获取数据库选择列表 */
export const getDatabase = (params) => request({
url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/get-source-list`,
method: 'post',
data: params
})
/** 获取敏感数据任务执行的数据表列表 */
export const getExecSensitiveTable = (execGuid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/sensitive-data-task/get-exec-sensitive-table?execGuid=${execGuid}`,
method: 'get'
})
/** 根据数据源或表获取敏感数据任务执行的字段列表 */
export const getExecSensitiveFieldTable = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/sensitive-data-task/get-exec-sensitive-field`,
method: 'post',
data: params
})
/** 获取当前数据表下的执行字段 */
export const getExecSensitiveFieldColumnListByCondition = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/sensitive-data-task/column-list-by-condition`,
method: 'post',
data: params
})
/** 获取敏感数据识别任务执行后的统计结果 */
export const getStatisticsNum = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/sensitive-data-task/statistics-num`,
method: 'get',
params
})
/** 修改敏感数据识别字段标签 */
export const updateSensitiveDataTaskFieldLabel = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/sensitive-data-task/batch-update-label`,
method: 'put',
data: params
})
/** 批量修改确认状态 */
export const batchUpdateSensitiveDataTaskFieldStatus = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/sensitive-data-task/batch-change-status`,
method: 'post',
data: params
})
/** 修改任务状态 */
export const confirmTaskStatus = (guid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/sensitive-data-task/confirm-task?execGuid=${guid}`,
method: 'get'
})
/** 获取敏感数据识别任务执行日志 */
export const getSensitiveDataTaskExecLog = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/sensitive-data-task/get-exec-sensitive-exec-log`,
method: 'post',
data: params
})
/** ---------- 匿名化处理 ------------------ */
/** 获取匿名化任务列表 */
export const getAnonTaskList = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/page-list`,
method: 'post',
data: params
})
/** 删除匿名化任务 */
export const deleteAnonTask = (data) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/delete`,
method: 'delete',
data
})
/** 保存匿名化任务 */
export const saveAnonTask = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/save`,
method: 'post',
data: params
})
/** 更新匿名化任务 */
export const updateAnonTask = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/update`,
method: 'put',
data: params
})
/** 获取匿名化任务详情 */
export const getAnonTaskDetail = (guid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/detail?guid=${guid}`,
method: 'get'
})
/** 执行匿名化任务 */
export const execAnonTask = (taskGuid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/exec-task?taskGuid=${taskGuid}`,
method: 'post'
})
/** 匿名化任务检验接口 */
export const anonTaskCheck = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/check`,
method: 'post',
data: params
})
/** 获取匿名化任务分析结果数据 */
export const getAnonAnalyzeResult = (execGuid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/get-anon-analyze?taskExecGuid=${execGuid}`,
method: 'get'
})
/** 获取匿名化任务分析结果数据 */
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'
})
/** 获取匿名化任务分析结果统计分页数据 */
export const getAnonAnalyzePageData = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/page-anon-analyze-data`,
method: 'post',
data: params
})
/** 获取匿名化任务结果数据 */
export const getAnonPageData = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/page-anon-data`,
method: 'post',
data: params
})
/** 字段中文转英文 */
export const chTransformEn =(params)=> request({
url: `${import.meta.env.VITE_APP_COMMON_URL}/common/convert-field-ch-name`,
method: "post",
data: params,
});
/** 根据选择的连接池获取表列表 */
export const getDsTableByDs = (params) => request({
url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/schema-table-page-list`,
method: 'post',
data: params
})
/** 根据数据表获取表字段结构 */
export const getDsTableFieldColumn = (params) => request({
url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/table-column-list`,
method: 'post',
data: params
});
/** 根据数据表获取表数据 */
export const getDsTableSampleData = (params) => request({
url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/table-data-preview-page`,
method: 'post',
data: params
});
/** 根据字段名称获取敏感数据识别标签 */
export const getLableByFieldName = (fieldName) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/sensitive-data-task/get-label-by-field-name?fieldName=${fieldName}`,
method: 'get'
});
/** 验证样本数据 */
export const validateAnonRule = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/check`,
method: 'post',
data: params
})
/** 导出匿名化结果数据 */
export const exportAnonExecData = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/export-anon-data?taskGuid=${params.taskGuid}&taskExecGuid=${params.execGuid}`,
method: 'get',
responseType: 'blob'
})
/** 下载匿名化评估报告 */
export const exportAnonReport = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/download-report?taskGuid=${params.taskGuid}&taskExecGuid=${params.execGuid}`,
method: 'post',
responseType: 'blob'
})
\ No newline at end of file
......
import type { RouteRecordRaw } from 'vue-router'
function Layout() {
return import('@/layouts/index.vue')
}
const routes: RouteRecordRaw[] = [
{
path: '/data-anonymization/label-management',
component: Layout,
meta: {
title: '标签管理',
icon: 'sidebar-videos',
},
children: [
{
path: '',
name: 'labelManagement',
component: () => import('@/views/data_anonymization/labelManagement.vue'),
meta: {
title: '标签管理',
sidebar: false,
breadcrumb: false,
cache: true
},
}
],
},
{
path: '/data-anonymization/generalize-file',
component: Layout,
meta: {
title: '泛化文件管理',
icon: 'sidebar-videos',
},
children: [
{
path: '',
name: 'generalizeFile',
component: () => import('@/views/data_anonymization/generalizeFile.vue'),
meta: {
title: '泛化文件管理',
sidebar: false,
breadcrumb: false,
cache: true
},
},
{
path: 'generalize-file-edit',
name: 'generalizeFileEdit',
component: () => import('@/views/data_anonymization/generalizeFileEdit.vue'),
meta: {
title: '新建泛化文件',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true,
editPage: true,
activeMenu: '/data-anonymization/generalize-file'
},
beforeEnter: (to, from) => {
if (to.query.fileName) {
to.meta.title = `编辑-${to.query.fileName}`;
}
}
},
],
},
{
path: '/data-anonymization/sensitive-identify',
component: Layout,
meta: {
title: '敏感数据识别',
icon: 'sidebar-videos',
},
children: [
{
path: '',
name: 'sensitiveIdentify',
component: () => import('@/views/data_anonymization/sensitiveIdentify.vue'),
meta: {
title: '敏感数据识别',
sidebar: false,
breadcrumb: false,
cache: true
},
},
{
path: 'sensitive-identify-config',
name: 'sensitiveIdentifyConfig',
component: () => import('@/views/data_anonymization/sensitiveIdentifyConfig.vue'),
meta: {
title: '敏感数据识别查看',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true,
editPage: false,
activeMenu: '/data-anonymization/sensitive-identify'
},
beforeEnter: (to, from) => {
if (to.query.taskName) {
to.meta.title = `敏感数据${to.query.isLook == '1' ? '日志查看' : '查看'}-${to.query.taskName}`;
}
}
},
{
path: 'sensitive-identify-task-exec-log',
name: 'sensitiveIdentifyTaskExecLog',
component: () => import('@/views/data_anonymization/sensitiveIdentifyTaskExecLog.vue'),
meta: {
title: '执行日志',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true
},
beforeEnter: (to, from) => {
if (to.query.guid) {
to.meta.title = `日志-${to.query.name}`;
}
}
}
],
},
{
path: '/data-anonymization/result-process',
component: Layout,
meta: {
title: '匿名化处理',
icon: 'sidebar-videos',
},
children: [
{
path: '',
name: 'resultProcess',
component: () => import('@/views/data_anonymization/resultProcess.vue'),
meta: {
title: '匿名化处理',
sidebar: false,
breadcrumb: false,
cache: true
},
},
{
path: 'anon-task-create',
name: 'anonTaskCreate',
component: () => import('@/views/data_anonymization/anonTaskCreate.vue'),
meta: {
title: '匿名化处理任务',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true,
editPage: true,
activeMenu: '/data-anonymization/result-process'
},
beforeEnter: (to, from) => {
if (to.query.taskName) {
to.meta.title = `编辑-${to.query.taskName}`;
}
}
},
{
path: 'anonResultView',
name: 'anonResultView',
component: () => import('@/views/data_anonymization/anonResultView.vue'),
meta: {
title: '查看数据',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true
},
beforeEnter: (to, from) => {
if (to.query.guid) {
to.meta.title = `查看数据-${to.query.taskName}`;
}
}
},
{
path: 'anonResultReportView',
name: 'anonResultReportView',
component: () => import('@/views/data_anonymization/anonResultReportView.vue'),
meta: {
title: '查看报告',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true
},
beforeEnter: (to, from) => {
if (to.query.guid) {
to.meta.title = `查看报告-${to.query.taskName}`;
}
}
},
],
},
]
export default routes
......@@ -216,47 +216,7 @@ const routes: RouteRecordRaw[] = [
editPage: true
},
}]
},
{
path: '/data-smart-contract-common/generalize-file',
component: Layout,
meta: {
title: '泛化文件管理',
icon: 'sidebar-videos',
},
children: [
{
path: '',
name: 'generalizeFile',
component: () => import('@/views/data_smart_contract/generalizeFile.vue'),
meta: {
title: '',
sidebar: false,
breadcrumb: false,
cache: true
},
},
{
path: 'generalize-file-edit',
name: 'generalizeFileEdit',
component: () => import('@/views/data_smart_contract/generalizeFileEdit.vue'),
meta: {
title: '新建泛化文件',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true,
editPage: true,
activeMenu: '/data-smart-contract-common/generalize-file'
},
beforeEnter: (to, from) => {
if (to.query.fileName) {
to.meta.title = `编辑-${to.query.fileName}`;
}
}
},
],
},
}
]
export default routes
\ No newline at end of file
......
......@@ -7,6 +7,7 @@ import DataSmartContract from './modules/dataSmartContract';
import DataFacilitator from './modules/dataFacilitator';
import HomeIndex from './modules/homeIndex';
import DataDelivery from './modules/dataDelivery';
import DataAnonymization from './modules/dataAnonymization';
import useSettingsStore from '@/store/modules/settings'
......@@ -99,6 +100,7 @@ const asyncRoutes: RouteRecordRaw[] = [
...DataFacilitator,
...HomeIndex,
...DataDelivery,
...DataAnonymization,
// ...DataAssetRegistry,
]
......
<route lang="yaml">
name: anonResultReportView
</route>
<script lang="ts" setup name="anonResultReportView">
import {
exportAnonReport,
getAnonAnalyzePageData,
getAnonAnalyzeResult,
getAnonTaskDetail,
} from '@/api/modules/dataAnonymization';
import { changeNum, download } from '@/utils/common';
import { ElMessage } from 'element-plus';
import anonResultAnalysis from './components/anonResultAnalysis.vue';
import { commonPageConfig } from '@/utils/enum';
import { calcColumnWidth } from '@/utils';
const route = useRoute();
const router = useRouter();
const fullPath = route.fullPath;
const taskGuid = ref(route.query.guid);
const { proxy } = getCurrentInstance() as any;
const resultDataLoading = ref(false);
const downPromise: any = ref()
/** 提交保存和编辑后的执行guid */
const taskExecGuid = ref(route.query.execGuid);
/** 记录原始的值信息,防止上一步之后未修改数据时不调用接口 */
const oldAnonTaskValueInfo: any = ref({});
/** 执行结果信息 */
const analysisResultInfo: any = ref({});
const containerRef = ref();
const containerWidth = ref(containerRef.value?.offsetWidth || 0)
/** ------------------------- 匿名化分析结果页面数据展示 ---------------- */
const pageInfo: any = ref({
...commonPageConfig,
})
const pageChange = (info) => {
pageInfo.value.curr = Number(info.curr);
pageInfo.value.limit = Number(info.limit);
getAnalysisResultPageData();
}
/** 每列字段对应的列宽计算结果。 */
const originResultTableFieldColumn = ref({});
/** 结果分析中的字段表格数据 */
const resultData: any = ref([]);
/** 结果分析中的字段信息 */
const analysisResultTableFields: any = ref([]);
const analysisResultLoading = ref(false);
/** 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
);
};
watch(
resultData,
(val: any[], oldVal) => {
if (!analysisResultTableFields.value?.length) {
originResultTableFieldColumn.value = {};
return;
}
originResultTableFieldColumn.value = {};
analysisResultTableFields.value.forEach((field, index) => {
originResultTableFieldColumn.value[field.enName] = calcTableColumnWidth(
val?.slice(0, 20) || [],
field.enName,
field.chName,
24
);
});
},
{
deep: true,
}
);
const getAnalysisResultPageData = () => {
analysisResultLoading.value = true;
getAnonAnalyzePageData({
pageIndex: pageInfo.value.curr,
pageSize: pageInfo.value.limit,
taskExecGuid: taskExecGuid.value,
}).then((res: any) => {
analysisResultLoading.value = false;
if (res?.code == proxy.$passCode) {
pageInfo.value.rows =
resultData.value = [];
res.data?.records?.forEach(d => {
let obj = {};
analysisResultTableFields.value.forEach(t => {
obj[t.enName] = d.fieldValue?.[t.enName];
});
obj['equivalenceClassNum'] = changeNum(d.equivalenceClassNum || 0, 0);
obj['reIdentifyRisk'] = changeNum(d.reIdentifyRisk || 0, 2);
obj['isGtThreshold'] = d.isGtThreshold;
resultData.value.push(obj);
});
pageInfo.value.rows = res.data?.totalRows ?? 0;
} else {
proxy.$ElMessage.error(res.msg);
}
})
}
/** 下载评估报告 */
const transfer = () => {
if (downPromise.value) {
return;
}
downPromise.value = exportAnonReport({
taskGuid: route.query.guid,
execGuid: taskExecGuid.value
}).then((res: any) => {
downPromise.value = null;
if (res && !res.msg) {
download(res, (route.query.taskName || oldAnonTaskValueInfo.value.taskName) + '_匿名化评估报告.docx', 'word')
} else {
res?.msg && ElMessage.error(res?.msg);
}
}).catch(() => {
downPromise.value = null;
})
}
onMounted(() => {
nextTick(() => {
containerWidth.value = containerRef.value?.offsetWidth || 0;
})
window.onresize = () => {
containerWidth.value = containerRef.value?.offsetWidth || 0;
}
})
onBeforeMount(() => {
resultDataLoading.value = true;
getAnonAnalyzeResult(taskExecGuid.value).then((res: any) => {
resultDataLoading.value = false;
if (res?.code == proxy.$passCode) {
analysisResultInfo.value = res.data || {};
analysisResultTableFields.value = res.data?.column || [];
pageInfo.value.curr = 1;
getAnalysisResultPageData();
} else {
res?.msg && proxy.$ElMessage.error(res.msg);
}
});
getAnonTaskDetail(taskGuid.value).then((res: any) => {
if (res?.code == proxy.$passCode) {
oldAnonTaskValueInfo.value = res.data || {};
} else {
res?.msg && proxy.$ElMessage.error(res.msg);
}
});
})
</script>
<template>
<div class="table_tool_wrap" v-loading="resultDataLoading" ref="containerRef">
<el-button style="margin-bottom: 8px;" type="primary" @click="transfer" v-preReClick>下载评估报告</el-button>
<anonResultAnalysis :show-title="true" :analysis-result-info="analysisResultInfo"
:analysis-result-loading="analysisResultLoading" :analysis-result-table-fields="analysisResultTableFields"
:old-anon-task-value-info="oldAnonTaskValueInfo" :container-width="containerWidth"
:origin-result-table-field-column="originResultTableFieldColumn" :page-info="pageInfo" :result-data="resultData"
@page-change="pageChange"></anonResultAnalysis>
</div>
</template>
<style lang="scss" scoped>
.table_tool_wrap {
width: 100%;
height: 100%;
padding: 8px 16px 16px;
overflow-y: auto;
}
</style>
<route lang="yaml">
name: anonResultView
</route>
<script lang="ts" setup name="anonResultView">
import { ref } from "vue";
import {
getAnonPageData,
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";
const { proxy } = getCurrentInstance() as any;
const route = useRoute();
const props = defineProps({
isPage: {
default: true,
type: Boolean
},
execGuid: {
default: '',
type: String
}
});
const tableData: any = ref([]);
const tableDataLoading = ref(false);
const tableFields: any = ref([]);
const pageInfo: any = ref({
...commonPageConfig,
rows: 0,
})
const getData = () => {
tableData.value = [];
if (!tableFields.value?.length) {
return;
}
tableDataLoading.value = true;
getAnonPageData({
pageIndex: pageInfo.value.curr,
pageSize: pageInfo.value.limit,
taskExecGuid: props.isPage ? route.query.execGuid : props.execGuid,
}).then((res: any) => {
tableDataLoading.value = false;
if (res.code == proxy.$passCode) {
tableData.value = [];
res.data?.records?.forEach(d => {
let obj = {};
tableFields.value.forEach(t => {
obj[t.enName] = d.fieldValue?.[t.enName];
});
tableData.value.push(obj);
});
pageInfo.value.rows = res.data?.totalRows ?? 0;
} else {
ElMessage.error(res.msg);
}
});
}
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) {
return;
}
tableDataLoading.value = true;
getLastAnonAnalyzeResult(val).then((res: any) => {
tableDataLoading.value = false;
if (res.code == proxy.$passCode) {
let column = res.data?.column || {};
tableFields.value = column;
pageInfo.value.curr = 1;
getData();
} else {
ElMessage.error(res.msg);
}
});
}, {
immediate: true
})
onBeforeMount(() => {
if (!props.isPage) {
return;
}
tableDataLoading.value = true;
getLastAnonAnalyzeResult(route.query.execGuid).then((res: any) => {
tableDataLoading.value = false;
if (res.code == proxy.$passCode) {
let column = res.data?.column || {};
tableFields.value = column;
getData();
} else {
ElMessage.error(res.msg);
}
});
});
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);
pageInfo.value.limit = Number(info.limit);
getData();
}
const promise: any = ref(null);
const exportData = () => {
if (promise.value) {
return;
}
promise.value = exportAnonExecData({
taskGuid: route.query.guid,
execGuid: route.query.execGuid
}).then((res: any) => {
promise.value = null;
if (res && !res.msg) {
download(res, route.query.taskName + '_匿名化数据.xlsx', 'excel')
} else {
res?.msg && ElMessage.error(res?.msg);
}
}).catch(() => {
promise.value = null;
})
}
</script>
<template>
<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>
<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>
</div>
<PageNav :class="[pageInfo.type]" :pageInfo="pageInfo" @pageChange="pageChange" />
</div>
</template>
<style lang="scss" scoped>
.table_tool_wrap {
width: 100%;
height: 100%;
padding: 8px 16px 16px;
.tips_text {
font-size: 14px;
color: var(--el-text-color-tip);
display: block;
font-weight: normal;
margin-bottom: 8px;
line-height: 21px;
}
.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
<route lang="yaml">
name: resultProcess
</route>
<script lang="ts" setup name="resultProcess">
import TableTools from "@/components/Tools/table_tools.vue";
import { commonPageConfig } from '@/components/PageNav/index';
import { TableColumnWidth } from "@/utils/enum";
import {
dataSourceTypeList,
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: "",
field: "taskName",
default: "",
placeholder: "数据集名称",
clearable: true,
}, {
type: "select",
label: "",
field: "dataSource",
default: null,
options: dataSourceTypeList,
placeholder: "数据来源",
clearable: true,
filterable: true,
}])
/** 分页及搜索传参信息配置。 */
const page = ref({
...commonPageConfig,
taskName: '',
dataSource: null
});
const tableInfo = ref({
id: 'data-file-table',
fields: [
{ label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
{ label: "数据集名称", field: "taskName", width: 160 },
{
label: "数据来源", field: "dataSource", width: 100, getName: (scope) => {
return scope.row.dataSource && dataSourceTypeList.find(f => f.value == scope.row.dataSource)?.label || '--';
}
},
{ label: "任务状态", field: "sensitiveIdentifyTaskStatus", width: TableColumnWidth.STATE, align: 'center', type: "tag" },
{ label: "导出时间", field: "exportTime", width: TableColumnWidth.DATETIME },
{ label: "修改人", field: "updateUserName", width: TableColumnWidth.USERNAME },
{ label: "修改时间", field: "updateTime", width: TableColumnWidth.DATETIME },
],
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
loading: false,
actionInfo: {
label: "操作",
type: "btn",
width: 230,
fixed: 'right',
btns: (scope) => {
return [{
label: "编辑", value: "edit", 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
}
});
}
}, {
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: "delete", 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,
});
}
});
})
}
}]
}
}
})
const toSearch = (val: any, clear: boolean = false) => {
if (clear) {
searchItemList.value.map((item) => (item.default = ""));
page.value.taskName = '';
page.value.dataSource = null;
} else {
page.value.taskName = val.taskName;
page.value.dataSource = val.dataSource;
}
getTableData();
};
const getTableData = () => {
tableInfo.value.loading = true
getAnonTaskList({
pageIndex: page.value.curr,
pageSize: page.value.limit,
taskName: page.value.taskName,
dataSource: page.value.dataSource
}).then((res: any) => {
if (res?.code == proxy.$passCode) {
const data = res.data || {};
tableInfo.value.data = data.records?.map(d => {
d.sensitiveIdentifyTaskStatus = d.status;
return d;
}) || []
tableInfo.value.page.limit = data.pageSize
tableInfo.value.page.curr = data.pageIndex
tableInfo.value.page.rows = data.totalRows
} else {
proxy.$ElMessage({
type: 'error',
message: res.msg,
})
}
tableInfo.value.loading = false
})
};
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
getTableData();
};
const handleCreate = () => {
router.push({
name: 'anonTaskCreate'
});
}
onBeforeMount(() => {
toSearch({});
anonymizationStore?.setIsAnonPageRefresh?.(false);
})
onActivated(() => {
if (anonymizationStore.isAnonPageRefresh) {//如果是首次加载,则不需要调用
page.value.curr = 1;
getTableData();
anonymizationStore.setIsAnonPageRefresh(false);
}
});
</script>
<template>
<div class="container_wrap">
<div class="table_tool_wrap">
<!-- 头部搜索 -->
<TableTools :searchItems="searchItemList" :searchId="'data-label-search'" @search="toSearch" :init="false" />
<div class="tools_btns">
<el-button type="primary" @click="handleCreate">新建</el-button>
</div>
</div>
<div class="table_panel_wrap">
<!-- 右侧标签管理表格 -->
<Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" />
</div>
</div>
</template>
<style lang="scss" scoped>
.table_tool_wrap {
width: 100%;
height: 84px !important;
padding: 0 8px;
.tools_btns {
padding: 0px 0 0;
}
}
.table_panel_wrap {
width: 100%;
height: calc(100% - 84px);
padding: 0px 8px 0;
}
</style>
\ No newline at end of file
<route lang="yaml">
name: sensitiveIdentifyTaskExecLog
</route>
<script lang="ts" setup name="sensitiveIdentifyTaskExecLog">
import { ref } from "vue";
import { useRouter, useRoute } from "vue-router";
import Table from "@/components/Table/index.vue";
import { ElMessage } from "element-plus";
import { commonPageConfig } from '@/components/PageNav/index';
import {
getSensitiveDataTaskExecLog,
} from '@/api/modules/dataAnonymization';
import { TableColumnWidth } from "@/utils/enum";
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const route = useRoute();
const guid = route.query.guid;
const wordName = route.query.name
const page = ref({
...commonPageConfig
});
const tableInfo = ref({
id: "word-log-table",
loading: false,
fields: [
{ label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
{ label: "执行人", field: "createUserName", width: TableColumnWidth.USERNAME },
{ label: "执行时间", field: "execTime", width: TableColumnWidth.DATETIME },
{ label: "执行状态", field: "sensitiveIdentifyTaskStatus", width: TableColumnWidth.STATE, align: 'center', type: "tag" },
{ label: "确认人", field: "confirmUserName", width: TableColumnWidth.USERNAME },
{ label: "确认时间", field: "confirmTime", width: TableColumnWidth.DATETIME },
{ label: "确认状态", field: "sensitiveIdentifyConfirmStatus", width: TableColumnWidth.STATE, align: 'center', type: "tag" },
],
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
label: "操作",
type: "btn",
width: 100,
fixed: 'right',
btns: (scope) => {
return [{
label: "查看", value: "report", disabled: scope.row['status'] != 'Y', click: (scope) => {
router.push({
name: 'sensitiveIdentifyConfig',
query: {
guid: route.query.guid,
execGuid: scope.row.guid,
taskName: route.query.name,
isLook: '1',
}
});
}
}];
}
}
});
const getTableData = () => {
tableInfo.value.loading = true;
getSensitiveDataTaskExecLog({ pageIndex: page.value.curr, pageSize: page.value.limit, taskGuid: guid }).then((res: any) => {
tableInfo.value.loading = false;
if (res?.code == proxy.$passCode) {
const data = res.data || {}
tableInfo.value.data = data.records?.map(d => {
d.sensitiveIdentifyTaskStatus = d.status;
d.sensitiveIdentifyConfirmStatus = d.confirmStatus;
return d;
}) || []
tableInfo.value.page.limit = data.pageSize
tableInfo.value.page.curr = data.pageIndex
tableInfo.value.page.rows = data.totalRows
} else {
ElMessage.error(res.msg);
}
})
};
const tableBtnClick = (scope, btn) => {
const type = btn.value;
const row = scope.row;
if (type == 'reportView') {
router.push({
name: 'analysisReport',
query: {
planGuid: row.planGuid,
reportExecGuid: row.guid,
name: wordName
}
});
}
};
onActivated(() => {
getTableData();
});
</script>
<template>
<div class="container_wrap">
<div class="table_panel_wrap">
<Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" />
</div>
</div>
</template>
<style lang="scss" scoped>
.container_wrap {
padding: 0;
.table_panel_wrap {
height: 100%;
padding: 16px 16px 0;
}
}
</style>
\ No newline at end of file
......@@ -1392,7 +1392,7 @@ onActivated(() => {
<ContentWrap v-show="!currentStep && detailType == 'sign' || currentStep == 3" id="sign-info" title="合约签署"
expandSwicth style="margin-top: 15px" :isExpand="expandSign" @expand="(v) => (expandSign = v)" description="">
<template v-for="(item, index) in signDetailInfo">
<div :class="{ 'h-title': true, 'mt6': index > 0 }">{{ item.executionerTypeName }}</div>
<div :class="{ 'h-title': true, 'mt6': <number>index > 0 }">{{ item.executionerTypeName }}</div>
<div class="list_panel">
<div class="list_item wrap">
<span class="item_label">签署主体标识</span>
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!