支持dicom文件
Showing
5 changed files
with
565 additions
and
50 deletions
| ... | @@ -351,3 +351,25 @@ export const htmlToWord = (params) => request({ | ... | @@ -351,3 +351,25 @@ export const htmlToWord = (params) => request({ |
| 351 | data: params, | 351 | data: params, |
| 352 | responseType: 'blob' | 352 | responseType: 'blob' |
| 353 | }) | 353 | }) |
| 354 | |||
| 355 | export const scanFolder = (dirPath = '') => request({ | ||
| 356 | url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/directory/scan?dirPath=${dirPath}`, | ||
| 357 | method: 'get' | ||
| 358 | }) | ||
| 359 | |||
| 360 | /** 获取扫描文件结果 */ | ||
| 361 | export const getDicomMeta = (taskGuid) => request({ | ||
| 362 | url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/get-dicom-meta?taskGuid=${taskGuid}`, | ||
| 363 | method: 'get' | ||
| 364 | }) | ||
| 365 | |||
| 366 | /** 获取扫描文件统计结果 */ | ||
| 367 | export const getDicomStatistics = (taskGuid) => request({ | ||
| 368 | url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/get-dicom-statistics?taskGuid=${taskGuid}`, | ||
| 369 | method: 'get' | ||
| 370 | }) | ||
| 371 | |||
| 372 | export const retryDicom = (taskGuid) => request({ | ||
| 373 | url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/anon-task/dicom/retry?taskGuid=${taskGuid}`, | ||
| 374 | method: 'get' | ||
| 375 | }) | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -273,7 +273,7 @@ defineExpose({ | ... | @@ -273,7 +273,7 @@ defineExpose({ |
| 273 | 273 | ||
| 274 | <template v-else-if="prefixInfo"> | 274 | <template v-else-if="prefixInfo"> |
| 275 | <span class="prefix-icon" style="margin-right: 4px"> | 275 | <span class="prefix-icon" style="margin-right: 4px"> |
| 276 | <template v-if="data.type < 2"> | 276 | <template v-if="data.type < 2 || data.type == 'DIRECTORY'"> |
| 277 | <el-icon v-if="node.expanded"> | 277 | <el-icon v-if="node.expanded"> |
| 278 | <svg-icon name="file-open" /> | 278 | <svg-icon name="file-open" /> |
| 279 | </el-icon> | 279 | </el-icon> | ... | ... |
| ... | @@ -862,8 +862,10 @@ export const tagMethod = (row, type) => { | ... | @@ -862,8 +862,10 @@ export const tagMethod = (row, type) => { |
| 862 | tag = '未执行'; | 862 | tag = '未执行'; |
| 863 | } else if (row[type] == 'E') { //部分通过 | 863 | } else if (row[type] == 'E') { //部分通过 |
| 864 | tag = '失败'; | 864 | tag = '失败'; |
| 865 | }else if (row[type] == 'R') { //部分通过 | 865 | } else if (row[type] == 'R') { //部分通过 |
| 866 | tag = '执行中'; | 866 | tag = '执行中'; |
| 867 | } else { | ||
| 868 | tag = '--' | ||
| 867 | } | 869 | } |
| 868 | } else if (type == 'sensitiveIdentifyConfirmStatus') { | 870 | } else if (type == 'sensitiveIdentifyConfirmStatus') { |
| 869 | if (row[type] == 'Y') { | 871 | if (row[type] == 'Y') { | ... | ... |
| ... | @@ -4,7 +4,6 @@ | ... | @@ -4,7 +4,6 @@ |
| 4 | 4 | ||
| 5 | <script lang="ts" setup name="anonResultReportView"> | 5 | <script lang="ts" setup name="anonResultReportView"> |
| 6 | import { | 6 | import { |
| 7 | exportAnonReport, | ||
| 8 | getAnonAnalyzePageData, | 7 | getAnonAnalyzePageData, |
| 9 | getAnonAnalyzeResult, | 8 | getAnonAnalyzeResult, |
| 10 | getAnonTaskDetail, | 9 | getAnonTaskDetail, |
| ... | @@ -253,15 +252,16 @@ onBeforeMount(() => { | ... | @@ -253,15 +252,16 @@ onBeforeMount(() => { |
| 253 | 252 | ||
| 254 | <template> | 253 | <template> |
| 255 | <div class="table_tool_wrap" v-loading="resultDataLoading" ref="containerRef" :element-loading-text="loadingText"> | 254 | <div class="table_tool_wrap" v-loading="resultDataLoading" ref="containerRef" :element-loading-text="loadingText"> |
| 256 | <el-button v-show="!isWordStyle" style="margin-bottom: 8px;" type="primary" @click="transfer" | 255 | <!-- 连接器不需要显示下载报告按钮 --> |
| 256 | <!-- <el-button v-show="!isWordStyle" style="margin-bottom: 8px;" type="primary" @click="transfer" | ||
| 257 | v-preReClick>生成Word评估报告</el-button> | 257 | v-preReClick>生成Word评估报告</el-button> |
| 258 | <div v-show="isWordStyle" style="margin-bottom: 8px;"> | 258 | <div v-show="isWordStyle" style="margin-bottom: 8px;"> |
| 259 | <el-button @click="isWordStyle = false">返回</el-button> | 259 | <el-button @click="isWordStyle = false">返回</el-button> |
| 260 | <el-button type="primary" @click="downloadWord">下载评估报告</el-button> | 260 | <el-button type="primary" @click="downloadWord">下载评估报告</el-button> |
| 261 | </div> | 261 | </div> --> |
| 262 | <anonResultAnalysis ref="resultReportRef" :show-title="true" :analysis-result-info="analysisResultInfo" | 262 | <anonResultAnalysis ref="resultReportRef" :show-title="true" :analysis-result-info="analysisResultInfo" |
| 263 | :isWordStyle="isWordStyle" :style="isWordStyle ? { | 263 | :isWordStyle="isWordStyle" :style="isWordStyle ? { |
| 264 | height: 'calc(100% - 36px)', | 264 | height: '100%', |
| 265 | 'overflow-y': 'auto', | 265 | 'overflow-y': 'auto', |
| 266 | 'margin-right': '-16px', | 266 | 'margin-right': '-16px', |
| 267 | 'padding-right': '16px', | 267 | 'padding-right': '16px', | ... | ... |
| ... | @@ -51,47 +51,87 @@ | ... | @@ -51,47 +51,87 @@ |
| 51 | <ContentWrap v-show="formRef?.formInline?.dataSource == 3" id="id-folder" title="提取文件" description="" | 51 | <ContentWrap v-show="formRef?.formInline?.dataSource == 3" id="id-folder" title="提取文件" description="" |
| 52 | style="margin-top: 16px;"> | 52 | style="margin-top: 16px;"> |
| 53 | <div class="folder-main"> | 53 | <div class="folder-main"> |
| 54 | <el-upload ref="uploadRef" class="upload-file" action="#" :file-list="folderList" :limit="1" directory | 54 | <el-button v-show="!clickSelectNode.path && !Object.keys(dicomStatisticsData)?.length" :icon="Upload" |
| 55 | :http-request="(file) => hanlderUploadFolder(file)"> | 55 | class="mr8" @click=uploadFolder>上传文件</el-button> |
| 56 | <template #trigger> | 56 | <Dialog ref="dialogRef" :dialog-info="uploadFileDialogInfo" @btnClick="dialogBtnClick"> |
| 57 | <el-button :icon="Upload" class="mr8">上传文件</el-button> | 57 | <template #extra-content> |
| 58 | <div class="folder-main-content" v-loading="uploadFileDialogInfo.contentLoading"> | ||
| 59 | <Tree ref="treeInfoRef" :treeInfo="folderTreeInfo" @nodeClick="nodeClick" key="path" | ||
| 60 | @loadNode="loadFolderTreeNode" /> | ||
| 61 | </div> | ||
| 62 | <div class="folder-foot">{{ '当前选中文件夹路径:' + (clickSelectNode.path || '--') }}</div> | ||
| 58 | </template> | 63 | </template> |
| 59 | </el-upload> | 64 | </Dialog> |
| 65 | <div v-show="clickSelectNode.path && dicomStatisticsData.state" class="folder-foot">{{ '当前提取文件夹路径:' + | ||
| 66 | (clickSelectNode.path || '--') }} | ||
| 67 | </div> | ||
| 68 | <!-- 正在扫描的状态 --> | ||
| 69 | <div class="folder-progress" | ||
| 70 | v-show="clickSelectNode.path && (dicomStatisticsData.state == 'S' || !Object.keys(dicomStatisticsData)?.length)"> | ||
| 71 | <div class="folder-title">正在扫描</div> | ||
| 72 | <el-progress :percentage="dicomStatisticsData.progress || 0" :stroke-width="12" striped striped-flow | ||
| 73 | :show-text="false" :duration="8" /> | ||
| 74 | <div v-show="Object.keys(dicomStatisticsData)?.length" style="display: flex;justify-content: space-between;"><span class="cnt">{{ '共扫描' + | ||
| 75 | changeNum(dicomStatisticsData.total, 0) + '个文件' }}</span><span v-show="dicomStatisticsData.remainingTime" class="desc">{{ '剩' + | ||
| 76 | transferTime(dicomStatisticsData.remainingTime) | ||
| 77 | }}</span></div> | ||
| 78 | </div> | ||
| 60 | <!-- 正在解析的状态 --> | 79 | <!-- 正在解析的状态 --> |
| 61 | <div class="folder-progress"> | 80 | <div class="folder-progress" |
| 81 | v-show="clickSelectNode.path && (dicomStatisticsData.state == 'R')"> | ||
| 62 | <div class="folder-title">正在解析</div> | 82 | <div class="folder-title">正在解析</div> |
| 63 | <el-progress :percentage="30" :stroke-width="12" striped striped-flow :show-text="false" :duration="8" /> | 83 | <el-progress :percentage="dicomStatisticsData.progress || 0" :stroke-width="12" striped striped-flow |
| 64 | <div style="display: flex;"><span class="cnt">{{ '共' + changeNum(100, 0) + '个文件, 已解析30%' }}</span></div> | 84 | :show-text="false" :duration="8" /> |
| 85 | <div style="display: flex;justify-content: space-between;"><span class="cnt">{{ '共' + | ||
| 86 | changeNum(dicomStatisticsData.total, 0) + | ||
| 87 | '个文件, 已解析' | ||
| 88 | + (dicomStatisticsData.progress || 0) + '%' }}</span><span v-show="dicomStatisticsData.remainingTime" class="desc">{{ '剩' + | ||
| 89 | transferTime(dicomStatisticsData.remainingTime) | ||
| 90 | }}</span></div> | ||
| 65 | </div> | 91 | </div> |
| 66 | <!-- 解析失败的状态 --> | 92 | <!-- 解析失败的状态 --> |
| 67 | <div class="folder-progress"> | 93 | <div class="folder-progress" v-show="clickSelectNode.path && dicomStatisticsData.state == 'E'"> |
| 68 | <div class="folder-title"> | 94 | <div class="folder-title"> |
| 69 | <el-icon class="title-icon fail"> | 95 | <el-icon class="title-icon fail"> |
| 70 | <CircleCloseFilled /> | 96 | <CircleCloseFilled /> |
| 71 | </el-icon><span>解析失败</span> | 97 | </el-icon><span>解析失败</span> |
| 72 | </div> | 98 | </div> |
| 73 | <el-progress :percentage="30" :stroke-width="12" color="#F30000" :show-text="false" /> | 99 | <el-progress :percentage="dicomStatisticsData.progress || 0" :stroke-width="12" color="#F30000" |
| 74 | <div style="display: flex;"><span class="cnt">{{ '已成功解析' + changeNum(100, 0) + '个文件, 失败' + changeNum(30, | 100 | :show-text="false" /> |
| 75 | 0) + | 101 | <div style="display: flex;justify-content: space-between;"><span class="cnt">{{ '已成功解析' + |
| 76 | '个文件' }}</span></div> | 102 | changeNum(dicomStatisticsData.successCount, 0) + '个文件, 失败' + changeNum(dicomStatisticsData.errorCount, |
| 103 | 0) + '个文件' }}</span><span class="desc">{{ '共耗时' | ||
| 104 | + calculateElapsedTime(dicomStatisticsData.parsingTime, dicomStatisticsData.parsingCompletedTime) | ||
| 105 | }}</span></div> | ||
| 77 | <div style="text-align: center;"> | 106 | <div style="text-align: center;"> |
| 78 | <el-button @click="reAnalyzing">重试</el-button> | 107 | <el-button @click="reAnalyzing">重试</el-button> |
| 108 | <el-button @click=deleteFolder>删除文件,重新上传解析</el-button> | ||
| 79 | </div> | 109 | </div> |
| 80 | </div> | 110 | </div> |
| 81 | <!-- 解析成功状态 --> | 111 | <!-- 解析成功状态 --> |
| 82 | <div class="folder-progress"> | 112 | <div class="folder-progress" |
| 113 | v-show="clickSelectNode.path && dicomStatisticsData.state == 'Y' && dicomStatisticsData.errorCount === 0"> | ||
| 83 | <div class="folder-title"> | 114 | <div class="folder-title"> |
| 84 | <el-icon class="title-icon success"> | 115 | <el-icon class="title-icon success"> |
| 85 | <svg-icon name="icon-success" /> | 116 | <svg-icon name="icon-success" /> |
| 86 | </el-icon><span>解析成功</span> | 117 | </el-icon><span>解析成功</span> |
| 87 | </div> | 118 | </div> |
| 88 | <el-progress :percentage="30" :stroke-width="12" color="#F30000" :show-text="false" /> | 119 | <el-progress :percentage="dicomStatisticsData.progress || 100" :stroke-width="12" color="#4FA55D" |
| 89 | <div style="display: flex;"><span class="cnt">{{ '已成功解析' + changeNum(100, 0) + '个文件, 失败' + changeNum(30, | 120 | :show-text="false" /> |
| 90 | 0) + | 121 | <div style="display: flex;justify-content: space-between;"><span class="cnt">{{ '已成功解析' + |
| 91 | '个文件' }}</span></div> | 122 | changeNum(dicomStatisticsData.successCount, 0) |
| 123 | + '个文件,失败' + changeNum(dicomStatisticsData.errorCount, 0) + '个文件' }}</span><span class="desc">{{ '共耗时' | ||
| 124 | + calculateElapsedTime(dicomStatisticsData.parsingTime, dicomStatisticsData.parsingCompletedTime) | ||
| 125 | }}</span> | ||
| 92 | </div> | 126 | </div> |
| 93 | </div> | 127 | </div> |
| 94 | 128 | </div> | |
| 129 | <div v-show="clickSelectNode.path && folderFileTableInfo.data?.length" class="preview-title">预览文件仅展示5条数据 | ||
| 130 | </div> | ||
| 131 | <Table v-show="clickSelectNode.path && folderFileTableInfo.data?.length" :tableInfo="folderFileTableInfo"> | ||
| 132 | </Table> | ||
| 133 | <div v-show="clickSelectNode.path && dicomStatisticsData.state == 'Y'" class="folder-bottom"><el-button | ||
| 134 | @click=deleteFolder>删除文件,重新上传解析</el-button></div> | ||
| 95 | </ContentWrap> | 135 | </ContentWrap> |
| 96 | </div> | 136 | </div> |
| 97 | <!-- 第二步 配置匿名化方案,单独抽取vue组件页面 --> | 137 | <!-- 第二步 配置匿名化方案,单独抽取vue组件页面 --> |
| ... | @@ -116,20 +156,22 @@ | ... | @@ -116,20 +156,22 @@ |
| 116 | <div v-show="analysisResultInfo.errorMsg" class="error-desc">{{ '【' + analysisResultInfo.errorMsg + '】' }} | 156 | <div v-show="analysisResultInfo.errorMsg" class="error-desc">{{ '【' + analysisResultInfo.errorMsg + '】' }} |
| 117 | </div> | 157 | </div> |
| 118 | </div> | 158 | </div> |
| 119 | <anonResultAnalysis v-show="isExecEnd && analysisResultInfo.status == 'Y'" ref="resultReportRef" v-loading="downloadLoading" | 159 | <anonResultAnalysis v-show="isExecEnd && analysisResultInfo.status == 'Y'" ref="resultReportRef" |
| 120 | :analysis-result-info="analysisResultInfo" :is-word-style="isWordStyle" :element-loading-text="loadingText" | 160 | v-loading="downloadLoading" :analysis-result-info="analysisResultInfo" :is-word-style="isWordStyle" |
| 121 | :analysis-result-loading="analysisResultLoading" :analysis-result-table-fields="analysisResultTableFields" | 161 | :element-loading-text="loadingText" :analysis-result-loading="analysisResultLoading" |
| 122 | :old-anon-task-value-info="oldAnonTaskValueInfo" :container-width="containerWidth" | 162 | :analysis-result-table-fields="analysisResultTableFields" :old-anon-task-value-info="oldAnonTaskValueInfo" |
| 123 | :origin-result-table-field-column="originResultTableFieldColumn" :page-info="pageInfo" | 163 | :container-width="containerWidth" :origin-result-table-field-column="originResultTableFieldColumn" |
| 124 | :result-data="resultData" :fullResultData="fullResultData" @page-change="pageChange"></anonResultAnalysis> | 164 | :page-info="pageInfo" :result-data="resultData" :fullResultData="fullResultData" @page-change="pageChange"> |
| 125 | <template #header> | 165 | </anonResultAnalysis> |
| 166 | <!-- 连接器只能查看报告 --> | ||
| 167 | <!-- <template #header> | ||
| 126 | <el-button v-show="isExecEnd && analysisResultInfo.status == 'Y' && !isWordStyle" type="primary" | 168 | <el-button v-show="isExecEnd && analysisResultInfo.status == 'Y' && !isWordStyle" type="primary" |
| 127 | v-loading="!!downPromise" @click="transfer">生成Word评估报告</el-button> | 169 | v-loading="!!downPromise" @click="transfer">生成Word评估报告</el-button> |
| 128 | <div v-show="isWordStyle"> | 170 | <div v-show="isWordStyle"> |
| 129 | <el-button @click="isWordStyle = false">返回</el-button> | 171 | <el-button @click="isWordStyle = false">返回</el-button> |
| 130 | <el-button type="primary" @click="downloadWord">下载评估报告</el-button> | 172 | <el-button type="primary" @click="downloadWord">下载评估报告</el-button> |
| 131 | </div> | 173 | </div> |
| 132 | </template> | 174 | </template> --> |
| 133 | </ContentWrap> | 175 | </ContentWrap> |
| 134 | </div> | 176 | </div> |
| 135 | <!-- 匿名化结果展示 --> | 177 | <!-- 匿名化结果展示 --> |
| ... | @@ -146,7 +188,9 @@ | ... | @@ -146,7 +188,9 @@ |
| 146 | <div class="bottom_tool_wrap"> | 188 | <div class="bottom_tool_wrap"> |
| 147 | <template v-if="step == 0"> | 189 | <template v-if="step == 0"> |
| 148 | <el-button @click="cancelTask">取消</el-button> | 190 | <el-button @click="cancelTask">取消</el-button> |
| 149 | <el-button type="primary" @click="changeStep(formRef?.formInline?.handleType == '02' ? 3 : 2)">下一步</el-button> | 191 | <el-button type="primary" |
| 192 | :disabled="formRef?.formInline?.handleType == '02' && formRef?.formInline?.dataSource == 3 && dicomStatisticsData?.progress != 100" | ||
| 193 | @click="changeStep(formRef?.formInline?.handleType == '02' ? 3 : 2)">下一步</el-button> | ||
| 150 | </template> | 194 | </template> |
| 151 | <template v-else-if="step == 1"> | 195 | <template v-else-if="step == 1"> |
| 152 | <el-button @click="changeStep(1)">上一步</el-button> | 196 | <el-button @click="changeStep(1)">上一步</el-button> |
| ... | @@ -184,8 +228,11 @@ import { | ... | @@ -184,8 +228,11 @@ import { |
| 184 | saveAnonTask, | 228 | saveAnonTask, |
| 185 | updateAnonTask, | 229 | updateAnonTask, |
| 186 | exportAnonExecData, | 230 | exportAnonExecData, |
| 187 | exportAnonReport, | ||
| 188 | htmlToWord, | 231 | htmlToWord, |
| 232 | scanFolder, | ||
| 233 | getDicomMeta, | ||
| 234 | getDicomStatistics, | ||
| 235 | retryDicom | ||
| 189 | } from '@/api/modules/dataAnonymization'; | 236 | } from '@/api/modules/dataAnonymization'; |
| 190 | import { | 237 | import { |
| 191 | parseAndDecodeUrl, | 238 | parseAndDecodeUrl, |
| ... | @@ -228,6 +275,38 @@ const { required } = useValidator(); | ... | @@ -228,6 +275,38 @@ const { required } = useValidator(); |
| 228 | const fullscreenLoading = ref(false); | 275 | const fullscreenLoading = ref(false); |
| 229 | const containerRef = ref(); | 276 | const containerRef = ref(); |
| 230 | 277 | ||
| 278 | const qualifiedIdentifierFloderList = ref([{ | ||
| 279 | enName: 'patient_birth_date', | ||
| 280 | chName: '患者出生日期', | ||
| 281 | }, { | ||
| 282 | enName: 'patient_birth_time', | ||
| 283 | chName: '患者出生时间' | ||
| 284 | }, { | ||
| 285 | enName: 'patient_sex', | ||
| 286 | chName: '患者性别' | ||
| 287 | }, { | ||
| 288 | enName: 'patient_age', | ||
| 289 | chName: '患者年龄' | ||
| 290 | }, { | ||
| 291 | enName: 'patient_weight', | ||
| 292 | chName: '患者体重' | ||
| 293 | }, { | ||
| 294 | enName: 'pregnancy_status', | ||
| 295 | chName: '怀孕状态' | ||
| 296 | }, { | ||
| 297 | enName: 'military_rank', | ||
| 298 | chName: '军衔' | ||
| 299 | }, { | ||
| 300 | enName: 'branch_of_service', | ||
| 301 | chName: '服役分支' | ||
| 302 | }, { | ||
| 303 | enName: 'ethnic_group', | ||
| 304 | chName: '种族' | ||
| 305 | }, { | ||
| 306 | enName: 'occupation', | ||
| 307 | chName: '职业' | ||
| 308 | }]); | ||
| 309 | |||
| 231 | const containerWidth = ref(containerRef.value?.offsetWidth || 0) | 310 | const containerWidth = ref(containerRef.value?.offsetWidth || 0) |
| 232 | 311 | ||
| 233 | const step = ref(0); | 312 | const step = ref(0); |
| ... | @@ -607,6 +686,9 @@ const setDataSelectFormItems = (info, isDetail = false) => { | ... | @@ -607,6 +686,9 @@ const setDataSelectFormItems = (info, isDetail = false) => { |
| 607 | } | 686 | } |
| 608 | } else if (item.field == 'qualifiedIdentifier') { | 687 | } else if (item.field == 'qualifiedIdentifier') { |
| 609 | item.visible = info['handleType'] == '02'; | 688 | item.visible = info['handleType'] == '02'; |
| 689 | if (info['dataSource'] == 3) { | ||
| 690 | item.options = qualifiedIdentifierFloderList.value; | ||
| 691 | } | ||
| 610 | } | 692 | } |
| 611 | }); | 693 | }); |
| 612 | stepsInfo.value = info.handleType == '02' ? reportStepsInfo.value : originStepsInfo.value; | 694 | stepsInfo.value = info.handleType == '02' ? reportStepsInfo.value : originStepsInfo.value; |
| ... | @@ -734,9 +816,12 @@ watch( | ... | @@ -734,9 +816,12 @@ watch( |
| 734 | ); | 816 | ); |
| 735 | 817 | ||
| 736 | watch(() => sampleTableFields.value, (val) => { | 818 | watch(() => sampleTableFields.value, (val) => { |
| 819 | let formInfo = formRef.value.formInline; | ||
| 820 | if (formInfo.dataSource == 3) { | ||
| 821 | return; | ||
| 822 | } | ||
| 737 | let item = dataSelectInfoItems.value.find(selectItem => selectItem.field == 'qualifiedIdentifier'); | 823 | let item = dataSelectInfoItems.value.find(selectItem => selectItem.field == 'qualifiedIdentifier'); |
| 738 | item && (item.options = val); | 824 | item && (item.options = val); |
| 739 | let formInfo = formRef.value.formInline; | ||
| 740 | if (formInfo.handleType == '02' && !(taskGuid.value && (formInfo.file?.[0] && formInfo.file?.[0]?.url == detailInfo.value.filePath?.url || (formInfo.tableName && formInfo.tableName == detailInfo.value.tableName)))) {//需要同步清除准标识符的字段选择 | 825 | if (formInfo.handleType == '02' && !(taskGuid.value && (formInfo.file?.[0] && formInfo.file?.[0]?.url == detailInfo.value.filePath?.url || (formInfo.tableName && formInfo.tableName == detailInfo.value.tableName)))) {//需要同步清除准标识符的字段选择 |
| 741 | setDataSelectFormItems(Object.assign({}, formInfo, { file: !formInfo['file'] ? [] : formInfo['file'], qualifiedIdentifier: [] })) | 826 | setDataSelectFormItems(Object.assign({}, formInfo, { file: !formInfo['file'] ? [] : formInfo['file'], qualifiedIdentifier: [] })) |
| 742 | } | 827 | } |
| ... | @@ -902,16 +987,343 @@ const uploadFileChange = (file) => { | ... | @@ -902,16 +987,343 @@ const uploadFileChange = (file) => { |
| 902 | } | 987 | } |
| 903 | 988 | ||
| 904 | /*** ----------------------- 解析扫描文件 ------------------------------ */ | 989 | /*** ----------------------- 解析扫描文件 ------------------------------ */ |
| 905 | const folderList: any = ref([]); | ||
| 906 | 990 | ||
| 907 | const hanlderUploadFolder = (file) => { | 991 | /** 上传选择文件夹对话框 */ |
| 908 | debugger | 992 | const uploadFileDialogInfo = ref({ |
| 909 | return Promise.resolve(); | 993 | visible: false, |
| 994 | size: 700, | ||
| 995 | direction: "column", | ||
| 996 | header: { | ||
| 997 | title: "选择文件夹", | ||
| 998 | }, | ||
| 999 | type: '', | ||
| 1000 | contents: [], | ||
| 1001 | footer: { | ||
| 1002 | btns: [ | ||
| 1003 | { type: "default", label: "取消", value: "cancel" }, | ||
| 1004 | { type: "primary", label: "确定", value: "submit", loading: false }, | ||
| 1005 | ], | ||
| 1006 | }, | ||
| 1007 | contentLoading: false, | ||
| 1008 | }); | ||
| 1009 | |||
| 1010 | const folderRefreshTimer = ref(); | ||
| 1011 | |||
| 1012 | const processFolderRefresh = async () => { | ||
| 1013 | await getDicomStatisticsData(taskGuid.value); | ||
| 1014 | if (!dicomStatisticsData.value.state || dicomStatisticsData.value.state == 'S' || dicomStatisticsData.value.state == 'R') { | ||
| 1015 | if (folderRefreshTimer.value) { | ||
| 1016 | return; | ||
| 1017 | } | ||
| 1018 | folderRefreshTimer.value = setInterval(async () => { | ||
| 1019 | processFolderRefresh(); | ||
| 1020 | }, 10000); | ||
| 1021 | } else if (dicomStatisticsData.value.state == 'Y') { | ||
| 1022 | getDicomMetaData(taskGuid.value); | ||
| 1023 | analysisResultInfo.value = {}; | ||
| 1024 | if (folderRefreshTimer.value) { | ||
| 1025 | clearInterval(folderRefreshTimer.value); | ||
| 1026 | folderRefreshTimer.value = null; | ||
| 1027 | } | ||
| 1028 | // processStepThreeResultView(); | ||
| 1029 | } else if (dicomStatisticsData.value.state == 'E') { | ||
| 1030 | if (folderRefreshTimer.value) { | ||
| 1031 | clearInterval(folderRefreshTimer.value); | ||
| 1032 | folderRefreshTimer.value = null; | ||
| 1033 | } | ||
| 1034 | } | ||
| 1035 | } | ||
| 1036 | |||
| 1037 | // TODO,需要将selectNode与oldSelectNode即对话框展开的做区分处理。 | ||
| 1038 | |||
| 1039 | const dialogBtnClick = (btn) => { | ||
| 1040 | if (btn.value == 'submit') { | ||
| 1041 | clickSelectNode.value = dialogOpenSelectNode.value; | ||
| 1042 | if (!clickSelectNode.value.path) { | ||
| 1043 | proxy.$ElMessage.error('请先选择文件夹'); | ||
| 1044 | return; | ||
| 1045 | } | ||
| 1046 | let saveParams = { ...formRef.value.formInline }; | ||
| 1047 | if (saveParams.coverageArea?.length) { | ||
| 1048 | saveParams.coverageArea = [saveParams.coverageArea]; | ||
| 1049 | } else { | ||
| 1050 | saveParams.coverageArea = []; | ||
| 1051 | } | ||
| 1052 | saveParams.filePath = { | ||
| 1053 | url: clickSelectNode.value.path | ||
| 1054 | }; | ||
| 1055 | saveParams.samplingRate = null; | ||
| 1056 | if (taskGuid.value) { | ||
| 1057 | saveParams.guid = taskGuid.value; | ||
| 1058 | } | ||
| 1059 | dicomStatisticsData.value = {}; | ||
| 1060 | folderFileTableInfo.value.data = []; | ||
| 1061 | if (!taskGuid.value) { //保存 | ||
| 1062 | uploadFileDialogInfo.value.footer.btns[1].loading = true; | ||
| 1063 | saveAnonTask(saveParams).then(async (res: any) => { | ||
| 1064 | uploadFileDialogInfo.value.footer.btns[1].loading = false; | ||
| 1065 | if (res.code == proxy.$passCode) { | ||
| 1066 | taskGuid.value = res.data?.taskGuid; | ||
| 1067 | taskExecGuid.value = res.data?.lastExecGuid; | ||
| 1068 | uploadFileDialogInfo.value.visible = false; | ||
| 1069 | anonymizationStore.setIsAnonPageRefresh(true); | ||
| 1070 | isExecEnd.value = false; | ||
| 1071 | oldAnonTaskValueInfo.value = saveParams; | ||
| 1072 | oldAnonTaskValueInfo.value.guid = taskGuid.value; | ||
| 1073 | if (folderRefreshTimer.value) { | ||
| 1074 | clearInterval(folderRefreshTimer.value); | ||
| 1075 | folderRefreshTimer.value = null; | ||
| 1076 | } | ||
| 1077 | await 100; | ||
| 1078 | processFolderRefresh(); | ||
| 1079 | } else { | ||
| 1080 | ElMessage.error(res.msg); | ||
| 1081 | } | ||
| 1082 | }); | ||
| 1083 | } else { //更新 | ||
| 1084 | uploadFileDialogInfo.value.footer.btns[1].loading = true; | ||
| 1085 | updateAnonTask(saveParams).then(async (res: any) => { | ||
| 1086 | uploadFileDialogInfo.value.footer.btns[1].loading = false; | ||
| 1087 | if (res.code == proxy.$passCode) { | ||
| 1088 | taskExecGuid.value = res.data; | ||
| 1089 | uploadFileDialogInfo.value.visible = false; | ||
| 1090 | anonymizationStore.setIsAnonPageRefresh(true); | ||
| 1091 | isExecEnd.value = false; | ||
| 1092 | oldAnonTaskValueInfo.value = saveParams; | ||
| 1093 | if (folderRefreshTimer.value) { | ||
| 1094 | clearInterval(folderRefreshTimer.value); | ||
| 1095 | folderRefreshTimer.value = null; | ||
| 1096 | } | ||
| 1097 | await 100; | ||
| 1098 | processFolderRefresh(); | ||
| 1099 | } else { | ||
| 1100 | ElMessage.error(res.msg); | ||
| 1101 | } | ||
| 1102 | }) | ||
| 1103 | } | ||
| 1104 | } else if (btn.value == 'cancel') { | ||
| 1105 | // clickSelectNode.value = {}; | ||
| 1106 | dialogOpenSelectNode.value = {}; | ||
| 1107 | uploadFileDialogInfo.value.visible = false; | ||
| 1108 | } | ||
| 1109 | }; | ||
| 1110 | |||
| 1111 | const folderTreeInfo = ref({ | ||
| 1112 | id: "data-pickup-tree", | ||
| 1113 | filter: true, | ||
| 1114 | queryValue: "", | ||
| 1115 | queryPlaceholder: "输入关键字搜索", | ||
| 1116 | props: { | ||
| 1117 | label: "name", | ||
| 1118 | value: "path", | ||
| 1119 | isLeaf: "isLeaf", | ||
| 1120 | }, | ||
| 1121 | prefix: { | ||
| 1122 | type: 'prefixIcon' | ||
| 1123 | }, | ||
| 1124 | nodeKey: 'path', | ||
| 1125 | lazy: true, | ||
| 1126 | expandedKey: [], | ||
| 1127 | currentNodeKey: '', | ||
| 1128 | expandOnNodeClick: true, | ||
| 1129 | data: <any>[], | ||
| 1130 | //customFilter: true, | ||
| 1131 | loading: false | ||
| 1132 | }); | ||
| 1133 | |||
| 1134 | const clickSelectNode: any = ref({}); | ||
| 1135 | |||
| 1136 | const nodeClick = (data, node) => { | ||
| 1137 | dialogOpenSelectNode.value = data; | ||
| 1138 | } | ||
| 1139 | |||
| 1140 | const loadFolderTreeNode = (node, resolve) => { | ||
| 1141 | if (node.level === 0 || node.isLeaf) { | ||
| 1142 | return resolve([]); | ||
| 1143 | } | ||
| 1144 | scanFolder(node.data.path).then((res: any) => { | ||
| 1145 | if (res?.code == proxy.$passCode) { | ||
| 1146 | resolve(res.data || []); | ||
| 1147 | } else { | ||
| 1148 | ElMessage.error(res.msg); | ||
| 1149 | } | ||
| 1150 | }) | ||
| 1151 | } | ||
| 1152 | |||
| 1153 | const dialogOpenSelectNode: any = ref({}) | ||
| 1154 | |||
| 1155 | const uploadFolder = () => { | ||
| 1156 | // 先检查信息是否填写完整。 | ||
| 1157 | formRef.value?.ruleFormRef?.validate((valid) => { | ||
| 1158 | if (valid) { | ||
| 1159 | let formInline = formRef.value?.formInline; | ||
| 1160 | if (formInline.handleType == '01' && formInline.dataSource == 3) { | ||
| 1161 | proxy.$ElMessage.warning('暂不支持处理类型为数据匿名化处理的文件夹数据,请修改'); | ||
| 1162 | return; | ||
| 1163 | } | ||
| 1164 | clickSelectNode.value = {}; | ||
| 1165 | dialogOpenSelectNode.value = {}; | ||
| 1166 | uploadFileDialogInfo.value.visible = true; | ||
| 1167 | folderTreeInfo.value.loading = true; | ||
| 1168 | scanFolder().then((res: any) => { | ||
| 1169 | folderTreeInfo.value.loading = false; | ||
| 1170 | if (res?.code == proxy.$passCode) { | ||
| 1171 | folderTreeInfo.value.data = res.data || []; | ||
| 1172 | } else { | ||
| 1173 | ElMessage.error(res.msg); | ||
| 1174 | } | ||
| 1175 | }) | ||
| 1176 | } else { | ||
| 1177 | proxy.$ElMessage.warning('请先填写完整数据选择基本信息'); | ||
| 1178 | } | ||
| 1179 | }) | ||
| 1180 | } | ||
| 1181 | |||
| 1182 | const deleteFolder = () => { | ||
| 1183 | proxy.$openMessageBox("确定要删除该文件夹扫描解析结果,重新上传吗?", () => { | ||
| 1184 | clickSelectNode.value = {}; | ||
| 1185 | folderFileTableInfo.value.data = []; | ||
| 1186 | dicomStatisticsData.value = {}; | ||
| 1187 | }, () => { | ||
| 1188 | proxy.$ElMessage.info("已取消删除"); | ||
| 1189 | }) | ||
| 910 | } | 1190 | } |
| 911 | 1191 | ||
| 912 | /** 重试 */ | 1192 | /** 重试 */ |
| 913 | const reAnalyzing = () => { | 1193 | const reAnalyzing = () => { |
| 1194 | fullscreenLoading.value = true; | ||
| 1195 | retryDicom(taskGuid.value).then((res: any) => { | ||
| 1196 | fullscreenLoading.value = false; | ||
| 1197 | if (res?.code == proxy.$passCode) { | ||
| 1198 | if (folderRefreshTimer.value) { | ||
| 1199 | clearInterval(folderRefreshTimer.value); | ||
| 1200 | folderRefreshTimer.value = null; | ||
| 1201 | } | ||
| 1202 | processFolderRefresh(); | ||
| 1203 | } else { | ||
| 1204 | res?.msg && ElMessage.error(res.msg); | ||
| 1205 | } | ||
| 1206 | }) | ||
| 1207 | } | ||
| 914 | 1208 | ||
| 1209 | /** 上传成功之后的文件信息 */ | ||
| 1210 | const folderFileTableInfo = ref({ | ||
| 1211 | id: "exec-contract-table", | ||
| 1212 | height: '212px', | ||
| 1213 | fields: <any>[], | ||
| 1214 | data: [], | ||
| 1215 | showPage: false, | ||
| 1216 | actionInfo: { | ||
| 1217 | show: false | ||
| 1218 | }, | ||
| 1219 | loading: false | ||
| 1220 | }); | ||
| 1221 | |||
| 1222 | const dicomMetaData: any = ref({}); | ||
| 1223 | const metaDataWidthsJson = ref({ | ||
| 1224 | '患者姓名': 140, | ||
| 1225 | '患者ID': 140, | ||
| 1226 | '患者出生日期': 120, | ||
| 1227 | '患者出生时间': 130, | ||
| 1228 | '患者性别': 100, | ||
| 1229 | "怀孕状态": 110, | ||
| 1230 | "种族": 100, | ||
| 1231 | "患者体重": 90, | ||
| 1232 | '患者年龄': 110, | ||
| 1233 | }); | ||
| 1234 | /** 获取预览的5条数据 */ | ||
| 1235 | const getDicomMetaData = (taskGuid) => { | ||
| 1236 | folderFileTableInfo.value.loading = true; | ||
| 1237 | getDicomMeta(taskGuid).then((res: any) => { | ||
| 1238 | folderFileTableInfo.value.loading = false; | ||
| 1239 | if (res?.code == proxy.$passCode) { | ||
| 1240 | dicomMetaData.value = res.data || {}; | ||
| 1241 | folderFileTableInfo.value.fields = [{ label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" }].concat(dicomMetaData.value?.column?.map(f => { | ||
| 1242 | return { | ||
| 1243 | label: f, field: f, width: metaDataWidthsJson.value[f] || 120 | ||
| 1244 | } | ||
| 1245 | })); | ||
| 1246 | let column = dicomMetaData.value?.column || []; | ||
| 1247 | folderFileTableInfo.value.data = dicomMetaData.value.datas?.map(d => { | ||
| 1248 | let json = {}; | ||
| 1249 | column.forEach((c, index) => { | ||
| 1250 | json[c] = d[index]; | ||
| 1251 | }) | ||
| 1252 | return json; | ||
| 1253 | }) | ||
| 1254 | } else { | ||
| 1255 | res?.msg && proxy.$ElMessage.error(res.msg); | ||
| 1256 | } | ||
| 1257 | }) | ||
| 1258 | } | ||
| 1259 | |||
| 1260 | const dicomStatisticsData: any = ref({}); | ||
| 1261 | |||
| 1262 | /** 获取解析文件结果数据 */ | ||
| 1263 | const getDicomStatisticsData = (taskGuid) => { | ||
| 1264 | return getDicomStatistics(taskGuid).then((res: any) => { | ||
| 1265 | if (res?.code == proxy.$passCode) { | ||
| 1266 | dicomStatisticsData.value = res.data || {}; | ||
| 1267 | } else { | ||
| 1268 | res?.msg && proxy.$ElMessage.error(res.msg); | ||
| 1269 | } | ||
| 1270 | }) | ||
| 1271 | } | ||
| 1272 | |||
| 1273 | /** 将时间转换为时分秒 */ | ||
| 1274 | const transferTime = (time) => { | ||
| 1275 | if (time == null) { | ||
| 1276 | return '--'; | ||
| 1277 | } | ||
| 1278 | |||
| 1279 | // 4. 将毫秒转换为小时、分钟和秒 | ||
| 1280 | const totalSeconds = Math.floor(time / 1000); | ||
| 1281 | const hours = Math.floor(totalSeconds / 3600); | ||
| 1282 | const minutes = Math.floor((totalSeconds % 3600) / 60); | ||
| 1283 | const seconds = totalSeconds % 60; | ||
| 1284 | |||
| 1285 | // 5. 格式化输出 | ||
| 1286 | const parts: any[] = []; | ||
| 1287 | |||
| 1288 | if (hours > 0) { | ||
| 1289 | parts.push(`${hours}小时`); | ||
| 1290 | } | ||
| 1291 | |||
| 1292 | if (minutes > 0 || hours > 0) { // 如果有小时,即使分钟为0也显示0分钟 | ||
| 1293 | parts.push(`${minutes}分钟`); | ||
| 1294 | } | ||
| 1295 | |||
| 1296 | parts.push(`${seconds}秒`); | ||
| 1297 | |||
| 1298 | return parts.join(''); | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | /** | ||
| 1302 | * 计算两个时间之间的耗时 | ||
| 1303 | * @param {string} parsingTime - 开始时间(ISO 8601格式) | ||
| 1304 | * @param {string} parsingCompletedTime - 结束时间(ISO 8601格式) | ||
| 1305 | * @returns {string} - 格式化的耗时字符串,如 "2小时30分钟" | ||
| 1306 | */ | ||
| 1307 | const calculateElapsedTime = (parsingTime, parsingCompletedTime) => { | ||
| 1308 | // 1. 将时间字符串转换为Date对象 | ||
| 1309 | const startTime = new Date(parsingTime); | ||
| 1310 | const endTime = new Date(parsingCompletedTime); | ||
| 1311 | |||
| 1312 | // 2. 计算时间差(毫秒) | ||
| 1313 | const timeDiff = endTime - startTime; | ||
| 1314 | |||
| 1315 | // 3. 检查时间是否有效 | ||
| 1316 | if (isNaN(timeDiff)) { | ||
| 1317 | // return "时间格式错误"; | ||
| 1318 | return '--'; | ||
| 1319 | } | ||
| 1320 | |||
| 1321 | if (timeDiff < 0) { | ||
| 1322 | //return "结束时间早于开始时间"; | ||
| 1323 | return '--'; | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | return transferTime(timeDiff); | ||
| 915 | } | 1327 | } |
| 916 | 1328 | ||
| 917 | /** 第二步的配置组件引用。 */ | 1329 | /** 第二步的配置组件引用。 */ |
| ... | @@ -954,8 +1366,14 @@ const changeStep = async (val) => { | ... | @@ -954,8 +1366,14 @@ const changeStep = async (val) => { |
| 954 | saveParams.dataSourceGuid = null; | 1366 | saveParams.dataSourceGuid = null; |
| 955 | saveParams.tableName = null; | 1367 | saveParams.tableName = null; |
| 956 | } else { | 1368 | } else { |
| 1369 | if (saveParams.dataSource == 3 && clickSelectNode.value.path) { | ||
| 1370 | saveParams.filePath = { | ||
| 1371 | url: clickSelectNode.value.path | ||
| 1372 | }; | ||
| 1373 | } else { | ||
| 957 | saveParams.filePath = null; | 1374 | saveParams.filePath = null; |
| 958 | } | 1375 | } |
| 1376 | } | ||
| 959 | let simpleFormInline = dataSimpleFormRef.value.formInline; | 1377 | let simpleFormInline = dataSimpleFormRef.value.formInline; |
| 960 | if (simpleFormInline.enableSamplingRate == 'Y') { | 1378 | if (simpleFormInline.enableSamplingRate == 'Y') { |
| 961 | saveParams.samplingRate = simpleFormInline.samplingRate && parseInt(simpleFormInline.samplingRate); | 1379 | saveParams.samplingRate = simpleFormInline.samplingRate && parseInt(simpleFormInline.samplingRate); |
| ... | @@ -984,6 +1402,8 @@ const changeStep = async (val) => { | ... | @@ -984,6 +1402,8 @@ const changeStep = async (val) => { |
| 984 | taskGuid.value = res.data?.taskGuid; | 1402 | taskGuid.value = res.data?.taskGuid; |
| 985 | isExecEnd.value = false; | 1403 | isExecEnd.value = false; |
| 986 | taskExecGuid.value = res.data?.lastExecGuid; | 1404 | taskExecGuid.value = res.data?.lastExecGuid; |
| 1405 | oldAnonTaskValueInfo.value = saveParams; | ||
| 1406 | oldAnonTaskValueInfo.value.guid = taskGuid.value; | ||
| 987 | step.value = val - 1; | 1407 | step.value = val - 1; |
| 988 | stepsInfo.value.step = val - 1; | 1408 | stepsInfo.value.step = val - 1; |
| 989 | analysisResultInfo.value = {}; | 1409 | analysisResultInfo.value = {}; |
| ... | @@ -992,7 +1412,6 @@ const changeStep = async (val) => { | ... | @@ -992,7 +1412,6 @@ const changeStep = async (val) => { |
| 992 | refreshTimer.value = null; | 1412 | refreshTimer.value = null; |
| 993 | } | 1413 | } |
| 994 | processStepThreeResultView(); | 1414 | processStepThreeResultView(); |
| 995 | oldAnonTaskValueInfo.value = saveParams; | ||
| 996 | anonymizationStore.setIsAnonPageRefresh(true); | 1415 | anonymizationStore.setIsAnonPageRefresh(true); |
| 997 | } else { | 1416 | } else { |
| 998 | ElMessage.error(res.msg); | 1417 | ElMessage.error(res.msg); |
| ... | @@ -1045,17 +1464,26 @@ const changeStep = async (val) => { | ... | @@ -1045,17 +1464,26 @@ const changeStep = async (val) => { |
| 1045 | } else { | 1464 | } else { |
| 1046 | formRef.value?.ruleFormRef?.validate((valid, errorItem) => { | 1465 | formRef.value?.ruleFormRef?.validate((valid, errorItem) => { |
| 1047 | if (valid) { | 1466 | if (valid) { |
| 1048 | if (formRef.value?.formInline?.dataSource == 2 && !sampleTableFields.value?.length) { | 1467 | let dataSource = formRef.value?.formInline?.dataSource; |
| 1468 | if (dataSource == 2 && !sampleTableFields.value?.length) { | ||
| 1049 | proxy.$ElMessage.error('上传文件的字段不能为空'); | 1469 | proxy.$ElMessage.error('上传文件的字段不能为空'); |
| 1050 | return; | 1470 | return; |
| 1051 | } | 1471 | } |
| 1472 | if (dataSource != 3) { | ||
| 1052 | dataSimpleFormRef.value?.ruleFormRef?.validate((valid) => { | 1473 | dataSimpleFormRef.value?.ruleFormRef?.validate((valid) => { |
| 1053 | if (valid) { | 1474 | if (valid) { |
| 1054 | Object.assign(saveParams, { riskThreshold: '0.05' }); | 1475 | // Object.assign(saveParams, { riskThreshold: '0.05' }); |
| 1055 | exec(saveParams); | 1476 | exec(saveParams); |
| 1056 | } | 1477 | } |
| 1057 | }); | 1478 | }); |
| 1058 | } else { | 1479 | } else { |
| 1480 | if (!clickSelectNode.value.path) { | ||
| 1481 | proxy.$ElMessage.error('请先上传文件'); | ||
| 1482 | return; | ||
| 1483 | } | ||
| 1484 | exec(saveParams); | ||
| 1485 | } | ||
| 1486 | } else { | ||
| 1059 | var obj = Object.keys(errorItem); | 1487 | var obj = Object.keys(errorItem); |
| 1060 | formRef.value.ruleFormRef?.scrollToField(obj[0]) | 1488 | formRef.value.ruleFormRef?.scrollToField(obj[0]) |
| 1061 | } | 1489 | } |
| ... | @@ -1101,15 +1529,15 @@ onBeforeMount(() => { | ... | @@ -1101,15 +1529,15 @@ onBeforeMount(() => { |
| 1101 | if (res?.code == proxy.$passCode) { | 1529 | if (res?.code == proxy.$passCode) { |
| 1102 | detailInfo.value = res.data || {}; | 1530 | detailInfo.value = res.data || {}; |
| 1103 | taskExecGuid.value = detailInfo.value.lastExecGuid; | 1531 | taskExecGuid.value = detailInfo.value.lastExecGuid; |
| 1532 | if (detailInfo.value.handleType == '01') { | ||
| 1104 | oldAnonTaskValueInfo.value = { | 1533 | oldAnonTaskValueInfo.value = { |
| 1105 | guid: detailInfo.value.guid, | 1534 | guid: detailInfo.value.guid, |
| 1106 | taskName: detailInfo.value.taskName, | 1535 | taskName: detailInfo.value.taskName, |
| 1107 | dataSource: detailInfo.value.dataSource, | 1536 | dataSource: detailInfo.value.dataSource, |
| 1108 | filePath: detailInfo.value.filePath && cloneDeep(detailInfo.value.filePath), | 1537 | handleType: detailInfo.value.handleType, |
| 1109 | dataSourceGuid: detailInfo.value.dataSourceGuid, | 1538 | coverageArea: detailInfo.value.coverageArea || [], |
| 1110 | tableName: detailInfo.value.tableName, | 1539 | qualifiedIdentifier: detailInfo.value.qualifiedIdentifier, |
| 1111 | samplingRate: detailInfo.value.samplingRate, | 1540 | samplingRate: detailInfo.value.samplingRate, |
| 1112 | // patientPopulationRate: detailInfo.value.patientPopulationRate && typeof detailInfo.value.patientPopulationRate == 'number' ? detailInfo.value.patientPopulationRate?.toFixed(9) : detailInfo.value.patientPopulationRate, | ||
| 1113 | dataSharingTypeCode: detailInfo.value.dataSharingTypeCode, | 1541 | dataSharingTypeCode: detailInfo.value.dataSharingTypeCode, |
| 1114 | anonTaskRules: cloneDeep(detailInfo.value.anonTaskRules), | 1542 | anonTaskRules: cloneDeep(detailInfo.value.anonTaskRules), |
| 1115 | anonPrivacyMode: { | 1543 | anonPrivacyMode: { |
| ... | @@ -1121,6 +1549,25 @@ onBeforeMount(() => { | ... | @@ -1121,6 +1549,25 @@ onBeforeMount(() => { |
| 1121 | tcThreshold: detailInfo.value.anonPrivacyMode?.tcThreshold, | 1549 | tcThreshold: detailInfo.value.anonPrivacyMode?.tcThreshold, |
| 1122 | } | 1550 | } |
| 1123 | } | 1551 | } |
| 1552 | } else { | ||
| 1553 | oldAnonTaskValueInfo.value = { | ||
| 1554 | guid: detailInfo.value.guid, | ||
| 1555 | taskName: detailInfo.value.taskName, | ||
| 1556 | dataSource: detailInfo.value.dataSource, | ||
| 1557 | handleType: detailInfo.value.handleType, | ||
| 1558 | coverageArea: detailInfo.value.coverageArea || [], | ||
| 1559 | qualifiedIdentifier: detailInfo.value.qualifiedIdentifier, | ||
| 1560 | samplingRate: detailInfo.value.samplingRate, | ||
| 1561 | dataSharingTypeCode: detailInfo.value.dataSharingTypeCode, | ||
| 1562 | } | ||
| 1563 | } | ||
| 1564 | if (detailInfo.value.dataSource == 1) { | ||
| 1565 | oldAnonTaskValueInfo.value.dataSourceGuid = detailInfo.value.dataSourceGuid; | ||
| 1566 | oldAnonTaskValueInfo.value.tableName = detailInfo.value.tableName; | ||
| 1567 | } else { | ||
| 1568 | oldAnonTaskValueInfo.value.filePath = detailInfo.value.filePath && cloneDeep(detailInfo.value.filePath); | ||
| 1569 | } | ||
| 1570 | detailInfo.value.dataSource == 3 && (clickSelectNode.value.path = oldAnonTaskValueInfo.value.filePath?.url); | ||
| 1124 | setDataSelectFormItems(Object.assign(detailInfo.value, { file: detailInfo.value.filePath ? [detailInfo.value.filePath] : [] }), true); | 1571 | setDataSelectFormItems(Object.assign(detailInfo.value, { file: detailInfo.value.filePath ? [detailInfo.value.filePath] : [] }), true); |
| 1125 | if (detailInfo.value.samplingRate != null) { | 1572 | if (detailInfo.value.samplingRate != null) { |
| 1126 | dataSimpleFormItems.value[0].default = 'Y'; | 1573 | dataSimpleFormItems.value[0].default = 'Y'; |
| ... | @@ -1135,7 +1582,7 @@ onBeforeMount(() => { | ... | @@ -1135,7 +1582,7 @@ onBeforeMount(() => { |
| 1135 | dataSelectInfoItems.value[6].visible = dataSource == 1; | 1582 | dataSelectInfoItems.value[6].visible = dataSource == 1; |
| 1136 | dataSelectInfoItems.value[8].visible = dataSource == 2; | 1583 | dataSelectInfoItems.value[8].visible = dataSource == 2; |
| 1137 | try { | 1584 | try { |
| 1138 | //文件解析 | 1585 | // 文件解析 |
| 1139 | if (dataSource == 2) { | 1586 | if (dataSource == 2) { |
| 1140 | let url = detailInfo.value.filePath?.url; | 1587 | let url = detailInfo.value.filePath?.url; |
| 1141 | sampleTableDataLoading.value = true; | 1588 | sampleTableDataLoading.value = true; |
| ... | @@ -1161,7 +1608,7 @@ onBeforeMount(() => { | ... | @@ -1161,7 +1608,7 @@ onBeforeMount(() => { |
| 1161 | } else { | 1608 | } else { |
| 1162 | proxy.$ElMessage.error(res.msg); | 1609 | proxy.$ElMessage.error(res.msg); |
| 1163 | } | 1610 | } |
| 1164 | } else { | 1611 | } else if (dataSource == 1) { |
| 1165 | const res: any = await getDatabase({ connectStatus: 1 }); | 1612 | const res: any = await getDatabase({ connectStatus: 1 }); |
| 1166 | if (res?.code == proxy.$passCode) { | 1613 | if (res?.code == proxy.$passCode) { |
| 1167 | dataSourceList.value = res.data || []; | 1614 | dataSourceList.value = res.data || []; |
| ... | @@ -1208,6 +1655,9 @@ onBeforeMount(() => { | ... | @@ -1208,6 +1655,9 @@ onBeforeMount(() => { |
| 1208 | ElMessage.error(res.msg); | 1655 | ElMessage.error(res.msg); |
| 1209 | } | 1656 | } |
| 1210 | }); | 1657 | }); |
| 1658 | } else if (dataSource == 3) { | ||
| 1659 | getDicomMetaData(taskGuid.value); | ||
| 1660 | await getDicomStatisticsData(taskGuid.value); | ||
| 1211 | } | 1661 | } |
| 1212 | fullscreenLoading.value = false; | 1662 | fullscreenLoading.value = false; |
| 1213 | } catch (error) { | 1663 | } catch (error) { |
| ... | @@ -1882,7 +2332,7 @@ onUnmounted(() => { | ... | @@ -1882,7 +2332,7 @@ onUnmounted(() => { |
| 1882 | } | 2332 | } |
| 1883 | 2333 | ||
| 1884 | .folder-progress { | 2334 | .folder-progress { |
| 1885 | width: 360px; | 2335 | width: 420px; |
| 1886 | 2336 | ||
| 1887 | .cnt { | 2337 | .cnt { |
| 1888 | font-size: 14px; | 2338 | font-size: 14px; |
| ... | @@ -1891,9 +2341,50 @@ onUnmounted(() => { | ... | @@ -1891,9 +2341,50 @@ onUnmounted(() => { |
| 1891 | margin-top: 8px; | 2341 | margin-top: 8px; |
| 1892 | } | 2342 | } |
| 1893 | 2343 | ||
| 2344 | .desc { | ||
| 2345 | font-size: 14px; | ||
| 2346 | color: #999999; | ||
| 2347 | line-height: 21px; | ||
| 2348 | margin-top: 8px; | ||
| 2349 | } | ||
| 2350 | |||
| 1894 | .el-button { | 2351 | .el-button { |
| 1895 | margin-top: 12px; | 2352 | margin-top: 12px; |
| 1896 | } | 2353 | } |
| 1897 | } | 2354 | } |
| 1898 | } | 2355 | } |
| 2356 | |||
| 2357 | .folder-main-content { | ||
| 2358 | height: 450px; | ||
| 2359 | padding: 8px 16px; | ||
| 2360 | |||
| 2361 | :deep(.tree_panel) { | ||
| 2362 | height: 100%; | ||
| 2363 | |||
| 2364 | .el-tree { | ||
| 2365 | overflow-y: auto; | ||
| 2366 | } | ||
| 2367 | } | ||
| 2368 | } | ||
| 2369 | |||
| 2370 | .folder-foot { | ||
| 2371 | padding: 0px 16px 8px; | ||
| 2372 | line-height: 21px; | ||
| 2373 | } | ||
| 2374 | |||
| 2375 | .preview-title { | ||
| 2376 | margin-bottom: 8px; | ||
| 2377 | font-size: 14px; | ||
| 2378 | color: #212121; | ||
| 2379 | line-height: 21px; | ||
| 2380 | font-weight: 600; | ||
| 2381 | } | ||
| 2382 | |||
| 2383 | .folder-bottom { | ||
| 2384 | width: 100%; | ||
| 2385 | padding: 8px 0px 0px; | ||
| 2386 | display: flex; | ||
| 2387 | justify-content: center; | ||
| 2388 | align-items: center; | ||
| 2389 | } | ||
| 1899 | </style> | 2390 | </style> |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or sign in to post a comment