16852fd6 by lihua

修改匿名化报告

1 parent 78bc58ff
...@@ -352,6 +352,13 @@ export const htmlToWord = (params) => request({ ...@@ -352,6 +352,13 @@ export const htmlToWord = (params) => request({
352 responseType: 'blob' 352 responseType: 'blob'
353 }) 353 })
354 354
355 export const downloadAnonReport = (params) => request({
356 url: `${import.meta.env.VITE_APP_ANONYMIZATION_BASEURL}/anon-task/download`,
357 method: 'postJsonD',
358 data: params,
359 responseType: 'blob'
360 })
361
355 /** 发送评测报告到邮箱 */ 362 /** 发送评测报告到邮箱 */
356 export const sendAnonReport = (params) => request({ 363 export const sendAnonReport = (params) => request({
357 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/send-mail-and-msg`, 364 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/send-mail-and-msg`,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
4 4
5 <script lang="ts" setup name="anonResultReportView"> 5 <script lang="ts" setup name="anonResultReportView">
6 import { 6 import {
7 downloadAnonReport,
7 getAnonAnalyzePageData, 8 getAnonAnalyzePageData,
8 getAnonAnalyzeResult, 9 getAnonAnalyzeResult,
9 getAnonTaskDetail, 10 getAnonTaskDetail,
...@@ -16,11 +17,14 @@ import anonResultAnalysis from './components/anonResultAnalysis.vue'; ...@@ -16,11 +17,14 @@ import anonResultAnalysis from './components/anonResultAnalysis.vue';
16 import { commonPageConfig, USERROLE } from '@/utils/enum'; 17 import { commonPageConfig, USERROLE } from '@/utils/enum';
17 import { calcColumnWidth } from '@/utils'; 18 import { calcColumnWidth } from '@/utils';
18 import html2canvas from 'html2canvas'; 19 import html2canvas from 'html2canvas';
20 import useUserStore from "@/store/modules/user";
19 21
20 const route = useRoute(); 22 const route = useRoute();
21 const router = useRouter(); 23 const router = useRouter();
22 const fullPath = route.fullPath; 24 const fullPath = route.fullPath;
23 const taskGuid = ref(route.query.guid); 25 const taskGuid = ref(route.query.guid);
26 const userStore = useUserStore();
27 const userData = JSON.parse(userStore.userData)
24 const { proxy } = getCurrentInstance() as any; 28 const { proxy } = getCurrentInstance() as any;
25 const resultDataLoading = ref(false); 29 const resultDataLoading = ref(false);
26 30
...@@ -209,7 +213,7 @@ const downloadWord = () => { ...@@ -209,7 +213,7 @@ const downloadWord = () => {
209 loadingText.value = `评测报告正在${route.query.dataOwner == '1' ? '发送' : '下载' }中,请勿关闭浏览器...`; 213 loadingText.value = `评测报告正在${route.query.dataOwner == '1' ? '发送' : '下载' }中,请勿关闭浏览器...`;
210 downPromise.value = convertHtml2Img(report, dom).then(() => { 214 downPromise.value = convertHtml2Img(report, dom).then(() => {
211 if (route.query.dataOwner == '1') { 215 if (route.query.dataOwner == '1') {
212 sendAnonReport({ taskGuid: taskGuid.value, html: encodeURIComponent(`<div>${getHTML(dom.innerHTML)}</div>`) }).then((res: any) => { 216 sendAnonReport({ taskGuid: taskGuid.value, title: `${analysisResultInfo.value.tenantName}持有的“${oldAnonTaskValueInfo.value.taskName}”`, evaluationDate: analysisResultInfo.value.execTime, deIdentProcessorName: userData.tenantName, html: encodeURIComponent(`<div>${getHTML(dom.innerHTML)}</div>`) }).then((res: any) => {
213 downPromise.value = null 217 downPromise.value = null
214 loadingText.value = ''; 218 loadingText.value = '';
215 resultDataLoading.value = false; 219 resultDataLoading.value = false;
...@@ -220,7 +224,7 @@ const downloadWord = () => { ...@@ -220,7 +224,7 @@ const downloadWord = () => {
220 } 224 }
221 }) 225 })
222 } else { 226 } else {
223 htmlToWord({ html: encodeURIComponent(`<div>${getHTML(dom.innerHTML)}</div>`) }).then((res: any) => { 227 downloadAnonReport({ taskGuid: taskGuid.value, title: `${analysisResultInfo.value.tenantName}持有的“${oldAnonTaskValueInfo.value.taskName}”`, evaluationDate: analysisResultInfo.value.execTime, deIdentProcessorName: userData.tenantName, html: encodeURIComponent(`<div>${getHTML(dom.innerHTML)}</div>`) }).then((res: any) => {
224 downPromise.value = null 228 downPromise.value = null
225 loadingText.value = ''; 229 loadingText.value = '';
226 resultDataLoading.value = false; 230 resultDataLoading.value = false;
...@@ -273,7 +277,7 @@ onBeforeMount(() => { ...@@ -273,7 +277,7 @@ onBeforeMount(() => {
273 <div class="table_tool_wrap" v-loading="resultDataLoading" ref="containerRef" :element-loading-text="loadingText"> 277 <div class="table_tool_wrap" v-loading="resultDataLoading" ref="containerRef" :element-loading-text="loadingText">
274 <!-- 连接器不需要显示下载报告按钮 --> 278 <!-- 连接器不需要显示下载报告按钮 -->
275 <template v-if="!isDataProvider"> 279 <template v-if="!isDataProvider">
276 <el-button v-show="!isWordStyle" style="margin-bottom: 8px;" type="primary" @click="transfer" 280 <el-button v-show="!isWordStyle && analysisResultInfo.rating >= 2" style="margin-bottom: 8px;" type="primary" @click="transfer"
277 v-preReClick>预览Word评估报告</el-button> 281 v-preReClick>预览Word评估报告</el-button>
278 <div v-show="isWordStyle" style="margin-bottom: 8px;"> 282 <div v-show="isWordStyle" style="margin-bottom: 8px;">
279 <el-button @click="isWordStyle = false">返回</el-button> 283 <el-button @click="isWordStyle = false">返回</el-button>
......
...@@ -168,7 +168,7 @@ ...@@ -168,7 +168,7 @@
168 </anonResultAnalysis> 168 </anonResultAnalysis>
169 <!-- 连接器只能查看报告 --> 169 <!-- 连接器只能查看报告 -->
170 <template v-if="!isDataProvider" #header> 170 <template v-if="!isDataProvider" #header>
171 <el-button v-show="isExecEnd && analysisResultInfo.status == 'Y' && !isWordStyle" type="primary" 171 <el-button v-show="isExecEnd && analysisResultInfo.status == 'Y' && !isWordStyle && analysisResultInfo.rating >= 2" type="primary"
172 v-loading="!!downPromise" @click="transfer">预览Word评估报告</el-button> 172 v-loading="!!downPromise" @click="transfer">预览Word评估报告</el-button>
173 <div v-show="isWordStyle"> 173 <div v-show="isWordStyle">
174 <el-button @click="isWordStyle = false">返回</el-button> 174 <el-button @click="isWordStyle = false">返回</el-button>
...@@ -237,6 +237,7 @@ import { ...@@ -237,6 +237,7 @@ import {
237 getDicomMeta, 237 getDicomMeta,
238 getDicomStatistics, 238 getDicomStatistics,
239 retryDicom, 239 retryDicom,
240 downloadAnonReport,
240 sendAnonReport 241 sendAnonReport
241 } from '@/api/modules/dataAnonymization'; 242 } from '@/api/modules/dataAnonymization';
242 import { 243 import {
...@@ -268,6 +269,7 @@ import html2canvas from 'html2canvas'; ...@@ -268,6 +269,7 @@ import html2canvas from 'html2canvas';
268 const anonymizationStore = useDataAnonymizationStore(); 269 const anonymizationStore = useDataAnonymizationStore();
269 const { proxy } = getCurrentInstance() as any; 270 const { proxy } = getCurrentInstance() as any;
270 const userStore = useUserStore(); 271 const userStore = useUserStore();
272 const userData = JSON.parse(userStore.userData)
271 const route = useRoute(); 273 const route = useRoute();
272 const router = useRouter(); 274 const router = useRouter();
273 const fullPath = route.fullPath; 275 const fullPath = route.fullPath;
...@@ -1252,6 +1254,7 @@ const dialogBtnClick = (btn) => { ...@@ -1252,6 +1254,7 @@ const dialogBtnClick = (btn) => {
1252 if (taskGuid.value) { 1254 if (taskGuid.value) {
1253 saveParams.guid = taskGuid.value; 1255 saveParams.guid = taskGuid.value;
1254 } 1256 }
1257 saveParams.dataSharingTypeName = saveParams.dataSharingTypeCode && dataSharingTypeList.value.find(d => d.value == saveParams.dataSharingTypeCode)?.label;
1255 dicomStatisticsData.value = {}; 1258 dicomStatisticsData.value = {};
1256 folderFileTableInfo.value.data = []; 1259 folderFileTableInfo.value.data = [];
1257 if (!taskGuid.value) { //保存 1260 if (!taskGuid.value) { //保存
...@@ -2219,7 +2222,8 @@ const downloadWord = () => { ...@@ -2219,7 +2222,8 @@ const downloadWord = () => {
2219 loadingText.value = '报告正在下载中,请勿关闭浏览器...'; 2222 loadingText.value = '报告正在下载中,请勿关闭浏览器...';
2220 downloadLoading.value = true; 2223 downloadLoading.value = true;
2221 downPromise.value = convertHtml2Img(report, dom).then(() => { 2224 downPromise.value = convertHtml2Img(report, dom).then(() => {
2222 htmlToWord({ html: encodeURIComponent(`<div>${getHTML(dom.innerHTML)}</div>`) }).then((res: any) => { 2225 downloadAnonReport({ taskGuid: oldAnonTaskValueInfo.value.guid, title: `${analysisResultInfo.value.tenantName}持有的“${oldAnonTaskValueInfo.value.taskName}”`, evaluationDate: analysisResultInfo.value.execTime,
2226 deIdentProcessorName: userData.tenantName, html: encodeURIComponent(`<div>${getHTML(dom.innerHTML)}</div>`) }).then((res: any) => {
2223 downPromise.value = null 2227 downPromise.value = null
2224 loadingText.value = ''; 2228 loadingText.value = '';
2225 downloadLoading.value = false; 2229 downloadLoading.value = false;
......
...@@ -198,57 +198,63 @@ ...@@ -198,57 +198,63 @@
198 </div> 198 </div>
199 </div> 199 </div>
200 </div> 200 </div>
201 <div v-show="isWordStyle" class="analysis-result-main report-main" ref="report"> 201 <div v-show="isWordStyle" class="analysis-result-main report-main" ref="report">
202 <div 202 <!-- 报告总览 -->
203 style="font-family: simsun;height: 40px;display: block;line-height: 32px;font-size: 18px;color: #212121;font-weight: 700;text-align: center;margin-top: 10px;margin-bottom: 10px;">匿名化效果评估指标</div> 203 <h1 style="font-family: simsun;font-size: 18px;font-weight: 700;text-align: center;margin-top: 10px;margin-bottom: 10px;color: #212121;">报告总览</h1>
204 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ' 依据GB/T 42460-2023《信息安全技术个人信息去标识化效果评估指南》附录D,对去标识化以后的数据集基于K匿名模型进行去标识化效果的评估。' }}</p> 204 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 一、评价对象:${analysisResultInfo.tenantName}2025年1月1日至2025年12月31日的${oldAnonTaskValueInfo.taskName},该数据集包含1张表,字段总数量共计${changeNum(analysisResultInfo.fieldNum || 0)}个,记录总数量共计${changeNum(analysisResultInfo.fieldCnExps || 0)}条,数据元素总量为${changeNum(analysisResultInfo.dataTotal || 0)}个 。` }}</p>
205 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;"> 205 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 二、评价方法:基于匿名化评估国家标准GB/T 42460-2023《信息安全技术 个人信息去标识化效果评估指南》、GB/T 37964-2019《信息安全技术 个人信息去标识化指南》,以及《中华人民共和国个人信息保护法》、《中华人民共和国数据安全法》、《中华人民共和国网络安全法》、《面向数据流通的匿名化效果实施指南 草案》、《面向数据流通的匿名化效果评估指南 草案》和《数据安全技术 个人信息匿名化处理指南及评价方法 征求意见稿》相关法律法规,采用“定性分析”与“定量计算”相结合的综合评估方法。` }}</p>
206 {{ ` 总体方案为先计算数据集每行记录、整体数据集的重标识风险,进而计算环境重标识攻击概率,最后再结合环境重标识攻击概率计算整个数据集的重标识整体风险。去标识化效果评估结果为${analysisResultInfo.rating + '级'}。具体指标如下:` }}</p> 206 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 三、评估结论:综合定性与定量评估结果,根据GB/T 42460-2023的分级标准,该${oldAnonTaskValueInfo.taskName}的匿名化效果评定为${analysisResultInfo.rating}级${analysisResultInfo.rating <=2 ? '(重标识风险较高)' : ''}。${`需要对准标识符${analysisResultInfo.qualifiedIdentifier?.map(f => f.chName)?.join('、')}做有效的泛化和抑制,满足 k-匿名要求(设定k10 ,从而使得该数据集适用于受控环境下进行跨机构流通。`} 。` }}</p>
207 <div 207 <div style="page-break-after: always;">
208 style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;font-weight: 700;margin: 8px 0px;"> 208 <span style="display: none;">&nbsp;</span>
209 匿名化结果分析</div> 209 </div>
210 <div class="kpi-content" v-show="Object.keys(analysisResultInfo).length > 0"> 210 <!-- 1. 评估基本信息 -->
211 <div class="border-content"> 211 <h1 style="font-family: simsun;font-size: 18px;font-weight: 700;text-align: center;margin-top: 10px;margin-bottom: 10px;color: #212121;">一、评估基本信息</h1>
212 <div class="text" style="color: #212121;">去标识化效果评估结果</div> 212 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 评估项目名称:${oldAnonTaskValueInfo.taskName}匿名化效果评估` }}</p>
213 <span class="number score-color">{{ analysisResultInfo.rating + '级' }}</span> 213 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 评估对象:${analysisResultInfo.tenantName}2025年1月1日至2025年12月31日的${oldAnonTaskValueInfo.taskName}(共计${changeNum(analysisResultInfo.fieldCnExps || 0)}条记录)` }}</p>
214 </div> 214 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 评估依据:GB/T 42460-2023《信息安全技术 个人信息去标识化效果评估指南》、GB/T 37964-2019《信息安全技术 个人信息去标识化指南》、《中华人民共和国个人信息保护法》、《中华人民共和国数据安全法》、《中华人民共和国网络安全法》、《面向数据流通的匿名化效果实施指南 草案》、《面向数据流通的匿名化效果评估指南 草案》和《数据安全技术 个人信息匿名化处理指南及评价方法 征求意见稿》。` }}</p>
215 <div class="border-content"> 215 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 评估日期:${analysisResultInfo.execTime}` }}</p>
216 <span class="text" style="color: #212121;">重标识风险最大值</span> 216
217 <span class="number">{{ analysisResultInfo.reIdentifyRiskRb != null ? 217 <!-- 2. 评估准备 -->
218 (analysisResultInfo.reIdentifyRiskRb || 0) : '--' 218 <h1 style="font-family: simsun;font-size: 18px;font-weight: 700;text-align: center;margin-top: 10px;margin-bottom: 10px;color: #212121;">二、评估准备</h1>
219 }}</span> 219 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 数据集与环境确认:待评估数据集包含${analysisResultInfo?.column?.slice(0, 4)?.map(f => f.chName).join('、')}${analysisResultInfo?.column?.length > 4 ? '等字段' : ''}。数据将用于跨机构的科学研究,处于半开放网络环境。` }}</p>
220 </div> 220 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 风险阈值设定:结合科研数据共享需求,设定可接受的重标识风险阈值为0.05(即5%)。` }}</p>
221 <div class="border-content"> 221
222 <span class="text" style="color: #212121;">重标识风险平均值</span> 222 <!-- 3. 定性评估 -->
223 <span class="number">{{ analysisResultInfo.reIdentifyRiskRc != null ? 223 <h1 style="font-family: simsun;font-size: 18px;font-weight: 700;text-align: center;margin-top: 10px;margin-bottom: 10px;color: #212121;">三、定性评估</h1>
224 (analysisResultInfo.reIdentifyRiskRc || 0) : '--' }}</span> 224 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 依据GB/T 37964标准,对数据集中的标识符进行了识别与分类处理:` }}</p>
225 </div> 225
226 <div class="border-content"> 226 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;font-weight: 700;">{{ ` 1.直接标识符处理` }}</p>
227 <span class="text" style="color: #212121;">环境重标识攻击概率</span> 227 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 识别字段:姓名、身份证号、手机号、住院号、家庭详细住址等。` }}</p>
228 <span class="number">{{ analysisResultInfo.envReAttackPr != null ? 228 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ' 处理措施:采用完全删除技术。' }}</p>
229 (analysisResultInfo.envReAttackPr || 0) : '--' }}</span> 229 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 评估结果:数据集中已完全消除直接标识符,无法通过单一字段直接识别特定患者。` }}</p>
230 </div> 230
231 <div class="border-content"> 231 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;font-weight: 700;">{{ ` 2.准标识符处理` }}</p>
232 <span class="text" style="color: #212121;">等价类门限风险</span> 232 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 识别字段:性别、年龄、职业、入院日期、出院日期、出生日期、婚姻、受教育水平等。` }}</p>
233 <span class="number">{{ analysisResultInfo.reIdentifyRiskRa != null ? 233 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ' 处理措施:' }}</p>
234 (analysisResultInfo.reIdentifyRiskRa || 0) : '--' }}</span> 234 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 时间泛化:将精确的“入院日期”、“出院日期”泛化为“年份”或住院天数、“年龄”泛化为“年龄段”(如将年龄转换为[40-50]区间)。` }}</p>
235 </div> 235 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 对准标识符的泛化确保同一属性组合(相同的准标识符)下的记录数满足 k-匿名要求(设定k≥10)。比如性别为男、年龄[40-50]、职业为其他、入院时间为2025年11月,出院时间为2025年11月的记录数满足10条以上。` }}</p>
236 <div class="border-content"> 236 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 评估结果:数据集中未对准标识符进行有效地泛化和抑制处理。` }}</p>
237 <span class="text" style="color: #212121;">重标识风险总体风险</span> 237
238 <span class="number">{{ analysisResultInfo.reIdentifyOverallRisk != null ? 238 <!-- 4. 定量评估(重标识风险计算) -->
239 (analysisResultInfo.reIdentifyOverallRisk || 0) : '--' }}</span> 239 <h1 style="font-family: simsun;font-size: 18px;font-weight: 700;text-align: center;margin-top: 10px;margin-bottom: 10px;color: #212121;">四、定量评估(重标识风险计算)</h1>
240 </div> 240 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 依据GB/T 42460-2023《信息安全技术个人信息去标识化效果评估指南》附录D,对去标识化以后的数据集基于K匿名模型进行去标识化效果的评估。总体方案为先对所有的数据进行直接标识符识别,判断无直接标识符内容后,再计算数据集每行记录、整体数据集的重标识风险,进而计算环境重标识攻击概率,最后再结合环境重标识攻击概率计算整个数据集的重标识整体风险。` }}</p>
241 <div class="border-content"> 241
242 <span class="text" style="color: #212121;">重标识可接受风险阈值</span> 242 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;font-weight: 700;">{{ ` 直接标识符:` }}<span style="font-weight: 500;">{{ '经扫描数据集的内容,比如现病史、既往史等长文本字段进行扫描,未发现直接标识符内容。' }}</span></p>
243 <span class="number">{{ oldAnonTaskValueInfo.anonPrivacyMode?.riskThreshold == null ? 0.05 : 243 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;font-weight: 700;">{{ ` 重标识风险总体风险:` }}<span style="font-weight: 500;">{{ `准标识符${analysisResultInfo.rating > 2 ? '' : '并未'}进行有效泛化,计算的重标识符总体风险为${analysisResultInfo.reIdentifyOverallRisk != null ?
244 (oldAnonTaskValueInfo.anonPrivacyMode?.riskThreshold || 0) }}</span> 244 (analysisResultInfo.reIdentifyOverallRisk || 0) * 100 : '--'}${analysisResultInfo.reIdentifyOverallRisk ? '%' : ''};` }}</span></p>
245 </div> 245 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;font-weight: 700;">{{ ` 重标识风险最大值:` }}<span style="font-weight: 500;">{{ `计算数据集中重标识风险最高的记录所对应的风险值。经计算,该数据集最大重标识风险值为${analysisResultInfo.reIdentifyRiskRb != null ?
246 </div> 246 (analysisResultInfo.reIdentifyRiskRb || 0) : '--'}${analysisResultInfo.reIdentifyRiskRb ? `(即${analysisResultInfo.reIdentifyRiskRb*100})` : ''}。` }}</span></p>
247 <div 247 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;font-weight: 700;">{{ ` 重标识风险平均值:` }}<span style="font-weight: 500;">{{ `模拟攻击者随机抽取一条记录并尝试重标识的平均风险。经计算,该数据集重标识风险的平均值为${analysisResultInfo.reIdentifyRiskRc != null ?
248 style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;font-weight: 700;margin: 8px 0px 4px;"> 248 (analysisResultInfo.reIdentifyRiskRc || 0) : '--'}${analysisResultInfo.reIdentifyRiskRc ? `(即${analysisResultInfo.reIdentifyRiskRc * 100})` : ''}。` }}</span></p>
249 重标识风险表</div> 249 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;font-weight: 700;">{{ ` 环境重标识攻击概率:` }}<span style="font-weight: 500;">{{ `${oldAnonTaskValueInfo.dataSharingTypeName}的数据集,环境重标识攻击概率为内部故意攻击概率、数据集包含熟人概率和数据泄露概率三者的最大值,经计算,该数据集的攻击概率为${analysisResultInfo.envReAttackPr != null ?
250 <div style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;margin-bottom: 4px;white-space: pre-wrap;">{{ ' 门限阈值的取值:完全公开共享数据发布,取值 1/20;受控公开共享数据发布,取值 1/5;领地公开共享数据发布,取值 1/3。' }}</div> 250 (analysisResultInfo.envReAttackPr || 0) : '--'}${analysisResultInfo.envReAttackPr ? `(即${analysisResultInfo.envReAttackPr * 100})` : ''}。` }}</span></p>
251 <table border="0" cellspacing="0" 251
252 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ' 具体计算指标如下:' }}</p>
253
254 <!-- 1. 重标识风险表 -->
255 <div style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;font-weight: 700;margin: 8px 0px 4px;">{{ ' 1. 重标识风险表' }}</div>
256 <div style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;margin-bottom: 4px;white-space: pre-wrap;">{{ ` 门限阈值的取值:该数据集为${oldAnonTaskValueInfo.dataSharingTypeName}数据,门限阈值为${oldAnonTaskValueInfo.dataSharingTypeCode == '01' ? '1/20' : (oldAnonTaskValueInfo.dataSharingTypeCode == '02' ? '1/5' : '1/3')} 。` }}</div>
257 <table border="0" cellspacing="0"
252 style="width:100%;word-break: break-all;margin: 0 auto;text-align: center;border-collapse: collapse;color: #212121"> 258 style="width:100%;word-break: break-all;margin: 0 auto;text-align: center;border-collapse: collapse;color: #212121">
253 <thead> 259 <thead>
254 <tr> 260 <tr>
...@@ -268,11 +274,10 @@ ...@@ -268,11 +274,10 @@
268 </tr> 274 </tr>
269 </tbody> 275 </tbody>
270 </table> 276 </table>
271 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" 277
272 style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;font-weight: 700;margin: 8px 0px 4px;"> 278 <!-- 2. 内部故意攻击概率 -->
273 内部故意攻击概率</div> 279 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;font-weight: 700;margin: 8px 0px 4px;">{{ ' 2. 内部故意攻击概率'}}</div>
274 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" 280 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;margin-bottom: 4px;white-space: pre-wrap;">{{ ' 重标识数据的动机和能力为低,从重标识攻击可能性分析表可得出在内部攻击方面,重标识攻击概率的取值为0.05。' }}</div>
275 style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;margin-bottom: 4px;white-space: pre-wrap;">{{ ' 重标识数据的动机和能力为低,从重标识攻击可能性分析表可得出在内部攻击方面,重标识攻击概率的取值为0.05。'}}</div>
276 <table v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" border="0" cellspacing="0" 281 <table v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" border="0" cellspacing="0"
277 style="width:100%;word-break: break-all;margin: 0 auto;text-align: center;border-collapse: collapse;color: #212121;"> 282 style="width:100%;word-break: break-all;margin: 0 auto;text-align: center;border-collapse: collapse;color: #212121;">
278 <thead> 283 <thead>
...@@ -295,58 +300,65 @@ ...@@ -295,58 +300,65 @@
295 </tr> 300 </tr>
296 </tbody> 301 </tbody>
297 </table> 302 </table>
298 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" 303
299 style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;font-weight: 700;margin: 8px 0px;">数据集包含熟人概率</div> 304 <!-- 3. 数据集包含熟人概率 -->
300 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" 305 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;font-weight: 700;margin: 8px 0px;">{{ ' 3. 数据集包含熟人概率'}}</div>
301 style="font-family: simsun;text-align: center; display: block;line-height: 21px;font-size: 14px;color: #212121;font-weight: 700">pr=1-1-p^m</div> 306 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" style="font-family: simsun;text-align: center; display: block;line-height: 21px;font-size: 14px;color: #212121;font-weight: 700">pr=1-1-p^m</div>
302 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" 307 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;white-space: pre-wrap;">
303 style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;white-space: pre-wrap;"> 308 {{ ` 数据集包含熟人概率可通过以上公式计算,${new Date().getFullYear()}年我国最新的人口统计为${analysisResultInfo?.allPerson ||
304 {{ ` 数据集包含熟人概率可通过以上公式计算,${new Date().getFullYear()}年我国最新的人口统计为${analysisResultInfo?.allPerson ||
305 0}亿人,其中该数据集的容量为${analysisResultInfo?.dataSetNum || 0}万,占总人口的比例为${analysisResultInfo.patientPopulationRate || 309 0}亿人,其中该数据集的容量为${analysisResultInfo?.dataSetNum || 0}万,占总人口的比例为${analysisResultInfo.patientPopulationRate ||
306 0}%,m值取推荐值150,数据集包含熟人的概率为${analysisResultInfo.randomAcquaintancePr || 0}。` }}</div> 310 0}%,m值取推荐值150,数据集包含熟人的概率为${analysisResultInfo.randomAcquaintancePr || 0}。` }}
307 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" 311 </div>
308 style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;font-weight: 700;margin: 8px 0px;">数据泄露概率 312
309 </div> 313 <!-- 4. 数据泄露概率 -->
310 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" 314 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;font-weight: 700;margin: 8px 0px;">{{ ' 4. 数据泄露概率'}}</div>
311 style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;white-space: pre-wrap;">{{ 315 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;white-space: pre-wrap;">{{ ' 对于安全和隐私控制能力评估为低的情况,推荐将数据泄露概率设定为0.55。' }}</div>
312 ' 对于安全和隐私控制能力评估为低的情况,推荐将数据泄露概率设定为0.55。' }}</div> 316 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;white-space: pre-wrap;">{{ ' 对于安全和隐私控制能力评估为中的情况,推荐将数据泄露概率设定为0.27。' }}</div>
313 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" 317 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;white-space: pre-wrap;">{{ ' 对于安全和隐私控制能力评估为高的情况,推荐将数据泄露概率设定为0.14。' }}</div>
314 style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;white-space: pre-wrap;">{{ ' 对于安全和隐私控制能力评估为中的情况,推荐将数据泄露概率设定为0.27。' }}</div> 318 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;white-space: pre-wrap;">{{ ` 数据接收方的安全和隐私控制能力为高,按照推荐值将数据泄露概率设定为${analysisResultInfo.dataBreachPr || 0}。` }}</div>
315 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" 319
316 style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;white-space: pre-wrap;">{{ ' 对于安全和隐私控制能力评估为高的情况,推荐将数据泄露概率设定为 0.14。' }}</div> 320 <!-- 对抗性测试 (评级>=3时展示) -->
317 <div v-show="oldAnonTaskValueInfo.dataSharingTypeCode != '01'" 321 <div v-show="analysisResultInfo.rating >= 3" style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;font-weight: 700;margin: 8px 0px;">{{ oldAnonTaskValueInfo.dataSharingTypeCode != '01' ? ' 5. 对抗性测试' : ' 2. 对抗性测试' }}</div>
318 style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;white-space: pre-wrap;">{{ ` 数据接收方的安全和隐私控制能力为高,按照推荐值将数据泄露概率设定为${analysisResultInfo.dataBreachPr || 0}。` }}</div> 322 <p v-show="analysisResultInfo.rating >= 3" style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;color: #212121;white-space: pre-wrap;">{{ ' 依据《数据安全技术个人信息匿名化处理指南及评价方法(征求意见稿)》4.2,去标识化的数据集达到3级可展开对数据级的对抗性测试和不可复原性核验。对抗性测试关键变量如下表:' }}</p>
319 <div style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;font-weight: 700;margin: 8px 0px;">备注:</div> 323 <table border="0" cellspacing="0" v-show="analysisResultInfo.rating >= 3" style="width:100%;word-break: break-all;margin: 4px auto 0px auto;text-align: center;border-collapse: collapse;color: #212121;">
320 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;color: #212121;margin-top: 8px;white-space: pre-wrap;">{{ ' 重标识风险最大值:所有等价类的重标识风险最大值;' }}</p> 324 <thead>
321 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;color: #212121;white-space: pre-wrap;">{{ ' 重标识风险平均值:所有等价类的重标识风险平均值;'}}</p> 325 <tr>
322 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;color: #212121;white-space: pre-wrap;">{{ ' 环境重标识攻击概率:完全公开共享数据发布,攻击者对数据集进行环境重标识攻击的概率为1。领地公开共享与受控公开共享数据发布,环境重标识攻击概率为内部故意攻击概率、数据集包含熟人概率和数据泄露概率三者的最大值;' }}</p> 326 <th v-for="(item, index) in adversarialTestFields" :key="index" style="border: 0.5px solid #d9d9d9">
323 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;color: #212121;white-space: pre-wrap;">{{ ' 等价类门限风险:完全公开共享数据发布,门限阈值取值1/20;受控公开共享数据发布,门限阈值取值 1/5;领地公开共享数据发布,门限阈值取值 1/3;等价类门限风险为:等价类的重标识风险大于门限阈值为1,小于等于为0,求和后除以等价类个数;'}}</p> 327 <span>{{ item.label }}</span>
324 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;color: #212121;white-space: pre-wrap;">{{ ' 重标识风险总体风险:完全公开共享,当等价类门限风险=0时,重标识风险总体风险公式为等价类重标识风险最大值*环境重标识攻击概率;当等价类门限风险!=0时,重标识风险总体风险为1。' }}</p> 328 </th>
325 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;color: #212121;white-space: pre-wrap;">{{ ' 受控公开共享和领地公开共享,当等价类门限风险=0时,重标识风险总体风险公式为等价类重标识风险平均值*环境重标识攻击概率;当等价类门限风险!=0时,重标识风险总体风险为1。' }}</p> 329 </tr>
326 <p v-show="analysisResultInfo.rating >= 3" style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;color: #212121;white-space: pre-wrap;">{{ ' 依据《数据安全技术个人信息匿名化处理指南及评价方法(征求意见稿)》4.2,去标识化的数据集达到3级可展开对数据级的对抗性测试和不可复原性核验。对抗性测试关键变量如下表:' }}</p> 330 </thead>
327 <table border="0" cellspacing="0" v-show="analysisResultInfo.rating >= 3" 331 <tbody>
328 style="width:100%;word-break: break-all;margin: 4px auto 0px auto;text-align: center;border-collapse: collapse;color: #212121;"> 332 <tr v-for="(recordItem, j) in analysisResultInfo?.adversarialTest || []" :key="j">
329 <thead> 333 <td v-for="(columnItem, i) in adversarialTestFields" :key="i" :style="{ border: '0.5px solid #d9d9d9', 'text-align': <any>(columnItem.align ?? 'left') }">
330 <tr> 334 <span :style="{ 'word-break': 'break-all' }">
331 <th v-for="(item, index) in adversarialTestFields" :key="index" style="border: 0.5px solid #d9d9d9"> 335 {{ columnItem.field == 'index' ? (j + 1) : recordItem[columnItem.field] === 0 ? 0 : (recordItem[columnItem.field] || '--') }}
332 <span>{{ item.label }}</span> 336 </span>
333 </th> 337 </td>
334 </tr> 338 </tr>
335 </thead> 339 </tbody>
336 <tbody> 340 </table>
337 <tr v-for="(recordItem, j) in analysisResultInfo?.adversarialTest || []" :key="j"> 341 <p v-show="analysisResultInfo.rating >= 3" style="font-family: simsun;margin: 4px 0px 0px;font-size: 14px;line-height: 21px;color: #212121;white-space: pre-wrap;">{{ ' 通过识别关键变量,选择标识度高于0.5的属性作为攻击测试的关键变量,在攻击测试中,涉及到的攻击场景,其重标识概率均远小于所接受的风险水平0.05。另外,未发现任何其它可能的安全性问题。' }}</p>
338 <td v-for="(columnItem, i) in adversarialTestFields" :key="i" 342
339 :style="{ border: '0.5px solid #d9d9d9', 'text-align': <any>(columnItem.align ?? 'left') }"> 343 <!-- 指标说明 -->
340 <span :style="{ 'word-break': 'break-all' }"> 344 <div style="font-family: simsun;display: block;line-height: 21px;font-size: 14px;color: #212121;font-weight: 700;margin: 8px 0px;">{{ ' 指标说明:'}}</div>
341 {{ columnItem.field == 'index' ? (j + 1) : recordItem[columnItem.field] === 0 ? 0 : 345 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;color: #212121;margin-top: 8px;white-space: pre-wrap;">{{ ' 重标识风险最大值:所有等价类的重标识风险最大值;' }}</p>
342 (recordItem[columnItem.field] || '--') }} 346 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;color: #212121;white-space: pre-wrap;">{{ ' 重标识风险平均值:所有等价类的重标识风险平均值;' }}</p>
343 </span> 347 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;color: #212121;white-space: pre-wrap;">{{ ' 环境重标识攻击概率:完全公开共享数据发布,攻击者对数据集进行环境重标识攻击的概率为1。领地公开共享与受控公开共享数据发布,环境重标识攻击概率为内部故意攻击概率、数据集包含熟人概率和数据泄露概率三者的最大值;' }}</p>
344 </td> 348 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;color: #212121;white-space: pre-wrap;">{{ ' 等价类门限风险:完全公开共享数据发布,门限阈值取值1/20;受控公开共享数据发布,门限阈值取值 1/5;领地公开共享数据发布,门限阈值取值 1/3;等价类门限风险为:等价类的重标识风险大于门限阈值为1,小于等于为0,求和后除以等价类个数;' }}</p>
345 </tr> 349 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;color: #212121;white-space: pre-wrap;">{{ ' 重标识风险总体风险:完全公开共享,当等价类门限风险=0时,重标识风险总体风险公式为等价类重标识风险最大值*环境重标识攻击概率;当等价类门限风险!=0时,重标识风险总体风险为1。' }}</p>
346 </tbody> 350 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;color: #212121;white-space: pre-wrap;">{{ ' 受控公开共享和领地公开共享,当等价类门限风险=0时,重标识风险总体风险公式为等价类重标识风险平均值*环境重标识攻击概率;当等价类门限风险!=0时,重标识风险总体风险为1。' }}</p>
347 </table> 351
348 <p v-show="analysisResultInfo.rating >= 3" style="font-family: simsun;margin: 4px 0px 0px;font-size: 14px;line-height: 21px;color: #212121;white-space: pre-wrap;">{{ ' 通过识别关键变量,选择标识度高于0.5的属性作为攻击测试的关键变量,在攻击测试中,涉及到的攻击场景,其重标识概率均远小于所接受的风险水平0.05。另外,未发现任何其它可能的安全性问题。' }}</p> 352 <!-- 5. 评估结论与分级 -->
349 </div> 353 <h1 style="font-family: simsun;font-size: 18px;font-weight: 700;text-align: center;margin-top: 10px;margin-bottom: 10px;color: #212121;">五、评估结论与分级</h1>
354 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;font-weight: 700;">{{ ` 定性评估结论:${analysisResultInfo.rating == 2 ? '数据集已消除所有直接标识符,但未对准标识符进行了有效的泛化与抑制处理。' : (analysisResultInfo.rating == 4 ? '数据集无任何的直接标识符和准标识符。' : '数据集已消除所有直接标识符,并对准标识符进行了有效的泛化与抑制处理。')}` }}</p>
355 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;font-weight: 700;">{{ ` 定量评估结论:${analysisResultInfo.rating == 2 ? '数据集的重标识风险总体风险(1)大于预设的可接受风险阈值(0.05)。' : (analysisResultInfo.rating == 4 ? '数据集重标识风险总体风险为0。' : '数据集的重标识风险总体风险(1)小于等于预设的可接受风险阈值(0.05)。')}` }}</p>
356 <p style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;font-weight: 700;">{{ ` 最终评级:综合定性与定量评估结果,根据GB/T 42460-2023的分级标准,该${oldAnonTaskValueInfo.taskName}的匿名化效果评定为${analysisResultInfo.rating}级${analysisResultInfo.rating <=2 ? '(重标识风险较高)' : ''}。` }}</p>
357
358 <!-- 6. 建议与改进 -->
359 <h1 v-show="analysisResultInfo.rating <= 2" style="font-family: simsun;font-size: 18px;font-weight: 700;text-align: center;margin-top: 10px;margin-bottom: 10px;color: #212121;">六、建议与改进</h1>
360 <p v-show="analysisResultInfo.rating <= 2" style="font-family: simsun;margin: 0px;font-size: 14px;line-height: 21px;white-space: pre-wrap;color: #212121;">{{ ` 需要对准标识符${analysisResultInfo.qualifiedIdentifier?.map(f => f.chName)?.join('、')}做有效的泛化和抑制,满足 k-匿名要求(设定k≥10) ,从而使得该数据集适用于受控环境下进行跨机构流通。` }}</p>
361 </div>
350 </div> 362 </div>
351 </template> 363 </template>
352 <script lang="ts" setup name="anonResultAnalysis"> 364 <script lang="ts" setup name="anonResultAnalysis">
...@@ -356,7 +368,7 @@ import Moment from 'moment'; ...@@ -356,7 +368,7 @@ import Moment from 'moment';
356 import { 368 import {
357 downDicomPath, 369 downDicomPath,
358 } from '@/api/modules/dataAnonymization'; 370 } from '@/api/modules/dataAnonymization';
359 import { download } from '@/utils/common'; 371 import { changeNum, download } from '@/utils/common';
360 import { ElMessage } from 'element-plus'; 372 import { ElMessage } from 'element-plus';
361 373
362 const props = defineProps({ 374 const props = defineProps({
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!