上传、下载添加提示;非dicom添加上传监控
continuous-integration/drone/push Build is passing Details

uat_us
DESKTOP-6C3NK6N\WXS 2024-09-12 14:22:52 +08:00
parent e845fdaad4
commit 986bce36e6
7 changed files with 650 additions and 461 deletions

View File

@ -37,6 +37,10 @@
</el-button>
</div>
</div>
<div class="tip">
<i class="el-icon-warning-outline"></i>
<div v-html="$t('download:tip:message')"></div>
</div>
<!--上传列表@selection-change="handleSelectionChange"-->
<el-table
ref="dicomFilesTable"
@ -464,4 +468,12 @@ export default {
justify-content: space-between;
margin: 10px 0;
}
.tip {
display: flex;
align-items: flex-start;
margin-top: 5px;
i {
margin: 3px 5px 0 0;
}
}
</style>

View File

@ -1,32 +1,10 @@
<template>
<div>
<div class="top">
<div>
<span>{{ $t('upload:dicom:title') }}</span>
<div class="btnBox">
<form id="inputForm" ref="uploadForm" enctype="multipart/form-data">
<div class="form-group">
<div id="directoryInputWrapper" class="btn btn-link file-input">
<el-button
type="primary"
:disabled="btnLoading"
:loading="btnLoading"
size="mini"
>
{{ $t('upload:dicom:button:upload') }}
</el-button>
<input
type="file"
name="file"
ref="pathClear"
:disabled="btnLoading"
webkitdirectory
multiple
title=""
@change="beginScanFiles($event)"
/>
</div>
</div>
</form>
<div class="tip">
<i class="el-icon-warning-outline"></i>
<div v-html="$t('upload:dicom:tip:message1')"></div>
</div>
</div>
<!--检查列表-->
@ -137,9 +115,37 @@
</template>
</el-table-column>
</el-table>
<div style="margin: 10px 0">
<div style="margin: 10px 0" class="top">
<span>{{ $t('upload:dicom:uploadTitle') }}</span>
<span style="margin-left: 10px">{{ $store.state.trials.uploadTip }}</span>
<div class="btnBox">
<span style="margin-right: 10px">
{{ $store.state.trials.uploadTip }}
</span>
<form id="inputForm" ref="uploadForm" enctype="multipart/form-data">
<div class="form-group">
<div id="directoryInputWrapper" class="btn btn-link file-input">
<el-button
type="primary"
:disabled="btnLoading"
:loading="btnLoading"
size="mini"
>
{{ $t('upload:dicom:button:upload') }}
</el-button>
<input
type="file"
name="file"
ref="pathClear"
:disabled="btnLoading"
webkitdirectory
multiple
title=""
@change="beginScanFiles($event)"
/>
</div>
</div>
</form>
</div>
</div>
<!--上传列表-->
<el-table
@ -1515,4 +1521,12 @@ export default {
opacity: 0;
cursor: pointer;
}
.tip {
display: flex;
align-items: flex-start;
margin-top: 5px;
i {
margin: 3px 5px 0 0;
}
}
</style>

View File

@ -2,12 +2,16 @@
<div class="nonedicomFile">
<div class="top">
<span>{{ $t('upload:nonedicom:title') }}</span>
<div class="tip">
<i class="el-icon-warning-outline"></i>
<div v-html="$t('upload:nonedicom:tip:message')"></div>
</div>
</div>
<!--检查列表-->
<el-table
:data="list"
style="width: 100%"
v-adaptive="{ bottomOffset: 40 }"
v-adaptive="{ bottomOffset: 60 }"
:loading="loading"
@sort-change="handleSortByColumn"
:default-sort="{ prop: 'TaskBlindName', order: 'descending' }"
@ -624,6 +628,7 @@ export default {
let res = await preArchiveStudy({
subjectVisitId: this.currentRow.SourceSubjectVisitId,
isDicom: false,
FileCount: this.selectArr.length,
})
if (res.IsSuccess) {
this.studyMonitorId = res.Result
@ -643,16 +648,15 @@ export default {
if (!this.uploadVisible) return
let file = this.fileList.filter((item) => item.id === arr[index].id)[0]
file.status = 1
console.log(file)
let path = `/${this.$route.query.trialId}/TaskImage/${
this.currentRow.SubjectId
}/${this.currentRow.VisitTaskId}/${this.$guid()}${file.name
.substring(file.name.lastIndexOf('.'))
.toLocaleLowerCase()}`
console.log(path)
file.curPath = path
const fileData = await this.fileToBlob(file.file)
let res = await this.fileToOss(path, fileData, file)
if (res) {
if (res && index <= 3) {
file.status = 2
this.successFileList.push({
fileName: file.name,
@ -662,7 +666,8 @@ export default {
})
let flag = arr.every((item) => item.status === 2)
if (flag) {
return this.submitFile(this.successFileList)
let RecordPath = await this.uploadRecord(arr)
return this.submitFile(this.successFileList, RecordPath)
}
} else {
file.status = 3
@ -671,12 +676,14 @@ export default {
if (flag) {
let failFileList = arr.filter((item) => item.status === 3)
if (failFileList && failFileList.length > 0) {
let RecordPath = await this.uploadRecord(arr)
this.$refs.filesTable.clearSelection()
failFileList.forEach((row) => {
row.uploadFileSize = 0
this.$refs.filesTable.toggleRowSelection(row)
})
this.isFail = true
this.submitFile(this.successFileList, RecordPath, true)
return false
}
}
@ -714,7 +721,7 @@ export default {
}
},
// Dicom
submitFile(uploadedFileList) {
submitFile(uploadedFileList, RecordPath, isReLoad = false) {
if (!this.uploadVisible) return
this.btnLoading = true
var params = {
@ -725,9 +732,15 @@ export default {
VisitTaskId: this.currentRow.VisitTaskId,
uploadedFileList: uploadedFileList,
}
if (RecordPath) {
params.RecordPath = RecordPath.path
params.FailedFileCount = RecordPath.Record.Failed.length
}
uploadNoneDicomFile(params)
.then((res) => {
this.resetFileDiaolg()
if (!isReLoad) {
this.resetFileDiaolg()
}
this.getList()
//
this.$emit('getList')
@ -739,6 +752,49 @@ export default {
this.btnLoading = false
})
},
//
uploadRecord(arr) {
return new Promise(async (resolve) => {
try {
let Record = {
Failed: [],
Existed: [],
Uploaded: [],
FileCount: arr.length,
}
arr.forEach((item) => {
let file = this.fileList.find((data) => data.id === item.id)
if (file.status === 2) {
Record.Uploaded.push(file.curPath)
}
if (file.status === 3) {
Record.Failed.push(file.curPath)
}
})
let text = JSON.stringify(Record)
let logJsonBlob = this.generateTxtFile(text)
let logJsonObjectName = `/${this.$route.query.trialId}/TaskImage/${this.currentRow.SubjectId}/${this.currentRow.VisitTaskId}/${this.studyMonitorId}.txt`
let logRes
try {
logRes = await this.OSSclient.put(logJsonObjectName, logJsonBlob)
if (logRes && logRes.url) {
resolve({ path: this.$getObjectName(logRes.url), Record })
} else {
resolve(false)
}
} catch (e) {
resolve(false)
}
} catch (err) {
console.log(err)
resolve(false)
}
})
},
generateTxtFile(text) {
let blob = new Blob(['\ufeff', text], { type: 'text/plain' })
return blob
},
},
}
</script>
@ -785,4 +841,12 @@ export default {
pointer-events: none; //pointer-events:none穿
}
}
.tip {
display: flex;
align-items: flex-start;
margin-top: 5px;
i {
margin: 3px 5px 0 0;
}
}
</style>

View File

@ -4,53 +4,74 @@ import store from '@/store'
streamSaver.mitm = `${window.location.origin}/mitm.html?version=2.0.0`
// 下载文件并压缩
function zipFiles(zipName, files) {
console.log("同步下载打包开始时间:" + new Date());
store.dispatch('trials/setUnLock', true)
files = formatFiles(files)
// 创建压缩文件输出流
const zipFileOutputStream = streamSaver.createWriteStream(zipName);
// 创建下载文件流
const fileIterator = files.values();
const readableZipStream = new ZIP({
async pull(ctrl) {
const fileInfo = fileIterator.next();
if (fileInfo.done) {//迭代终止
ctrl.close();
} else {
let { name, url } = fileInfo.value;
url = decodeUtf8(url);
return fetch(url).then(res => {
ctrl.enqueue({
name,
stream: () => res.body
});
})
}
}
});
if (window.WritableStream && readableZipStream.pipeTo) {
// 开始下载
readableZipStream
.pipeTo(zipFileOutputStream)
.then(() => {
console.log("同步下载打包结束时间:" + new Date());
store.dispatch('trials/setUnLock', false)
return new Promise((resolve) => {
try {
console.log("同步下载打包开始时间:" + new Date());
store.dispatch('trials/setUnLock', true)
files = formatFiles(files)
// 创建压缩文件输出流
const zipFileOutputStream = streamSaver.createWriteStream(zipName);
// 创建下载文件流
const fileIterator = files.values();
const readableZipStream = new ZIP({
async pull(ctrl) {
const fileInfo = fileIterator.next();
if (fileInfo.done) {//迭代终止
ctrl.close();
} else {
let { name, url } = fileInfo.value;
url = decodeUtf8(url);
return fetch(url).then(res => {
ctrl.enqueue({
name,
stream: () => res.body
});
})
}
}
});
}
if (window.WritableStream && readableZipStream.pipeTo) {
// 开始下载
readableZipStream
.pipeTo(zipFileOutputStream)
.then(() => {
console.log("同步下载打包结束时间:" + new Date());
store.dispatch('trials/setUnLock', false)
resolve(true)
}).catch(err => {
console.log(err);
resolve(false)
});
} else {
resolve(false)
}
} catch (err) {
console.log(err);
resolve(false)
}
})
}
// 下载文件并修改名称
async function updateFile(file, name) {
try {
store.dispatch('trials/setUnLock', true)
const fileOutputStream = streamSaver.createWriteStream(name);
file = decodeUtf8(file);
let res = await fetch(file);
res.body.pipeTo(fileOutputStream).then(() => {
return new Promise(async resolve => {
try {
store.dispatch('trials/setUnLock', true)
});
} catch (err) {
console.log(err)
}
const fileOutputStream = streamSaver.createWriteStream(name);
file = decodeUtf8(file);
let res = await fetch(file);
res.body.pipeTo(fileOutputStream).then(() => {
store.dispatch('trials/setUnLock', true)
resolve(true)
}).catch(err => {
console.log(err)
resolve(false)
});
} catch (err) {
console.log(err)
resolve(false)
}
})
}
// 同名文件修改名称
function formatFiles(files) {
@ -78,8 +99,8 @@ function decodeUtf8(bytes) {
str2.pop();
return str2.join("/") + '/' + name;
}
export function downLoadFile(file, name, type = 'file') {
if (type === 'zip') return zipFiles(name, file);
return updateFile(file, name)
export async function downLoadFile(file, name, type = 'file') {
if (type === 'zip') return await zipFiles(name, file);
return await updateFile(file, name)
}

View File

@ -928,6 +928,7 @@ export default {
let res = await preArchiveStudy({
subjectVisitId: this.subjectVisitId,
isDicom: false,
FileCount: this.selectArr.length,
})
if (res.IsSuccess) {
this.studyMonitorId = res.Result
@ -952,6 +953,7 @@ export default {
}/${this.$guid()}${file.name
.substring(file.name.lastIndexOf('.'))
.toLocaleLowerCase()}`
file.curPath = path
const fileData = await this.fileToBlob(file.file)
let res = await this.fileToOss(path, fileData, file)
if (res) {
@ -964,7 +966,8 @@ export default {
})
let flag = arr.every((item) => item.status === 2)
if (flag) {
return this.submitFile(this.successFileList)
let RecordPath = await this.uploadRecord(arr)
return this.submitFile(this.successFileList, RecordPath)
}
} else {
file.status = 3
@ -973,12 +976,14 @@ export default {
if (flag) {
let failFileList = arr.filter((item) => item.status === 3)
if (failFileList && failFileList.length > 0) {
let RecordPath = await this.uploadRecord(arr)
this.$refs.filesTable.clearSelection()
failFileList.forEach((row) => {
row.uploadFileSize = 0
this.$refs.filesTable.toggleRowSelection(row)
})
this.isFail = true
this.submitFile(this.successFileList, RecordPath, true)
return false
}
}
@ -1016,7 +1021,7 @@ export default {
}
},
// Dicom
submitFile(uploadedFileList) {
submitFile(uploadedFileList, RecordPath, isReLoad = false) {
if (!this.uploadVisible) return
this.btnLoading = true
var params = {
@ -1026,9 +1031,15 @@ export default {
studyMonitorId: this.studyMonitorId,
uploadedFileList: uploadedFileList,
}
if (RecordPath) {
params.RecordPath = RecordPath.path
params.FailedFileCount = RecordPath.Record.Failed.length
}
uploadNoneDicomFile(params)
.then((res) => {
this.resetFileDiaolg()
if (!isReLoad) {
this.resetFileDiaolg()
}
this.getNoneDicomList()
//
this.$emit('getList')
@ -1040,6 +1051,49 @@ export default {
this.btnLoading = false
})
},
//
uploadRecord(arr) {
return new Promise(async (resolve) => {
try {
let Record = {
Failed: [],
Existed: [],
Uploaded: [],
FileCount: arr.length,
}
arr.forEach((item) => {
let file = this.fileList.find((data) => data.id === item.id)
if (file.status === 2) {
Record.Uploaded.push(file.curPath)
}
if (file.status === 3) {
Record.Failed.push(file.curPath)
}
})
let text = JSON.stringify(Record)
let logJsonBlob = this.generateTxtFile(text)
let logJsonObjectName = `/${this.trialId}/Image/${this.data.SubjectId}/${this.data.Id}/${this.studyMonitorId}.txt`
let logRes
try {
logRes = await this.OSSclient.put(logJsonObjectName, logJsonBlob)
if (logRes && logRes.url) {
resolve({ path: this.$getObjectName(logRes.url), Record })
} else {
resolve(false)
}
} catch (e) {
resolve(false)
}
} catch (err) {
console.log(err)
resolve(false)
}
})
},
generateTxtFile(text) {
let blob = new Blob(['\ufeff', text], { type: 'text/plain' })
return blob
},
resetFileDiaolg() {
this.btnLoading = false
this.uploadVisible = false

File diff suppressed because it is too large Load Diff

View File

@ -49,6 +49,13 @@
>
{{ $store.state.trials.uploadTip }}
</div> -->
<el-tooltip
:content="$t('trials:download:tip:message')"
placement="top-end"
effect="light"
>
<i class="el-icon-warning-outline" style="font-size: 18px"></i>
</el-tooltip>
<!-- 下载所有影像 -->
<el-button
v-if="
@ -317,6 +324,13 @@
>
{{ $store.state.trials.uploadTip }}
</div> -->
<el-tooltip
:content="$t('trials:download:tip:message')"
placement="top-end"
effect="light"
>
<i class="el-icon-warning-outline" style="font-size: 18px"></i>
</el-tooltip>
<!-- 下载所有影像 -->
<el-button
v-if="
@ -1667,7 +1681,9 @@ export default {
if (item.actionContent) {
//
actions.push(`${item.actionContent}`)
str = `${str}${this.$t('trials:audit:form:actionMatters')}<br><div style='margin-left:20px'>${item.actionContent}</div>`
str = `${str}${this.$t(
'trials:audit:form:actionMatters'
)}<br><div style='margin-left:20px'>${item.actionContent}</div>`
}
contents.push(str)
}