Compare commits
193 Commits
c904b21287
...
v1.12.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 0df193c474 | |||
| 7d9be5e2b3 | |||
| df417afbbb | |||
| 48c76cb0bb | |||
| 83182a4d0f | |||
| 10408bde30 | |||
| 1705469056 | |||
| 8f5b75fcd5 | |||
| 0c3a69d4d0 | |||
| 2683a5a7c9 | |||
| d17b95a200 | |||
| 9a8bf1e637 | |||
| 4aa43b009b | |||
| bb798ce4ad | |||
| da4cc0a8ef | |||
| fb55a1d536 | |||
| 2986d43f39 | |||
| 13c9c9b4c3 | |||
| d0a7a4132f | |||
| dffad5a122 | |||
| ef3ca59842 | |||
| 1aaf1927f5 | |||
| 6fab860497 | |||
| f3ff162cdd | |||
| b7655ebad0 | |||
| 79df77b30c | |||
| cfe03844a7 | |||
| 6eebf590f8 | |||
| c09220dbd3 | |||
| 2dd2aeede7 | |||
| 5ae8348765 | |||
| 3b8505ba3a | |||
| fe8398df9d | |||
| 27caa4ff77 | |||
| 3b96a5326e | |||
| 9b63c2c82e | |||
| 342f833eb8 | |||
| 56b00791f4 | |||
| 474c0dca70 | |||
| a7806d07bb | |||
| f6e87596ee | |||
| d1448d4cc6 | |||
| bf985bcbc8 | |||
| 70db0d9258 | |||
| 8f1ab432b2 | |||
| 3f0573eeb3 | |||
| 2ed051e25b | |||
| dde53103f9 | |||
| 042a5fe59b | |||
| 8dda50f78e | |||
| 7c06c94177 | |||
| 42652cd9ee | |||
| 2370c25ed7 | |||
| cdefe6d640 | |||
| 9ef348efbf | |||
| 06e876619f | |||
| 3334e24c66 | |||
| 9b3e169ef2 | |||
| fa30c68153 | |||
| e08f094435 | |||
| d047df807e | |||
| 2c5e33903d | |||
| b024252f98 | |||
| c1be3bbf4d | |||
| f2b07131aa | |||
| 6c71803a11 | |||
| 91078abd15 | |||
| 04f8a938c3 | |||
| 2c85013008 | |||
| 9d839e46cd | |||
| 509f8f02b6 | |||
| 9cc1962b3b | |||
| 774ab78a7c | |||
| 16794dfe1d | |||
| 1c69ed08cd | |||
| 833324e1ac | |||
| f36a00cf81 | |||
| 233bcbb1d0 | |||
| b644098203 | |||
| 424a59c4d9 | |||
| a3e3db3d5b | |||
| a803ee2c00 | |||
| 5a8ec13c2f | |||
| d911d55129 | |||
| ebedae85e7 | |||
| d54dfae99f | |||
| 00396f3c9d | |||
| 2138bd3345 | |||
| 0416b1bca8 | |||
| 6dd579e910 | |||
| 98dc6beba5 | |||
| f7a62b2016 | |||
| eb50f24204 | |||
| 3c4cce70c5 | |||
| a566c1a0b8 | |||
| 3bdd567f1e | |||
| cbbbb227ea | |||
| 91dc08493b | |||
| bacdbd9fa1 | |||
| 3d096f397f | |||
| 4f7a308cf1 | |||
| bb3e3e52a5 | |||
| f918004dda | |||
| fd683d74f9 | |||
| d7838051e8 | |||
| b727d6b068 | |||
| 3b14944671 | |||
| 2b820a114b | |||
| 3f69434251 | |||
| ee545589af | |||
| feed991971 | |||
| a56b536e95 | |||
| eaf856a755 | |||
| 8f497ed363 | |||
| c33c2d6a09 | |||
| cc788b9833 | |||
| 0aaf2f3edb | |||
| 2a80893932 | |||
| 6a0859aaab | |||
| 690b29c5c5 | |||
| 0d3cb15806 | |||
| 4b32c290e7 | |||
| 390df569c9 | |||
| 05c6e9727f | |||
| 87eac9f478 | |||
| ef489552ea | |||
| dd80abed02 | |||
| 6ce18843ee | |||
| fb48b59587 | |||
| ed2b75d331 | |||
| 0c040719b0 | |||
| 5dc5213202 | |||
| bdfef06b5f | |||
| 1d009c8e18 | |||
| c03e85ff22 | |||
| 0a752ed92f | |||
| eab207fc35 | |||
| 5ef755249c | |||
| 8da7b81235 | |||
| 276d8adac0 | |||
| 12da4c5d9f | |||
| 850d64f0aa | |||
| 541d44b4f2 | |||
| a1137c0a5b | |||
| e2e20a24fd | |||
| 2f1fcfa81d | |||
| ba4a5c0d1d | |||
| face77f949 | |||
| de80b75c0b | |||
| f050df725e | |||
| 290210c27e | |||
| be2651501d | |||
| 2df6c37fd0 | |||
| 34cc69abb0 | |||
| 26914c2b2b | |||
| 98ce2b27da | |||
| 5805ea0778 | |||
| 17737d901c | |||
| 51a94ad89e | |||
| a2491c4ba5 | |||
| 9187c9db8c | |||
| 5e67f8b65f | |||
| 6218b536f9 | |||
| 7493c1a98a | |||
| d91a9170de | |||
| 3d0a3116e1 | |||
| 76e41f4d5f | |||
| 57bec076b7 | |||
| 36ea567229 | |||
| d3a4842504 | |||
| e9dd669d48 | |||
| 4d27cbfe41 | |||
| 13cfcb0935 | |||
| 8c40241658 | |||
| b8208dffed | |||
| 10b8cc6a5e | |||
| edf1377374 | |||
| f8b4dd70c8 | |||
| 71acbc5f78 | |||
| 33a8d8743e | |||
| a357fe7ce6 | |||
| 07fbbf5a74 | |||
| 79b14eee67 | |||
| 9f76310101 | |||
| 1bacf16361 | |||
| 4b700b5db3 | |||
| b7f4cccbfa | |||
| 1483a8c670 | |||
| dab5a44f2d | |||
| 45a54d69a4 | |||
| 289a100a81 | |||
| 8b70d38cfe | |||
| 285f864036 |
@@ -11,6 +11,14 @@
|
||||
<meta http-equiv="Cache-control" content="no-store,no-cache,must-revalidate">
|
||||
<meta http-equiv="Cache" content="no-cache">
|
||||
<title><%= webpackConfig.name %></title>
|
||||
<style>
|
||||
.customPromptTip {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: -100px;
|
||||
z-index: 99999;
|
||||
}
|
||||
</style>
|
||||
<% if (eval(process.env.VUE_APP_LOGIN_FOR_PERMISSION)) { %>
|
||||
<script>
|
||||
window.zzSessionStorage = {
|
||||
|
||||
@@ -281,7 +281,13 @@ export function getCommonDocumentList(param) {
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function getCommonDocument(param) {
|
||||
return request({
|
||||
url: `/CommonDocument/getCommonDocument`,
|
||||
method: 'get',
|
||||
params: param
|
||||
})
|
||||
}
|
||||
export function addOrUpdateCommonDocument(param) {
|
||||
return request({
|
||||
url: `/CommonDocument/addOrUpdateCommonDocument`,
|
||||
|
||||
@@ -203,6 +203,15 @@ export function qCVisitList_Export(data) {
|
||||
data
|
||||
})
|
||||
}
|
||||
// 导出影像指控问题和答案
|
||||
export function GetTrialQCQuestionAnserList_Export(data) {
|
||||
return requestDownload({
|
||||
url: `/ExcelExport/GetTrialQCQuestionAnserList_Export`,
|
||||
responseType: 'blob',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 导出下载记录
|
||||
export function getTrialDownloadList_Export(data) {
|
||||
return requestDownload({
|
||||
@@ -273,3 +282,21 @@ export function GetEmailNoticeConfigList_Export(data) {
|
||||
data
|
||||
})
|
||||
}
|
||||
// 导出重传审批
|
||||
export function GetImageBackList_Export(data) {
|
||||
return requestDownload({
|
||||
url: `/ExcelExport/GetImageBackList_Export`,
|
||||
responseType: 'blob',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 导出医学审核配置
|
||||
export function GetReadingMedicineSystemQuestionList_Export(data) {
|
||||
return requestDownload({
|
||||
url: `/ExcelExport/GetReadingMedicineSystemQuestionList_Export`,
|
||||
responseType: 'blob',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
+15
-6
@@ -45,10 +45,11 @@ export function saveImageLabelList(param) {
|
||||
})
|
||||
}
|
||||
|
||||
export function getStudyInfo(studyId) {
|
||||
export function getStudyInfo(studyId, params) {
|
||||
return request({
|
||||
url: `/Study/item/${studyId}`,
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
export function getSeriesList(url) {
|
||||
@@ -75,10 +76,11 @@ export function getRelationVisitList(visitNum, tpCode) {
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
export function getAllRelationStudyList(studyId) {
|
||||
export function getAllRelationStudyList(studyId, params) {
|
||||
return request({
|
||||
url: `/study/getAllRelationStudyList/${studyId}`,
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
export function getTrialListByReviewer(param) {
|
||||
@@ -134,7 +136,7 @@ export function AddAdjudicationReport(param) {
|
||||
}
|
||||
|
||||
export function getVisitStudyList(trialId, subjectVisitId, isReading, visitTaskId) {
|
||||
let url = `/SubjectVisit/getVisitStudyList/${trialId}/${subjectVisitId}/${isReading}`
|
||||
let url = `/SubjectVisit/getVisitStudyList/${trialId}/${subjectVisitId}/${isReading}`
|
||||
url = visitTaskId ? `${url}?visitTaskId=${visitTaskId}` : url
|
||||
return request({
|
||||
url: url,
|
||||
@@ -284,4 +286,11 @@ export function deleteSingleTableQuestionMark(param, type) {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 阅片导入
|
||||
export function readingImport(param) {
|
||||
return request({
|
||||
url: `/ReadingCalculate/readingImport`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
+88
-4
@@ -969,13 +969,20 @@ export function takeOrReleaseQCTask(trialId, subjectVisitId, obtainOrCancel) {
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
export function replaceQCTaskActionUser(trialId, subjectVisitId) {
|
||||
export function replaceQCTaskActionUser(trialId, subjectVisitId, params = {}) {
|
||||
return request({
|
||||
url: `/QCOperation/replaceQCTaskActionUser/${trialId}/${subjectVisitId}`,
|
||||
method: 'put'
|
||||
method: 'put',
|
||||
params
|
||||
})
|
||||
}
|
||||
export function getTrialUserRoleList(params) {
|
||||
return request({
|
||||
url: `/TrialMaintenance/getTrialUserRoleList`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function verifyReuploadIsCanJump(trialId, qcChallengeId) {
|
||||
return request({
|
||||
url: `/QCOperation/verifyReuploadIsCanJump/${trialId}/${qcChallengeId}`,
|
||||
@@ -3037,7 +3044,13 @@ export function readClinicalData(param) {
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
||||
export function viewstudyPart(param) {
|
||||
return request({
|
||||
url: `/ReadingImageTask/viewstudyPart`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
export function getCustomQuestionPreview(param) {
|
||||
return request({
|
||||
url: `/ReadingQuestion/getCustomQuestionPreview`,
|
||||
@@ -4197,4 +4210,75 @@ export function getExportSubjectVisitImageList(data) {
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 影像质控-更正dicom
|
||||
export function updateDicomStudyInfo(data) {
|
||||
return request({
|
||||
url: `/Inspection/QCOperation/UpdateDicomStudyInfo`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 影像质控-更正非dicom
|
||||
export function updateNoneDicomStudy(data) {
|
||||
return request({
|
||||
url: `/Inspection/NoneDicomStudy/UpdateNoneDicomStudy`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 阅片单元-获取访视计划
|
||||
export function getVisitStage(data) {
|
||||
return request({
|
||||
url: `/VisitPlan/getVisitStage`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 稽查管理-列表
|
||||
export function getAuditRecordList(data) {
|
||||
return request({
|
||||
url: `/AuditDocument/getAuditRecordList`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 稽查管理-列表(EA)
|
||||
export function getAuditRecordSelectList(data) {
|
||||
return request({
|
||||
url: `/AuditDocument/getAuditRecordSelectList`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 稽查管理-列表新增修改
|
||||
export function addOrUpdateAuditRecord(data) {
|
||||
return request({
|
||||
url: `/AuditDocument/addOrUpdateAuditRecord`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 稽查管理-文档授权
|
||||
export function setAuditRecordPermission(data) {
|
||||
return request({
|
||||
url: `/AuditDocument/setAuditRecordPermission`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 稽查管理-人员管理
|
||||
export function addOrDeleteAuditRecordUser(data) {
|
||||
return request({
|
||||
url: `/AuditDocument/addOrDeleteAuditRecordUser`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 稽查管理-删除
|
||||
export function deleteAuditRecord(auditRecordId) {
|
||||
return request({
|
||||
url: `/AuditDocument/deleteAuditRecord/${auditRecordId}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 54 KiB |
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div id="canvas" ref="canvas" v-loading="loading" element-loading-text="Loading..."
|
||||
<div id="canvas" ref="canvas" v-loading="loading" :element-loading-text="NSTip"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)" style="width:100%;height:100%;position:relative;"
|
||||
class="cornerstone-element" @contextmenu.prevent="onContextmenu" @mouseup="sliderMouseup">
|
||||
<div v-show="dicomInfo.series" class="info-series">
|
||||
@@ -39,6 +39,8 @@
|
||||
</div>
|
||||
|
||||
<div class="info-subject">
|
||||
<div v-if="series.subjectCode">{{ series.subjectCode }}</div>
|
||||
<div v-if="series.visitName">{{ series.visitName }}</div>
|
||||
<div>{{ stack.description }}</div>
|
||||
<!-- <div>{{ dicomInfo.hospital }}</div> -->
|
||||
<!-- <div v-show="dicomInfo.pid">{{ dicomInfo.pid }}</div> -->
|
||||
@@ -112,6 +114,11 @@ import DicomTags from './DicomTags'
|
||||
export default {
|
||||
name: 'DicomCanvas',
|
||||
components: { DicomTags },
|
||||
computed: {
|
||||
NSTip() {
|
||||
return `${this.$store.state.trials.downloadSize}, NS: ${this.$store.state.trials.downloadTip}`
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
{{ question.QuestionName }}
|
||||
</span>
|
||||
<!-- 添加 -->
|
||||
<el-button type="primary" size="mini" @click="openAddTableCol(question)">
|
||||
<el-button type="primary" size="mini" @click="openAddTableCol(question)" v-if="SecondReviewState <= 0">
|
||||
{{ $t('trials:readingUnit:qsList:title:add') }}
|
||||
</el-button>
|
||||
</div>
|
||||
@@ -29,7 +29,8 @@
|
||||
: scope.row[item.Id] }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('common:action:action')" min-width="100" show-overflow-tooltip>
|
||||
<el-table-column :label="$t('common:action:action')" min-width="100" show-overflow-tooltip
|
||||
v-if="SecondReviewState <= 0">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="mini" @click="openAddTableCol(question, scope.$index)">
|
||||
{{ $t('common:button:edit') }}
|
||||
@@ -164,7 +165,6 @@
|
||||
import { getTrialClinicalQuestionCalculateRelation } from '@/api/dictionary'
|
||||
import QuestionTableFormItem from './QuestionTableFormItem'
|
||||
import { mapGetters } from 'vuex'
|
||||
import DicomEvent from "../../../views/trials/trials-panel/reading/dicoms/components/DicomEvent";
|
||||
|
||||
export default {
|
||||
name: 'QuestionFormItem',
|
||||
@@ -176,6 +176,10 @@ export default {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
SecondReviewState: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
questionForm: {
|
||||
type: Object,
|
||||
default() {
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
:disabled="openType === 'look'">
|
||||
<template>
|
||||
<QuestionFormItem class="father" v-for="question of questions" :key="question.Id" :question="question"
|
||||
:question-form="questionForm" :trial-clinical-id="trialClinicalId" @resetFormItemData="resetFormItemData"
|
||||
@setFormItemData="setFormItemData" />
|
||||
:question-form="questionForm" :trial-clinical-id="trialClinicalId" :SecondReviewState="SecondReviewState"
|
||||
@resetFormItemData="resetFormItemData" @setFormItemData="setFormItemData" />
|
||||
</template>
|
||||
</el-form>
|
||||
<div class="base-dialog-footer" v-if="!isViewer && openType !== 'look' && [2, 3].includes(clinicalDataLevel)"
|
||||
<div class="base-dialog-footer"
|
||||
v-if="!isViewer && openType !== 'look' && [2, 3].includes(clinicalDataLevel) && SecondReviewState <= 0"
|
||||
style="text-align:right;margin-top:10px;">
|
||||
<!-- 取消 -->
|
||||
<el-button size="small" type="primary" @click="close"
|
||||
@@ -55,6 +56,10 @@ export default {
|
||||
return 2
|
||||
}
|
||||
},
|
||||
SecondReviewState: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
openType: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
<QuestionsForm v-if="clinicalUploadType === 2" :data="data" :trial-clinical-id="trialClinicalId"
|
||||
:is-viewer="isViewer" :visit-id="visitId" :subject-id="subjectId" :open-type="openType"
|
||||
:system-clinical-id="systemClinicalId" :trial-id="trialId" :reading-id="readingId"
|
||||
:clinical-form-id="clinicalFormId" :clinical-data-level="clinicalDataLevel" @close="close"></QuestionsForm>
|
||||
<uploadClinicalData v-else :subject-visit-id="subjectVisitId" :data="data" :enum-type="0" :allow-add-or-edit="true"
|
||||
@getList="() => { }">
|
||||
:clinical-form-id="clinicalFormId" :SecondReviewState="SecondReviewState" :clinical-data-level="clinicalDataLevel"
|
||||
@close="close"></QuestionsForm>
|
||||
<uploadClinicalData v-else :subject-visit-id="subjectVisitId" :SecondReviewState="SecondReviewState" :data="data"
|
||||
:enum-type="0" :allow-add-or-edit="true" @getList="() => { }">
|
||||
</uploadClinicalData>
|
||||
<div class="base-dialog-footer" v-if="!isViewer && openType !== 'look' && [0, 1].includes(clinicalDataLevel)"
|
||||
<div class="base-dialog-footer"
|
||||
v-if="!isViewer && openType !== 'look' && [0, 1].includes(clinicalDataLevel) && SecondReviewState <= 0"
|
||||
style="text-align:right;margin-top:10px;">
|
||||
<!-- 保存 -->
|
||||
<el-button size="small" type="primary" @click="submitClinicalForm">
|
||||
@@ -92,6 +94,10 @@ export default {
|
||||
type: String,
|
||||
default: () => ''
|
||||
},
|
||||
SecondReviewState: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
clinicalUploadType: {
|
||||
type: Number,
|
||||
default: () => {
|
||||
|
||||
@@ -22,10 +22,9 @@
|
||||
<i class="el-icon-warning-outline"></i>
|
||||
<div v-html="$t('download:tip:message')"></div>
|
||||
</div>
|
||||
<!--上传列表@selection-change="handleSelectionChange"-->
|
||||
<!--上传列表@selection-change="handleSelectionChange" @sort-change="handleSortByColumn"-->
|
||||
<el-table ref="dicomFilesTable" v-adaptive="{ bottomOffset: 85 }" height="100" :data="list" :loading="loading"
|
||||
class="dicomFiles-table" @sort-change="handleSortByColumn"
|
||||
:default-sort="{ prop: 'TaskBlindName', order: 'descending' }">
|
||||
class="dicomFiles-table" :default-sort="{ prop: 'TaskBlindName', order: 'descending' }">
|
||||
<!-- <el-table-column
|
||||
type="selection"
|
||||
width="55"
|
||||
@@ -37,10 +36,10 @@
|
||||
show-overflow-tooltip />
|
||||
<!--任务名称-->
|
||||
<el-table-column :label="$t('download:table:taskName')" min-width="130" show-overflow-tooltip prop="TaskBlindName"
|
||||
sortable="custom" />
|
||||
sortable />
|
||||
<!--检查类型-->
|
||||
<el-table-column :label="$t('download:table:studyType')" min-width="130" show-overflow-tooltip prop="IsDicom"
|
||||
sortable="custom">
|
||||
sortable>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ $fd('IsDicom', scope.row.IsDicom) }}</span>
|
||||
</template>
|
||||
@@ -150,13 +149,13 @@ export default {
|
||||
open: null,
|
||||
downloadId: null,
|
||||
IsReadingTaskViewInOrder: 0, // 阅片规则
|
||||
bodyPart: [],
|
||||
bodyPart: {},
|
||||
modelTaskId: null,
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
this.bodyPart.Bodypart = await this.$getBodyPart(this.$route.query.trialId)
|
||||
this.getList()
|
||||
this.bodyPart = await this.$getBodyPart(this.$route.query.trialId)
|
||||
this.title = `Download Images:${this.SubjectCode}(${this.Criterion.TrialReadingCriterionName})`
|
||||
},
|
||||
beforeDestroy() {
|
||||
@@ -298,24 +297,47 @@ export default {
|
||||
if (data.StudyList && data.StudyList.length > 0) {
|
||||
let StudyList = data.StudyList
|
||||
StudyList.forEach((study) => {
|
||||
if (study.StudyDIRPath) {
|
||||
let obj = {
|
||||
name: `${data.SubjectCode}/${data.TaskBlindName
|
||||
}/${this.$fd('IsDicom', true)}/${study.StudyCode
|
||||
}/DICOMDIR`,
|
||||
url: this.OSSclientConfig.basePath + study.StudyDIRPath,
|
||||
}
|
||||
if (this.IsReadingTaskViewInOrder === 0) {
|
||||
obj = {
|
||||
name: `${data.TaskBlindName}/${this.$fd(
|
||||
'IsDicom',
|
||||
true
|
||||
)}/DICOMDIR`,
|
||||
url: this.OSSclientConfig.basePath + study.StudyDIRPath,
|
||||
}
|
||||
}
|
||||
files.push(obj)
|
||||
}
|
||||
if (study.SeriesList.length > 0) {
|
||||
study.SeriesList.forEach((series) => {
|
||||
if (series.InstancePathList.length > 0) {
|
||||
series.InstancePathList.forEach((instance) => {
|
||||
if (series.InstanceList.length > 0) {
|
||||
series.InstanceList.forEach((instance) => {
|
||||
let fileName = instance.Path.split('/').pop()
|
||||
if (instance.FileName) {
|
||||
fileName = instance.FileName
|
||||
}
|
||||
let obj = {
|
||||
name: `${data.SubjectCode}/${data.TaskBlindName
|
||||
}/${this.$fd('IsDicom', true)}/${study.StudyCode
|
||||
}/${fileName}`,
|
||||
}/IMAGE/${fileName}`,
|
||||
url: this.OSSclientConfig.basePath + instance.Path,
|
||||
IsEncapsulated: instance.IsEncapsulated
|
||||
}
|
||||
if (this.IsReadingTaskViewInOrder === 0) {
|
||||
obj = {
|
||||
name: `${data.TaskBlindName}/${this.$fd(
|
||||
'IsDicom',
|
||||
true
|
||||
)}/${fileName}`,
|
||||
)}/IMAGE/${fileName}`,
|
||||
url: this.OSSclientConfig.basePath + instance.Path,
|
||||
IsEncapsulated: instance.IsEncapsulated
|
||||
}
|
||||
}
|
||||
files.push(obj)
|
||||
@@ -406,7 +428,7 @@ export default {
|
||||
let trialId = this.$route.query.trialId
|
||||
var token = getToken()
|
||||
const routeData = this.$router.resolve({
|
||||
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${row.SourceSubjectVisitId}&TokenKey=${token}`,
|
||||
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${row.SourceSubjectVisitId}&TokenKey=${token}&isReading=true`,
|
||||
})
|
||||
this.open = window.open(routeData.href, '_blank')
|
||||
},
|
||||
|
||||
@@ -283,6 +283,7 @@ export default {
|
||||
}
|
||||
if (this.visitTaskId) {
|
||||
this.form.VisitTaskId = this.visitTaskId
|
||||
this.form.QuestionType = 6
|
||||
}
|
||||
if (this.SubjectVisitId) {
|
||||
this.form.SubjectVisitId = this.SubjectVisitId
|
||||
|
||||
@@ -406,17 +406,15 @@ export default {
|
||||
subjectVisitId: null,
|
||||
errStudyUidList: [],
|
||||
open: null,
|
||||
bodyPart: [],
|
||||
bodyPart: {},
|
||||
openIsUpload: false,
|
||||
TrialModality: [],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
async mounted() {
|
||||
this.trialId = this.$route.query.trialId
|
||||
this.bodyPart = await this.$getBodyPart(this.$route.query.trialId)
|
||||
this.bodyPart.Bodypart = await this.$getBodyPart(this.$route.query.trialId)
|
||||
this.getList()
|
||||
this.uploadQueues = []
|
||||
this.OSSclient.close()
|
||||
},
|
||||
@@ -646,6 +644,7 @@ export default {
|
||||
resolve()
|
||||
})
|
||||
var validFilesCount = 0
|
||||
scope.uploadQueues = []
|
||||
for (var i = 0; i < checkFiles.length; ++i) {
|
||||
; (function (index) {
|
||||
p = p.then(function () {
|
||||
@@ -731,6 +730,8 @@ export default {
|
||||
fileList: [],
|
||||
dicomInfo: {
|
||||
studyId: data.string('x00200010'),
|
||||
DicomStudyDate: data.string('x00080020'),
|
||||
DicomStudyTime: data.string('x00080030'),
|
||||
studyUid: studyUid,
|
||||
patientId: data.string('x00100020'),
|
||||
patientName: patientNameStr,
|
||||
@@ -841,6 +842,8 @@ export default {
|
||||
)
|
||||
seriesItem = {
|
||||
seriesUid: seriesUid,
|
||||
DicomSeriesDate: data.string('x00080021'),
|
||||
DicomSeriesTime: data.string('x00080031'),
|
||||
seriesNumber: data.intString('x00200011') || 1,
|
||||
modality: data.string('x00080060') || '',
|
||||
description: seriesDescriptionStr,
|
||||
@@ -880,6 +883,10 @@ export default {
|
||||
}
|
||||
instanceItem = {
|
||||
instanceUid: instanceUid,
|
||||
SOPClassUID: data.string('x00080016'),
|
||||
TransferSytaxUID: data.string('x00020010'),
|
||||
MediaStorageSOPInstanceUID: instanceUid,
|
||||
MediaStorageSOPClassUID: data.string('x00080016'),
|
||||
instanceNumber: data.intString('x00200013') || 1,
|
||||
frameCount: data.intString('x00280008') || 1,
|
||||
instanceTime: instanceTime,
|
||||
@@ -887,7 +894,7 @@ export default {
|
||||
imageColumns: data.uint16('x00280011') || 0,
|
||||
sliceLocation: data.intString('x00201041') || 0,
|
||||
sliceThickness: data.string('x00180050') || '',
|
||||
numberOfFrames: data.intString('x00280008') || 0,
|
||||
numberOfFrames: data.intString('x00280008') || 1,
|
||||
pixelSpacing: data.string('x00280030') || '',
|
||||
imagerPixelSpacing: data.string('x00181164') || '',
|
||||
frameOfReferenceUID: data.string('x00200052') || '',
|
||||
@@ -1088,6 +1095,8 @@ export default {
|
||||
acquisitionNumber: dicomInfo.acquisitionNumber,
|
||||
triggerTime: dicomInfo.triggerTime,
|
||||
bodyPartExamined: '',
|
||||
DicomStudyDate: dicomInfo.DicomStudyDate,
|
||||
DicomStudyTime: dicomInfo.DicomStudyTime,
|
||||
seriesList: [],
|
||||
},
|
||||
}
|
||||
@@ -1112,6 +1121,10 @@ export default {
|
||||
instanceList.push({
|
||||
studyInstanceUid: dicomInfo.studyUid,
|
||||
seriesInstanceUid: v.seriesUid,
|
||||
SOPClassUID: o.SOPClassUID,
|
||||
TransferSytaxUID: o.TransferSytaxUID,
|
||||
MediaStorageSOPInstanceUID: o.MediaStorageSOPInstanceUID,
|
||||
MediaStorageSOPClassUID: o.MediaStorageSOPClassUID,
|
||||
sopInstanceUid: o.instanceUid,
|
||||
instanceNumber: o.instanceNumber,
|
||||
instanceTime: o.instanceTime,
|
||||
@@ -1193,6 +1206,10 @@ export default {
|
||||
studyInstanceUid: dicomInfo.studyUid,
|
||||
seriesInstanceUid: v.seriesUid,
|
||||
sopInstanceUid: o.instanceUid,
|
||||
SOPClassUID: o.SOPClassUID,
|
||||
TransferSytaxUID: o.TransferSytaxUID,
|
||||
MediaStorageSOPInstanceUID: o.MediaStorageSOPInstanceUID,
|
||||
MediaStorageSOPClassUID: o.MediaStorageSOPClassUID,
|
||||
instanceNumber: o.instanceNumber,
|
||||
instanceTime: o.instanceTime,
|
||||
imageRows: o.imageRows,
|
||||
@@ -1238,6 +1255,8 @@ export default {
|
||||
seriesInstanceUid: v.seriesUid,
|
||||
seriesNumber: v.seriesNumber,
|
||||
seriesTime: v.seriesTime,
|
||||
DicomSeriesDate: v.DicomSeriesDate,
|
||||
DicomSeriesTime: v.DicomSeriesTime,
|
||||
sliceThickness: v.sliceThickness,
|
||||
imagePositionPatient: v.imagePositionPatient,
|
||||
imageOrientationPatient: v.imageOrientationPatient,
|
||||
|
||||
@@ -18,7 +18,11 @@
|
||||
<el-table-column prop="Modality" :label="$t('upload:nonedicom:table:molityType')" sortable="custom">
|
||||
</el-table-column>
|
||||
<!--检查部位-->
|
||||
<el-table-column prop="BodyPart" :label="$t('upload:nonedicom:table:bodyPart')" sortable="custom" />
|
||||
<el-table-column prop="BodyPart" :label="$t('upload:nonedicom:table:bodyPart')" sortable="custom">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ getBodyPart(scope.row.BodyPart, scope.row.BodyPartForEditOther) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!--原文件数-->
|
||||
<el-table-column prop="FileCount" :label="$t('upload:nonedicom:table:fileCount')">
|
||||
<template slot-scope="scope">
|
||||
@@ -262,6 +266,7 @@ export default {
|
||||
currentRow: {},
|
||||
studyMonitorId: null,
|
||||
open: null,
|
||||
BodyPart: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -289,7 +294,8 @@ export default {
|
||||
store.dispatch('trials/setUnLock', this.btnLoading)
|
||||
},
|
||||
},
|
||||
created() {
|
||||
async created() {
|
||||
this.BodyPart.Bodypart = await this.$getBodyPart(this.$route.query.trialId)
|
||||
this.getList()
|
||||
},
|
||||
beforeDestroy() {
|
||||
@@ -674,6 +680,26 @@ export default {
|
||||
let blob = new Blob(['\ufeff', text], { type: 'text/plain' })
|
||||
return blob
|
||||
},
|
||||
getBodyPart(bodyPart, other) {
|
||||
if (!bodyPart && !other) return ''
|
||||
var separator = ','
|
||||
if (bodyPart.indexOf('|') > -1) {
|
||||
separator = '|'
|
||||
} else if (bodyPart.indexOf(',') > -1) {
|
||||
separator = ','
|
||||
} else if (bodyPart.indexOf(',') > -1) {
|
||||
separator = ','
|
||||
}
|
||||
var arr = bodyPart.split(separator)
|
||||
var newArr = arr.map((i) => {
|
||||
return this.$fd('Bodypart', i.trim(), 'Code', this.BodyPart, 'Name')
|
||||
})
|
||||
if (other) {
|
||||
newArr.push(other)
|
||||
}
|
||||
newArr = newArr.filter(Boolean)
|
||||
return newArr.join(' | ')
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -4,118 +4,49 @@
|
||||
<div slot="dialog-body">
|
||||
<el-table :data="modelList" style="width: 100%" height="300">
|
||||
<!--检查编号-->
|
||||
<el-table-column
|
||||
prop="StudyCode"
|
||||
:label="$t('trials:uploadImage:table:StudyCode')"
|
||||
/>
|
||||
<el-table-column prop="StudyCode" :label="$t('trials:uploadImage:table:StudyCode')" />
|
||||
<!--检查类型-->
|
||||
<el-table-column
|
||||
prop="ModalityForEdit"
|
||||
:label="$t('trials:uploadImage:table:ModalityForEdit')"
|
||||
v-if="IsDicom"
|
||||
/>
|
||||
<el-table-column prop="ModalityForEdit" :label="$t('trials:uploadImage:table:ModalityForEdit')"
|
||||
v-if="IsDicom" />
|
||||
<!--检查模态-->
|
||||
<el-table-column
|
||||
prop="Modalities"
|
||||
:label="$t('trials:uploadImage:table:Modalities')"
|
||||
v-if="IsDicom"
|
||||
/>
|
||||
<el-table-column prop="Modalities" :label="$t('trials:uploadImage:table:Modalities')" v-if="IsDicom" />
|
||||
<!--检查部位-->
|
||||
<el-table-column
|
||||
prop="BodyPartForEdit"
|
||||
:label="$t('trials:uploadImage:table:BodyPartForEdit')"
|
||||
v-if="IsDicom"
|
||||
>
|
||||
<el-table-column prop="BodyPartForEdit" :label="$t('trials:uploadImage:table:BodyPartForEdit')"
|
||||
v-if="IsDicom">
|
||||
<template slot-scope="scope">
|
||||
<span>{{
|
||||
$fd(
|
||||
'Bodypart',
|
||||
scope.row.BodyPartForEdit,
|
||||
'Code',
|
||||
{ Bodypart: bodyPart },
|
||||
'Name'
|
||||
)
|
||||
}}</span>
|
||||
<span>{{ getBodyPart(scope.row.BodyPartForEdit, scope.row.BodyPartForEditOther) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!--序列数量-->
|
||||
<el-table-column
|
||||
prop="SeriesCount"
|
||||
:label="$t('trials:uploadImage:table:SeriesCount')"
|
||||
v-if="IsDicom"
|
||||
/>
|
||||
<el-table-column prop="ReadingSeriesCount" :label="$t('trials:uploadImage:table:SeriesCount')"
|
||||
v-if="IsDicom" />
|
||||
<!--图像数量-->
|
||||
<el-table-column
|
||||
prop="InstanceCount"
|
||||
:label="$t('trials:uploadImage:table:InstanceCount')"
|
||||
v-if="IsDicom"
|
||||
/>
|
||||
<el-table-column prop="ReadingInstanceCount" :label="$t('trials:uploadImage:table:InstanceCount')"
|
||||
v-if="IsDicom" />
|
||||
<!--检查时间-->
|
||||
<el-table-column
|
||||
prop="StudyTime"
|
||||
:label="$t('trials:uploadImage:table:StudyTime')"
|
||||
v-if="IsDicom"
|
||||
min-width="130"
|
||||
/>
|
||||
<el-table-column prop="StudyTime" :label="$t('trials:uploadImage:table:StudyTime')" v-if="IsDicom"
|
||||
min-width="130" />
|
||||
<!--检查模态-->
|
||||
<el-table-column
|
||||
prop="Modality"
|
||||
:label="$t('trials:uploadImage:table:Modalities')"
|
||||
v-if="!IsDicom"
|
||||
/>
|
||||
<el-table-column prop="Modality" :label="$t('trials:uploadImage:table:Modalities')" v-if="!IsDicom" />
|
||||
<!--检查部位-->
|
||||
<el-table-column
|
||||
prop="BodyPart"
|
||||
:label="$t('trials:uploadImage:table:BodyPartForEdit')"
|
||||
v-if="!IsDicom"
|
||||
>
|
||||
<el-table-column prop="BodyPart" :label="$t('trials:uploadImage:table:BodyPartForEdit')" v-if="!IsDicom">
|
||||
<template slot-scope="scope">
|
||||
<span>{{
|
||||
$fd(
|
||||
'Bodypart',
|
||||
scope.row.BodyPart,
|
||||
'Code',
|
||||
{ Bodypart: bodyPart },
|
||||
'Name'
|
||||
)
|
||||
}}</span>
|
||||
<span>{{ getBodyPart(scope.row.BodyPart, scope.row.BodyPartForEditOther) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!--文件数量-->
|
||||
<el-table-column
|
||||
prop="FileCount"
|
||||
:label="$t('trials:uploadImage:table:FileCount')"
|
||||
v-if="!IsDicom"
|
||||
/>
|
||||
<el-table-column prop="ReadingFileCount" :label="$t('trials:uploadImage:table:FileCount')" v-if="!IsDicom" />
|
||||
<!--检查时间-->
|
||||
<el-table-column
|
||||
prop="ImageDate"
|
||||
:label="$t('trials:uploadImage:table:StudyTime')"
|
||||
v-if="!IsDicom"
|
||||
min-width="130"
|
||||
/>
|
||||
<el-table-column
|
||||
:label="$t('common:action:action')"
|
||||
fixed="right"
|
||||
width="80"
|
||||
>
|
||||
<el-table-column prop="ImageDate" :label="$t('trials:uploadImage:table:StudyTime')" v-if="!IsDicom"
|
||||
min-width="130" />
|
||||
<el-table-column :label="$t('common:action:action')" fixed="right" width="80">
|
||||
<template slot-scope="scope">
|
||||
<!--预览--->
|
||||
<el-button
|
||||
circle
|
||||
icon="el-icon-view"
|
||||
:title="$t('trials:uploadImage:button:preview')"
|
||||
v-if="!isUpload"
|
||||
@click.stop="preview(scope.row)"
|
||||
/>
|
||||
<el-button circle icon="el-icon-view" :title="$t('trials:uploadImage:button:preview')" v-if="!isUpload"
|
||||
@click.stop="preview(scope.row)" />
|
||||
<!--编辑--->
|
||||
<el-button
|
||||
circle
|
||||
icon="el-icon-edit-outline"
|
||||
:title="$t('trials:uploadImage:button:edit')"
|
||||
v-else
|
||||
@click.stop="openEdit(scope.row)"
|
||||
/>
|
||||
<el-button circle icon="el-icon-edit-outline" :title="$t('trials:uploadImage:button:edit')" v-else
|
||||
@click.stop="openEdit(scope.row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -124,42 +55,20 @@
|
||||
<!--新增检查部位-->
|
||||
<base-model v-if="editModality_model.visible" :config="editModality_model">
|
||||
<template slot="dialog-body">
|
||||
<el-form
|
||||
ref="editModalityform"
|
||||
:inline="true"
|
||||
:model="form"
|
||||
class="demo-form-inline"
|
||||
:rules="rules"
|
||||
>
|
||||
<el-form-item
|
||||
:label="$t('trials:uploadImage:form:ModalityForEdit')"
|
||||
prop="Modality"
|
||||
label-width="150px"
|
||||
>
|
||||
<el-form ref="editModalityform" :inline="true" :model="form" class="demo-form-inline" :rules="rules">
|
||||
<el-form-item :label="$t('trials:uploadImage:form:ModalityForEdit')" prop="Modality" label-width="150px">
|
||||
<el-select v-model="form.Modality" placeholder="">
|
||||
<el-option
|
||||
v-for="item in TrialModality"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
>
|
||||
<el-option v-for="item in TrialModality" :key="item" :label="item" :value="item">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
<template slot="dialog-footer">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="updateTaskStudyModality"
|
||||
:loading="loading"
|
||||
>
|
||||
<el-button type="primary" @click="updateTaskStudyModality" :loading="loading">
|
||||
{{ $t('common:button:confirm') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
@click="editModality_model.visible = false"
|
||||
:loading="loading"
|
||||
>
|
||||
<el-button @click="editModality_model.visible = false" :loading="loading">
|
||||
{{ $t('common:button:cancel') }}
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -180,9 +89,9 @@ export default {
|
||||
},
|
||||
},
|
||||
bodyPart: {
|
||||
type: Array,
|
||||
type: Object,
|
||||
default: () => {
|
||||
return []
|
||||
return {}
|
||||
},
|
||||
},
|
||||
modelList: {
|
||||
@@ -206,7 +115,6 @@ export default {
|
||||
default: true,
|
||||
},
|
||||
isUpload: {
|
||||
required: true,
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
@@ -236,6 +144,7 @@ export default {
|
||||
],
|
||||
},
|
||||
loading: false,
|
||||
BodyPart: {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -245,13 +154,13 @@ export default {
|
||||
if (this.IsDicom) {
|
||||
var token = getToken()
|
||||
routeData = this.$router.resolve({
|
||||
path: `/showdicom?studyId=${row.Id}&TokenKey=${token}&type=Study&visitTaskId=${this.visitTaskId}`,
|
||||
path: `/showdicom?studyId=${row.Id}&TokenKey=${token}&type=Study&visitTaskId=${this.visitTaskId}&isReading=true`,
|
||||
})
|
||||
} else {
|
||||
let trialId = this.$route.query.trialId
|
||||
var token = getToken()
|
||||
routeData = this.$router.resolve({
|
||||
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${row.SourceSubjectVisitId}&studyId=${row.Id}&TokenKey=${token}`,
|
||||
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${row.SourceSubjectVisitId}&studyId=${row.Id}&TokenKey=${token}&isReading=true`,
|
||||
})
|
||||
}
|
||||
window.open(routeData.href, '_blank')
|
||||
@@ -284,8 +193,28 @@ export default {
|
||||
console.log(err)
|
||||
}
|
||||
},
|
||||
getBodyPart(bodyPart, other) {
|
||||
if (!bodyPart && !other) return ''
|
||||
var separator = ','
|
||||
if (bodyPart.indexOf('|') > -1) {
|
||||
separator = '|'
|
||||
} else if (bodyPart.indexOf(',') > -1) {
|
||||
separator = ','
|
||||
} else if (bodyPart.indexOf(',') > -1) {
|
||||
separator = ','
|
||||
}
|
||||
var arr = bodyPart.split(separator)
|
||||
console.log(this.bodyPart)
|
||||
var newArr = arr.map((i) => {
|
||||
return this.$fd('Bodypart', i.trim(), 'Code', this.bodyPart, 'Name')
|
||||
})
|
||||
if (other) {
|
||||
newArr.push(other)
|
||||
}
|
||||
newArr = newArr.filter(Boolean)
|
||||
return newArr.join(' | ')
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -29,6 +29,10 @@ export default {
|
||||
MedicalAudit: 215, // 医学审核
|
||||
HeavyReadingApproval: 216, // 重阅审批
|
||||
ResetAndAsyncCriterion: 218, //同步签名
|
||||
ResetImageQualityControlQuestion: 112, // 重置影像质控问题
|
||||
CreateReviewTask: 113, // 生成复核任务
|
||||
ReviewImageQualityControlQuestion: 219, // 复核质控问题
|
||||
CorrectImageExaminationInformation: 220, // 更正影像检查信息
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
+16
-1
@@ -202,6 +202,7 @@ async function VueInit() {
|
||||
// 获取版本信息
|
||||
let PublishInfo = await getCurrentPublishInfo();
|
||||
Vue.prototype.$version = PublishInfo.Result;
|
||||
Vue.prototype.$companyInfo = PublishInfo.OtherInfo;
|
||||
// 获取检查部位
|
||||
Vue.prototype.$getBodyPart = (id) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
@@ -275,6 +276,20 @@ async function VueInit() {
|
||||
}
|
||||
return companyName;
|
||||
}
|
||||
Vue.prototype.$reg = () => {
|
||||
if (localStorage.getItem('CompanyInfo')) {
|
||||
let { EmailRegexStr } = JSON.parse(localStorage.getItem('CompanyInfo'))
|
||||
if (EmailRegexStr) {
|
||||
return { EmailRegexStr }
|
||||
}
|
||||
} else if (Vue.prototype.$companyInfo) {
|
||||
let { EmailRegexStr } = Vue.prototype.$companyInfo
|
||||
if (EmailRegexStr) {
|
||||
return { EmailRegexStr }
|
||||
}
|
||||
}
|
||||
return { EmailRegexStr: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$' };
|
||||
}
|
||||
Vue.prototype.$updateDictionary = function () {
|
||||
Vue.prototype.$d = function (code) {
|
||||
var dictInfo = res.Result
|
||||
@@ -316,7 +331,7 @@ async function VueInit() {
|
||||
})
|
||||
}
|
||||
let CompanyInfo = JSON.parse(localStorage.getItem('CompanyInfo'))
|
||||
if (CompanyInfo && CompanyInfo.SystemShortName) {
|
||||
if (CompanyInfo && CompanyInfo.SystemShortName && text.toUpperCase() !== "CIRCLE") {
|
||||
let test = new RegExp('IRC', 'ig')
|
||||
text = text.replace(test, CompanyInfo.SystemShortName)
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ const getters = {
|
||||
paymentHistoryQuery: state => state.financials.paymentHistoryQuery,
|
||||
revenusQuery: state => state.financials.revenusQuery,
|
||||
visitTaskList: state => state.reading.visitTaskList,
|
||||
BodyPart: state => state.reading.BodyPart,
|
||||
organList: state => state.reading.organList,
|
||||
seriesStack: state => state.reading.seriesStack,
|
||||
activeHangingAgreement: state => state.reading.activeHangingAgreement,
|
||||
|
||||
@@ -12,6 +12,7 @@ import { getCustomTag } from '@/api/reading'
|
||||
|
||||
import requestPoolManager from '@/utils/request-pool'
|
||||
import { getReadingVisitStudyList } from '@/api/trials'
|
||||
import { getNetWorkSpeed, setNetWorkSpeedSizeAll, workSpeedclose } from "@/utils"
|
||||
const hangingAgreement = [
|
||||
{ name: 'A', row: 1, col: 1 },
|
||||
{ name: 'A|A', row: 1, col: 2 },
|
||||
@@ -31,7 +32,8 @@ const getDefaultState = () => {
|
||||
lastCanvasTaskId: '',
|
||||
imageQuality: null,
|
||||
imageQualityIssues: null,
|
||||
currentLoadIns: []
|
||||
currentLoadIns: [],
|
||||
BodyPart: []
|
||||
}
|
||||
}
|
||||
function getQuestions(questions) {
|
||||
@@ -170,6 +172,45 @@ function getQuestionAnswer(questions, questionMark, answers) {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
function getQuerys(e) {
|
||||
if (!e) return "";
|
||||
var t = {},
|
||||
r = [],
|
||||
n = "",
|
||||
a = "";
|
||||
try {
|
||||
var i = [];
|
||||
if (e.indexOf("?") >= 0 && (i = e.substring(e.indexOf("?") + 1, e.length).split("&")), i.length > 0) for (var o in i) n = (r = i[o].split("="))[0],
|
||||
a = r[1],
|
||||
t[n] = a
|
||||
} catch (s) {
|
||||
t = {}
|
||||
}
|
||||
return t
|
||||
}
|
||||
async function getBodyPart(bodyPart, other) {
|
||||
if (!bodyPart && !other) return ''
|
||||
var separator = ','
|
||||
if (bodyPart.indexOf('|') > -1) {
|
||||
separator = '|'
|
||||
} else if (bodyPart.indexOf(',') > -1) {
|
||||
separator = ','
|
||||
} else if (bodyPart.indexOf(',') > -1) {
|
||||
separator = ','
|
||||
}
|
||||
let BodyPart = {}
|
||||
let query = getQuerys(window.location.href)
|
||||
BodyPart.Bodypart = await Vue.prototype.$getBodyPart(query.trialId)
|
||||
var arr = bodyPart.split(separator)
|
||||
var newArr = arr.map((i) => {
|
||||
return Vue.prototype.$fd('Bodypart', i.trim(), 'Code', BodyPart, 'Name')
|
||||
})
|
||||
if (other) {
|
||||
newArr.push(other)
|
||||
}
|
||||
newArr = newArr.filter(Boolean)
|
||||
return newArr
|
||||
}
|
||||
// function getKeySeriesInfo(keyInstance, series) {
|
||||
// const obj = {}
|
||||
// const set = new Set()
|
||||
@@ -644,15 +685,15 @@ const actions = {
|
||||
resolve(noneDicomMeasureData)
|
||||
})
|
||||
},
|
||||
addMeasuredData({ state }, obj) {
|
||||
addMeasuredData({ state }, obj) {
|
||||
return new Promise(resolve => {
|
||||
const criterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
|
||||
var measureData = state.visitTaskList[index].MeasureData
|
||||
// var idx = measureData.findIndex(item => item.MeasureData.uuid === obj.data.MeasureData.data.uuid)
|
||||
|
||||
|
||||
if (criterionType === 21) {
|
||||
let i = measureData.findIndex(i=>i.TableQuestionId === obj.data.TableQuestionId)
|
||||
let i = measureData.findIndex(i => i.TableQuestionId === obj.data.TableQuestionId)
|
||||
if (i > -1) {
|
||||
for (const k in state.visitTaskList[index].MeasureData[i]) {
|
||||
if (k !== 'Id' && obj.data[k]) {
|
||||
@@ -676,7 +717,7 @@ const actions = {
|
||||
console.log('新增标记成功')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
})
|
||||
@@ -775,15 +816,15 @@ const actions = {
|
||||
const criterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||
if (criterionType === 21) {
|
||||
const i = measureData.findIndex(item => item.QuestionId === obj.questionId && item.OrderMarkName === obj.orderMarkName)
|
||||
if (i > -1) {
|
||||
if (measureData[i].FristAddTaskId) {
|
||||
measureData[i].MeasureData = ''
|
||||
console.log('清除标记成功', i)
|
||||
} else {
|
||||
measureData.splice(i, 1)
|
||||
console.log('移除标记成功', i)
|
||||
}
|
||||
if (i > -1) {
|
||||
if (measureData[i].FristAddTaskId) {
|
||||
measureData[i].MeasureData = ''
|
||||
console.log('清除标记成功', i)
|
||||
} else {
|
||||
measureData.splice(i, 1)
|
||||
console.log('移除标记成功', i)
|
||||
}
|
||||
}
|
||||
state.visitTaskList[index].MeasureData = measureData
|
||||
} else {
|
||||
var idx = measureData.findIndex(item => item.QuestionId === obj.questionId && item.RowIndex === obj.rowIndex)
|
||||
@@ -810,7 +851,7 @@ const actions = {
|
||||
state.visitTaskList[index].MeasureData = measureData
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if (idx > -1) {
|
||||
// measureData.splice(idx, 1)
|
||||
|
||||
@@ -849,6 +890,20 @@ const actions = {
|
||||
var studyList = []
|
||||
var keyImages = []
|
||||
getReadingVisitStudyList(obj.trialId, obj.subjectVisitId, obj.visitTaskId).then(res => {
|
||||
try {
|
||||
state.BodyPart = []
|
||||
res.Result.forEach(async item => {
|
||||
let arr = await getBodyPart(item.BodyPartForEdit, item.BodyPartForEditOther)
|
||||
state.BodyPart.push({
|
||||
StudyId: item.StudyId,
|
||||
StudyCode: item.StudyCode,
|
||||
BodyPart: arr,
|
||||
Modalities: item.Modalities
|
||||
})
|
||||
})
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
const i = res.Result.findIndex(i => i.IsCriticalSequence)
|
||||
if (i > -1) {
|
||||
const seriesList = res.Result[i].SeriesList && res.Result[i].SeriesList
|
||||
@@ -1072,16 +1127,22 @@ const actions = {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let file = series.instanceInfoList.find(item => item.ImageId === obj.imageId)
|
||||
if (file) {
|
||||
getNetWorkSpeed()
|
||||
setNetWorkSpeedSizeAll(obj.percentComplete, obj.FileTotal, obj.imageId)
|
||||
}
|
||||
if (prefetchInstanceCount >= instanceCount * 100) {
|
||||
series.prefetchInstanceCount = instanceCount * 100
|
||||
// 设置当前序列状态为已下载完成
|
||||
series.loadStatus = true
|
||||
workSpeedclose()
|
||||
}
|
||||
if (prefetchInstanceCount2 !== null && instanceCount2 !== null && prefetchInstanceCount2 >= instanceCount2 * 100) {
|
||||
pSeries.prefetchInstanceCount = instanceCount2 * 100
|
||||
// 设置当前序列状态为已下载完成
|
||||
pSeries.loadStatus = true
|
||||
workSpeedclose()
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('error')
|
||||
|
||||
@@ -10,6 +10,8 @@ const getDefaultState = () => {
|
||||
unlock: false,
|
||||
config: {},
|
||||
uploadTip: '0.00KB/s',
|
||||
downloadTip: '0.00KB/s',
|
||||
downloadSize: '',
|
||||
timer: null,
|
||||
whiteList: [],
|
||||
checkTaskId: null
|
||||
|
||||
@@ -15,6 +15,7 @@ export const anonymization = function (file, config) {
|
||||
let dataset = dcmjs.data.DicomMessage.readFile(buffer)
|
||||
for (var i = 0; i < AnonymizeFixedList.length; i++) {
|
||||
let AnonymizeFixed = AnonymizeFixedList[i]
|
||||
if (!dataset.dict.hasOwnProperty(`${AnonymizeFixed.Group + AnonymizeFixed.Element}`)) continue
|
||||
if (dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element]) {
|
||||
dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element].Value[0] = AnonymizeFixed.ReplaceValue
|
||||
} else {
|
||||
@@ -28,6 +29,7 @@ export const anonymization = function (file, config) {
|
||||
}
|
||||
for (var i = 0; i < AnonymizeNotFixedList.length; i++) {
|
||||
let AnonymizeNotFixed = AnonymizeNotFixedList[i]
|
||||
// if (!dataset.dict.hasOwnProperty(`${AnonymizeNotFixed.Group + AnonymizeNotFixed.Element}`)) continue
|
||||
if (AnonymizeNotFixed.Group + AnonymizeNotFixed.Element === '00100020') {
|
||||
console.log(`${DicomStoreInfo.TrialCode}_${DicomStoreInfo.SubjectCode}`)
|
||||
if (dataset.dict[AnonymizeNotFixed.Group + AnonymizeNotFixed.Element]) {
|
||||
@@ -42,7 +44,7 @@ export const anonymization = function (file, config) {
|
||||
}
|
||||
} else {
|
||||
if (dataset.dict[AnonymizeNotFixed.Group + AnonymizeNotFixed.Element]) {
|
||||
dataset.dict[AnonymizeNotFixed.Group + AnonymizeNotFixed.Element].Value[0] = DicomStoreInfo[AnonymizeNotFixed.ReplaceValue] ? DicomStoreInfo[AnonymizeNotFixed.ReplaceValue].toString() : ''
|
||||
dataset.dict[AnonymizeNotFixed.Group + AnonymizeNotFixed.Element].Value[0] = DicomStoreInfo[AnonymizeNotFixed.ReplaceValue] || Number(DicomStoreInfo[AnonymizeNotFixed.ReplaceValue]) === 0 ? DicomStoreInfo[AnonymizeNotFixed.ReplaceValue].toString() : ''
|
||||
} else {
|
||||
dataset.dict[AnonymizeNotFixed.Group + AnonymizeNotFixed.Element] = {
|
||||
vr: AnonymizeNotFixed.ValueRepresentation,
|
||||
@@ -53,9 +55,9 @@ export const anonymization = function (file, config) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// console.log(dataset)
|
||||
|
||||
try {
|
||||
let newDicomFile = dataset.write()
|
||||
let newDicomFile = dataset.write() // fragmentMultiframe 原始数据是否进行分割
|
||||
const bufferArray = new Uint8Array(newDicomFile)
|
||||
const blob = new Blob([bufferArray], { type: 'application/octet-stream' })
|
||||
resolve({ blob, pixelDataElement })
|
||||
|
||||
+96
-1
@@ -1,4 +1,5 @@
|
||||
|
||||
import store from "@/store";
|
||||
/**
|
||||
* Parse the time to string
|
||||
* @param {(Object|string|number)} time
|
||||
@@ -92,7 +93,6 @@ export function deepClone(source, map = new WeakMap()) {
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
export function formatSize(size, fixed = 2) {
|
||||
if (isNaN(parseFloat(size))) return ''
|
||||
let kbSize = size / 1024
|
||||
@@ -101,4 +101,99 @@ export function formatSize(size, fixed = 2) {
|
||||
}
|
||||
let mbSize = kbSize / 1024
|
||||
return `${mbSize.toFixed(fixed)}MB`
|
||||
}
|
||||
|
||||
let timer = null, // 网速定时器
|
||||
lastPercentage = 0,
|
||||
percentageById = {},
|
||||
imageId = null,
|
||||
bytesReceivedPerSecond = {}; // 时间节点上传文件总量
|
||||
// 获取网速
|
||||
export function getNetWorkSpeed() {
|
||||
if (timer) return false;
|
||||
// if (lastPercentage < 100) return false;
|
||||
if (imageId && imageId !== Id) return false
|
||||
imageId = null
|
||||
timer = setInterval(() => {
|
||||
let timeList = Object.keys(bytesReceivedPerSecond).sort((a, b) => a - b);
|
||||
if (timeList.length > 0) {
|
||||
let totalBytes = timeList.reduce((sum, bytes) => sum + bytesReceivedPerSecond[bytes], 0) / (5 * 1024);
|
||||
let unit = 'KB/s';
|
||||
if (totalBytes > 1024) {
|
||||
totalBytes = totalBytes / 1024;
|
||||
unit = "MB/s";
|
||||
}
|
||||
store.state.trials.downloadTip = totalBytes.toFixed(3) + unit;
|
||||
}
|
||||
if (timeList.length >= 5) {
|
||||
delete bytesReceivedPerSecond[timeList[0]]
|
||||
}
|
||||
let time = new Date().getTime();
|
||||
bytesReceivedPerSecond[time] = 0;
|
||||
}, 1000)
|
||||
|
||||
}
|
||||
export function setNetWorkSpeedSize(totalPercentage, total, Id) {
|
||||
if (imageId && imageId !== Id) return false
|
||||
imageId = Id
|
||||
let percentage = totalPercentage - lastPercentage
|
||||
percentage = percentage / 100
|
||||
lastPercentage = totalPercentage
|
||||
// console.log(percentage, totalPercentage, total)
|
||||
let time = new Date().getTime();
|
||||
let timeList = Object.keys(bytesReceivedPerSecond).sort((a, b) => a - b);
|
||||
let bytesTime = timeList.find(item => time - item < 1000);
|
||||
if (bytesTime) {
|
||||
bytesReceivedPerSecond[bytesTime] += total * percentage;
|
||||
} else {
|
||||
// console.log("未查询到时间")
|
||||
if (timeList.length > 0) {
|
||||
bytesReceivedPerSecond[timeList[timeList.length - 1]] += total * percentage;
|
||||
} else {
|
||||
bytesReceivedPerSecond[time] = total * percentage;
|
||||
}
|
||||
}
|
||||
store.state.trials.uploadSize = `${formatSize(totalPercentage / 100 * total)}/${formatSize(total)}`
|
||||
}
|
||||
export function setNetWorkSpeedSizeAll(totalPercentage, total, Id) {
|
||||
if (!percentageById[Id]) {
|
||||
percentageById[Id] = 0
|
||||
}
|
||||
let percentage = totalPercentage - percentageById[Id]
|
||||
percentage = percentage / 100
|
||||
percentageById[Id] = totalPercentage
|
||||
// console.log(percentage, totalPercentage, total)
|
||||
let time = new Date().getTime();
|
||||
let timeList = Object.keys(bytesReceivedPerSecond).sort((a, b) => a - b);
|
||||
let bytesTime = timeList.find(item => time - item < 1000);
|
||||
if (bytesTime) {
|
||||
bytesReceivedPerSecond[bytesTime] += total * percentage;
|
||||
} else {
|
||||
// console.log("未查询到时间")
|
||||
if (timeList.length > 0) {
|
||||
bytesReceivedPerSecond[timeList[timeList.length - 1]] += total * percentage;
|
||||
} else {
|
||||
bytesReceivedPerSecond[time] = total * percentage;
|
||||
}
|
||||
}
|
||||
let isComplete = Object.keys(percentageById).every(key => percentageById[key >= 100])
|
||||
if (isComplete) {
|
||||
workSpeedclose(true)
|
||||
}
|
||||
}
|
||||
export function workSpeedclose(isForce = false) {
|
||||
if (!isForce && lastPercentage < 100) {
|
||||
return false
|
||||
}
|
||||
console.log('workSpeedclose')
|
||||
if (timer) {
|
||||
clearInterval(timer);
|
||||
timer = null;
|
||||
store.state.trials.downloadTip = '0KB/s'
|
||||
store.state.trials.downloadSize = ''
|
||||
}
|
||||
bytesReceivedPerSecond = {};
|
||||
lastPercentage = 0;
|
||||
imageId = null;
|
||||
percentageById = {};
|
||||
}
|
||||
+23
-1
@@ -1,6 +1,7 @@
|
||||
import streamSaver from "streamsaver";
|
||||
import "streamsaver/examples/zip-stream.js";
|
||||
import store from '@/store'
|
||||
import dcmjs from './dcmUpload/dcmjs'
|
||||
streamSaver.mitm = `${window.location.origin}/mitm.html?version=2.0.0`
|
||||
// 下载文件并压缩
|
||||
function zipFiles(zipName, files) {
|
||||
@@ -19,7 +20,10 @@ function zipFiles(zipName, files) {
|
||||
if (fileInfo.done) {//迭代终止
|
||||
ctrl.close();
|
||||
} else {
|
||||
let { name, url } = fileInfo.value;
|
||||
let { name, url, IsEncapsulated = false } = fileInfo.value;
|
||||
if (IsEncapsulated) {
|
||||
url = await downloadFileToUrl(url)
|
||||
}
|
||||
// url = decodeUtf8(url); // 待定,可能做过特殊处理
|
||||
return fetch(url).then(res => {
|
||||
ctrl.enqueue({
|
||||
@@ -99,6 +103,24 @@ function decodeUtf8(bytes) {
|
||||
str2.pop();
|
||||
return str2.join("/") + '/' + name;
|
||||
}
|
||||
// 下载文件进行修改并输出本地url
|
||||
function downloadFileToUrl(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url);
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.onload = function () {
|
||||
const arraybuffer = xhr.response;
|
||||
let dataset = dcmjs.data.DicomMessage.readFile(arraybuffer)
|
||||
let newDicomFile = dataset.write({ fragmentMultiframe: false }) // fragmentMultiframe 原始数据是否进行分割
|
||||
const bufferArray = new Uint8Array(newDicomFile)
|
||||
const blob = new Blob([bufferArray], { type: 'application/octet-stream' })
|
||||
const href = URL.createObjectURL(blob)
|
||||
resolve(href)
|
||||
};
|
||||
xhr.send();
|
||||
})
|
||||
}
|
||||
export async function downLoadFile(file, name, type = 'file') {
|
||||
if (type === 'zip') return await zipFiles(name, file);
|
||||
return await updateFile(file, name)
|
||||
|
||||
@@ -179,7 +179,8 @@ export default {
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
type: 'email',
|
||||
// type: 'email',
|
||||
pattern: new RegExp(this.$reg().EmailRegexStr),
|
||||
message: 'Please input the correct email address',
|
||||
trigger: ['blur'],
|
||||
},
|
||||
|
||||
@@ -19,14 +19,9 @@
|
||||
</div>
|
||||
<div class="viewerSidethumbs ps" style="position: relative;">
|
||||
<div class="viewerSidethumbinner">
|
||||
<div
|
||||
v-for="(item, index) in seriesList"
|
||||
:key="index"
|
||||
:class="{'viewerSideActive': index==0}"
|
||||
<div v-for="(item, index) in seriesList" :key="index" :class="{ 'viewerSideActive': index == 0 }"
|
||||
style="position: relative;margin-bottom:5px;border-radius: 2px;border: 1px solid #404040;"
|
||||
series-type="current"
|
||||
@click="showSeriesImage($event,index,item)"
|
||||
>
|
||||
series-type="current" @click="showSeriesImage($event, index, item)">
|
||||
<div class="viewernavigatorwrapper">
|
||||
<!-- <el-image
|
||||
class="image-preview"
|
||||
@@ -34,14 +29,8 @@
|
||||
:src="item.previewImageUrl"
|
||||
fit="fill"
|
||||
/> -->
|
||||
<img
|
||||
class="image-preview"
|
||||
:src="item.previewImageUrl"
|
||||
crossorigin="anonymous"
|
||||
alt=""
|
||||
style="width: 72px;height:72px;"
|
||||
fit="fill"
|
||||
>
|
||||
<img class="image-preview" :src="item.previewImageUrl" crossorigin="anonymous" alt=""
|
||||
style="width: 72px;height:72px;" fit="fill">
|
||||
<div class="viewernavitextwrapper">
|
||||
<div style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
|
||||
<div v-if="item.keySeries" style="color:red">
|
||||
@@ -51,23 +40,17 @@
|
||||
#{{ item.seriesNumber }}
|
||||
</div>
|
||||
<div v-if="item.isExistMutiFrames && item.instanceCount > 1">
|
||||
<el-popover
|
||||
v-model="item.isShowPopper"
|
||||
placement="right-start"
|
||||
trigger="manual"
|
||||
popper-class="instance_frame_wrapper"
|
||||
>
|
||||
<el-popover v-model="item.isShowPopper" placement="right-start" trigger="manual"
|
||||
popper-class="instance_frame_wrapper">
|
||||
<div style="text-align: right;">
|
||||
<i class="el-icon-circle-close" style="font-size: 20px;cursor: pointer;color:#ddd;" @click="item.isShowPopper = false" />
|
||||
<i class="el-icon-circle-close" style="font-size: 20px;cursor: pointer;color:#ddd;"
|
||||
@click="item.isShowPopper = false" />
|
||||
</div>
|
||||
<div class="frame_list">
|
||||
<div
|
||||
v-for="(instance, idx) in item.instanceInfoList"
|
||||
:key="instance.Id"
|
||||
<div v-for="(instance, idx) in item.instanceInfoList" :key="instance.Id"
|
||||
class="frame_content"
|
||||
:style="{'margin-bottom':idx<item.instanceInfoList.length-1? '5px':'0px'}"
|
||||
@click="showMultiFrames(item, index, instance)"
|
||||
>
|
||||
:style="{ 'margin-bottom': idx < item.instanceInfoList.length - 1 ? '5px' : '0px' }"
|
||||
@click="showMultiFrames(item, index, instance)">
|
||||
<div>
|
||||
<div>{{ instance.InstanceNumber }}</div>
|
||||
<div>
|
||||
@@ -75,22 +58,17 @@
|
||||
</div>
|
||||
<div v-if="showDelete">
|
||||
<span>{{ $t('trials:audit:table:isDelete') }}</span>
|
||||
<el-switch
|
||||
v-model="instance.IsDeleted"
|
||||
size="mini"
|
||||
@change="changeInstanceDeleteStatus($event, item, instance)"
|
||||
/>
|
||||
<el-switch v-model="instance.IsDeleted" size="mini"
|
||||
@change="changeInstanceDeleteStatus($event, item, instance)" />
|
||||
<span style="margin-left:10px;">{{ $t('trials:audit:table:isReading') }}</span>
|
||||
<el-switch
|
||||
v-model="instance.IsReading"
|
||||
size="mini"
|
||||
@change="changeInstanceReadingStatus($event, item, instance)"
|
||||
/>
|
||||
<el-switch v-model="instance.IsReading" size="mini"
|
||||
@change="changeInstanceReadingStatus($event, item, instance)" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;" @click="popperClick(seriesList, item)" />
|
||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;"
|
||||
@click="popperClick(seriesList, item)" />
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
@@ -100,7 +78,8 @@
|
||||
<div v-show="!item.keySeries && item.sliceThickness" style="padding: 1px;">
|
||||
T: {{ parseFloat(item.sliceThickness).toFixed(2) }}
|
||||
</div>
|
||||
<div v-show="!item.keySeries &&item.description" style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
<div v-show="!item.keySeries && item.description"
|
||||
style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
{{ item.description }}
|
||||
</div>
|
||||
<div v-if="!item.keySeries" style="padding: 1px;">
|
||||
@@ -109,27 +88,23 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
|
||||
<div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;"
|
||||
@click.stop="">
|
||||
|
||||
<div>
|
||||
<span style="font-size: 12px;margin-right: 5px">{{ $t('trials:audit:table:isReading') }}</span>
|
||||
<el-switch
|
||||
v-model="item.isReading"
|
||||
size="mini"
|
||||
@change="changeReadingStatus($event, item)"
|
||||
/>
|
||||
<span style="font-size: 12px;margin-right: 5px">{{ $t('trials:audit:table:isReading')
|
||||
}}</span>
|
||||
<el-switch v-model="item.isReading" size="mini" @change="changeReadingStatus($event, item)" />
|
||||
</div>
|
||||
<div>
|
||||
<span style="font-size: 12px;margin-right: 5px">{{ $t('trials:audit:table:isDelete') }}</span>
|
||||
<el-switch
|
||||
v-model="item.isDeleted"
|
||||
size="mini"
|
||||
@change="changeDeleteStatus($event, item)"
|
||||
/>
|
||||
<el-switch v-model="item.isDeleted" size="mini" @change="changeDeleteStatus($event, item)" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="item.prefetchInstanceCount>0 && item.prefetchInstanceCount<item.instanceCount * 100">
|
||||
<el-progress :percentage="parseInt((item.prefetchInstanceCount/item.instanceCount).toFixed(2))" />
|
||||
<div
|
||||
v-if="item.prefetchInstanceCount > 0 && item.prefetchInstanceCount < item.instanceCount * 100">
|
||||
<el-progress
|
||||
:percentage="parseInt((item.prefetchInstanceCount / item.instanceCount).toFixed(2))" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -164,6 +139,7 @@ import requestPoolManager from '@/utils/request-pool'
|
||||
import store from '@/store'
|
||||
import { changeURLStatic } from '@/utils/history.js'
|
||||
import metaDataProvider from '@/utils/metaDataProvider'
|
||||
import { getNetWorkSpeed, setNetWorkSpeedSize, workSpeedclose } from "@/utils"
|
||||
cornerstone.metaData.addProvider(metaDataProvider, { priority: 10 })
|
||||
var config = {
|
||||
maxWebWorkers: 4,
|
||||
@@ -184,7 +160,7 @@ export default {
|
||||
'dicom-viewer': dicomViewer
|
||||
},
|
||||
|
||||
data: function() {
|
||||
data: function () {
|
||||
return {
|
||||
trialId: '',
|
||||
studyId: '',
|
||||
@@ -216,10 +192,13 @@ export default {
|
||||
imageList: [],
|
||||
showSeriesList: [],
|
||||
currentLoadIns: [],
|
||||
isFromCRCUpload: false
|
||||
isFromCRCUpload: false,
|
||||
isReading: null,
|
||||
activeSeriesId: null,
|
||||
isPacs: false
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
created: function () {
|
||||
requestPoolManager.resetRequestPool()
|
||||
this.type = this.$router.currentRoute.query.type ? this.$router.currentRoute.query.type : ''
|
||||
|
||||
@@ -230,6 +209,12 @@ export default {
|
||||
store.dispatch('user/setToken', this.$router.currentRoute.query.TokenKey)
|
||||
changeURLStatic('TokenKey', '')
|
||||
}
|
||||
if (this.$router.currentRoute.query.isReading) {
|
||||
this.isReading = this.$router.currentRoute.query.isReading
|
||||
}
|
||||
if (this.$router.currentRoute.query.isPacs) {
|
||||
this.isPacs = Boolean(this.$router.currentRoute.query.isPacs)
|
||||
}
|
||||
this.studyId = this.$router.currentRoute.query.studyId
|
||||
this.isFromCRCUpload = !!this.$router.currentRoute.query.isFromCRCUpload
|
||||
if (this.type === 'Series') {
|
||||
@@ -256,10 +241,15 @@ export default {
|
||||
cornerstone.imageCache.purgeCache()
|
||||
requestPoolManager.resetRequestPool()
|
||||
})
|
||||
workSpeedclose(true)
|
||||
},
|
||||
methods: {
|
||||
async loadStudy() {
|
||||
const data = await getStudyInfo(this.studyId)
|
||||
let params = {}
|
||||
if (this.isPacs) {
|
||||
params.IsPacs = true
|
||||
}
|
||||
const data = await getStudyInfo(this.studyId, params)
|
||||
if (data.IsSuccess) {
|
||||
if (data.Result) {
|
||||
this.studyCode = data.Result.StudyCode
|
||||
@@ -267,7 +257,13 @@ export default {
|
||||
this.seriesCount = data.Result.SeriesCount
|
||||
this.description = data.Result.Description
|
||||
}
|
||||
const url = `/series/list/${this.studyId}`
|
||||
let isReading = !!this.isReading ? `?IsReading=true` : ''
|
||||
if (isReading && this.isPacs) {
|
||||
isReading += `&IsPacs=true`
|
||||
} else if (!isReading && this.isPacs) {
|
||||
isReading = `?IsPacs=true`
|
||||
}
|
||||
const url = `/series/list/${this.studyId}${isReading}`
|
||||
this.getSeriesList(url)
|
||||
}
|
||||
},
|
||||
@@ -317,7 +313,9 @@ export default {
|
||||
loadStatus: false,
|
||||
imageloadedArr: [],
|
||||
isExistMutiFrames: item.IsExistMutiFrames,
|
||||
isShowPopper: false
|
||||
isShowPopper: false,
|
||||
subjectCode: item.SubjectCode,
|
||||
visitName: item.VisitName
|
||||
})
|
||||
})
|
||||
this.seriesList = seriesList
|
||||
@@ -377,7 +375,9 @@ export default {
|
||||
loadStatus: false,
|
||||
imageloadedArr: [],
|
||||
isExistMutiFrames: item.IsExistMutiFrames,
|
||||
isShowPopper: false
|
||||
isShowPopper: false,
|
||||
subjectCode: item.SubjectCode,
|
||||
visitName: item.VisitName
|
||||
})
|
||||
})
|
||||
this.seriesList = seriesList
|
||||
@@ -447,7 +447,9 @@ export default {
|
||||
loadStatus: false,
|
||||
imageloadedArr: [],
|
||||
isExistMutiFrames: isExistMutiFrames,
|
||||
isShowPopper: false
|
||||
isShowPopper: false,
|
||||
subjectCode: res.OtherInfo.SubjectCode,
|
||||
visitName: res.OtherInfo.VisitName
|
||||
})
|
||||
this.seriesList = seriesList
|
||||
if (this.seriesList.length > 0) {
|
||||
@@ -462,6 +464,8 @@ export default {
|
||||
}
|
||||
},
|
||||
showSeriesImage(e, seriesIndex, series) {
|
||||
this.activeSeriesId = series.seriesId
|
||||
workSpeedclose(true)
|
||||
// if (seriesIndex === this.currentSeriesIndex) return
|
||||
const element = e.currentTarget
|
||||
const elements = document.querySelectorAll('[series-type]')
|
||||
@@ -531,7 +535,9 @@ export default {
|
||||
isReading: series.isReading,
|
||||
isDeleted: series.isDeleted,
|
||||
previewImageUrl: series.previewImageUrl,
|
||||
instanceCount: series.instanceCount
|
||||
instanceCount: series.instanceCount,
|
||||
subjectCode: series.SubjectCode,
|
||||
visitName: series.VisitName
|
||||
}
|
||||
this.$refs.dicomViewer.loadImageStack(seriesInfo)
|
||||
if (!series.loadStatus) {
|
||||
@@ -597,7 +603,9 @@ export default {
|
||||
keySeries: seriesInfo.KeySeries,
|
||||
loadStatus: false,
|
||||
imageloadedArr: [],
|
||||
isShowPopper: false
|
||||
isShowPopper: false,
|
||||
subjectCode: seriesInfo.SubjectCode,
|
||||
visitName: seriesInfo.VisitName
|
||||
})
|
||||
this.seriesList = seriesList
|
||||
if (this.seriesList.length > 0) {
|
||||
@@ -851,6 +859,9 @@ export default {
|
||||
const seriesIndex = params.seriesIndex
|
||||
var prefetchInstanceCount = this.seriesList[seriesIndex].prefetchInstanceCount
|
||||
var instanceCount = this.seriesList[seriesIndex].instanceCount
|
||||
if (!this.activeSeriesId) {
|
||||
this.activeSeriesId = this.seriesList[seriesIndex].seriesId
|
||||
}
|
||||
if (this.seriesList[seriesIndex].imageloadedArr.indexOf(imageId) < 0 && this.seriesList[seriesIndex].imageloadedArr.length < this.seriesList[seriesIndex].instanceCount) {
|
||||
const i = this.currentLoadIns.findIndex(i => i.imageId === imageId)
|
||||
if (i > -1) {
|
||||
@@ -870,10 +881,16 @@ export default {
|
||||
this.seriesList[seriesIndex].imageloadedArr.push(imageId)
|
||||
}
|
||||
}
|
||||
let file = this.seriesList[seriesIndex].instanceInfoList.find(item => item.ImageId === imageId)
|
||||
if (file && this.activeSeriesId === this.seriesList[seriesIndex].seriesId) {
|
||||
getNetWorkSpeed()
|
||||
setNetWorkSpeedSize(percentComplete, e.detail.total, imageId)
|
||||
}
|
||||
if (prefetchInstanceCount >= instanceCount * 100) {
|
||||
this.seriesList[seriesIndex].prefetchInstanceCount = instanceCount * 100
|
||||
// 设置当前序列状态为已下载完成
|
||||
this.seriesList[seriesIndex].loadStatus = true
|
||||
workSpeedclose()
|
||||
if (!this.isFromCRCUpload) {
|
||||
this.loadAllImages()
|
||||
}
|
||||
@@ -881,90 +898,102 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.viewerContainer .el-tabs--border-card{
|
||||
background:none;
|
||||
.viewerContainer .el-tabs--border-card {
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
.viewerContainer .el-tabs__item{
|
||||
|
||||
.viewerContainer .el-tabs__item {
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
}
|
||||
.viewerContainer .el-tabs--border-card>.el-tabs__content{
|
||||
|
||||
.viewerContainer .el-tabs--border-card>.el-tabs__content {
|
||||
padding: 5px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.viewerContainer ::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
.viewerContainer ::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
.viewerContainer .relationVisit{
|
||||
|
||||
.viewerContainer .relationVisit {
|
||||
line-height: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.viewerContainer{
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background-color: #444;
|
||||
overflow: hidden;
|
||||
}
|
||||
.viewerContainer .viewerBanner {
|
||||
background: linear-gradient(0,#444,#222);
|
||||
min-height: 28px;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
height: 30px;
|
||||
padding-top: 0;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
font-weight: bold;
|
||||
|
||||
.viewerContainer {
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background-color: #444;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerBanner {
|
||||
background: linear-gradient(0, #444, #222);
|
||||
min-height: 28px;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
height: 30px;
|
||||
padding-top: 0;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
/* height: 95%; */
|
||||
height: 99%;
|
||||
overflow: hidden;
|
||||
text-overflow: clip;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
/* height: 95%; */
|
||||
height: 99%;
|
||||
overflow: hidden;
|
||||
text-overflow: clip;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper>div {
|
||||
display: inline-block;
|
||||
white-space: normal;
|
||||
display: inline-block;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel {
|
||||
width: 215px;
|
||||
background-color: #323232;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin-right: 2px;
|
||||
color: #D0D0D0;
|
||||
overflow-y: auto;
|
||||
width: 215px;
|
||||
background-color: #323232;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin-right: 2px;
|
||||
color: #D0D0D0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper>div>.sidePanelBody {
|
||||
background: rgba(50,50,50,1);
|
||||
word-break: break-all;
|
||||
display: table;
|
||||
width: 100%;
|
||||
border: 1px solid #3e3f3a;
|
||||
background: rgba(50, 50, 50, 1);
|
||||
word-break: break-all;
|
||||
display: table;
|
||||
width: 100%;
|
||||
border: 1px solid #3e3f3a;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper>div>div.sidePanelBody>div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.viewerContainer .studyDesc{
|
||||
|
||||
.viewerContainer .studyDesc {
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
@@ -972,81 +1001,96 @@ export default {
|
||||
color: #d0d0d0;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.viewerContainer .ps {
|
||||
overflow: hidden !important;
|
||||
overflow-anchor: none;
|
||||
-ms-overflow-style: none;
|
||||
touch-action: auto;
|
||||
-ms-touch-action: auto;
|
||||
overflow: hidden !important;
|
||||
overflow-anchor: none;
|
||||
-ms-overflow-style: none;
|
||||
touch-action: auto;
|
||||
-ms-touch-action: auto;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .viewernavigatorwrapper {
|
||||
display: flex;
|
||||
width: 200px;
|
||||
height: 84px;
|
||||
padding: 1px 2px 1px 8px;
|
||||
margin: 6px 0 6px 1px;
|
||||
/* border-radius: 2px;
|
||||
display: flex;
|
||||
width: 200px;
|
||||
height: 84px;
|
||||
padding: 1px 2px 1px 8px;
|
||||
margin: 6px 0 6px 1px;
|
||||
/* border-radius: 2px;
|
||||
border: 1px solid #404040; */
|
||||
}
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress__text{
|
||||
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress__text {
|
||||
display: none;
|
||||
}
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress-bar{
|
||||
padding-right:0px;
|
||||
}
|
||||
.viewerContainer .ui-draggable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.viewerContainer .viewerLeftSidePanel .image-preview {
|
||||
border: 2px solid #252525;
|
||||
cursor: pointer;
|
||||
}
|
||||
.viewerContainer .viewerLeftSidePanel .viewernavitextwrapper {
|
||||
/* width: 120px;
|
||||
height: 80px; */
|
||||
flex:1;
|
||||
padding: 3px 1px 3px 4px;
|
||||
vertical-align: top;
|
||||
font-size: 12px;
|
||||
}
|
||||
.viewerContainer .viewerLeftSidePanel .viewerlabelwrapper {
|
||||
width: 20px;
|
||||
|
||||
font-size: 12px;
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress-bar {
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.viewerContainer .ui-draggable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .image-preview {
|
||||
border: 2px solid #252525;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .viewernavitextwrapper {
|
||||
/* width: 120px;
|
||||
height: 80px; */
|
||||
flex: 1;
|
||||
padding: 3px 1px 3px 4px;
|
||||
vertical-align: top;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .viewerlabelwrapper {
|
||||
width: 20px;
|
||||
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerSideActive {
|
||||
background: #16477b;
|
||||
background: #16477b80;
|
||||
border: 1px solid #23527b;
|
||||
background: #16477b;
|
||||
background: #16477b80;
|
||||
border: 1px solid #23527b;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContent {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
display: block;
|
||||
background-color: black;
|
||||
color: #D0D0D0;
|
||||
font-size: 13px;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
display: block;
|
||||
background-color: black;
|
||||
color: #D0D0D0;
|
||||
font-size: 13px;
|
||||
}
|
||||
.instance_frame_wrapper{
|
||||
|
||||
.instance_frame_wrapper {
|
||||
min-width: 120px;
|
||||
background-color: #2c2c2c;
|
||||
border: 1px solid #2c2c2c;
|
||||
padding: 5px;
|
||||
}
|
||||
.frame_list{
|
||||
|
||||
.frame_list {
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.instance_frame_wrapper ::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
||||
|
||||
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
.frame_content{
|
||||
|
||||
.frame_content {
|
||||
/* height: 50px; */
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
@@ -1055,6 +1099,7 @@ export default {
|
||||
font-size: 12px;
|
||||
border: 1px solid #404040;
|
||||
}
|
||||
|
||||
.frame_content:hover {
|
||||
/* font-weight: bold; */
|
||||
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
||||
@@ -1063,6 +1108,7 @@ export default {
|
||||
border-color: #213a54 !important;
|
||||
background-color: #213a54;
|
||||
}
|
||||
|
||||
/* .viewerRightSidePanel {
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
:key="index"
|
||||
> -->
|
||||
<el-collapse v-model="activeNames">
|
||||
<el-collapse-item v-for="(study, index) in studyList" :key="`${study.StudyId}`" :name="`${study.StudyId}`">
|
||||
<el-collapse-item v-for="(study, index) in studyList" :key="`${study.StudyId}`"
|
||||
:name="`${study.StudyId}`">
|
||||
<template slot="title">
|
||||
|
||||
<div class="text-desc">
|
||||
@@ -25,8 +26,10 @@
|
||||
<!-- <div v-show="study.Description" class="text-desc">
|
||||
{{ study.Description }}
|
||||
</div> -->
|
||||
<el-tooltip v-show="study.Description" class="item" effect="dark" :content="study.Description" placement="bottom">
|
||||
<div v-show="study.Description" style="width: 50px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
<el-tooltip v-show="study.Description" class="item" effect="dark" :content="study.Description"
|
||||
placement="bottom">
|
||||
<div v-show="study.Description"
|
||||
style="width: 50px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
{{ study.Description }}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
@@ -37,44 +40,29 @@
|
||||
<div v-show="study.Description" class="text-desc" style="background-color: #1f1f1f;">
|
||||
{{ study.Description }}
|
||||
</div>
|
||||
<div
|
||||
v-for="(series, i) in study.SeriesList"
|
||||
:key="i"
|
||||
:class="{'viewerSideActive': i==0 && index === 0}"
|
||||
<div v-for="(series, i) in study.SeriesList" :key="i"
|
||||
:class="{ 'viewerSideActive': i == 0 && index === 0 }"
|
||||
style="position: relative;margin-bottom:5px;border-radius: 2px;border: 1px solid #404040;"
|
||||
series-type="current"
|
||||
@click="showSeriesImage($event,index,i,series)"
|
||||
>
|
||||
series-type="current" @click="showSeriesImage($event, index, i, series)">
|
||||
<div class="viewernavigatorwrapper">
|
||||
<img
|
||||
class="image-preview"
|
||||
:src="series.previewImageUrl"
|
||||
crossorigin="anonymous"
|
||||
alt=""
|
||||
style="width: 85px;height:85px;"
|
||||
fit="fill"
|
||||
>
|
||||
<img class="image-preview" :src="series.previewImageUrl" crossorigin="anonymous" alt=""
|
||||
style="width: 85px;height:85px;" fit="fill">
|
||||
<div class="viewernavitextwrapper">
|
||||
<div style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
|
||||
<div>#{{ series.seriesNumber }}</div>
|
||||
<div v-if="series.isExistMutiFrames && series.instanceCount > 1">
|
||||
<el-popover
|
||||
v-model="series.isShowPopper"
|
||||
placement="right-start"
|
||||
trigger="manual"
|
||||
popper-class="instance_frame_wrapper"
|
||||
>
|
||||
<el-popover v-model="series.isShowPopper" placement="right-start" trigger="manual"
|
||||
popper-class="instance_frame_wrapper">
|
||||
<div style="text-align: right;">
|
||||
<i class="el-icon-circle-close" style="font-size: 20px;cursor: pointer;color:#ddd;" @click="series.isShowPopper = false" />
|
||||
<i class="el-icon-circle-close"
|
||||
style="font-size: 20px;cursor: pointer;color:#ddd;"
|
||||
@click="series.isShowPopper = false" />
|
||||
</div>
|
||||
<div class="frame_list">
|
||||
<div
|
||||
v-for="(instance, idx) in series.instanceInfoList"
|
||||
:key="instance.Id"
|
||||
<div v-for="(instance, idx) in series.instanceInfoList" :key="instance.Id"
|
||||
class="frame_content"
|
||||
:style="{'margin-bottom':idx<series.instanceInfoList.length-1? '5px':'0px'}"
|
||||
@click="showMultiFrames(index,series, i, instance)"
|
||||
>
|
||||
:style="{ 'margin-bottom': idx < series.instanceInfoList.length - 1 ? '5px' : '0px' }"
|
||||
@click="showMultiFrames(index, series, i, instance)">
|
||||
<!-- <div>
|
||||
<img
|
||||
class="image-preview"
|
||||
@@ -92,23 +80,20 @@
|
||||
</div>
|
||||
<div v-if="showDelete">
|
||||
<span>{{ $t('trials:audit:table:isDelete') }}</span>
|
||||
<el-switch
|
||||
v-model="instance.IsDeleted"
|
||||
size="mini"
|
||||
@change="changeInstanceDeleteStatus($event, series, instance)"
|
||||
/>
|
||||
<span style="margin-left:10px;">{{ $t('trials:audit:table:isReading') }}</span>
|
||||
<el-switch
|
||||
v-model="instance.IsReading"
|
||||
size="mini"
|
||||
@change="changeInstanceReadingStatus($event, series, instance)"
|
||||
/>
|
||||
<el-switch v-model="instance.IsDeleted" size="mini"
|
||||
@change="changeInstanceDeleteStatus($event, series, instance)" />
|
||||
<span style="margin-left:10px;">{{ $t('trials:audit:table:isReading')
|
||||
}}</span>
|
||||
<el-switch v-model="instance.IsReading" size="mini"
|
||||
@change="changeInstanceReadingStatus($event, series, instance)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;" @click="popperClick(studyList, series)" />
|
||||
<i slot="reference" class="el-icon-connection"
|
||||
style="font-size: 15px;cursor: pointer;"
|
||||
@click="popperClick(studyList, series)" />
|
||||
</el-popover>
|
||||
</div>
|
||||
|
||||
@@ -116,12 +101,14 @@
|
||||
<div v-show="series.InstanceCount" style="padding: 1px;">
|
||||
{{ series.modality }}: {{ series.instanceCount }} image
|
||||
</div>
|
||||
<div v-show=" series.sliceThickness" style="padding: 1px;">
|
||||
<div v-show="series.sliceThickness" style="padding: 1px;">
|
||||
T: {{ series.sliceThickness }}
|
||||
</div>
|
||||
|
||||
<el-tooltip v-show="series.description" class="item" effect="dark" :content="series.description" placement="bottom">
|
||||
<div v-show="series.description" style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
<el-tooltip v-show="series.description" class="item" effect="dark"
|
||||
:content="series.description" placement="bottom">
|
||||
<div v-show="series.description"
|
||||
style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
{{ series.description }}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
@@ -131,30 +118,27 @@
|
||||
<div />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
|
||||
<div v-if="showDelete"
|
||||
style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
|
||||
|
||||
<div>
|
||||
<span style="font-size: 12px;">{{ $t('trials:audit:table:isReading') }}</span>
|
||||
<el-switch
|
||||
v-model="series.isReading"
|
||||
size="mini"
|
||||
@change="changeReadingStatus($event, series)"
|
||||
/>
|
||||
<el-switch v-model="series.isReading" size="mini"
|
||||
@change="changeReadingStatus($event, series)" />
|
||||
</div>
|
||||
<div>
|
||||
<span style="font-size: 12px;">{{ $t('trials:audit:table:isDelete') }}</span>
|
||||
<el-switch
|
||||
v-model="series.isDeleted"
|
||||
size="mini"
|
||||
@change="changeDeleteStatus($event, series)"
|
||||
/>
|
||||
<el-switch v-model="series.isDeleted" size="mini"
|
||||
@change="changeDeleteStatus($event, series)" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div style="position: absolute;bottom: -10px;left: 0;width: 100%;">
|
||||
<el-progress v-if="series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount" :percentage="Number(series.prefetchInstanceCount/series.instanceCount)*100" />
|
||||
</div> -->
|
||||
<div v-if="series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount * 100">
|
||||
<el-progress :percentage="parseInt((series.prefetchInstanceCount/series.instanceCount).toFixed(2))" />
|
||||
<div
|
||||
v-if="series.prefetchInstanceCount > 0 && series.prefetchInstanceCount < series.instanceCount * 100">
|
||||
<el-progress
|
||||
:percentage="parseInt((series.prefetchInstanceCount / series.instanceCount).toFixed(2))" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -165,102 +149,109 @@
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="!visitTaskId" :label="$t('trials:dicom-show:relatedVisit')" name="relation-study" class="pane-relation-wrapper">
|
||||
<el-tab-pane v-show="!visitTaskId" :label="$t('trials:dicom-show:relatedVisit')" name="relation-study"
|
||||
class="pane-relation-wrapper">
|
||||
<div class="viewerSidethumbinner">
|
||||
<el-collapse v-model="relationActiveName" @change="handelRelationActiveChange">
|
||||
<el-collapse-item v-for="(study,studyIndex) in relationStudyList" :key="`${study.StudyId}`" :name="`${study.StudyId}`">
|
||||
<template slot="title">
|
||||
|
||||
<div class="text-desc">
|
||||
{{ study.StudyCode }}
|
||||
<el-collapse v-model="relationActiveName" @change="handelRelationActiveChange">
|
||||
<template v-for="item in relationStudyListByVisitName">
|
||||
<div :key="`${item.VisitName}`">
|
||||
<div v-show="item.VisitName" class="text-desc" style="background-color: #1f1f1f;">
|
||||
{{ item.VisitName }}
|
||||
</div>
|
||||
<!-- <div v-show="study.Description" class="text-desc">
|
||||
<template v-for="(study, studyIndex) in relationStudyList">
|
||||
<el-collapse-item :key="`${study.StudyId}`" :name="`${study.StudyId}`"
|
||||
v-if="study.VisitName === item.VisitName">
|
||||
<template slot="title">
|
||||
|
||||
<div class="text-desc">
|
||||
{{ study.StudyCode }}
|
||||
</div>
|
||||
<!-- <div v-show="study.Description" class="text-desc">
|
||||
{{ study.Description }}
|
||||
</div> -->
|
||||
|
||||
<div v-show="study.SeriesCount" class="text-desc">
|
||||
{{ study.Modalities }} : {{ study.SeriesCount }} Series
|
||||
</div>
|
||||
</template>
|
||||
<div v-show="study.Description" class="text-desc" style="background-color: #1f1f1f;">
|
||||
{{ study.Description }}
|
||||
</div>
|
||||
<div v-if="study.seriesList" class="viewerSidethumbs ps" style="position: relative;">
|
||||
<div class="viewerSidethumbinner">
|
||||
<div
|
||||
v-for="(seriesItem, index) in study.seriesList"
|
||||
:key="index"
|
||||
class="viewernavigatorwrapper"
|
||||
style="position: relative;border:1px solid #434343;"
|
||||
series-type="relation"
|
||||
@click="showRelationSeriesImage($event,seriesItem,studyIndex,index)"
|
||||
>
|
||||
<!-- <el-image
|
||||
<div v-show="study.SeriesCount" class="text-desc">
|
||||
{{ study.Modalities }} : {{ study.SeriesCount }} Series
|
||||
</div>
|
||||
</template>
|
||||
<div v-show="study.Description" class="text-desc" style="background-color: #1f1f1f;">
|
||||
{{ study.Description }}
|
||||
</div>
|
||||
<div class="viewerSidethumbs ps" style="position: relative;">
|
||||
<div class="viewerSidethumbinner">
|
||||
<div v-for="(seriesItem, index) in study.seriesList" :key="seriesItem.seriesId">
|
||||
<div class="viewernavigatorwrapper"
|
||||
style="position: relative;border:1px solid #434343;" series-type="relation"
|
||||
@click="showRelationSeriesImage($event, seriesItem, studyIndex, index)">
|
||||
<img class="image-preview" :src="seriesItem.previewImageUrl" crossorigin="anonymous"
|
||||
alt="" style="width: 85px;height:85px;" fit="fill">
|
||||
|
||||
<div class="viewernavitextwrapper">
|
||||
<div
|
||||
style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
|
||||
<div v-if="seriesItem.keySeries" style="color:red">
|
||||
Key Images
|
||||
</div>
|
||||
<div v-else>#{{ seriesItem.seriesNumber }}</div>
|
||||
<div v-if="seriesItem.isExistMutiFrames && seriesItem.instanceCount > 1">
|
||||
<el-popover placement="right-start" trigger="click"
|
||||
popper-class="instance_frame_wrapper">
|
||||
<div class="frame_list">
|
||||
<div v-for="(instance, idx) in seriesItem.instanceInfoList"
|
||||
:key="instance.Id" class="frame_content"
|
||||
:style="{ 'margin-bottom': idx < seriesItem.instanceInfoList.length - 1 ? '5px' : '0px' }"
|
||||
@click="showMultiFrames(studyIndex, seriesItem, index, instance)">
|
||||
<div>
|
||||
<div>{{ instance.InstanceNumber }}</div>
|
||||
<div>{{ `${instance.NumberOfFrames > 0 ? instance.NumberOfFrames : 1}
|
||||
frame`
|
||||
}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<i slot="reference" class="el-icon-connection"
|
||||
style="font-size: 15px;cursor: pointer;" />
|
||||
</el-popover>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-show="seriesItem.instanceCount" style="padding: 1px;">
|
||||
{{ seriesItem.modality }}: {{ seriesItem.instanceCount }} image
|
||||
</div>
|
||||
<div v-show="seriesItem.sliceThickness" style="padding: 1px;">
|
||||
T: {{ seriesItem.sliceThickness }}
|
||||
</div>
|
||||
<el-tooltip v-show="seriesItem.description" class="item" effect="dark"
|
||||
:content="seriesItem.description" placement="bottom">
|
||||
<div v-show="seriesItem.description"
|
||||
style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
{{ seriesItem.description }}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <el-image
|
||||
class="image-preview"
|
||||
style="height:72px;width:72px;"
|
||||
:src="seriesItem.previewImageUrl"
|
||||
fit="fill"
|
||||
/> -->
|
||||
<img
|
||||
class="image-preview"
|
||||
:src="seriesItem.previewImageUrl"
|
||||
crossorigin="anonymous"
|
||||
alt=""
|
||||
style="width: 85px;height:85px;"
|
||||
fit="fill"
|
||||
>
|
||||
|
||||
<div class="viewernavitextwrapper">
|
||||
<div style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
|
||||
<div v-if="seriesItem.keySeries" style="color:red">
|
||||
Key Images
|
||||
<div
|
||||
v-if="seriesItem.prefetchInstanceCount > 0 && seriesItem.prefetchInstanceCount < seriesItem.instanceCount * 100">
|
||||
<el-progress
|
||||
:percentage="parseInt((seriesItem.prefetchInstanceCount / seriesItem.instanceCount).toFixed(2))" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>#{{ seriesItem.seriesNumber }}</div>
|
||||
<div v-if="seriesItem.isExistMutiFrames && seriesItem.instanceCount > 1">
|
||||
<el-popover
|
||||
placement="right-start"
|
||||
trigger="click"
|
||||
popper-class="instance_frame_wrapper"
|
||||
>
|
||||
<div class="frame_list">
|
||||
<div
|
||||
v-for="(instance, idx) in seriesItem.instanceInfoList"
|
||||
:key="instance.Id"
|
||||
class="frame_content"
|
||||
:style="{'margin-bottom':idx<seriesItem.instanceInfoList.length-1? '5px':'0px'}"
|
||||
@click="showMultiFrames(studyIndex,seriesItem, index, instance)"
|
||||
>
|
||||
<div>
|
||||
<div>{{ instance.InstanceNumber }}</div>
|
||||
<div>{{ `${instance.NumberOfFrames > 0 ? instance.NumberOfFrames : 1} frame` }}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;" />
|
||||
</el-popover>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-show="seriesItem.instanceCount" style="padding: 1px;">
|
||||
{{ seriesItem.modality }}: {{ seriesItem.instanceCount }} image
|
||||
</div>
|
||||
<div v-show="seriesItem.sliceThickness" style="padding: 1px;">
|
||||
T: {{ seriesItem.sliceThickness }}
|
||||
</div>
|
||||
<el-tooltip v-show="seriesItem.description" class="item" effect="dark" :content="seriesItem.description" placement="bottom">
|
||||
<div v-show="seriesItem.description" style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
{{ seriesItem.description }}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<!-- <div style="position: absolute;bottom: -10px;left: 0;width: 100%;">
|
||||
<el-progress v-if="seriesItem.prefetchInstanceCount>0 && seriesItem.prefetchInstanceCount<seriesItem.instanceCount" :percentage="Number(seriesItem.prefetchInstanceCount/seriesItem.instanceCount)*100" />
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</template>
|
||||
|
||||
</el-collapse>
|
||||
|
||||
</div>
|
||||
@@ -287,6 +278,7 @@ import { getTaskUploadedDicomStudyList } from '@/api/reading'
|
||||
import requestPoolManager from '@/utils/request-pool'
|
||||
import store from '@/store'
|
||||
import { changeURLStatic } from '@/utils/history.js'
|
||||
import { getNetWorkSpeed, setNetWorkSpeedSize, workSpeedclose } from "@/utils"
|
||||
import metaDataProvider from '@/utils/metaDataProvider'
|
||||
cornerstone.metaData.addProvider(metaDataProvider, { priority: 10 })
|
||||
// import * as cornerstoneTools from 'cornerstone-tools'
|
||||
@@ -315,6 +307,7 @@ export default {
|
||||
visitInfo: '',
|
||||
activeName: 'current-study',
|
||||
relationStudyList: [],
|
||||
relationStudyListByVisitName: [],
|
||||
cachedImages: [],
|
||||
isReading: null,
|
||||
isStartLoad: false,
|
||||
@@ -328,7 +321,8 @@ export default {
|
||||
currentLoadIns: [],
|
||||
isFromCRCUpload: false,
|
||||
visitTaskId: null,
|
||||
page: ''
|
||||
page: '',
|
||||
activeSeriesId: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -361,6 +355,7 @@ export default {
|
||||
cornerstone.imageCache.purgeCache()
|
||||
requestPoolManager.resetRequestPool()
|
||||
})
|
||||
workSpeedclose(true)
|
||||
},
|
||||
methods: {
|
||||
// 获取某个访视下所有的检查信息
|
||||
@@ -422,7 +417,9 @@ export default {
|
||||
loadStatus: false,
|
||||
imageloadedArr: [],
|
||||
isExistMutiFrames: series.IsExistMutiFrames,
|
||||
isShowPopper: false
|
||||
isShowPopper: false,
|
||||
subjectCode: series.SubjectCode,
|
||||
visitName: series.VisitName
|
||||
})
|
||||
})
|
||||
data.SeriesList = seriesList
|
||||
@@ -459,6 +456,8 @@ export default {
|
||||
}
|
||||
},
|
||||
showSeriesImage(e, studyIndex, seriesIndex, series) {
|
||||
this.activeSeriesId = series.seriesId
|
||||
workSpeedclose(true)
|
||||
const element = e.currentTarget
|
||||
const elements = document.querySelectorAll('[series-type]')
|
||||
Array.from(elements).forEach((e) => {
|
||||
@@ -521,7 +520,9 @@ export default {
|
||||
isReading: series.isReading,
|
||||
isDeleted: series.isDeleted,
|
||||
previewImageUrl: series.previewImageUrl,
|
||||
instanceCount: series.instanceCount
|
||||
instanceCount: series.instanceCount,
|
||||
subjectCode: series.SubjectCode,
|
||||
visitName: series.VisitName
|
||||
}
|
||||
this.$refs.dicomViewer.loadImageStack(seriesInfo)
|
||||
if (!series.loadStatus) {
|
||||
@@ -707,10 +708,26 @@ export default {
|
||||
spinner: 'el-icon-loading'
|
||||
})
|
||||
try {
|
||||
const res = await getAllRelationStudyList(this.subjectVisitId)
|
||||
let params = {
|
||||
IsReading: !!this.isReading
|
||||
}
|
||||
const res = await getAllRelationStudyList(this.subjectVisitId, params)
|
||||
loading.close()
|
||||
this.relationStudyList = res.Result
|
||||
this.relationStudyListByVisitName = []
|
||||
res.Result.forEach(item => {
|
||||
let index = this.relationStudyListByVisitName.findIndex(d => d.VisitName === item.VisitName)
|
||||
if (index < 0) {
|
||||
this.relationStudyListByVisitName.push({
|
||||
VisitName: item.VisitName,
|
||||
series: [item]
|
||||
})
|
||||
} else {
|
||||
this.relationStudyListByVisitName[index].series.push(item)
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
loading.close()
|
||||
}
|
||||
}
|
||||
@@ -739,7 +756,8 @@ export default {
|
||||
spinner: 'el-icon-loading'
|
||||
})
|
||||
try {
|
||||
const data = await getSeriesList(`/series/list/${studyId}`)
|
||||
let isReading = !!this.isReading ? `?IsReading=true` : ''
|
||||
const data = await getSeriesList(`/series/list/${studyId}${isReading}`)
|
||||
loading.close()
|
||||
if (data.Result != null && data.Result.length > 0) {
|
||||
var seriesList = []
|
||||
@@ -749,9 +767,15 @@ export default {
|
||||
item.InstanceInfoList.forEach(i => {
|
||||
if (i.NumberOfFrames && i.NumberOfFrames > 1) {
|
||||
for (let j = 0; j < i.NumberOfFrames; j++) {
|
||||
if (!i.ImageId) {
|
||||
i.ImageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${i.Path}?frame=${j}&instanceId=${i.Id}&idx=${index}|${seriesIndex}&isRelation=1`
|
||||
}
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${i.Path}?frame=${j}&instanceId=${i.Id}&idx=${index}|${seriesIndex}&isRelation=1`)
|
||||
}
|
||||
} else {
|
||||
if (!i.ImageId) {
|
||||
i.ImageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${i.Path}?instanceId=${i.Id}&idx=${index}|${seriesIndex}&isRelation=1`
|
||||
}
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${i.Path}?instanceId=${i.Id}&idx=${index}|${seriesIndex}&isRelation=1`)
|
||||
}
|
||||
})
|
||||
@@ -772,12 +796,17 @@ export default {
|
||||
loadStatus: false,
|
||||
imageloadedArr: [],
|
||||
isExistMutiFrames: item.IsExistMutiFrames,
|
||||
isShowPopper: false
|
||||
isShowPopper: false,
|
||||
subjectCode: item.SubjectCode,
|
||||
visitName: item.VisitName
|
||||
})
|
||||
})
|
||||
scope.relationStudyList[index].seriesCount = seriesList.length
|
||||
scope.relationStudyList[index].seriesList = seriesList
|
||||
scope.relationStudyList[index].showSeries = true
|
||||
// scope.relationStudyList[index].seriesCount = seriesList.length
|
||||
// scope.relationStudyList[index].seriesList = seriesList
|
||||
// scope.relationStudyList[index].showSeries = true
|
||||
scope.$set(scope.relationStudyList[index], 'seriesCount', seriesList.length)
|
||||
scope.$set(scope.relationStudyList[index], 'seriesList', seriesList)
|
||||
scope.$set(scope.relationStudyList[index], 'showSeries', true)
|
||||
scope.$forceUpdate()
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -786,6 +815,8 @@ export default {
|
||||
}
|
||||
},
|
||||
showRelationSeriesImage(e, series, studyIndex, index) {
|
||||
this.activeSeriesId = series.seriesId
|
||||
workSpeedclose(true)
|
||||
this.currentRelationIndex = index
|
||||
const element = e.currentTarget
|
||||
const elements = document.querySelectorAll('[series-type]')
|
||||
@@ -805,6 +836,9 @@ export default {
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
|
||||
})
|
||||
}
|
||||
if (this.imageList.length > 0) {
|
||||
this.loopLoad()
|
||||
}
|
||||
}
|
||||
},
|
||||
loadAllImages() {
|
||||
@@ -864,8 +898,11 @@ export default {
|
||||
}
|
||||
const studyIndex = params.idx.split('|')[0]
|
||||
const seriesIndex = params.idx.split('|')[1]
|
||||
var series = !params.isRelation ? this.studyList[studyIndex].SeriesList[seriesIndex] : null
|
||||
var series = !params.isRelation ? this.studyList[studyIndex].SeriesList[seriesIndex] : this.relationStudyList[studyIndex].seriesList[seriesIndex]
|
||||
if (!series) return
|
||||
if (!this.activeSeriesId) {
|
||||
this.activeSeriesId = series.seriesId
|
||||
}
|
||||
var prefetchInstanceCount = series.prefetchInstanceCount
|
||||
var instanceCount = series.instanceCount
|
||||
if (series.imageloadedArr.indexOf(imageId) < 0) {
|
||||
@@ -887,6 +924,11 @@ export default {
|
||||
series.imageloadedArr.push(imageId)
|
||||
}
|
||||
}
|
||||
let file = series.instanceInfoList.find(item => item.ImageId === imageId)
|
||||
if (file && this.activeSeriesId === series.seriesId) {
|
||||
getNetWorkSpeed()
|
||||
setNetWorkSpeedSize(percentComplete, e.detail.total, imageId)
|
||||
}
|
||||
if (prefetchInstanceCount >= instanceCount * 100) {
|
||||
series.prefetchInstanceCount = instanceCount * 100
|
||||
// 设置当前序列状态为已下载完成
|
||||
@@ -894,96 +936,110 @@ export default {
|
||||
if (!this.isFromCRCUpload) {
|
||||
this.loadAllImages()
|
||||
}
|
||||
workSpeedclose()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style >
|
||||
.viewerContainer .el-tabs--border-card{
|
||||
background:none;
|
||||
<style>
|
||||
.viewerContainer .el-tabs--border-card {
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
.viewerContainer .el-tabs__item{
|
||||
|
||||
.viewerContainer .el-tabs__item {
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
width: 100px;
|
||||
padding: 0!important;
|
||||
padding: 0 !important;
|
||||
text-align: center;
|
||||
transform: scale(.8);
|
||||
}
|
||||
.viewerContainer .el-tabs--border-card>.el-tabs__content{
|
||||
|
||||
.viewerContainer .el-tabs--border-card>.el-tabs__content {
|
||||
padding: 5px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.viewerContainer ::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
.viewerContainer ::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
.viewerContainer .relationVisit{
|
||||
|
||||
.viewerContainer .relationVisit {
|
||||
line-height: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.viewerContainer{
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background-color: #444;
|
||||
overflow: hidden;
|
||||
}
|
||||
.viewerContainer .viewerBanner {
|
||||
background: linear-gradient(0,#444,#222);
|
||||
min-height: 28px;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
height: 30px;
|
||||
padding-top: 0;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
font-weight: bold;
|
||||
|
||||
.viewerContainer {
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background-color: #444;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerBanner {
|
||||
background: linear-gradient(0, #444, #222);
|
||||
min-height: 28px;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
height: 30px;
|
||||
padding-top: 0;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
/* height: 95%; */
|
||||
height: 99%;
|
||||
/* overflow: hidden;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
/* height: 95%; */
|
||||
height: 99%;
|
||||
/* overflow: hidden;
|
||||
text-overflow: clip; */
|
||||
/* white-space: nowrap; */
|
||||
/* white-space: nowrap; */
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper>div {
|
||||
display: inline-block;
|
||||
white-space: normal;
|
||||
display: inline-block;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel {
|
||||
width: 220px;
|
||||
background-color: #323232;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin-right: 2px;
|
||||
color: #D0D0D0;
|
||||
overflow-y: auto;
|
||||
width: 220px;
|
||||
background-color: #323232;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin-right: 2px;
|
||||
color: #D0D0D0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper>div>.sidePanelBody {
|
||||
background: rgba(50,50,50,1);
|
||||
word-break: break-all;
|
||||
display: table;
|
||||
width: 100%;
|
||||
border: 1px solid #3e3f3a;
|
||||
background: rgba(50, 50, 50, 1);
|
||||
word-break: break-all;
|
||||
display: table;
|
||||
width: 100%;
|
||||
border: 1px solid #3e3f3a;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContentWrapper>div>div.sidePanelBody>div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.viewerContainer .text-desc{
|
||||
|
||||
.viewerContainer .text-desc {
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
@@ -991,107 +1047,126 @@ export default {
|
||||
color: #d0d0d0;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.viewerContainer .ps {
|
||||
overflow: hidden !important;
|
||||
overflow-anchor: none;
|
||||
-ms-overflow-style: none;
|
||||
touch-action: auto;
|
||||
-ms-touch-action: auto;
|
||||
overflow: hidden !important;
|
||||
overflow-anchor: none;
|
||||
-ms-overflow-style: none;
|
||||
touch-action: auto;
|
||||
-ms-touch-action: auto;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .viewernavigatorwrapper {
|
||||
display: flex;
|
||||
width: 220px;
|
||||
/* height: 84px; */
|
||||
padding: 1px 2px 1px 2px;
|
||||
margin: 2px 0 1px 1px;
|
||||
/* border-radius: 2px;
|
||||
display: flex;
|
||||
width: 220px;
|
||||
/* height: 84px; */
|
||||
padding: 1px 2px 1px 2px;
|
||||
margin: 2px 0 1px 1px;
|
||||
/* border-radius: 2px;
|
||||
border: 1px solid #404040; */
|
||||
|
||||
}
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress__text{
|
||||
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress__text {
|
||||
display: none;
|
||||
}
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress-bar{
|
||||
padding-right:0px;
|
||||
}
|
||||
.viewerContainer .ui-draggable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.viewerContainer .viewerLeftSidePanel .image-preview {
|
||||
border: 2px solid #252525;
|
||||
cursor: pointer;
|
||||
}
|
||||
.viewerContainer .viewerLeftSidePanel .viewernavitextwrapper {
|
||||
/* width: 120px;
|
||||
height: 80px; */
|
||||
flex:1;
|
||||
padding: 3px 1px 3px 4px;
|
||||
vertical-align: top;
|
||||
font-size: 12px;
|
||||
}
|
||||
.viewerContainer .viewerLeftSidePanel .viewerlabelwrapper {
|
||||
width: 20px;
|
||||
|
||||
font-size: 12px;
|
||||
.viewerContainer .viewernavigatorwrapper .el-progress-bar {
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.viewerContainer .ui-draggable-handle {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .image-preview {
|
||||
border: 2px solid #252525;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .viewernavitextwrapper {
|
||||
/* width: 120px;
|
||||
height: 80px; */
|
||||
flex: 1;
|
||||
padding: 3px 1px 3px 4px;
|
||||
vertical-align: top;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerLeftSidePanel .viewerlabelwrapper {
|
||||
width: 20px;
|
||||
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerSideActive {
|
||||
background: #16477b;
|
||||
background: #16477b80;
|
||||
border: 1px solid #23527b;
|
||||
background: #16477b;
|
||||
background: #16477b80;
|
||||
border: 1px solid #23527b;
|
||||
}
|
||||
|
||||
.viewerContainer .viewerContent {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
display: block;
|
||||
background-color: black;
|
||||
color: #D0D0D0;
|
||||
font-size: 13px;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
display: block;
|
||||
background-color: black;
|
||||
color: #D0D0D0;
|
||||
font-size: 13px;
|
||||
}
|
||||
.viewerContainer .pane-relation-wrapper{
|
||||
|
||||
.viewerContainer .pane-relation-wrapper {
|
||||
min-height: 500px;
|
||||
}
|
||||
.viewerContainer .el-collapse{
|
||||
|
||||
.viewerContainer .el-collapse {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.viewerContainer .el-collapse-item{
|
||||
background-color: #585453!important;
|
||||
.viewerContainer .el-collapse-item {
|
||||
background-color: #585453 !important;
|
||||
color: #ddd;
|
||||
|
||||
}
|
||||
.viewerContainer .el-collapse-item__content{
|
||||
padding-bottom:5px;
|
||||
background-color: #2c2c2c!important;
|
||||
|
||||
.viewerContainer .el-collapse-item__content {
|
||||
padding-bottom: 5px;
|
||||
background-color: #2c2c2c !important;
|
||||
color: #ddd;
|
||||
}
|
||||
.viewerContainer .el-collapse-item__header{
|
||||
background-color: #585453!important;
|
||||
|
||||
.viewerContainer .el-collapse-item__header {
|
||||
background-color: #585453 !important;
|
||||
color: #ddd;
|
||||
border-bottom-color:#5a5a5a;
|
||||
border-bottom-color: #5a5a5a;
|
||||
padding-left: 5px;
|
||||
height: 40px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.instance_frame_wrapper{
|
||||
|
||||
.instance_frame_wrapper {
|
||||
min-width: 120px;
|
||||
background-color: #2c2c2c;
|
||||
border: 1px solid #2c2c2c;
|
||||
padding: 5px;
|
||||
}
|
||||
.frame_list{
|
||||
|
||||
.frame_list {
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.instance_frame_wrapper ::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
||||
|
||||
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
.frame_content{
|
||||
|
||||
.frame_content {
|
||||
/* height: 50px; */
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
@@ -1100,6 +1175,7 @@ export default {
|
||||
font-size: 12px;
|
||||
border: 1px solid #404040;
|
||||
}
|
||||
|
||||
.frame_content:hover {
|
||||
/* font-weight: bold; */
|
||||
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
||||
@@ -1121,4 +1197,3 @@ export default {
|
||||
font-size: 13px;
|
||||
} */
|
||||
</style>
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ import ppt from '@/assets/file_icon/ppt.png'
|
||||
import pptx from '@/assets/file_icon/pptx.png'
|
||||
import xls from '@/assets/file_icon/xls.png'
|
||||
import xlsx from '@/assets/file_icon/xlsx.png'
|
||||
import mp4 from '@/assets/file_icon/mp4.png'
|
||||
import PreviewFile from '@/components/PreviewFile'
|
||||
import imageViewer from './image-viewer'
|
||||
import { getSystemDocumentAttachmentList } from '@/api/dictionary'
|
||||
@@ -117,6 +118,7 @@ export default {
|
||||
pptx,
|
||||
xls,
|
||||
xlsx,
|
||||
mp4,
|
||||
rowData: {},
|
||||
list: [],
|
||||
searchData: defaultSearchData(),
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
<template>
|
||||
<el-form ref="sysTemplateFrom" v-loading="loading" :model="form" label-width="140px" size="small" :rules="rules"
|
||||
class="upload-temporary-file">
|
||||
<div class="base-dialog-body">
|
||||
<el-form-item :label="$t('dictionary:attachment:label:code')" prop="Code">
|
||||
<el-input v-model="form.Code" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dictionary:attachment:label:businessScenario')" prop="BusinessScenarioEnum">
|
||||
<el-select v-model="form.BusinessScenarioEnum" style="width: 100%" size="small" filterable>
|
||||
<el-option v-for="item of $d.Common_File_BusinessScenario" :key="item.id" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('dictionary:attachment:label:file')">
|
||||
<div class="upload-container">
|
||||
<el-upload class="upload-demo" action accept="" :before-upload="beforeUpload" :http-request="handleUploadFile"
|
||||
:on-preview="handlePreview" :on-remove="handleRemoveFile" :show-file-list="true" :file-list="fileList"
|
||||
:limit="1" :on-exceed="handleExceed" :disabled="(!form.FileTypeEnum && form.FileTypeEnum !== 0)">
|
||||
<el-button size="small" type="primary" :disabled="(!form.FileTypeEnum && form.FileTypeEnum !== 0)"
|
||||
:loading="btnLoading">Select</el-button>
|
||||
<!-- <span slot="tip" style="margin-left: 10px" class="el-upload__tip">
|
||||
(must be in xlsx/xls/doc/docx format)
|
||||
</span> -->
|
||||
</el-upload>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dictionary:attachment:label:name')" prop="Name">
|
||||
<el-input v-model="form.Name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dictionary:attachment:export:form:nameCN')" prop="NameCN">
|
||||
<el-input v-model="form.NameCN" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.Id !== ''" :label="$t('dictionary:attachment:label:isDeleted')">
|
||||
<el-radio-group v-model="form.IsDeleted">
|
||||
<el-radio v-for="item of $d.YesOrNo" :label="item.value" :key="item.id">{{ item.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dictionary:attachment:label:description')">
|
||||
<el-input v-model="form.Description" type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="base-dialog-footer" style="text-align: right; margin-top: 10px">
|
||||
<el-form-item style="text-align: right">
|
||||
<el-button size="small" type="primary" :disabled="(!form.FileTypeEnum && form.FileTypeEnum !== 0)"
|
||||
:loading="saveBtnLoading" @click="handleSave">{{ $t('common:button:save') }}</el-button>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
addOrUpdateCommonDocument,
|
||||
uploadCommonDoc,
|
||||
Upload,
|
||||
} from '@/api/dictionary'
|
||||
import { getBasicDataSelects } from '@/api/dictionary/dictionary'
|
||||
export default {
|
||||
name: 'TemplateForm',
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
Id: '',
|
||||
Code: '',
|
||||
FileTypeEnum: 0,
|
||||
BusinessScenarioEnum: null,
|
||||
Name: '',
|
||||
NameCN: '',
|
||||
Path: '',
|
||||
Description: '',
|
||||
IsDeleted: false,
|
||||
},
|
||||
rules: {
|
||||
Code: [
|
||||
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] },
|
||||
],
|
||||
Name: [
|
||||
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] },
|
||||
],
|
||||
NameCN: [
|
||||
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] },
|
||||
],
|
||||
BusinessScenarioEnum: [
|
||||
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] },
|
||||
],
|
||||
},
|
||||
fileList: [],
|
||||
btnLoading: false,
|
||||
saveBtnLoading: false,
|
||||
loading: false,
|
||||
dictionaryList: {},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initForm()
|
||||
},
|
||||
methods: {
|
||||
async initForm() {
|
||||
await this.getDicData()
|
||||
if (Object.keys(this.data).length > 0) {
|
||||
if (this.data.Path) {
|
||||
this.fileList = [
|
||||
{
|
||||
name: this.data.Name,
|
||||
path: this.data.Path,
|
||||
url: this.data.Path,
|
||||
type: this.data.Type,
|
||||
},
|
||||
]
|
||||
}
|
||||
for (const k in this.form) {
|
||||
if (this.data.hasOwnProperty(k)) {
|
||||
this.form[k] = this.data[k]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// 获取文件类型下拉框
|
||||
getDicData() {
|
||||
this.loading = true
|
||||
getBasicDataSelects(['Common_File_ModuleType', 'Common_File_Type'])
|
||||
.then((res) => {
|
||||
this.dictionaryList = { ...res.Result }
|
||||
this.loading = false
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
beforeUpload(file) {
|
||||
// 检测文件类型是否符合要求
|
||||
if (this.checkFileSuffix(file.name)) {
|
||||
this.fileList = []
|
||||
return true
|
||||
} else {
|
||||
this.$alert(this.$t('dictionary:attachment:export:alert:formatFile'))
|
||||
|
||||
return false
|
||||
}
|
||||
},
|
||||
async handleUploadFile(param) {
|
||||
this.loading = true
|
||||
this.form.FileName = param.file.name
|
||||
let extendName = param.file.name
|
||||
.substring(param.file.name.lastIndexOf('.'))
|
||||
.toLocaleLowerCase()
|
||||
let file = await this.fileToBlob(param.file)
|
||||
let res = await this.OSSclient.put(`/System/Tools/${this.$guid()}${extendName}`, file)
|
||||
this.form.Path = this.$getObjectName(res.url)
|
||||
this.form.NameCN = param.file.name
|
||||
this.fileList.push({
|
||||
name: param.file.name,
|
||||
path: this.form.Path,
|
||||
fullPath: this.form.Path,
|
||||
url: this.form.Path,
|
||||
})
|
||||
this.loading = false
|
||||
this.btnLoading = false
|
||||
// Upload(formData, 1).then((res) => {
|
||||
// this.fileList.push({
|
||||
// name: param.file.name,
|
||||
// path: res.Result.FilePath,
|
||||
// fullPath: res.Result.FullFilePath,
|
||||
// url: res.Result.FilePath,
|
||||
// })
|
||||
|
||||
// })
|
||||
},
|
||||
fileToBlob(file) {
|
||||
// 创建 FileReader 对象
|
||||
const reader = new FileReader()
|
||||
return new Promise((resolve) => {
|
||||
// FileReader 添加 load 事件
|
||||
reader.addEventListener('load', (e) => {
|
||||
let blob
|
||||
if (typeof e.target.result === 'object') {
|
||||
blob = new Blob([e.target.result])
|
||||
} else {
|
||||
blob = e.target.result
|
||||
}
|
||||
resolve(blob)
|
||||
})
|
||||
// FileReader 以 ArrayBuffer 格式 读取 File 对象中数据
|
||||
reader.readAsArrayBuffer(file)
|
||||
})
|
||||
},
|
||||
handleSave() {
|
||||
this.$refs.sysTemplateFrom.validate((valid) => {
|
||||
if (!valid) return
|
||||
if (!this.form.Name) {
|
||||
this.$alert(this.$t('dictionary:attachment:message:msg1'))
|
||||
return
|
||||
}
|
||||
this.saveBtnLoading = true
|
||||
addOrUpdateCommonDocument(this.form)
|
||||
.then((res) => {
|
||||
this.saveBtnLoading = false
|
||||
this.$emit('closeDialog')
|
||||
this.$emit('getList')
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
})
|
||||
.catch(() => {
|
||||
this.saveBtnLoading = false
|
||||
})
|
||||
})
|
||||
},
|
||||
handleRemoveFile() {
|
||||
this.fileList = []
|
||||
this.form.Path = ''
|
||||
this.form.NameCN = ''
|
||||
this.form.Name = ''
|
||||
},
|
||||
handlePreview(file) {
|
||||
if (file.fullPath) {
|
||||
window.open(file.fullPath, '_blank')
|
||||
}
|
||||
},
|
||||
handleExceed(files, fileList) {
|
||||
this.$message.warning(this.$t('upload:rule:maxFile1'))
|
||||
},
|
||||
checkFileSuffix(fileName) {
|
||||
return true
|
||||
var typeArr = ['xls', 'xlsx', 'doc', 'docx']
|
||||
var extendName = fileName
|
||||
.substring(fileName.lastIndexOf('.') + 1)
|
||||
.toLocaleLowerCase()
|
||||
if (typeArr.indexOf(extendName) !== -1) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.upload-temporary-file {
|
||||
.upload-container .el-upload--text {
|
||||
border: none;
|
||||
width: 80px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.upload-container .el-input--small {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.upload-container .el-icon-circle-check {
|
||||
color: #428bca;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.account_item_clear {
|
||||
.el-tag__close {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<BaseContainer>
|
||||
<template slot="search-container">
|
||||
<el-form :inline="true" size="small">
|
||||
<!-- 业务场景 -->
|
||||
<el-form-item :label="$t('dictionary:attachment:label:businessScenario')">
|
||||
<el-select v-model="searchData.BusinessScenarioEnum" style="width: 150px">
|
||||
<el-option v-for="item of $d.Common_File_BusinessScenario" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- 文件名称 -->
|
||||
<el-form-item :label="$t('dictionary:attachment:label:name')">
|
||||
<el-input v-model="searchData.Name" style="width: 130px" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<!-- 查询 -->
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleSearch">
|
||||
{{ $t('common:button:search') }}
|
||||
</el-button>
|
||||
<!-- 重置 -->
|
||||
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
|
||||
{{ $t('common:button:reset') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-button type="primary" style="float: right" size="small" @click="handleAdd">
|
||||
{{ $t('common:button:new') }}
|
||||
</el-button>
|
||||
</el-form>
|
||||
</template>
|
||||
<template slot="main-container">
|
||||
<el-table v-adaptive="{ bottomOffset: 60 }" v-loading="loading" :data="list" stripe height="100"
|
||||
@sort-change="handleSortChange">
|
||||
<el-table-column type="index" width="40" />
|
||||
<el-table-column prop="Code" :label="$t('dictionary:attachment:label:code')" show-overflow-tooltip
|
||||
sortable="custom" />
|
||||
<!-- 业务场景 -->
|
||||
<el-table-column prop="BusinessScenarioEnum" :label="$t('dictionary:attachment:label:businessScenario')"
|
||||
show-overflow-tooltip sortable="custom">
|
||||
<template slot-scope="scope">
|
||||
{{
|
||||
$fd(
|
||||
'Common_File_BusinessScenario',
|
||||
scope.row.BusinessScenarioEnum
|
||||
)
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 文件名称 -->
|
||||
<el-table-column prop="Name" :label="$t('dictionary:attachment:label:name')" show-overflow-tooltip
|
||||
sortable="custom" />
|
||||
<el-table-column prop="NameCN" :label="$t('dictionary:attachment:upload:table:nameCN')" show-overflow-tooltip
|
||||
sortable="custom" />
|
||||
<!-- 描述 -->
|
||||
<el-table-column prop="Description" :label="$t('dictionary:attachment:label:description')"
|
||||
show-overflow-tooltip />
|
||||
<!-- 是否废除 -->
|
||||
<el-table-column prop="IsDeleted" :label="$t('dictionary:attachment:label:isDeleted')" show-overflow-tooltip
|
||||
sortable="custom">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.IsDeleted" type="danger">{{
|
||||
$fd('YesOrNo', scope.row.IsDeleted)
|
||||
}}</el-tag>
|
||||
<el-tag v-else type="primary">{{
|
||||
$fd('YesOrNo', scope.row.IsDeleted)
|
||||
}}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 上传时间 -->
|
||||
<el-table-column prop="UpdateTime" :label="$t('dictionary:attachment:label:updateTime')" show-overflow-tooltip
|
||||
sortable="custom" />
|
||||
|
||||
<el-table-column :label="$t('common:action:action')" width="300">
|
||||
<template slot-scope="scope">
|
||||
<!-- <el-button type="text" @click="PreviewFile(scope.row)">
|
||||
{{ $t('common:button:preview') }}
|
||||
</el-button> -->
|
||||
<el-button type="text" @click="handleDownload(scope.row)">
|
||||
{{ $t('common:button:download') }}
|
||||
</el-button>
|
||||
<el-button type="text" @click="handleEdit(scope.row)">
|
||||
{{ $t('common:button:edit') }}
|
||||
</el-button>
|
||||
<el-button type="text" @click="handleDelete(scope.row)">
|
||||
{{ $t('common:button:delete') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页组件 -->
|
||||
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
|
||||
@pagination="getList" />
|
||||
|
||||
<!-- 新增/编辑 -->
|
||||
<el-dialog v-if="editDialog.visible" :visible.sync="editDialog.visible" :close-on-click-modal="false"
|
||||
:title="editDialog.title" width="600px" custom-class="base-dialog-wrapper">
|
||||
<TemplateForm :data="currentRow" @closeDialog="closeDialog" @getList="getList" />
|
||||
</el-dialog>
|
||||
</template>
|
||||
</BaseContainer>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
getCommonDocumentList,
|
||||
DownloadCommonDoc,
|
||||
deleteCommonDocument,
|
||||
} from '@/api/dictionary'
|
||||
import BaseContainer from '@/components/BaseContainer'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import TemplateForm from './TemplateForm'
|
||||
import { downLoadFile } from '@/utils/stream.js'
|
||||
const FileTypeEnum = 0
|
||||
const searchDataDefault = () => {
|
||||
return {
|
||||
FileTypeEnum: FileTypeEnum,
|
||||
BusinessScenarioEnum: null,
|
||||
Name: '',
|
||||
PageIndex: 1,
|
||||
PageSize: 20,
|
||||
}
|
||||
}
|
||||
export default {
|
||||
name: 'ToolsTemplate',
|
||||
components: { BaseContainer, Pagination, TemplateForm },
|
||||
data() {
|
||||
return {
|
||||
searchData: searchDataDefault(),
|
||||
list: [],
|
||||
total: 0,
|
||||
currentRow: {},
|
||||
editDialog: { title: '', visible: false },
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getList()
|
||||
},
|
||||
computed: {
|
||||
isEN() {
|
||||
return this.$i18n.locale !== 'zh'
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleDelete(row) {
|
||||
// 确定删除该模版?
|
||||
this.$confirm(this.$t('dictionary:attachment:message:msg1')).then(() => {
|
||||
deleteCommonDocument(row.Id).then(() => {
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
this.getList()
|
||||
})
|
||||
}).catch(() => { })
|
||||
},
|
||||
PreviewFile(row) {
|
||||
let basePath = window.location.origin
|
||||
if (window.location.protocol !== 'https:') {
|
||||
basePath = 'https://irc.test.extimaging.com'
|
||||
}
|
||||
let data = {
|
||||
name: row.NameCN,
|
||||
path: basePath + row.Path,
|
||||
}
|
||||
this.$emit('PreviewFile', data)
|
||||
},
|
||||
getList() {
|
||||
this.loading = true
|
||||
getCommonDocumentList(this.searchData)
|
||||
.then((res) => {
|
||||
this.loading = false
|
||||
this.list = res.Result.CurrentPageData
|
||||
this.total = res.Result.TotalCount
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
// 新增
|
||||
handleAdd() {
|
||||
this.editDialog.title = this.$t('common:button:new')
|
||||
this.currentRow = { FileTypeEnum: FileTypeEnum }
|
||||
this.editDialog.visible = true
|
||||
},
|
||||
// 下载
|
||||
async handleDownload(row) {
|
||||
try {
|
||||
this.loading = true
|
||||
let fileName = this.isEN ? row.Name : row.NameCN;
|
||||
let type = fileName
|
||||
.substring(fileName.lastIndexOf('.'))
|
||||
.toLocaleLowerCase()
|
||||
if (!type) {
|
||||
let extendName = row.Path
|
||||
.substring(row.Path.lastIndexOf('.'))
|
||||
.toLocaleLowerCase()
|
||||
fileName += extendName
|
||||
}
|
||||
let res = await downLoadFile(this.OSSclientConfig.basePath + row.Path, fileName)
|
||||
this.loading = false
|
||||
} catch (err) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
// 编辑
|
||||
handleEdit(row) {
|
||||
this.editDialog.title = this.$t('common:button:edit')
|
||||
this.currentRow = { ...row }
|
||||
this.editDialog.visible = true
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchData.PageIndex = 1
|
||||
this.getList()
|
||||
},
|
||||
handleReset() {
|
||||
this.searchData = searchDataDefault()
|
||||
this.getList()
|
||||
},
|
||||
closeDialog() {
|
||||
this.editDialog.visible = false
|
||||
},
|
||||
// 排序
|
||||
handleSortChange(column) {
|
||||
if (column.order === 'ascending') {
|
||||
this.searchData.Asc = true
|
||||
} else {
|
||||
this.searchData.Asc = false
|
||||
}
|
||||
this.searchData.SortField = column.prop
|
||||
this.searchData.PageIndex = 1
|
||||
this.getList()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .search {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
@@ -1,52 +1,22 @@
|
||||
<template>
|
||||
<div class="attachment-wrapper">
|
||||
<el-tabs v-model="activeTab" @tab-click="clickTab">
|
||||
<el-tab-pane
|
||||
v-for="item in $d.Common_File_Type"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:name="String(item.value)"
|
||||
>
|
||||
<UploadTemplate
|
||||
v-if="activeTab === '1' && item.value == activeTab"
|
||||
@PreviewFile="PreviewFile"
|
||||
/>
|
||||
<ExportTemplate
|
||||
v-if="activeTab === '2' && item.value == activeTab"
|
||||
@PreviewFile="PreviewFile"
|
||||
/>
|
||||
<el-tab-pane v-for="item in $d.Common_File_Type" :key="item.value" :label="item.label" :name="String(item.value)">
|
||||
<UploadTemplate v-if="activeTab === '1' && item.value == activeTab" @PreviewFile="PreviewFile" />
|
||||
<ExportTemplate v-if="activeTab === '2' && item.value == activeTab" @PreviewFile="PreviewFile" />
|
||||
<EmailTemplate v-if="activeTab === '3' && item.value == activeTab" />
|
||||
<CommonTemplate v-if="activeTab === '4' && item.value == activeTab" />
|
||||
<SignatureTemplate
|
||||
v-if="activeTab === '5' && item.value == activeTab"
|
||||
/>
|
||||
<SignatureTemplate v-if="activeTab === '5' && item.value == activeTab" />
|
||||
<ToolsTemplate v-if="activeTab === '0' && item.value == activeTab" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<!-- 预览 -->
|
||||
<el-dialog
|
||||
v-if="Preview.visible"
|
||||
:visible.sync="Preview.visible"
|
||||
:close-on-click-modal="false"
|
||||
:fullscreen="true"
|
||||
:title="Preview.title"
|
||||
width="600px"
|
||||
custom-class="base-dialog-wrapper"
|
||||
>
|
||||
<vue-office-docx
|
||||
v-if="docxTypes.includes(Preview.type)"
|
||||
:src="Preview.path"
|
||||
style="height: calc(100vh - 70px)"
|
||||
@rendered="renderedHandler"
|
||||
@error="errorHandler"
|
||||
/>
|
||||
<vue-office-excel
|
||||
v-else-if="excelTypes.includes(Preview.type)"
|
||||
:src="Preview.path"
|
||||
:options="options"
|
||||
style="height: calc(100vh - 70px)"
|
||||
@rendered="renderedHandler"
|
||||
@error="errorHandler"
|
||||
/>
|
||||
<el-dialog v-if="Preview.visible" :visible.sync="Preview.visible" :close-on-click-modal="false" :fullscreen="true"
|
||||
:title="Preview.title" width="600px" custom-class="base-dialog-wrapper">
|
||||
<vue-office-docx v-if="docxTypes.includes(Preview.type)" :src="Preview.path" style="height: calc(100vh - 70px)"
|
||||
@rendered="renderedHandler" @error="errorHandler" />
|
||||
<vue-office-excel v-else-if="excelTypes.includes(Preview.type)" :src="Preview.path" :options="options"
|
||||
style="height: calc(100vh - 70px)" @rendered="renderedHandler" @error="errorHandler" />
|
||||
<PreviewFile v-else :file-path="Preview.path" :file-type="Preview.type" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
@@ -57,6 +27,7 @@ import ExportTemplate from './components/ExportTemplate'
|
||||
import EmailTemplate from './components/EmailTemplate'
|
||||
import CommonTemplate from './components/CommonTemplate'
|
||||
import SignatureTemplate from './components/SignatureTemplate'
|
||||
import ToolsTemplate from './components/ToolsTemplate'
|
||||
import VueOfficeDocx from '@vue-office/docx'
|
||||
import '@vue-office/docx/lib/index.css'
|
||||
import VueOfficeExcel from '@vue-office/excel'
|
||||
@@ -73,6 +44,7 @@ export default {
|
||||
VueOfficeDocx,
|
||||
VueOfficeExcel,
|
||||
PreviewFile,
|
||||
ToolsTemplate
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -142,16 +114,18 @@ export default {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.el-tabs__header {
|
||||
height: 40px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.el-tabs__content {
|
||||
flex: 1;
|
||||
|
||||
.el-tab-pane {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -43,6 +43,7 @@
|
||||
:data="list"
|
||||
stripe
|
||||
height="100"
|
||||
@sort-change="handleSortByColumn"
|
||||
>
|
||||
<el-table-column type="index" width="60" />
|
||||
<!-- Group -->
|
||||
@@ -50,6 +51,7 @@
|
||||
prop="Group"
|
||||
:label="$t('template:anonymization:label:group')"
|
||||
show-overflow-tooltip
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- Element -->
|
||||
<el-table-column
|
||||
@@ -57,24 +59,28 @@
|
||||
:label="$t('template:anonymization:label:element')"
|
||||
show-overflow-tooltip
|
||||
min-width="110"
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- Tag Description -->
|
||||
<el-table-column
|
||||
prop="TagDescription"
|
||||
:label="$t('template:anonymization:label:tagDescription')"
|
||||
min-width="110"
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- Tag DescriptionCN -->
|
||||
<el-table-column
|
||||
prop="TagDescriptionCN"
|
||||
:label="$t('template:anonymization:label:tagDescriptionCN')"
|
||||
min-width="110"
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- Value Representation -->
|
||||
<el-table-column
|
||||
prop="ValueRepresentation"
|
||||
:label="$t('template:anonymization:label:valueRepresentation')"
|
||||
min-width="110"
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- Is Fixed -->
|
||||
<el-table-column :label="$t('template:anonymization:label:isFixed')" width="100">
|
||||
@@ -92,6 +98,7 @@
|
||||
prop="ReplaceValue"
|
||||
:label="$t('template:anonymization:label:valueReplace')"
|
||||
min-width="110"
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- Is Enable -->
|
||||
<el-table-column :label="$t('template:anonymization:label:isEnable')" width="100" fixed="right">
|
||||
@@ -139,7 +146,9 @@ const searchDataDefault = () => {
|
||||
IsAdd: false,
|
||||
TagDescriptionCN: '',
|
||||
PageIndex: 1,
|
||||
PageSize: 500
|
||||
PageSize: 500,
|
||||
Asc: false,
|
||||
SortField: ''
|
||||
}
|
||||
}
|
||||
export default {
|
||||
@@ -159,6 +168,17 @@ export default {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
// 排序
|
||||
handleSortByColumn(column) {
|
||||
if (column.order === 'ascending') {
|
||||
this.searchData.Asc = true
|
||||
} else {
|
||||
this.searchData.Asc = false
|
||||
}
|
||||
this.searchData.SortField = column.prop
|
||||
this.searchData.PageIndex = 1
|
||||
this.getList()
|
||||
},
|
||||
switchChange(event, item) {
|
||||
this.loading = true
|
||||
addOrUpdateSystemAnonymization(item).then(res => {
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
:data="list"
|
||||
stripe
|
||||
height="100"
|
||||
@sort-change="handleSortByColumn"
|
||||
>
|
||||
<el-table-column type="index" width="60" />
|
||||
<!-- Group -->
|
||||
@@ -50,6 +51,7 @@
|
||||
prop="Group"
|
||||
:label="$t('template:anonymization:label:group')"
|
||||
show-overflow-tooltip
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- Element -->
|
||||
<el-table-column
|
||||
@@ -57,24 +59,28 @@
|
||||
:label="$t('template:anonymization:label:element')"
|
||||
show-overflow-tooltip
|
||||
min-width="110"
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- Tag Description -->
|
||||
<el-table-column
|
||||
prop="TagDescription"
|
||||
:label="$t('template:anonymization:label:tagDescription')"
|
||||
min-width="110"
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- Tag DescriptionCN -->
|
||||
<el-table-column
|
||||
prop="TagDescriptionCN"
|
||||
:label="$t('template:anonymization:label:tagDescriptionCN')"
|
||||
min-width="110"
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- Value Representation -->
|
||||
<el-table-column
|
||||
prop="ValueRepresentation"
|
||||
:label="$t('template:anonymization:label:valueRepresentation')"
|
||||
min-width="110"
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- Is Fixed -->
|
||||
<el-table-column :label="$t('template:anonymization:label:isFixed')" width="100">
|
||||
@@ -92,6 +98,7 @@
|
||||
prop="ReplaceValue"
|
||||
:label="$t('template:anonymization:label:valueReplace')"
|
||||
min-width="110"
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- Is Enable -->
|
||||
<el-table-column :label="$t('template:anonymization:label:isEnable')" width="100" fixed="right">
|
||||
@@ -138,7 +145,9 @@ const searchDataDefault = () => {
|
||||
TagDescriptionCN: '',
|
||||
IsAdd: true,
|
||||
PageIndex: 1,
|
||||
PageSize: 500
|
||||
PageSize: 500,
|
||||
Asc: false,
|
||||
SortField: ''
|
||||
}
|
||||
}
|
||||
export default {
|
||||
@@ -158,6 +167,17 @@ export default {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
// 排序
|
||||
handleSortByColumn(column) {
|
||||
if (column.order === 'ascending') {
|
||||
this.searchData.Asc = true
|
||||
} else {
|
||||
this.searchData.Asc = false
|
||||
}
|
||||
this.searchData.SortField = column.prop
|
||||
this.searchData.PageIndex = 1
|
||||
this.getList()
|
||||
},
|
||||
switchChange(event, item) {
|
||||
this.loading = true
|
||||
addOrUpdateSystemAnonymization(item).then(res => {
|
||||
|
||||
@@ -30,13 +30,13 @@
|
||||
<el-form-item
|
||||
:label="$t('trials:auditRecord:table:criterion')"
|
||||
>
|
||||
<el-select v-model="searchData.CriterionTypeEnum">
|
||||
<el-select v-model="searchData.CriterionTypeEnum" clearable>
|
||||
<el-option v-for="item of $d.CriterionType" :key="item.id" :value="item.value" :label="item.label" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- 是否通用 -->
|
||||
<el-form-item :label="$t('dictionary:medicalAudit:label:IsGeneral')">
|
||||
<el-select v-model="searchData.IsGeneral">
|
||||
<el-select v-model="searchData.IsGeneral" clearable>
|
||||
<el-option v-for="item of $d.YesOrNo" :key="item.id" :value="item.value" :label="item.label" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@@ -51,6 +51,9 @@
|
||||
>
|
||||
{{ $t('common:button:reset') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleExport">
|
||||
{{ $t('common:button:export') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span style="margin-left:auto">
|
||||
@@ -66,6 +69,7 @@
|
||||
:data="list"
|
||||
stripe
|
||||
height="100"
|
||||
@sort-change="handleSortByColumn"
|
||||
>
|
||||
<!-- 序号 -->
|
||||
<el-table-column
|
||||
@@ -79,6 +83,7 @@
|
||||
:label="$t('trials:MIMqcCfg:table:questionName')"
|
||||
show-overflow-tooltip
|
||||
min-width="140"
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- 审核问题 -->
|
||||
<el-table-column
|
||||
@@ -86,6 +91,7 @@
|
||||
:label="$t('common:title:languageType')"
|
||||
show-overflow-tooltip
|
||||
min-width="160"
|
||||
sortable="custom"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
{{ $fd('LanguageType', scope.row.LanguageType) }}
|
||||
@@ -97,6 +103,7 @@
|
||||
:label="$t('trials:qcCfg:table:type')"
|
||||
show-overflow-tooltip
|
||||
min-width="140"
|
||||
sortable="custom"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
{{ $fd('QcType', scope.row.Type) }}
|
||||
@@ -108,6 +115,7 @@
|
||||
:label="$t('trials:qcCfg:table:typeValue')"
|
||||
show-overflow-tooltip
|
||||
min-width="140"
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- 任务类型 -->
|
||||
<el-table-column
|
||||
@@ -115,6 +123,7 @@
|
||||
:label="$t('trials:medicalFeedbackCfg:title:taskType')"
|
||||
show-overflow-tooltip
|
||||
min-width="140"
|
||||
sortable="custom"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.ReadingCategory === 1" type="primary">
|
||||
@@ -136,6 +145,7 @@
|
||||
:label="$t('trials:auditRecord:table:criterion')"
|
||||
min-width="160"
|
||||
show-overflow-tooltip
|
||||
sortable="custom"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<div>
|
||||
@@ -148,6 +158,7 @@
|
||||
:label="$t('dictionary:medicalAudit:label:IsGeneral')"
|
||||
min-width="120"
|
||||
show-overflow-tooltip
|
||||
sortable="custom"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<div>
|
||||
@@ -161,6 +172,7 @@
|
||||
:label="$t('trials:qcCfg:table:parentQs')"
|
||||
show-overflow-tooltip
|
||||
min-width="140"
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- 父问题触发值 -->
|
||||
<el-table-column
|
||||
@@ -168,12 +180,14 @@
|
||||
:label="$t('trials:qcCfg:table:parentTriggerValue')"
|
||||
show-overflow-tooltip
|
||||
min-width="160"
|
||||
sortable="custom"
|
||||
/>
|
||||
<!-- 是否必填 -->
|
||||
<el-table-column
|
||||
prop="IsRequired"
|
||||
:label="$t('trials:qcCfg:table:isRequired')"
|
||||
min-width="120"
|
||||
sortable="custom"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
{{ $fd('YesOrNo', scope.row.IsRequired) }}
|
||||
@@ -184,6 +198,7 @@
|
||||
prop="IsEnable"
|
||||
:label="$t('trials:qcCfg:table:isEnable')"
|
||||
min-width="120"
|
||||
sortable="custom"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
{{ $fd('YesOrNo', scope.row.IsEnable) }}
|
||||
@@ -215,7 +230,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import { getReadingMedicineSystemQuestionList, deleteReadingMedicineSystemQuestion } from '@/api/dictionary'
|
||||
|
||||
import { GetReadingMedicineSystemQuestionList_Export } from '@/api/export'
|
||||
import BoxContent from '@/components/BoxContent'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import MedicalAuditForm from './MedicalAuditForm'
|
||||
@@ -228,7 +243,9 @@ const searchDataDefault = () => {
|
||||
LanguageType: null,
|
||||
Type: '',
|
||||
CriterionTypeEnum: null,
|
||||
IsGeneral: null
|
||||
IsGeneral: null,
|
||||
Asc: false,
|
||||
SortField: ''
|
||||
}
|
||||
}
|
||||
export default {
|
||||
@@ -248,6 +265,20 @@ export default {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
async handleExport() {
|
||||
await GetReadingMedicineSystemQuestionList_Export(this.searchData)
|
||||
},
|
||||
// 排序
|
||||
handleSortByColumn(column) {
|
||||
if (column.order === 'ascending') {
|
||||
this.searchData.Asc = true
|
||||
} else {
|
||||
this.searchData.Asc = false
|
||||
}
|
||||
this.searchData.SortField = column.prop
|
||||
this.searchData.PageIndex = 1
|
||||
this.getList()
|
||||
},
|
||||
// 获取受试者列表信息
|
||||
getList() {
|
||||
this.loading = true
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<el-form-item :label="$t('dictionary:sign:label:sceneType')" prop="Name">
|
||||
<el-input v-model="form.Name" />
|
||||
</el-form-item>
|
||||
<el-form-item label="$t('dictionary:sign:label:value')" prop="Value">
|
||||
<el-form-item :label="$t('dictionary:sign:label:value')" prop="Value">
|
||||
<el-input v-model="form.Value" type="textarea" rows="5" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dictionary:sign:label:valueCN')" prop="ValueCN">
|
||||
|
||||
@@ -164,6 +164,14 @@ export default {
|
||||
},
|
||||
},
|
||||
],
|
||||
Email: [
|
||||
{
|
||||
// type: 'email',
|
||||
pattern: new RegExp(this.$reg().EmailRegexStr),
|
||||
message: this.$t('rules:email'),
|
||||
trigger: 'blur,change',
|
||||
},
|
||||
]
|
||||
},
|
||||
userId: null,
|
||||
loading: false,
|
||||
|
||||
@@ -125,6 +125,9 @@ export default {
|
||||
} else {
|
||||
var reg =
|
||||
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
|
||||
if (this.$reg().EmailRegexStr) {
|
||||
reg = new RegExp(this.$reg().EmailRegexStr)
|
||||
}
|
||||
if (this.form.EmailOrPhone && reg.test(this.form.EmailOrPhone)) {
|
||||
this.sendDisabled = false
|
||||
callback()
|
||||
|
||||
+79
-134
@@ -7,20 +7,13 @@
|
||||
<div class="login-l">
|
||||
<div class="login-logo">
|
||||
<img v-if="language === 'zh'" src="@/assets/zzlogo2.png" alt="" />
|
||||
<img
|
||||
v-else-if="NODE_ENV === 'usa'"
|
||||
src="@/assets/zzlogo-usa.png"
|
||||
alt=""
|
||||
class="usa-logo"
|
||||
/>
|
||||
<img v-else-if="NODE_ENV === 'usa'" src="@/assets/zzlogo-usa.png" alt="" class="usa-logo" />
|
||||
<img v-else src="@/assets/zzlogo4.png" alt="" />
|
||||
</div>
|
||||
<div
|
||||
:class="{
|
||||
'login-image': true,
|
||||
'login-image-usa': true,
|
||||
}"
|
||||
>
|
||||
<div :class="{
|
||||
'login-image': true,
|
||||
'login-image-usa': true,
|
||||
}">
|
||||
<svg-icon icon-class="login-bg" style="width: 90%; height: 90%" />
|
||||
<!-- <img src="@/assets/login-bg.png" v-else /> -->
|
||||
</div>
|
||||
@@ -29,77 +22,43 @@
|
||||
<div class="title-container">
|
||||
<!-- IRC Management System -->
|
||||
<div v-if="NODE_ENV === 'usa'">
|
||||
<svg-icon
|
||||
icon-class="login-logo"
|
||||
style="width: 300px; height: 94px"
|
||||
/>
|
||||
<svg-icon icon-class="login-logo" style="width: 300px; height: 94px" />
|
||||
</div>
|
||||
<div class="title" v-else>{{ $t('login:title:system') }}</div>
|
||||
</div>
|
||||
<el-form
|
||||
ref="loginForm"
|
||||
:model="loginForm"
|
||||
:rules="loginRules"
|
||||
class="login-form"
|
||||
auto-complete="on"
|
||||
label-position="left"
|
||||
>
|
||||
<el-form-item
|
||||
prop="username"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('login:formRule:userName'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on"
|
||||
label-position="left">
|
||||
<el-form-item prop="username" :rules="[
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('login:formRule:userName'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
]">
|
||||
<span class="svg-container">
|
||||
<svg-icon icon-class="user" />
|
||||
</span>
|
||||
<!-- User Name -->
|
||||
<el-input
|
||||
ref="username"
|
||||
v-model="loginForm.username"
|
||||
size="small"
|
||||
:placeholder="$t('login:form:userName')"
|
||||
name="username"
|
||||
type="text"
|
||||
tabindex="1"
|
||||
/>
|
||||
<el-input ref="username" v-model="loginForm.username" size="small" :placeholder="$t('login:form:userName')"
|
||||
name="username" type="text" tabindex="1" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
prop="password"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('login:formRule:password'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<el-form-item prop="password" :rules="[
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('login:formRule:password'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
]">
|
||||
<span class="svg-container">
|
||||
<svg-icon icon-class="password" />
|
||||
</span>
|
||||
<!-- password -->
|
||||
<el-input
|
||||
:key="passwordType"
|
||||
ref="password"
|
||||
v-model="loginForm.password"
|
||||
size="small"
|
||||
:type="passwordType"
|
||||
:placeholder="$t('login:form:password')"
|
||||
name="password"
|
||||
auto-complete="new-password"
|
||||
autocomplete="new-password"
|
||||
tabindex="2"
|
||||
@keyup.enter.native="handleLogin"
|
||||
/>
|
||||
<el-input :key="passwordType" ref="password" v-model="loginForm.password" size="small" :type="passwordType"
|
||||
:placeholder="$t('login:form:password')" name="password" auto-complete="new-password"
|
||||
autocomplete="new-password" tabindex="2" @keyup.enter.native="handleLogin" />
|
||||
<span class="show-pwd" @click="showPwd">
|
||||
<svg-icon
|
||||
:icon-class="passwordType === 'password' ? 'eye' : 'eye-open'"
|
||||
/>
|
||||
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
|
||||
</span>
|
||||
<!-- <el-input
|
||||
:key="passwordType"
|
||||
@@ -118,33 +77,20 @@
|
||||
</span> -->
|
||||
</el-form-item>
|
||||
<!-- Login -->
|
||||
<el-button
|
||||
:loading="loading"
|
||||
type="primary"
|
||||
style="
|
||||
<el-button :loading="loading" type="primary" style="
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
background-color: rgb(0, 147, 221);
|
||||
"
|
||||
size="medium"
|
||||
@click.native.prevent="handleLogin"
|
||||
>
|
||||
" size="medium" @click.native.prevent="handleLogin">
|
||||
{{ $t('login:button:login') }}
|
||||
</el-button>
|
||||
<div style="text-align: right">
|
||||
<TopLang
|
||||
v-if="
|
||||
VUE_APP_OSS_CONFIG_REGION !== 'oss-us-west-1' &&
|
||||
NODE_ENV !== 'usa'
|
||||
"
|
||||
/>
|
||||
<TopLang v-if="
|
||||
VUE_APP_OSS_CONFIG_REGION !== 'oss-us-west-1' &&
|
||||
NODE_ENV !== 'usa'
|
||||
" />
|
||||
<!-- Forget password? -->
|
||||
<el-button
|
||||
type="text"
|
||||
size="medium"
|
||||
@click.native.prevent="handleResetPwd"
|
||||
style="color: rgb(0, 147, 221)"
|
||||
>
|
||||
<el-button type="text" size="medium" @click.native.prevent="handleResetPwd" style="color: rgb(0, 147, 221)">
|
||||
{{ $t('login:button:forgetPassword') }}
|
||||
</el-button>
|
||||
</div>
|
||||
@@ -152,19 +98,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="language === 'zh'" class="login-footer">
|
||||
<span
|
||||
>Copyright © {{ new Date().getFullYear() }} 上海展影医疗科技有限公司
|
||||
版权所有</span
|
||||
>
|
||||
<span>Copyright © {{ new Date().getFullYear() }} 上海展影医疗科技有限公司
|
||||
版权所有</span>
|
||||
<span> | </span>
|
||||
<a target="_blank" href="https://beian.miit.gov.cn/">
|
||||
<span> 沪ICP备2021037850-2 </span>
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a
|
||||
target="_blank"
|
||||
href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=31011002005859"
|
||||
>
|
||||
<a target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=31011002005859">
|
||||
<img src="@/assets/filing.png" />
|
||||
<span>沪公网安备 31011002005859号</span>
|
||||
</a>
|
||||
@@ -180,43 +121,23 @@
|
||||
<span style="color: #428bca">About</span>
|
||||
</a>
|
||||
</div>
|
||||
<Vcode
|
||||
:show="isShow"
|
||||
:fail-text="$t('login:button:failText')"
|
||||
:success-text="$t('login:button:successText')"
|
||||
:slider-text="$t('login:button:sliderText')"
|
||||
:imgs="[Img1]"
|
||||
@success="onSuccess"
|
||||
/>
|
||||
<el-dialog
|
||||
v-if="aboutVisible"
|
||||
:visible.sync="aboutVisible"
|
||||
width="680px"
|
||||
style="margin-top: 0"
|
||||
:close-on-click-modal="false"
|
||||
size="small"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
<Vcode :show="isShow" :fail-text="$t('login:button:failText')" :success-text="$t('login:button:successText')"
|
||||
:slider-text="$t('login:button:sliderText')" :imgs="[Img1]" @success="onSuccess" />
|
||||
<el-dialog v-if="aboutVisible" :visible.sync="aboutVisible" width="680px" style="margin-top: 0"
|
||||
:close-on-click-modal="false" size="small">
|
||||
<div style="
|
||||
margin: 0 auto;
|
||||
width: 600px;
|
||||
line-height: 28px;
|
||||
text-align: center;
|
||||
"
|
||||
>
|
||||
<h1
|
||||
style="text-align: center; margin-bottom: 30px"
|
||||
v-if="NODE_ENV === 'usa'"
|
||||
>
|
||||
">
|
||||
<h1 style="text-align: center; margin-bottom: 30px" v-if="NODE_ENV === 'usa'">
|
||||
About
|
||||
</h1>
|
||||
<h1 style="text-align: center; margin-bottom: 30px" v-else>关于</h1>
|
||||
<p style="margin-bottom: 0px" v-if="NODE_ENV === 'usa'">
|
||||
<!-- {{ $t('login:title:system_title_about') }} -->
|
||||
<svg-icon
|
||||
icon-class="login-logo"
|
||||
style="width: 250px; height: 71px"
|
||||
/>
|
||||
<svg-icon icon-class="login-logo" style="width: 250px; height: 71px" />
|
||||
</p>
|
||||
<p style="margin-bottom: 0px" v-else>{{ $t('login:title:system') }}</p>
|
||||
<p style="margin-bottom: 20px; margin-top: 0">
|
||||
@@ -247,13 +168,8 @@
|
||||
</div>
|
||||
</el-dialog>
|
||||
<browserTip ref="browserTip" />
|
||||
<toggleRole
|
||||
v-if="toggleRoleVisible"
|
||||
:visible.sync="toggleRoleVisible"
|
||||
:loading="toggleRoleLoading"
|
||||
@save="loginByRole"
|
||||
@cancel="cancel"
|
||||
/>
|
||||
<toggleRole v-if="toggleRoleVisible" :visible.sync="toggleRoleVisible" :loading="toggleRoleLoading"
|
||||
@save="loginByRole" @cancel="cancel" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -339,7 +255,14 @@ export default {
|
||||
this.location = this.$route.query.location
|
||||
zzSessionStorage.setItem('loginType', this.loginType)
|
||||
localStorage.setItem('location', this.location)
|
||||
if (process.env.VUE_APP_OSS_CONFIG_REGION === 'oss-us-west-1') {
|
||||
// zh-CN navigator.language
|
||||
console.log(navigator.language, 'navigator.language')
|
||||
if (navigator.language !== 'zh-CN' && navigator.language !== 'zh-TW') {
|
||||
this.$i18n.locale = 'en'
|
||||
this.setLanguage('en')
|
||||
this.$updateDictionary()
|
||||
}
|
||||
else if (process.env.VUE_APP_OSS_CONFIG_REGION === 'oss-us-west-1') {
|
||||
this.$i18n.locale = 'en'
|
||||
this.setLanguage('en')
|
||||
this.$updateDictionary()
|
||||
@@ -516,7 +439,7 @@ export default {
|
||||
Array.isArray(this.$store.state.user.roles) &&
|
||||
this.$store.state.user.roles.filter((item) => item.IsUserRoleDisabled)
|
||||
.length ===
|
||||
this.$store.state.user.roles.length - 1
|
||||
this.$store.state.user.roles.length - 1
|
||||
) {
|
||||
let role = this.$store.state.user.roles.find(
|
||||
(item) => !item.IsUserRoleDisabled
|
||||
@@ -640,6 +563,7 @@ $cursor: #fff;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
.login-r {
|
||||
.el-form-item {
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
@@ -655,23 +579,28 @@ $cursor: #fff;
|
||||
$bg: #2d3a4b;
|
||||
$dark_gray: #889aa4;
|
||||
$light_gray: #606266;
|
||||
|
||||
.login-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background: rgb(249, 249, 249);
|
||||
|
||||
::v-deep .el-input__inner::placeholder {
|
||||
color: $dark_gray;
|
||||
}
|
||||
|
||||
.login-header {
|
||||
margin: 10px 0px 20px 10px;
|
||||
height: 3rem;
|
||||
width: 720px;
|
||||
|
||||
.login-logo {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.login-body {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
@@ -685,32 +614,39 @@ $light_gray: #606266;
|
||||
box-sizing: border-box;
|
||||
background: rgb(255, 255, 255);
|
||||
border-radius: 10px 0px 0px 10px;
|
||||
|
||||
.login-l {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
|
||||
.login-logo {
|
||||
position: absolute;
|
||||
top: 35px;
|
||||
left: 50px;
|
||||
|
||||
img {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.usa-logo {
|
||||
height: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
.login-image {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 0px;
|
||||
// transform: translateY(-50%);
|
||||
height: 100%;
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.login-image-usa {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
@@ -718,6 +654,7 @@ $light_gray: #606266;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
.login-r {
|
||||
position: relative;
|
||||
float: left;
|
||||
@@ -735,16 +672,19 @@ $light_gray: #606266;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.title-container {
|
||||
// margin-bottom: 50px;
|
||||
text-align: center;
|
||||
margin-top: 20%;
|
||||
|
||||
.title {
|
||||
font-size: 35px;
|
||||
color: $light_gray;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.title-logo-message {
|
||||
font-size: 26px;
|
||||
color: $light_gray;
|
||||
@@ -784,6 +724,7 @@ $light_gray: #606266;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.login-footer {
|
||||
position: absolute;
|
||||
bottom: 50px;
|
||||
@@ -797,6 +738,7 @@ $light_gray: #606266;
|
||||
align-items: center;
|
||||
// color: rgb(180, 190, 199);
|
||||
color: #909399;
|
||||
|
||||
a {
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
@@ -805,13 +747,16 @@ $light_gray: #606266;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
span {
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
// p{
|
||||
// display: inline-block;
|
||||
// height:20px;
|
||||
|
||||
@@ -7,78 +7,47 @@
|
||||
<div class="left-content">
|
||||
<!-- 检查层级 -->
|
||||
<el-collapse v-model="activeNames" @change="handleChange">
|
||||
<el-collapse-item
|
||||
v-for="(study, i) in studyList"
|
||||
:key="study.CodeView"
|
||||
:name="study.CodeView"
|
||||
><template slot="title">
|
||||
<el-collapse-item v-for="(study, i) in studyList" :key="study.CodeView" :name="study.CodeView"><template
|
||||
slot="title">
|
||||
<div class="study-desc">
|
||||
<span>{{ study.CodeView }}</span>
|
||||
<span v-if="OtherInfo.IsShowStudyName" style="margin-left: 5px">
|
||||
{{ study.StudyName }}
|
||||
</span>
|
||||
<span style="margin: 0 5px">{{ study.Modality }}</span>
|
||||
<span>{{ getBodyPart(study.BodyPart) }}</span>
|
||||
<span>{{ getBodyPart(study.BodyPart, study.BodyPartForEditOther) }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 文件层级 -->
|
||||
<div
|
||||
v-if="study.NoneDicomStudyFileList.length === 0"
|
||||
class="empty-text"
|
||||
>
|
||||
<div v-if="study.NoneDicomStudyFileList.length === 0" class="empty-text">
|
||||
<slot name="empty">{{ $t('trials:audit:message:noData') }}</slot>
|
||||
</div>
|
||||
<div v-else id="imgList" style="height: 100%; overflow: hidden">
|
||||
<template v-for="(item, j) in study.NoneDicomStudyFileList">
|
||||
<div
|
||||
:id="`img${item.Id}`"
|
||||
:key="item.Id"
|
||||
:class="{
|
||||
'is-boxActive': item.Id === currentFileId,
|
||||
}"
|
||||
class="img-box"
|
||||
@click="selected(item, i, j, true)"
|
||||
>
|
||||
<div :id="`img${item.Id}`" :key="item.Id" :class="{
|
||||
'is-boxActive': item.Id === currentFileId,
|
||||
}" class="img-box" @click="selected(item, i, j, true)">
|
||||
<div class="file-image">
|
||||
<el-image
|
||||
v-if="
|
||||
[
|
||||
'image/jpeg',
|
||||
'image/jpg',
|
||||
'image/png',
|
||||
'image/bmp',
|
||||
].includes(item.FileType)
|
||||
"
|
||||
style="width: 100%; height: 100%"
|
||||
<el-image v-if="
|
||||
[
|
||||
'image/jpeg',
|
||||
'image/jpg',
|
||||
'image/png',
|
||||
'image/bmp',
|
||||
].includes(item.FileType)
|
||||
" style="width: 100%; height: 100%"
|
||||
:src="`${OSSclientConfig.basePath}${item.Path}?x-oss-process=image/resize,w_50,h_50/format,png`"
|
||||
fit="contain"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<el-image
|
||||
v-else-if="item.FileType === 'application/pdf'"
|
||||
style="width: 100%; height: 100%"
|
||||
:src="pdf"
|
||||
fit="contain"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<el-image
|
||||
v-else-if="
|
||||
item.FileType === 'application/x-zip-compressed'
|
||||
"
|
||||
style="width: 100%; height: 100%"
|
||||
:src="zip"
|
||||
fit="contain"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
fit="contain" crossorigin="anonymous" />
|
||||
<el-image v-else-if="item.FileType === 'application/pdf'" style="width: 100%; height: 100%"
|
||||
:src="pdf" fit="contain" crossorigin="anonymous" />
|
||||
<el-image v-else-if="
|
||||
item.FileType === 'application/x-zip-compressed'
|
||||
" style="width: 100%; height: 100%" :src="zip" fit="contain" crossorigin="anonymous" />
|
||||
</div>
|
||||
<div v-if="item.FileName.length < 15" class="img-text">
|
||||
{{ `${j + 1}. ${item.FileName}` }}
|
||||
</div>
|
||||
<el-tooltip
|
||||
v-else
|
||||
:content="item.FileName"
|
||||
placement="bottom"
|
||||
>
|
||||
<el-tooltip v-else :content="item.FileName" placement="bottom">
|
||||
<div class="img-text">
|
||||
{{ `${j + 1}. ${item.FileName}` }}
|
||||
</div>
|
||||
@@ -86,23 +55,15 @@
|
||||
<div v-if="isQcCheck" class="switchBox">
|
||||
<div class="item">
|
||||
<span>{{ $t('trials:audit:table:isReading') }}</span>
|
||||
<el-switch
|
||||
v-model="item.IsReading"
|
||||
:disabled="item.IsDeleted || isAudit"
|
||||
@change="changeReadingStatus($event, study, item)"
|
||||
:active-text="$fd('YesOrNo', true)"
|
||||
:inactive-text="$fd('YesOrNo', false)"
|
||||
/>
|
||||
<el-switch v-model="item.IsReading" :disabled="item.IsDeleted || isAudit"
|
||||
@change="changeReadingStatus($event, study, item)" :active-text="$fd('YesOrNo', true)"
|
||||
:inactive-text="$fd('YesOrNo', false)" />
|
||||
</div>
|
||||
<div class="item">
|
||||
<span>{{ $t('trials:audit:table:isDelete') }}</span>
|
||||
<el-switch
|
||||
v-model="item.IsDeleted"
|
||||
:disabled="isAudit"
|
||||
@change="changeDeleteStatus($event, study, item)"
|
||||
:active-text="$fd('YesOrNo', true)"
|
||||
:inactive-text="$fd('YesOrNo', false)"
|
||||
/>
|
||||
<el-switch v-model="item.IsDeleted" :disabled="isAudit"
|
||||
@change="changeDeleteStatus($event, study, item)" :active-text="$fd('YesOrNo', true)"
|
||||
:inactive-text="$fd('YesOrNo', false)" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -115,14 +76,8 @@
|
||||
<!-- 预览图像 -->
|
||||
<el-card class="box-card right">
|
||||
<div style="width: 100%; height: 100%" v-if="!showPDF">
|
||||
<Preview
|
||||
v-if="previewImage.imgList.length > 0"
|
||||
ref="previewImage"
|
||||
style="width: 100%"
|
||||
:preview-image="previewImage"
|
||||
:value="currentStudyFileIndex"
|
||||
@selectedImg="selectedImg"
|
||||
/>
|
||||
<Preview v-if="previewImage.imgList.length > 0" ref="previewImage" style="width: 100%"
|
||||
:preview-image="previewImage" :value="currentStudyFileIndex" @selectedImg="selectedImg" />
|
||||
</div>
|
||||
<div style="width: 100%; height: 100%" v-else>
|
||||
<PreviewFile :file-path="pdfFile.path" :file-type="pdfFile.type" />
|
||||
@@ -174,7 +129,7 @@ export default {
|
||||
subjectVisitId: '',
|
||||
sudyId: '',
|
||||
loading: false,
|
||||
bp: [],
|
||||
BodyPart: {},
|
||||
OtherInfo: {},
|
||||
showPDF: false,
|
||||
pdfFile: {
|
||||
@@ -188,7 +143,7 @@ export default {
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
this.bp = await this.$getBodyPart(this.$route.query.trialId)
|
||||
this.BodyPart.Bodypart = await this.$getBodyPart(this.$route.query.trialId)
|
||||
this.isQcCheck = !!this.$route.query.isQcCheck
|
||||
},
|
||||
async mounted() {
|
||||
@@ -202,7 +157,7 @@ export default {
|
||||
// 默认选择第一个文件
|
||||
},
|
||||
methods: {
|
||||
handleChange() {},
|
||||
handleChange() { },
|
||||
changeReadingStatus(callback, row, file) {
|
||||
let statusStr = ''
|
||||
if (callback) {
|
||||
@@ -245,7 +200,7 @@ export default {
|
||||
this.loading = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch(() => { })
|
||||
},
|
||||
changeDeleteStatus(callback, row, file) {
|
||||
let statusStr = ''
|
||||
@@ -295,8 +250,8 @@ export default {
|
||||
// file.IsDeleted = !file.IsDeleted
|
||||
})
|
||||
},
|
||||
getBodyPart(bodyPart) {
|
||||
if (!bodyPart) return ''
|
||||
getBodyPart(bodyPart, other) {
|
||||
if (!bodyPart && !other) return ''
|
||||
var separator = ','
|
||||
if (bodyPart.indexOf('|') > -1) {
|
||||
separator = '|'
|
||||
@@ -307,14 +262,12 @@ export default {
|
||||
}
|
||||
var arr = bodyPart.split(separator)
|
||||
var newArr = arr.map((i) => {
|
||||
return this.$fd(
|
||||
'Bodypart',
|
||||
i.trim(),
|
||||
'Code',
|
||||
{ Bodypart: this.bp },
|
||||
'Name'
|
||||
)
|
||||
return this.$fd('Bodypart', i.trim(), 'Code', this.BodyPart, 'Name')
|
||||
})
|
||||
if (other) {
|
||||
newArr.push(other)
|
||||
}
|
||||
newArr = newArr.filter(Boolean)
|
||||
return newArr.join(' | ')
|
||||
},
|
||||
// 获取非Dicom检查信息
|
||||
@@ -406,24 +359,29 @@ export default {
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
|
||||
::v-deep .el-card__body {
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.study-desc {
|
||||
padding: 10px 5px;
|
||||
line-height: 20px;
|
||||
background-color: #d5d5d5;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 220px;
|
||||
height: 100%;
|
||||
@@ -434,6 +392,7 @@ export default {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.title {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
@@ -443,6 +402,7 @@ export default {
|
||||
background-color: #4e4e4e;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.left-content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
@@ -474,6 +434,7 @@ export default {
|
||||
// margin-bottom: 5px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.img-text {
|
||||
display: inline-block;
|
||||
width: calc(100% - 60px);
|
||||
@@ -481,33 +442,41 @@ export default {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis; /* 用省略号表示溢出的文本 */
|
||||
text-overflow: ellipsis;
|
||||
/* 用省略号表示溢出的文本 */
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.img-box:nth-last-child(1) {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.is-boxActive {
|
||||
// border-color: #409eff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.is-boxActiv:after {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
margin-left: 10px;
|
||||
|
||||
::v-deep .el-card__body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.switchBox {
|
||||
width: 100%;
|
||||
margin: 5px 0;
|
||||
color: #4e4e4e;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -515,17 +484,21 @@ export default {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.file-image {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
::v-deep .el-collapse-item__header {
|
||||
background-color: #d5d5d5;
|
||||
}
|
||||
|
||||
::v-deep .el-collapse-item__header {
|
||||
min-height: 48px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
::v-deep .el-collapse-item__content {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
@@ -172,6 +172,13 @@ export default {
|
||||
],
|
||||
Phone: [
|
||||
{ required: true, validator: checkPhone, trigger: 'blur' }
|
||||
],
|
||||
Email: [
|
||||
{
|
||||
pattern: new RegExp(this.$reg().EmailRegexStr),
|
||||
message: 'Please input the correct email address',
|
||||
trigger: 'blur,change',
|
||||
}
|
||||
]
|
||||
},
|
||||
siteOptions: [],
|
||||
|
||||
@@ -117,6 +117,9 @@ export default {
|
||||
} else {
|
||||
var reg =
|
||||
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
|
||||
if (this.$reg().EmailRegexStr) {
|
||||
reg = new RegExp(this.$reg().EmailRegexStr)
|
||||
}
|
||||
if (this.form.Email && reg.test(this.form.Email)) {
|
||||
this.sendDisabled = false
|
||||
callback()
|
||||
|
||||
@@ -136,6 +136,9 @@ export default {
|
||||
} else {
|
||||
var reg =
|
||||
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
|
||||
if (this.$reg().EmailRegexStr) {
|
||||
reg = new RegExp(this.$reg().EmailRegexStr)
|
||||
}
|
||||
if (this.form.Email && reg.test(this.form.Email)) {
|
||||
this.sendDisabled = false
|
||||
callback()
|
||||
|
||||
@@ -158,6 +158,9 @@ export default {
|
||||
callback(new Error(this.$t('trials:researchForm:formRule:specify')))
|
||||
} else {
|
||||
var reg = /^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
|
||||
if (this.$reg().EmailRegexStr) {
|
||||
reg = new RegExp(this.$reg().EmailRegexStr)
|
||||
}
|
||||
if (this.form.EmailOrPhone && reg.test(this.form.EmailOrPhone)) {
|
||||
callback()
|
||||
} else {
|
||||
@@ -170,6 +173,9 @@ export default {
|
||||
callback(new Error(this.$t('trials:researchForm:formRule:specify')))
|
||||
} else {
|
||||
var reg = /^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
|
||||
if (this.$reg().EmailRegexStr) {
|
||||
reg = new RegExp(this.$reg().EmailRegexStr)
|
||||
}
|
||||
if (this.form.ReplaceUserEmailOrPhone && reg.test(this.form.ReplaceUserEmailOrPhone)) {
|
||||
callback()
|
||||
} else {
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<el-input v-model="form.Phone" :disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory" />
|
||||
</el-form-item>
|
||||
<!-- 联系邮箱 -->
|
||||
<el-form-item :label="$t('trials:researchForm:form:contactorEmail')">
|
||||
<el-form-item :label="$t('trials:researchForm:form:contactorEmail')" prop="Email">
|
||||
<el-input v-model="form.Email" disabled />
|
||||
</el-form-item>
|
||||
|
||||
@@ -183,6 +183,13 @@ export default {
|
||||
],
|
||||
Phone: [
|
||||
{ required: true, validator: checkPhone, trigger: 'blur' }
|
||||
],
|
||||
Email: [
|
||||
{
|
||||
pattern: new RegExp(this.$reg().EmailRegexStr),
|
||||
message: 'Please input the correct email address',
|
||||
trigger: 'blur,change',
|
||||
}
|
||||
]
|
||||
},
|
||||
siteOptions: [],
|
||||
|
||||
@@ -108,6 +108,9 @@ export default {
|
||||
} else {
|
||||
var reg =
|
||||
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
|
||||
if (this.$reg().EmailRegexStr) {
|
||||
reg = new RegExp(this.$reg().EmailRegexStr)
|
||||
}
|
||||
if (this.form.Email && reg.test(this.form.Email)) {
|
||||
this.sendDisabled = false
|
||||
callback()
|
||||
|
||||
@@ -139,6 +139,9 @@ export default {
|
||||
} else {
|
||||
var reg =
|
||||
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
|
||||
if (this.$reg().EmailRegexStr) {
|
||||
reg = new RegExp(this.$reg().EmailRegexStr)
|
||||
}
|
||||
if (this.form.Email && reg.test(this.form.Email)) {
|
||||
this.sendDisabled = false
|
||||
callback()
|
||||
|
||||
@@ -131,6 +131,9 @@ export default {
|
||||
callback(new Error(this.$t('trials:researchForm:formRule:specify')))
|
||||
} else {
|
||||
var reg = /^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
|
||||
if (this.$reg().EmailRegexStr) {
|
||||
reg = new RegExp(this.$reg().EmailRegexStr)
|
||||
}
|
||||
if (this.form.EmailOrPhone && reg.test(this.form.EmailOrPhone)) {
|
||||
// this.sendDisabled = false
|
||||
callback()
|
||||
@@ -145,6 +148,9 @@ export default {
|
||||
callback(new Error(this.$t('trials:researchForm:formRule:specify')))
|
||||
} else {
|
||||
var reg = /^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
|
||||
if (this.$reg().EmailRegexStr) {
|
||||
reg = new RegExp(this.$reg().EmailRegexStr)
|
||||
}
|
||||
if (this.form.ReplaceUserEmailOrPhone && reg.test(this.form.ReplaceUserEmailOrPhone)) {
|
||||
callback()
|
||||
} else {
|
||||
|
||||
@@ -110,6 +110,9 @@ export default {
|
||||
} else {
|
||||
var reg =
|
||||
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
|
||||
if (this.$reg().EmailRegexStr) {
|
||||
reg = new RegExp(this.$reg().EmailRegexStr)
|
||||
}
|
||||
if (this.form.EmailOrPhone && reg.test(this.form.EmailOrPhone)) {
|
||||
this.sendDisabled = false
|
||||
callback()
|
||||
@@ -125,6 +128,9 @@ export default {
|
||||
} else {
|
||||
var reg =
|
||||
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
|
||||
if (this.$reg().EmailRegexStr) {
|
||||
reg = new RegExp(this.$reg().EmailRegexStr)
|
||||
}
|
||||
if (
|
||||
this.form.ReplaceUserEmailOrPhone &&
|
||||
reg.test(this.form.ReplaceUserEmailOrPhone)
|
||||
|
||||
@@ -285,7 +285,8 @@ export default {
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
type: 'email',
|
||||
// type: 'email',
|
||||
pattern: new RegExp(this.$reg().EmailRegexStr),
|
||||
message: 'Please input the correct email address',
|
||||
trigger: 'blur,change',
|
||||
},
|
||||
|
||||
@@ -254,7 +254,7 @@
|
||||
<el-date-picker
|
||||
v-model="form.StartTime"
|
||||
type="year"
|
||||
value-format="yyyy-MM-DD"
|
||||
value-format="yyyy"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
@@ -265,7 +265,7 @@
|
||||
<el-date-picker
|
||||
v-model="form.EndTime"
|
||||
type="year"
|
||||
value-format="yyyy-MM-DD"
|
||||
value-format="yyyy"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
@@ -904,12 +904,23 @@ export default {
|
||||
try {
|
||||
if (key === 'clinicalTrials') {
|
||||
let validate = await this.$refs.clinicalTrialsFrom.validate()
|
||||
console.log(validate, 'validate')
|
||||
if (!validate) return false
|
||||
this.form.DoctorId = this.reviewerId
|
||||
if (this.trialId) {
|
||||
this.form.TrialId = this.trialId
|
||||
}
|
||||
if (this.form.StartTime) {
|
||||
let arr = this.form.StartTime.split("-")
|
||||
if (arr.length <= 1) {
|
||||
this.form.StartTime = `${this.form.StartTime}-01-01`
|
||||
}
|
||||
}
|
||||
if (this.form.EndTime) {
|
||||
let arr = this.form.EndTime.split("-")
|
||||
if (arr.length <= 1) {
|
||||
this.form.EndTime = `${this.form.EndTime}-12-31`
|
||||
}
|
||||
}
|
||||
this.loading = true
|
||||
let res = await addOrUpdateTrialExperience(this.form)
|
||||
this.loading = false
|
||||
|
||||
@@ -38,7 +38,11 @@
|
||||
<span v-if="isEN">{{ DATA.DepartmentOther }}</span>
|
||||
<span v-else>{{ DATA.DepartmentOtherCN }}</span>
|
||||
</span>
|
||||
<span class="el-icon-user" v-if="DATA.Rank || DATA.RankCN">
|
||||
<span class="el-icon-user" v-if="DATA.RankOther || DATA.RankOtherCN">
|
||||
<span v-if="isEN">{{ DATA.RankOther }}</span>
|
||||
<span v-else>{{ DATA.RankOtherCN }}</span>
|
||||
</span>
|
||||
<span class="el-icon-user" v-else-if="DATA.Rank || DATA.RankCN">
|
||||
<span v-if="isEN">{{ DATA.Rank }}</span>
|
||||
<span v-else>{{ DATA.RankCN }}</span>
|
||||
</span>
|
||||
@@ -327,7 +331,13 @@
|
||||
:label="$t('curriculumVitae:info:form:physician')"
|
||||
prop="RankId"
|
||||
>
|
||||
<el-select v-model="form.RankId" clearable placeholder="">
|
||||
<el-select v-model="form.RankId" clearable placeholder="" @change="()=>{
|
||||
if($fd('Rank', form.RankId, 'id') !==
|
||||
$t('curriculumVitae:selectLabel:Other')){
|
||||
form.RankOther = null
|
||||
form.RankOtherCN = null
|
||||
}
|
||||
}">
|
||||
<el-option
|
||||
v-for="item in $d.Rank"
|
||||
:key="item.id"
|
||||
@@ -548,7 +558,8 @@ export default {
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
type: 'email',
|
||||
// type: 'email',
|
||||
pattern: new RegExp(this.$reg().EmailRegexStr),
|
||||
message: this.$t('rules:email'),
|
||||
trigger: 'blur,change',
|
||||
},
|
||||
|
||||
@@ -72,7 +72,11 @@
|
||||
reviewerData.EmploymentView.DepartmentOtherCN
|
||||
}}</span>
|
||||
</span>
|
||||
<span class="el-icon-user"
|
||||
<span class="el-icon-user" v-if="reviewerData.EmploymentView.RankOther || reviewerData.EmploymentView.RankOtherCN">
|
||||
<span v-if="isEN">{{ reviewerData.EmploymentView.RankOther }}</span>
|
||||
<span v-else>{{ reviewerData.EmploymentView.RankOtherCN }}</span>
|
||||
</span>
|
||||
<span class="el-icon-user" v-else
|
||||
><span v-if="isEN">{{ reviewerData.EmploymentView.Rank }}</span>
|
||||
<span v-else>{{ reviewerData.EmploymentView.RankCN }}</span></span
|
||||
>
|
||||
@@ -417,7 +421,12 @@
|
||||
v-if="true"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ $fd('Indication', scope.row.IndicationEnum) }}</span>
|
||||
<span v-if="scope.row.EvaluationContent">
|
||||
{{ scope.row.EvaluationContent }}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ $fd('Indication', scope.row.IndicationEnum) }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
|
||||
@@ -530,6 +530,9 @@ export default {
|
||||
emailList.forEach((item) => {
|
||||
var pattern =
|
||||
/^([A-Za-z0-9_\-\.\u4e00-\u9fa5])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,8})$/
|
||||
if (this.$reg().EmailRegexStr) {
|
||||
pattern = new RegExp(this.$reg().EmailRegexStr)
|
||||
}
|
||||
if (!pattern.test(item)) {
|
||||
isError = true
|
||||
}
|
||||
|
||||
@@ -439,7 +439,8 @@ export default {
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
type: 'email',
|
||||
// type: 'email',
|
||||
pattern: new RegExp(this.$reg().EmailRegexStr),
|
||||
message: 'Please input the correct email address',
|
||||
trigger: ['blur'],
|
||||
},
|
||||
|
||||
@@ -219,6 +219,13 @@ export default {
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
},
|
||||
{
|
||||
prop: 'JoinedTrialCount',
|
||||
label: this.$t('system:userlist:table:JoinedTrialCount'),
|
||||
minWidth: 150,
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
},
|
||||
{
|
||||
prop: 'LastLoginTime',
|
||||
label: this.$t('system:userlist:table:LastLoginTime'),
|
||||
|
||||
@@ -289,7 +289,10 @@ export default {
|
||||
},
|
||||
handleEmailChange() {
|
||||
var reg =
|
||||
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
|
||||
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/
|
||||
if (this.$reg().EmailRegexStr) {
|
||||
reg = new RegExp(this.$reg().EmailRegexStr)
|
||||
}
|
||||
if (this.userForm.EMail && reg.test(this.userForm.EMail)) {
|
||||
this.sendDisabled = false
|
||||
} else {
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
<el-input v-model="searchData.userName" clearable style="width: 120px" />
|
||||
</el-form-item>
|
||||
<!-- 用户类型 -->
|
||||
<el-form-item :label="$t('trials:signRecords:table:userType')" v-if="!isDoc">
|
||||
<el-form-item :label="$t('trials:signRecords:table:userType')" v-if="!isDoc && !isEASystem">
|
||||
<el-select v-model="searchData.UserTypeId" clearable filterable style="width: 120px">
|
||||
<el-option v-for="item of userTypeOptions"
|
||||
v-show="isSystem || (item.UserTypeEnum !== 26 && item.UserTypeEnum !== 27)" :key="item.Id"
|
||||
@@ -69,7 +69,7 @@
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('trials:signRecords:table:isSign')" v-if="!isDoc || !viewStatus">
|
||||
<el-form-item :label="$t('trials:signRecords:table:isSign')" v-if="(!isDoc || !viewStatus) && !isEASystem">
|
||||
<el-select v-model="searchData.IsConfirmed" clearable style="width: 120px">
|
||||
<el-option v-for="i of $d.TrainingStatusEnum" :key="'IsConfirmed' + i.label" :value="i.value"
|
||||
:label="i.label" />
|
||||
@@ -78,12 +78,12 @@
|
||||
<el-form-item :label="isDoc
|
||||
? $t('trials:signRecords:table:isDeletedFile')
|
||||
: $t('trials:signRecords:table:isDeleted')
|
||||
">
|
||||
" v-if="!isEASystem">
|
||||
<el-select v-model="searchData.IsDeleted" clearable style="width: 120px">
|
||||
<el-option v-for="i of $d.TrainingStatus" :key="'IsDeleted' + i.label" :value="i.value" :label="i.label" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('trials:signRecords:table:username')" v-if="isDoc">
|
||||
<el-form-item :label="$t('trials:signRecords:table:username')" v-if="isDoc && !isEASystem">
|
||||
<el-input v-model="searchData.UserName" style="width: 120px" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('trials:signRecords:table:confirmTime')" v-if="isDoc || isSystem">
|
||||
@@ -91,7 +91,7 @@
|
||||
:default-time="['00:00:00', '23:59:59']" type="datetimerange">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('trials:signRecords:table:uploadTime')" v-if="isSystem">
|
||||
<el-form-item :label="$t('trials:signRecords:table:uploadTime')" v-if="isSystem && !isEASystem">
|
||||
<el-date-picker v-model="timeListC" value-format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd HH:mm:ss"
|
||||
type="datetimerange" :default-time="['00:00:00', '23:59:59']" @change="changeTimeListC" />
|
||||
</el-form-item>
|
||||
@@ -305,6 +305,11 @@ export default {
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isEASystem() {
|
||||
return this.isSystem && this.hasPermi(['role:ea'])
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getTypeOptions()
|
||||
this.getUserSelect()
|
||||
@@ -360,6 +365,14 @@ export default {
|
||||
},
|
||||
// 获取系统文件数据
|
||||
getList() {
|
||||
if (this.isEASystem) {
|
||||
this.searchData.IsConfirmed = true
|
||||
if (!this.searchData.FileTypeId && !this.searchData.Name && !this.searchData.UserId && !this.searchData.userName && (!Array.isArray(this.timeList) || this.timeList.length < 2)) {
|
||||
this.list = []
|
||||
this.total = 0
|
||||
return false
|
||||
}
|
||||
}
|
||||
this.loading = true
|
||||
if (this.viewStatus) {
|
||||
this.searchData.IsConfirmed = true
|
||||
@@ -398,6 +411,7 @@ export default {
|
||||
getTypeOptions() {
|
||||
if (this.isSystem) {
|
||||
this.typeOptions = this.$d.Sys_Document
|
||||
if (this.isEASystem) this.typeOptions = this.typeOptions.filter(item => item.raw.ChildGroup !== "Trial")
|
||||
} else {
|
||||
getTrialDocAndSystemDocType(this.trialId).then((res) => {
|
||||
this.typeOptions = res.Result
|
||||
|
||||
@@ -535,7 +535,8 @@ export default {
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
type: 'email',
|
||||
// type: 'email',
|
||||
pattern: new RegExp(this.$reg().EmailRegexStr),
|
||||
message: this.$t('rules:email'),
|
||||
trigger: 'blur,change',
|
||||
},
|
||||
@@ -610,6 +611,9 @@ export default {
|
||||
emailList.forEach((item) => {
|
||||
var pattern =
|
||||
/^([A-Za-z0-9_\-\.\u4e00-\u9fa5])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,8})$/
|
||||
if (this.$reg().EmailRegexStr) {
|
||||
pattern = new RegExp(this.$reg().EmailRegexStr)
|
||||
}
|
||||
if (!pattern.test(item)) {
|
||||
isError = true
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<el-table-column prop="Name" :label="$t('trials:self-attachment:table:fileName')" show-overflow-tooltip
|
||||
sortable="custom" />
|
||||
<el-table-column :label="$t('trials:self-attachment:table:AttachmentCount')" prop="AttachmentCount"
|
||||
show-overflow-tooltip sortable="custom">
|
||||
show-overflow-tooltip>
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" @click.stop="openAttachment(scope.row, true)">{{ scope.row.AttachmentCount
|
||||
}}</el-button>
|
||||
|
||||
@@ -842,7 +842,7 @@ export default {
|
||||
var trialId = this.$route.query.trialId
|
||||
var file = await this.fileToBlob(param.file)
|
||||
const res = await this.OSSclient.put(
|
||||
`/${trialId}/Read/${this.subjectId}/visit/${param.file.name}`,
|
||||
`/${trialId}/Read/${this.subjectId}/${this.visitTaskId}/${param.file.name}`,
|
||||
file
|
||||
)
|
||||
console.log(res)
|
||||
|
||||
@@ -1,63 +1,56 @@
|
||||
<template>
|
||||
<div
|
||||
id="canvas"
|
||||
ref="canvas"
|
||||
v-loading="loading"
|
||||
element-loading-text="Loading..."
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
||||
style="position:relative;"
|
||||
class="cornerstone-element"
|
||||
@mouseup="sliderMouseup"
|
||||
@contextmenu.prevent="onContextmenu"
|
||||
>
|
||||
<div id="canvas" ref="canvas" v-loading="loading" :element-loading-text="NSTip"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)" style="position:relative;" class="cornerstone-element"
|
||||
@mouseup="sliderMouseup" @contextmenu.prevent="onContextmenu">
|
||||
<!-- 临床数据 -->
|
||||
<div v-if="stack.isExistsClinicalData" class="info-cd" @click.stop="handleViewCD($event)">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:clinicalData')" placement="bottom">
|
||||
<svg-icon icon-class="documentation" class="svg-icon" />
|
||||
</el-tooltip>
|
||||
|
||||
</div>
|
||||
<!-- 检查部位 -->
|
||||
<div v-if="CriterionType == 19 || CriterionType == 20"
|
||||
:class="{ 'info-cd': true, 'info-cd2': stack.isExistsClinicalData }" @click.stop="handleViewBP($event)">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:BodyPart')" placement="bottom">
|
||||
<!-- <svg-icon icon-class="documentation" class="svg-icon" /> -->
|
||||
<i class="el-icon-tickets"></i>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<!-- 切换访视 -->
|
||||
<div
|
||||
v-if="stack.imageRendered && isReadingTaskViewInOrder === 1"
|
||||
class="info-visit"
|
||||
@dblclick.stop="preventDefault($event)"
|
||||
>
|
||||
<div
|
||||
class="arrw_div_wrapper"
|
||||
:style="{cursor:stack.visitTaskNum <= minVistNum?'not-allowed':'pointer',color:stack.visitTaskNum <= minVistNum?'#888':'#fff'}"
|
||||
@click.stop.prevent="toggleSeries($event,-1)"
|
||||
@dblclick.stop="preventDefault($event)"
|
||||
>
|
||||
<div v-if="stack.imageRendered && isReadingTaskViewInOrder === 1" class="info-visit"
|
||||
@dblclick.stop="preventDefault($event)">
|
||||
<div class="arrw_div_wrapper"
|
||||
:style="{ cursor: stack.visitTaskNum <= minVistNum ? 'not-allowed' : 'pointer', color: stack.visitTaskNum <= minVistNum ? '#888' : '#fff' }"
|
||||
@click.stop.prevent="toggleSeries($event, -1)" @dblclick.stop="preventDefault($event)">
|
||||
<i class="el-icon-caret-left" />
|
||||
</div>
|
||||
<div class="blind_name_wrapper">
|
||||
{{ stack.taskBlindName }}
|
||||
</div>
|
||||
<div
|
||||
class="arrw_div_wrapper"
|
||||
:style="{cursor:stack.visitTaskNum >= maxVistNum?'not-allowed':'pointer',color:stack.visitTaskNum >= maxVistNum?'#888':'#fff'}"
|
||||
@click.stop.prevent="toggleSeries($event,1)"
|
||||
@dblclick.stop="preventDefault($event)"
|
||||
>
|
||||
<div class="arrw_div_wrapper"
|
||||
:style="{ cursor: stack.visitTaskNum >= maxVistNum ? 'not-allowed' : 'pointer', color: stack.visitTaskNum >= maxVistNum ? '#888' : '#fff' }"
|
||||
@click.stop.prevent="toggleSeries($event, 1)" @dblclick.stop="preventDefault($event)">
|
||||
<i class="el-icon-caret-right" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-series">
|
||||
<h2 v-if="isReadingShowSubjectInfo" style="color:#f44336;padding: 5px 0px;margin: 0;">{{ subjectCode }} {{ stack.taskBlindName }}</h2>
|
||||
<h2 v-if="isReadingShowSubjectInfo" style="color:#f44336;padding: 5px 0px;margin: 0;">{{ subjectCode }} {{
|
||||
stack.taskBlindName }}</h2>
|
||||
<div v-show="dicomInfo.series">Series: #{{ dicomInfo.series }}</div>
|
||||
<div>Image: #{{ dicomInfo.frame }}</div>
|
||||
<div>{{ dicomInfo.modality }}</div>
|
||||
</div>
|
||||
<div class="info-image">
|
||||
<div v-show="mousePosition.mo">
|
||||
Pos: {{ mousePosition.x?mousePosition.x.toFixed(0):'' }}, {{ mousePosition.y?mousePosition.y.toFixed(0):'' }}
|
||||
Pos: {{ mousePosition.x ? mousePosition.x.toFixed(0) : '' }}, {{ mousePosition.y ? mousePosition.y.toFixed(0) :
|
||||
'' }}
|
||||
</div>
|
||||
<div v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
|
||||
<div
|
||||
v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
|
||||
HU: {{ mousePosition.mo }}
|
||||
</div>
|
||||
<div v-else-if="(dicomInfo.modality === 'PT' && mousePosition.suv)">
|
||||
SUVbw(g/ml): {{ digitPlaces === -1 ?mousePosition.suv.toFixed(3) :mousePosition.suv.toFixed(digitPlaces) }}
|
||||
SUVbw(g/ml): {{ digitPlaces === -1 ? mousePosition.suv.toFixed(3) : mousePosition.suv.toFixed(digitPlaces) }}
|
||||
</div>
|
||||
<div v-else-if="mousePosition.mo">
|
||||
Density: {{ mousePosition.mo }}
|
||||
@@ -81,8 +74,12 @@
|
||||
<!-- <div v-show="dicomInfo.acc">ACC {{ dicomInfo.acc }}</div> -->
|
||||
<!-- <div>{{ dicomInfo.time }}</div> -->
|
||||
</div>
|
||||
<div ref="sliderBox" class="my_slider_box" style="position: absolute;right: 1px;height: calc(100% - 140px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer" @click.stop="goViewer($event)">
|
||||
<div :style="{top: height + '%'}" style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move" @click.stop.prevent="() => {return}" @mousedown.stop="sliderMousedown($event)" />
|
||||
<div ref="sliderBox" class="my_slider_box"
|
||||
style="position: absolute;right: 1px;height: calc(100% - 140px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer"
|
||||
@click.stop="goViewer($event)">
|
||||
<div :style="{ top: height + '%' }"
|
||||
style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move"
|
||||
@click.stop.prevent="() => { return }" @mousedown.stop="sliderMousedown($event)" />
|
||||
</div>
|
||||
<div style="position: absolute;left: 50%;top: 30px;color: #f44336;transform: translateX(-50%);">
|
||||
{{ markers.top }}
|
||||
@@ -117,7 +114,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
.my_slider_box:after{
|
||||
.my_slider_box:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -20px;
|
||||
@@ -308,7 +305,10 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['visitTaskList', 'currentReadingTaskState'])
|
||||
...mapGetters(['visitTaskList', 'currentReadingTaskState']),
|
||||
NSTip() {
|
||||
return `NS: ${this.$store.state.trials.downloadTip}`
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
currentReadingTaskState: {
|
||||
@@ -572,7 +572,7 @@ export default {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
|
||||
}).catch(() => {})
|
||||
}).catch(() => { })
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
@@ -1111,7 +1111,7 @@ export default {
|
||||
var frame = imageInfo.frame
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
this.stack.instanceId = instanceId
|
||||
|
||||
|
||||
const element = this.$refs.canvas
|
||||
cornerstone.enable(element)
|
||||
element.tabIndex = 0
|
||||
@@ -1165,7 +1165,7 @@ export default {
|
||||
|
||||
// const scope = this
|
||||
Array.from(toolButtons).forEach((toolBtn) => {
|
||||
// Add the tool
|
||||
// Add the tool
|
||||
const toolName = toolBtn.getAttribute('data-tool')
|
||||
const apiTool = cornerstoneTools[`${toolName}Tool`]
|
||||
if (apiTool) {
|
||||
@@ -1173,17 +1173,17 @@ export default {
|
||||
|
||||
if (!toolAlreadyAddedToElement) {
|
||||
if (toolName === 'Length') {
|
||||
cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true }})
|
||||
cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true } })
|
||||
} else if (toolName === 'Bidirectional') {
|
||||
// cornerstoneTools.addToolForElement(element, BidirectionalTool, { digits: this.digitPlaces })
|
||||
// , handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true
|
||||
cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true }})
|
||||
// cornerstoneTools.addToolForElement(element, BidirectionalTool, { digits: this.digitPlaces })
|
||||
// , handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true
|
||||
cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true } })
|
||||
} else if (toolName === 'ArrowAnnotate') {
|
||||
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
||||
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true } })
|
||||
} else if (toolName === 'RectangleRoi') {
|
||||
cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
||||
cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true } })
|
||||
} else if (toolName === 'Probe' && parseInt(localStorage.getItem('CriterionType')) === 21) {
|
||||
cornerstoneTools.addToolForElement(element, ProbeTool, { configuration: { fixedRadius: 5, handleRadius: true, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces }})
|
||||
cornerstoneTools.addToolForElement(element, ProbeTool, { configuration: { fixedRadius: 5, handleRadius: true, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces } })
|
||||
} else {
|
||||
cornerstoneTools.addToolForElement(element, apiTool)
|
||||
}
|
||||
@@ -1209,10 +1209,10 @@ export default {
|
||||
mouseButtonMask: 4
|
||||
})
|
||||
|
||||
// if (!cornerstoneTools.getToolForElement(element, OrientationMarkersTool)) {
|
||||
// cornerstoneTools.addToolForElement(element, OrientationMarkersTool)
|
||||
// }
|
||||
// cornerstoneTools.setToolActiveForElement(element, 'OrientationMarkers', { })
|
||||
// if (!cornerstoneTools.getToolForElement(element, OrientationMarkersTool)) {
|
||||
// cornerstoneTools.addToolForElement(element, OrientationMarkersTool)
|
||||
// }
|
||||
// cornerstoneTools.setToolActiveForElement(element, 'OrientationMarkers', { })
|
||||
}
|
||||
|
||||
// cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'stackPrefetch', 'playClip'])
|
||||
@@ -1229,7 +1229,7 @@ export default {
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
this.stack.instanceId = instanceId
|
||||
this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1)
|
||||
|
||||
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
@@ -1257,9 +1257,8 @@ export default {
|
||||
data.string('x00080030')
|
||||
)
|
||||
this.dicomInfo.series = data.string('x00200011')
|
||||
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${
|
||||
this.stack.imageIds.length
|
||||
}`
|
||||
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${this.stack.imageIds.length
|
||||
}`
|
||||
this.dicomInfo.size = `${data.uint16('x00280011')}*${data.uint16(
|
||||
'x00280010'
|
||||
)}`
|
||||
@@ -1462,9 +1461,9 @@ export default {
|
||||
var element = cornerstone.getEnabledElement(this.canvas)
|
||||
const { rowPixelSpacing, colPixelSpacing } = this.getPixelSpacing(element.image)
|
||||
const dx =
|
||||
(data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1)
|
||||
(data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1)
|
||||
const dy =
|
||||
(data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1)
|
||||
(data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1)
|
||||
const length = Math.sqrt(dx * dx + dy * dy)
|
||||
|
||||
return length.toFixed(this.digitPlaces)
|
||||
@@ -1478,9 +1477,9 @@ export default {
|
||||
if (imagePlane) {
|
||||
return {
|
||||
rowPixelSpacing:
|
||||
imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing,
|
||||
imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing,
|
||||
colPixelSpacing:
|
||||
imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing
|
||||
imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1537,7 +1536,7 @@ export default {
|
||||
},
|
||||
debounce(callback, delay) {
|
||||
let timerId
|
||||
return function() {
|
||||
return function () {
|
||||
clearTimeout(timerId)
|
||||
timerId = setTimeout(() => {
|
||||
callback.apply(this, arguments)
|
||||
@@ -2013,95 +2012,114 @@ export default {
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
},
|
||||
handleViewBP(e) {
|
||||
DicomEvent.$emit('previewBP', this.stack.visitTaskId)
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.context-menu-wrapper{
|
||||
position: absolute;
|
||||
ul{
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
.context-menu-wrapper {
|
||||
position: absolute;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
background: #343333;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
border: 1px solid #2a2a2a;
|
||||
border-radius: 3px;
|
||||
height: auto;
|
||||
min-height: 50px;
|
||||
line-height: 1.5em;
|
||||
width: 80px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.menu {
|
||||
li {
|
||||
padding: 2px 5px;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #666;
|
||||
|
||||
div {
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.submenu {
|
||||
position: absolute;
|
||||
left: 77px;
|
||||
top: -1px;
|
||||
background: #343333;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
border: 1px solid #2a2a2a;
|
||||
border-radius: 3px;
|
||||
height: auto;
|
||||
min-height: 50px;
|
||||
line-height: 1.5em;
|
||||
width:80px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.menu{
|
||||
display: none;
|
||||
|
||||
li {
|
||||
padding: 2px 5px;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #666;
|
||||
div{
|
||||
|
||||
div {
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
.submenu{
|
||||
position: absolute;
|
||||
left: 77px;
|
||||
top: -1px;
|
||||
background: #343333;
|
||||
color: #fff;
|
||||
display: none;
|
||||
li {
|
||||
padding: 2px 5px;
|
||||
border-bottom: 1px solid #666;
|
||||
div{
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.menu li:hover{
|
||||
background-color: #ff5722;
|
||||
.submenu{
|
||||
display:block;
|
||||
}
|
||||
}
|
||||
.menu_active{
|
||||
cursor: pointer;
|
||||
}
|
||||
.menu_disabled{
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
}
|
||||
.info-visit{
|
||||
position: absolute;
|
||||
left:50%;
|
||||
top: 5px;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.arrw_div_wrapper{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #3f3f3f;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
border-radius: 10%;
|
||||
}
|
||||
.blind_name_wrapper{
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
background-color: #00000057;
|
||||
color: #fff;
|
||||
padding:0 10px;
|
||||
font-size: 14px;
|
||||
|
||||
.menu li:hover {
|
||||
background-color: #ff5722;
|
||||
|
||||
.submenu {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.info-cd{
|
||||
|
||||
.menu_active {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.menu_disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.info-visit {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 5px;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.arrw_div_wrapper {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #3f3f3f;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
border-radius: 10%;
|
||||
}
|
||||
|
||||
.blind_name_wrapper {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
background-color: #00000057;
|
||||
color: #fff;
|
||||
padding: 0 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.info-cd {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 5px;
|
||||
@@ -2110,6 +2128,11 @@ export default {
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.info-cd2 {
|
||||
left: 35px;
|
||||
}
|
||||
|
||||
.info-series {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
@@ -2119,6 +2142,7 @@ export default {
|
||||
font-size: 12px;
|
||||
/* z-index: 1; */
|
||||
}
|
||||
|
||||
.info-image {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
@@ -2138,6 +2162,7 @@ export default {
|
||||
font-size: 12px;
|
||||
/* z-index: 1; */
|
||||
}
|
||||
|
||||
.info-instance {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
@@ -2170,6 +2195,7 @@ export default {
|
||||
margin: 10px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.menu__item:hover {
|
||||
color: #ff0000;
|
||||
}
|
||||
@@ -2189,11 +2215,12 @@ li:hover {
|
||||
background-color: #e0e0e2;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.msg-div {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
color: #000;
|
||||
padding: 5px 20px;
|
||||
}
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
color: #000;
|
||||
padding: 5px 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -721,7 +721,7 @@ export default {
|
||||
file = this.convertBase64ToBlob(file)
|
||||
var trialId = this.$route.query.trialId
|
||||
var subjectId = this.$route.query.trialId
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${fileName}.png`, file)
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/${this.visitTaskId}/${fileName}.png`, file)
|
||||
return { isSuccess: true, result: result }
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
|
||||
+1
-1
@@ -739,7 +739,7 @@ export default {
|
||||
file = this.convertBase64ToBlob(file)
|
||||
var trialId = this.$route.query.trialId
|
||||
var subjectId = this.$route.query.trialId
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${fileName}.png`, file)
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/${this.visitTaskId}/${fileName}.png`, file)
|
||||
return { isSuccess: true, result: result }
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
|
||||
@@ -872,7 +872,7 @@ export default {
|
||||
file = this.convertBase64ToBlob(file)
|
||||
var trialId = this.$route.query.trialId
|
||||
var subjectId = this.$route.query.trialId
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${fileName}.png`, file)
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/${this.visitTaskId}/${fileName}.png`, file)
|
||||
return { isSuccess: true, result: result }
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<div class="add-icon" @click.prevent="downloadTpl">
|
||||
<i class="el-icon-download" />
|
||||
</div>
|
||||
<div class="add-icon" style="margin: 0 5px;" @click.prevent="uploadTpl(item.LesionType)">
|
||||
<div class="add-icon" style="margin: 0 5px;" @click.prevent="uploadTpl(item.LesionType, item.QuestionName)">
|
||||
<i class="el-icon-upload2" />
|
||||
</div>
|
||||
<div class="add-icon" @click.prevent="handleAddOrEdit('add', item)">
|
||||
@@ -174,7 +174,7 @@
|
||||
<!-- 导入 -->
|
||||
<el-dialog v-if="upload.visible" :visible.sync="upload.visible" :close-on-click-modal="false"
|
||||
:title="upload.title" width="500px">
|
||||
<UploadExcel :visit-task-id="visitTaskId" @close="uploadDlgClose" />
|
||||
<UploadExcel :visit-task-id="visitTaskId" :TableName="upload.TableName" @close="uploadDlgClose" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
@@ -233,7 +233,7 @@ export default {
|
||||
formChanged: false,
|
||||
digitPlaces: 2,
|
||||
addOrEdit: { visible: false, title: '' },
|
||||
upload: { visible: false, title: '' },
|
||||
upload: { visible: false, title: '', TableName: '' },
|
||||
qsList: [],
|
||||
answersList: [],
|
||||
qsForm: {},
|
||||
@@ -668,7 +668,8 @@ export default {
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
uploadTpl(lesionType) {
|
||||
uploadTpl(lesionType, TableName) {
|
||||
this.upload.TableName = TableName
|
||||
this.upload.title = `导入( ${this.$fd('LesionType', lesionType)} )`
|
||||
this.upload.visible = true
|
||||
},
|
||||
|
||||
@@ -33,12 +33,16 @@
|
||||
</el-form>
|
||||
</template>
|
||||
<script>
|
||||
import { uploadIVUSTemplate } from '@/api/reading'
|
||||
import { readingImport } from '@/api/reading'
|
||||
export default {
|
||||
props: {
|
||||
visitTaskId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
TableName: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -63,7 +67,9 @@ export default {
|
||||
var data = new FormData()
|
||||
data.append('file', param.file)
|
||||
data.append('visitTaskId', this.visitTaskId)
|
||||
await uploadIVUSTemplate(data)
|
||||
data.append('readingImportType', 0)
|
||||
data.append('TableName', this.TableName)
|
||||
await readingImport(data)
|
||||
this.$emit('close')
|
||||
this.$message.success('导入成功!')
|
||||
loading.close()
|
||||
|
||||
@@ -1073,7 +1073,7 @@ export default {
|
||||
file = this.convertBase64ToBlob(file)
|
||||
var trialId = this.$route.query.trialId
|
||||
var subjectId = this.$route.query.trialId
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${fileName}.png`, file)
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/${this.visitTaskId}/${fileName}.png`, file)
|
||||
return { isSuccess: true, result: result }
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
|
||||
@@ -715,7 +715,7 @@ export default {
|
||||
file = this.convertBase64ToBlob(file)
|
||||
var trialId = this.$route.query.trialId
|
||||
var subjectId = this.$route.query.trialId
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${fileName}.png`, file)
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/${this.visitTaskId}/${fileName}.png`, file)
|
||||
return { isSuccess: true, result: result }
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
|
||||
@@ -276,7 +276,7 @@ export default {
|
||||
window.opener.postMessage(data, window.location)
|
||||
},
|
||||
async receiveMsg(event) {
|
||||
console.log('nonedicoms', event.data.type)
|
||||
// console.log('nonedicoms', event.data.type)
|
||||
if (event.data.type === 'isCanActiveNoneDicomTool') {
|
||||
if (event.data.data.isCanActiveTool) {
|
||||
// this.model = 'ArrowAnnotate'
|
||||
@@ -304,8 +304,12 @@ export default {
|
||||
// this.canvasData.splice(i, 1)
|
||||
// }
|
||||
// }
|
||||
var idx = this.canvasData.findIndex(item => item.data.uuid === event.data.data.data.uuid)
|
||||
this.canvasData.splice(idx, 1)
|
||||
if (!event.data.data) {
|
||||
this.canvasData = []
|
||||
} else {
|
||||
var idx = this.canvasData.findIndex(item => item.data.uuid === event.data.data.data.uuid)
|
||||
this.canvasData.splice(idx, 1)
|
||||
}
|
||||
ctx.clearRect(0, 0, this.canvasSize.width, this.canvasSize.height) // 清除画布后立刻重新绘制视觉上形成动画
|
||||
await ctx.drawImage(
|
||||
this.currentImg,
|
||||
@@ -512,6 +516,11 @@ export default {
|
||||
this.canvasData.push(this.currentDrawData) // 添加当前绘图数据
|
||||
}
|
||||
}
|
||||
// 向主窗体发送测量数据
|
||||
if (this.model) {
|
||||
var data = { type: 'setMeasurement', data: this.currentDrawData }
|
||||
window.opener.postMessage(data, window.location)
|
||||
}
|
||||
this.isMouseDown = false // 关闭鼠标状态
|
||||
this.model = ''
|
||||
this.lesionName = ''
|
||||
@@ -519,9 +528,6 @@ export default {
|
||||
x: e.offsetX, // 更新位置
|
||||
y: e.offsetY
|
||||
}
|
||||
// 向主窗体发送测量数据
|
||||
var data = { type: 'setMeasurement', data: this.currentDrawData }
|
||||
window.opener.postMessage(data, window.location)
|
||||
},
|
||||
|
||||
// 画标注
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<div class="add-icon" @click.prevent="downloadTpl(item.LesionType)">
|
||||
<i class="el-icon-download" />
|
||||
</div>
|
||||
<div class="add-icon" style="margin: 0 5px;" @click.prevent="uploadTpl(item.LesionType)">
|
||||
<div class="add-icon" style="margin: 0 5px;" @click.prevent="uploadTpl(item.LesionType, item.QuestionName)">
|
||||
<i class="el-icon-upload2" />
|
||||
</div>
|
||||
<div class="add-icon" @click.prevent="handleAddOrEdit('add', item)">
|
||||
@@ -169,7 +169,7 @@
|
||||
<!-- 导入 -->
|
||||
<el-dialog v-if="upload.visible" :visible.sync="upload.visible" :close-on-click-modal="false"
|
||||
:title="upload.title" width="500px">
|
||||
<UploadExcel :visit-task-id="visitTaskId" :lesion-type="upload.lesionType" @close="uploadDlgClose" />
|
||||
<UploadExcel :visit-task-id="visitTaskId" :lesion-type="upload.lesionType" :TableName="upload.TableName" @close="uploadDlgClose" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
@@ -228,7 +228,7 @@ export default {
|
||||
formChanged: false,
|
||||
digitPlaces: 2,
|
||||
addOrEdit: { visible: false, title: '', lesionType: null },
|
||||
upload: { visible: false, title: '', lesionType: null },
|
||||
upload: { visible: false, title: '', lesionType: null, TableName: '', },
|
||||
qsList: [],
|
||||
answersList: [],
|
||||
qsForm: {},
|
||||
@@ -669,8 +669,9 @@ export default {
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
uploadTpl(lesionType) {
|
||||
uploadTpl(lesionType, TableName) {
|
||||
this.upload.lesionType = lesionType
|
||||
this.upload.TableName = TableName
|
||||
this.upload.title = `导入( ${this.$fd('LesionType', lesionType)} )`
|
||||
this.upload.visible = true
|
||||
},
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</el-form>
|
||||
</template>
|
||||
<script>
|
||||
import { uploadOCTFCTTemplate, uploadOCTLipidAngleTemplate } from '@/api/reading'
|
||||
import { readingImport } from '@/api/reading'
|
||||
export default {
|
||||
props: {
|
||||
visitTaskId: {
|
||||
@@ -43,6 +43,10 @@ export default {
|
||||
lesionType: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
TableName: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -67,10 +71,13 @@ export default {
|
||||
var data = new FormData()
|
||||
data.append('file', param.file)
|
||||
data.append('visitTaskId', this.visitTaskId)
|
||||
data.append('TableName', this.TableName)
|
||||
if (this.lesionType === 112) {
|
||||
await uploadOCTFCTTemplate(data)
|
||||
data.append('readingImportType', 1)
|
||||
await readingImport(data)
|
||||
} else {
|
||||
await uploadOCTLipidAngleTemplate(data)
|
||||
data.append('readingImportType', 2)
|
||||
await readingImport(data)
|
||||
}
|
||||
this.$emit('close')
|
||||
this.$message.success('导入成功!')
|
||||
|
||||
@@ -364,6 +364,15 @@ export default {
|
||||
this.lesionName = this.getLesionInfo(this.orderMark, this.rowIndex)
|
||||
this.isCurrentTaskAdd = this.answers.IsCurrentTaskAdd ? this.answers.IsCurrentTaskAdd : 'True'
|
||||
this.lesionMark = this.getLesionName(this.orderMark, this.questionForm.RowIndex)
|
||||
|
||||
var isLymphLesion = this.getQuestionVal(2)
|
||||
isLymphLesion = isLymphLesion ? parseInt(isLymphLesion) : null
|
||||
var lesionOrgan = this.getQuestionVal(6)
|
||||
const lesionPart = this.getQuestionVal(8)
|
||||
|
||||
this.$emit('resetQuestions', { isLymphLesion, lesionPart, lesionOrgan, saveTypeEnum: this.questionForm.saveTypeEnum, lesionState, lesionNum, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: this.questionForm })
|
||||
|
||||
|
||||
this.isRender = true
|
||||
},
|
||||
getLesionName(orderMark, rowIndex) {
|
||||
@@ -590,7 +599,7 @@ export default {
|
||||
file = this.convertBase64ToBlob(file)
|
||||
var trialId = this.$route.query.trialId
|
||||
var subjectId = this.$route.query.trialId
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${fileName}.png`, file)
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/${this.visitTaskId}/${fileName}.png`, file)
|
||||
return { isSuccess: true, result: result }
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
|
||||
@@ -452,7 +452,7 @@ export default {
|
||||
file = this.convertBase64ToBlob(file)
|
||||
var trialId = this.$route.query.trialId
|
||||
var subjectId = this.$route.query.trialId
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${fileName}.png`, file)
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/${this.visitTaskId}/${fileName}.png`, file)
|
||||
return { isSuccess: true, result: result }
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
|
||||
@@ -7,14 +7,10 @@
|
||||
<div class="visit-name-wrapper">
|
||||
|
||||
<div v-if="(visitTaskList.length > 0)" style="display: flex;flex-direction: row;">
|
||||
<div
|
||||
v-for="s in visitTaskList"
|
||||
:key="s.VisitTaskId"
|
||||
class="visit-item"
|
||||
:class="{'visit-item-active': activeTaskVisitId==s.VisitTaskId}"
|
||||
|
||||
@click.prevent="handleClick(s)"
|
||||
>{{ s.TaskBlindName }}</div>
|
||||
<div v-for="s in visitTaskList" :key="s.VisitTaskId" class="visit-item"
|
||||
:class="{ 'visit-item-active': activeTaskVisitId == s.VisitTaskId }" @click.prevent="handleClick(s)">
|
||||
{{
|
||||
s.TaskBlindName }}</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -22,23 +18,12 @@
|
||||
|
||||
</div>
|
||||
<div class="right">
|
||||
<div
|
||||
v-for="s in visitTaskList"
|
||||
v-show="activeTaskVisitId === s.VisitTaskId"
|
||||
:key="s.VisitTaskId"
|
||||
class="study-wrapper"
|
||||
>
|
||||
<StudyList
|
||||
v-if="selectArr.includes(s.VisitTaskId)"
|
||||
:ref="s.VisitTaskId"
|
||||
:visit-task-id="s.VisitTaskId"
|
||||
:trial-id="trialId"
|
||||
:subject-visit-id="s.VisitId"
|
||||
:task-blind-name="s.TaskBlindName"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
@loadImageStack="loadImageStack"
|
||||
@previewNoneDicoms="previewNoneDicoms"
|
||||
/>
|
||||
<div v-for="s in visitTaskList" v-show="activeTaskVisitId === s.VisitTaskId" :key="s.VisitTaskId"
|
||||
class="study-wrapper">
|
||||
<StudyList v-if="selectArr.includes(s.VisitTaskId)" :ref="s.VisitTaskId" :visit-task-id="s.VisitTaskId"
|
||||
:trial-id="trialId" :subject-visit-id="s.VisitId" :task-blind-name="s.TaskBlindName"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo" @loadImageStack="loadImageStack"
|
||||
@previewNoneDicoms="previewNoneDicoms" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -46,20 +31,12 @@
|
||||
</div>
|
||||
<div class="dicom-viewer">
|
||||
<div class="container">
|
||||
<DicomViewer
|
||||
v-if="activeTaskVisitId"
|
||||
ref="dicomViewer"
|
||||
:is-show="isShow"
|
||||
:question-form-change-state="questionFormChangeState"
|
||||
:question-form-change-num="questionFormChangeNum"
|
||||
:is-exists-clinical-data="isExistsClinicalData"
|
||||
:is-exists-no-dicom-file="isExistsNoDicomFile"
|
||||
<DicomViewer v-if="activeTaskVisitId" ref="dicomViewer" :is-show="isShow"
|
||||
:question-form-change-state="questionFormChangeState" :question-form-change-num="questionFormChangeNum"
|
||||
:is-exists-clinical-data="isExistsClinicalData" :is-exists-no-dicom-file="isExistsNoDicomFile"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
:is-reading-task-view-in-order="isReadingTaskViewInOrder"
|
||||
:is-exists-manual="isExistsManual"
|
||||
:iseCRFShowInDicomReading="iseCRFShowInDicomReading"
|
||||
@previewCD="previewCD"
|
||||
/>
|
||||
:is-reading-task-view-in-order="isReadingTaskViewInOrder" :is-exists-manual="isExistsManual"
|
||||
:iseCRFShowInDicomReading="iseCRFShowInDicomReading" @previewCD="previewCD" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -75,6 +52,7 @@ import { getToken } from '@/utils/auth'
|
||||
import { mapGetters } from 'vuex'
|
||||
import * as dicomParser from 'dicom-parser'
|
||||
import * as cornerstone from 'cornerstone-core'
|
||||
import { workSpeedclose } from "@/utils"
|
||||
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
|
||||
// import metaDataProvider from '@/utils/metaDataProvider'
|
||||
// cornerstone.metaData.addProvider(metaDataProvider, { priority: 10 });
|
||||
@@ -248,6 +226,7 @@ export default {
|
||||
DicomEvent.$off('addNoneDicomMeasureData')
|
||||
DicomEvent.$off('selectSeries')
|
||||
window.removeEventListener('beforeunload', e => { cornerstone.imageCache.purgeCache() })
|
||||
workSpeedclose(true)
|
||||
},
|
||||
methods: {
|
||||
async getVisitInfo() {
|
||||
@@ -474,7 +453,7 @@ export default {
|
||||
getSeriesInfoByMark(baseSeries, visitTaskId, obj, visitTaskIdx) {
|
||||
var seriesInfo = null
|
||||
if (obj) {
|
||||
// 根据任务ID测量病灶信息
|
||||
// 根据任务ID测量病灶信息
|
||||
var index = visitTaskIdx
|
||||
if (index > -1) {
|
||||
var idx = -1
|
||||
@@ -497,7 +476,7 @@ export default {
|
||||
// var instanceIdx = series.instanceList.findIndex(imageId => !!~imageId.indexOf(instanceId))
|
||||
const frame = this.visitTaskList[index].MeasureData[idx].MeasureData.frame
|
||||
// const filterStr = series.isExistMutiFrames ? `frame=${frame}&instanceId=${instanceId}` : `instanceId=${instanceId}`
|
||||
let n = series.instanceInfoList.findIndex(k=>k.Id === instanceId)
|
||||
let n = series.instanceInfoList.findIndex(k => k.Id === instanceId)
|
||||
let filterStr = ''
|
||||
if (n > -1 && series.isExistMutiFrames) {
|
||||
if (series.instanceInfoList[n].NumberOfFrames > 0) {
|
||||
@@ -538,13 +517,15 @@ export default {
|
||||
params[key] = value
|
||||
}
|
||||
params.percentComplete = e.detail.percentComplete
|
||||
params.FileTotal = e.detail.total
|
||||
params.imageId = imageId
|
||||
store.dispatch('reading/setImageLoadedProgress', params)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.dicom-container{
|
||||
.dicom-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
@@ -553,32 +534,35 @@ export default {
|
||||
background-color: #000;
|
||||
box-sizing: border-box;
|
||||
user-select: none;
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
|
||||
.dicom-viewer{
|
||||
.dicom-viewer {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.container{
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
.dicom-list{
|
||||
width: 200px;
|
||||
padding: 5px 0px;
|
||||
|
||||
.dicom-list {
|
||||
width: 200px;
|
||||
padding: 5px 0px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.container{
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
@@ -586,7 +570,8 @@ export default {
|
||||
// border: 1px solid #ccc;
|
||||
|
||||
}
|
||||
::v-deep.el-tabs{
|
||||
|
||||
::v-deep.el-tabs {
|
||||
box-sizing: border-box;
|
||||
padding: 0 5px;
|
||||
height: 100%;
|
||||
@@ -594,26 +579,31 @@ export default {
|
||||
flex-direction: column;
|
||||
// justify-content: flex-start;
|
||||
border: 1px solid #727272;
|
||||
.el-tabs__item{
|
||||
|
||||
.el-tabs__item {
|
||||
color: #fff;
|
||||
}
|
||||
.el-tabs__header{
|
||||
|
||||
.el-tabs__header {
|
||||
height: 55px;
|
||||
margin:0px;
|
||||
margin: 0px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-tabs__content{
|
||||
|
||||
.el-tabs__content {
|
||||
flex: 1;
|
||||
margin:0px;
|
||||
margin: 0px;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-tabs__item{
|
||||
|
||||
.el-tabs__item {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
}
|
||||
.dicom-desc{
|
||||
|
||||
.dicom-desc {
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
@@ -621,23 +611,28 @@ export default {
|
||||
color: #d0d0d0;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.ps {
|
||||
overflow-anchor: none;
|
||||
touch-action: auto;
|
||||
}
|
||||
|
||||
.series-active {
|
||||
background-color: #607d8b!important;
|
||||
border: 1px solid #607d8b!important;
|
||||
background-color: #607d8b !important;
|
||||
border: 1px solid #607d8b !important;
|
||||
}
|
||||
::v-deep.el-progress__text{
|
||||
|
||||
::v-deep.el-progress__text {
|
||||
color: #ccc;
|
||||
font-size: 12px;
|
||||
}
|
||||
.series{
|
||||
|
||||
.series {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
|
||||
.series-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -650,11 +645,13 @@ export default {
|
||||
border-radius: 2px;
|
||||
border: 1px solid #404040;
|
||||
background-color: #3a3a3a;
|
||||
.el-progress__text{
|
||||
|
||||
.el-progress__text {
|
||||
display: none;
|
||||
}
|
||||
.el-progress-bar{
|
||||
padding-right:0px;
|
||||
|
||||
.el-progress-bar {
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
@@ -663,9 +660,11 @@ export default {
|
||||
border: 2px solid #252525;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.image-desc {
|
||||
vertical-align: top;
|
||||
p{
|
||||
|
||||
p {
|
||||
width: 100px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
@@ -678,7 +677,8 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
.related-study-wrapper{
|
||||
|
||||
.related-study-wrapper {
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
padding-bottom: 5px;
|
||||
@@ -686,14 +686,15 @@ export default {
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
.left{
|
||||
.left {
|
||||
position: relative;
|
||||
width: 25px;
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
.visit-name-wrapper{
|
||||
|
||||
.visit-name-wrapper {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
|
||||
@@ -708,30 +709,34 @@ export default {
|
||||
// flex-direction: row;
|
||||
// align-content: flex-start;
|
||||
}
|
||||
.visit-item{
|
||||
|
||||
.visit-item {
|
||||
margin-left: 10px;
|
||||
white-space: nowrap;
|
||||
padding: 0px 4px;
|
||||
padding: 0px 4px;
|
||||
border: 1px solid #999999;
|
||||
border-bottom:none ;
|
||||
border-bottom: none;
|
||||
text-align: center;
|
||||
background-color: #4e4e4e;
|
||||
color: #d5d5d5;
|
||||
cursor: pointer;
|
||||
// margin-left: 10px;
|
||||
}
|
||||
.visit-item-active{
|
||||
|
||||
.visit-item-active {
|
||||
background-color: #607d8b;
|
||||
border: 1px solid #607d8b;
|
||||
}
|
||||
}
|
||||
.right{
|
||||
width:170px;
|
||||
flex:1;
|
||||
|
||||
.right {
|
||||
width: 170px;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
border-left: 1px solid #4a4a4a;
|
||||
color: #d5d5d5;
|
||||
.study-wrapper{
|
||||
|
||||
.study-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -801,7 +801,7 @@ export default {
|
||||
file = this.convertBase64ToBlob(file)
|
||||
var trialId = this.$route.query.trialId
|
||||
var subjectId = this.$route.query.trialId
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${fileName}.png`, file)
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/${this.visitTaskId}/${fileName}.png`, file)
|
||||
return { isSuccess: true, result: result }
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
|
||||
@@ -727,7 +727,7 @@ export default {
|
||||
file = this.convertBase64ToBlob(file)
|
||||
var trialId = this.$route.query.trialId
|
||||
var subjectId = this.$route.query.trialId
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${fileName}.png`, file)
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/${this.visitTaskId}/${fileName}.png`, file)
|
||||
return { isSuccess: true, result: result }
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
<template>
|
||||
<div
|
||||
id="canvas"
|
||||
ref="canvas"
|
||||
v-loading="loading"
|
||||
element-loading-text="Loading..."
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
||||
style="position:relative;"
|
||||
class="cornerstone-element"
|
||||
@mouseup="sliderMouseup"
|
||||
@contextmenu.prevent="onContextmenu"
|
||||
>
|
||||
<div id="canvas" ref="canvas" v-loading="loading" :element-loading-text="NSTip"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)" style="position:relative;" class="cornerstone-element"
|
||||
@mouseup="sliderMouseup" @contextmenu.prevent="onContextmenu">
|
||||
<!-- 临床数据 -->
|
||||
<div v-if="stack.isExistsClinicalData" class="info-cd" @click.stop="handleViewCD($event)">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:clinicalData')" placement="bottom">
|
||||
@@ -18,46 +10,39 @@
|
||||
|
||||
</div>
|
||||
<!-- 切换访视 -->
|
||||
<div
|
||||
v-if="stack.imageRendered && isReadingTaskViewInOrder === 1"
|
||||
class="info-visit"
|
||||
@dblclick.stop="preventDefault($event)"
|
||||
>
|
||||
<div
|
||||
class="arrw_div_wrapper"
|
||||
:style="{cursor:stack.visitTaskNum <= minVistNum?'not-allowed':'pointer',color:stack.visitTaskNum <= minVistNum?'#888':'#fff'}"
|
||||
@click.stop.prevent="toggleSeries($event,-1)"
|
||||
@dblclick.stop="preventDefault($event)"
|
||||
>
|
||||
<div v-if="stack.imageRendered && isReadingTaskViewInOrder === 1" class="info-visit"
|
||||
@dblclick.stop="preventDefault($event)">
|
||||
<div class="arrw_div_wrapper"
|
||||
:style="{ cursor: stack.visitTaskNum <= minVistNum ? 'not-allowed' : 'pointer', color: stack.visitTaskNum <= minVistNum ? '#888' : '#fff' }"
|
||||
@click.stop.prevent="toggleSeries($event, -1)" @dblclick.stop="preventDefault($event)">
|
||||
<i class="el-icon-caret-left" />
|
||||
</div>
|
||||
<div class="blind_name_wrapper">
|
||||
{{ stack.taskBlindName }}
|
||||
</div>
|
||||
<div
|
||||
class="arrw_div_wrapper"
|
||||
:style="{cursor:stack.visitTaskNum >= maxVistNum?'not-allowed':'pointer',color:stack.visitTaskNum >= maxVistNum?'#888':'#fff'}"
|
||||
@click.stop.prevent="toggleSeries($event,1)"
|
||||
@dblclick.stop="preventDefault($event)"
|
||||
>
|
||||
<div class="arrw_div_wrapper"
|
||||
:style="{ cursor: stack.visitTaskNum >= maxVistNum ? 'not-allowed' : 'pointer', color: stack.visitTaskNum >= maxVistNum ? '#888' : '#fff' }"
|
||||
@click.stop.prevent="toggleSeries($event, 1)" @dblclick.stop="preventDefault($event)">
|
||||
<i class="el-icon-caret-right" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-series">
|
||||
<h2 v-if="isReadingShowSubjectInfo" style="color:#f44336;padding: 5px 0px;margin: 0;">{{ subjectCode }} {{ stack.taskBlindName }}</h2>
|
||||
<h2 v-if="isReadingShowSubjectInfo" style="color:#f44336;padding: 5px 0px;margin: 0;">{{ subjectCode }} {{
|
||||
stack.taskBlindName }}</h2>
|
||||
<div v-show="dicomInfo.series">Series: #{{ dicomInfo.series }}</div>
|
||||
<div>Image: #{{ dicomInfo.frame }}</div>
|
||||
<div>{{ dicomInfo.modality }}</div>
|
||||
</div>
|
||||
<div class="info-image">
|
||||
<div v-show="mousePosition.mo">
|
||||
Pos: {{ mousePosition.x?mousePosition.x.toFixed(0):'' }}, {{ mousePosition.y?mousePosition.y.toFixed(0):'' }}
|
||||
Pos: {{ mousePosition.x ? mousePosition.x.toFixed(0) : '' }}, {{ mousePosition.y ? mousePosition.y.toFixed(0) : '' }}
|
||||
</div>
|
||||
<div v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
|
||||
<div
|
||||
v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
|
||||
HU: {{ mousePosition.mo }}
|
||||
</div>
|
||||
<div v-else-if="(dicomInfo.modality === 'PT' && mousePosition.suv)">
|
||||
SUVbw(g/ml): {{ digitPlaces === -1 ?mousePosition.suv.toFixed(3) :mousePosition.suv.toFixed(digitPlaces) }}
|
||||
SUVbw(g/ml): {{ digitPlaces === -1 ? mousePosition.suv.toFixed(3) : mousePosition.suv.toFixed(digitPlaces) }}
|
||||
</div>
|
||||
<div v-else-if="mousePosition.mo">
|
||||
Density: {{ mousePosition.mo }}
|
||||
@@ -81,8 +66,12 @@
|
||||
<!-- <div v-show="dicomInfo.acc">ACC {{ dicomInfo.acc }}</div> -->
|
||||
<!-- <div>{{ dicomInfo.time }}</div> -->
|
||||
</div>
|
||||
<div ref="sliderBox" class="my_slider_box" style="position: absolute;right: 1px;height: calc(100% - 140px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer" @click.stop="goViewer($event)">
|
||||
<div :style="{top: height + '%'}" style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move" @click.stop.prevent="() => {return}" @mousedown.stop="sliderMousedown($event)" />
|
||||
<div ref="sliderBox" class="my_slider_box"
|
||||
style="position: absolute;right: 1px;height: calc(100% - 140px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer"
|
||||
@click.stop="goViewer($event)">
|
||||
<div :style="{ top: height + '%' }"
|
||||
style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move"
|
||||
@click.stop.prevent="() => { return }" @mousedown.stop="sliderMousedown($event)" />
|
||||
</div>
|
||||
<div style="position: absolute;left: 50%;top: 30px;color: #f44336;transform: translateX(-50%);">
|
||||
{{ markers.top }}
|
||||
@@ -117,7 +106,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
.my_slider_box:after{
|
||||
.my_slider_box:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -20px;
|
||||
@@ -306,7 +295,10 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['visitTaskList', 'currentReadingTaskState'])
|
||||
...mapGetters(['visitTaskList', 'currentReadingTaskState']),
|
||||
NSTip() {
|
||||
return `NS: ${this.$store.state.trials.downloadTip}`
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
currentReadingTaskState: {
|
||||
@@ -562,7 +554,7 @@ export default {
|
||||
mouseDown(e) {
|
||||
this.image = e.detail.image
|
||||
var pointNearTool = this.pointNearTool(e)
|
||||
if (pointNearTool) {
|
||||
if (pointNearTool) {
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
@@ -574,7 +566,7 @@ export default {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
|
||||
}).catch(() => {})
|
||||
}).catch(() => { })
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
@@ -672,7 +664,7 @@ export default {
|
||||
this.sliderInfo.isMove = false
|
||||
},
|
||||
getMeasureData() {
|
||||
console.log('getMeasureData')
|
||||
console.log('getMeasureData')
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.stack.visitTaskId)
|
||||
this.measureData = this.visitTaskList[idx].MeasureData
|
||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||
@@ -889,7 +881,7 @@ export default {
|
||||
} else {
|
||||
// cornerstoneTools.setToolEnabledForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
|
||||
cornerstoneTools.setToolPassiveForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
|
||||
|
||||
|
||||
}
|
||||
if (this.stack.instanceId.includes(data.InstanceId) && ((this.stack.isExistMutiFrames && (data.MeasureData.frame === this.stack.frame) && data.MeasureData) || (!this.stack.isExistMutiFrames && data.MeasureData))) {
|
||||
// console.log('renderMeasuredData', this.stack.frame,data.MeasureData.frame,this.stack.isExistMutiFrames)
|
||||
@@ -991,32 +983,32 @@ export default {
|
||||
var idx = this.measureData.findIndex(item => item.MeasureData && item.MeasureData.data && item.MeasureData.data.uuid === toolState.data[i].uuid)
|
||||
if (idx > -1) {
|
||||
DicomEvent.$emit('setCollapseActive', this.measureData[idx])
|
||||
const measureData = {}
|
||||
// var markName = this.measureData[idx].OrderMarkName
|
||||
var markName = this.measureData[idx].MeasureData.data.remark
|
||||
if (this.activeToolName === 'Eraser' && this.disabledMarks.indexOf(markName) === -1) {
|
||||
const questionInfo = this.measureData[idx]
|
||||
measureData.orderMarkName = markName
|
||||
this.$emit('moveMeasureData', { measureData, questionInfo, orderMarkName: markName})
|
||||
}
|
||||
if ((this.disabledMarks.indexOf(markName) === -1 || !this.disabledMarks) && this.activeToolName !== 'Eraser') {
|
||||
const questionInfo = this.measureData[idx]
|
||||
const canvas = this.canvas.querySelector('canvas')
|
||||
measureData.pictureBaseStr = canvas.toDataURL('image/png', 1)
|
||||
measureData.studyId = this.stack.studyId
|
||||
measureData.seriesId = this.stack.seriesId
|
||||
measureData.instanceId = instanceId
|
||||
measureData.frame = this.stack.frame ? this.stack.frame : 0
|
||||
measureData.data = toolState.data[i]
|
||||
measureData.type = toolType
|
||||
measureData.thick = this.dicomInfo.thick
|
||||
measureData.location = this.dicomInfo.location
|
||||
measureData.ww = Math.round(viewport.voi.windowWidth)
|
||||
measureData.wc = Math.round(viewport.voi.windowCenter)
|
||||
measureData.data.active = false
|
||||
this.$emit('modifyMeasureData', { measureData, questionInfo })
|
||||
}
|
||||
|
||||
const measureData = {}
|
||||
// var markName = this.measureData[idx].OrderMarkName
|
||||
var markName = this.measureData[idx].MeasureData.data.remark
|
||||
if (this.activeToolName === 'Eraser' && this.disabledMarks.indexOf(markName) === -1) {
|
||||
const questionInfo = this.measureData[idx]
|
||||
measureData.orderMarkName = markName
|
||||
this.$emit('moveMeasureData', { measureData, questionInfo, orderMarkName: markName })
|
||||
}
|
||||
if ((this.disabledMarks.indexOf(markName) === -1 || !this.disabledMarks) && this.activeToolName !== 'Eraser') {
|
||||
const questionInfo = this.measureData[idx]
|
||||
const canvas = this.canvas.querySelector('canvas')
|
||||
measureData.pictureBaseStr = canvas.toDataURL('image/png', 1)
|
||||
measureData.studyId = this.stack.studyId
|
||||
measureData.seriesId = this.stack.seriesId
|
||||
measureData.instanceId = instanceId
|
||||
measureData.frame = this.stack.frame ? this.stack.frame : 0
|
||||
measureData.data = toolState.data[i]
|
||||
measureData.type = toolType
|
||||
measureData.thick = this.dicomInfo.thick
|
||||
measureData.location = this.dicomInfo.location
|
||||
measureData.ww = Math.round(viewport.voi.windowWidth)
|
||||
measureData.wc = Math.round(viewport.voi.windowCenter)
|
||||
measureData.data.active = false
|
||||
this.$emit('modifyMeasureData', { measureData, questionInfo })
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -1118,7 +1110,7 @@ export default {
|
||||
const toolButtons = document.querySelectorAll('[data-tool]')
|
||||
// const scope = this
|
||||
Array.from(toolButtons).forEach((toolBtn) => {
|
||||
// Add the tool
|
||||
// Add the tool
|
||||
const toolName = toolBtn.getAttribute('data-tool')
|
||||
const apiTool = cornerstoneTools[`${toolName}Tool`]
|
||||
if (apiTool) {
|
||||
@@ -1126,17 +1118,17 @@ export default {
|
||||
|
||||
if (!toolAlreadyAddedToElement) {
|
||||
if (toolName === 'Length') {
|
||||
cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true }})
|
||||
cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true } })
|
||||
} else if (toolName === 'Bidirectional') {
|
||||
// cornerstoneTools.addToolForElement(element, BidirectionalTool, { digits: this.digitPlaces })
|
||||
// , handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true
|
||||
cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true }})
|
||||
// cornerstoneTools.addToolForElement(element, BidirectionalTool, { digits: this.digitPlaces })
|
||||
// , handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true
|
||||
cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true } })
|
||||
} else if (toolName === 'ArrowAnnotate') {
|
||||
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
||||
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true } })
|
||||
} else if (toolName === 'RectangleRoi') {
|
||||
cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
||||
cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true } })
|
||||
} else if (toolName === 'CircleRoi') {
|
||||
cornerstoneTools.addToolForElement(element, CircleRoiTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true, showMinMax: true }})
|
||||
cornerstoneTools.addToolForElement(element, CircleRoiTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true, showMinMax: true } })
|
||||
} else {
|
||||
cornerstoneTools.addToolForElement(element, apiTool)
|
||||
}
|
||||
@@ -1162,10 +1154,10 @@ export default {
|
||||
mouseButtonMask: 4
|
||||
})
|
||||
|
||||
// if (!cornerstoneTools.getToolForElement(element, OrientationMarkersTool)) {
|
||||
// cornerstoneTools.addToolForElement(element, OrientationMarkersTool)
|
||||
// }
|
||||
// cornerstoneTools.setToolActiveForElement(element, 'OrientationMarkers', { })
|
||||
// if (!cornerstoneTools.getToolForElement(element, OrientationMarkersTool)) {
|
||||
// cornerstoneTools.addToolForElement(element, OrientationMarkersTool)
|
||||
// }
|
||||
// cornerstoneTools.setToolActiveForElement(element, 'OrientationMarkers', { })
|
||||
}
|
||||
|
||||
// cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'stackPrefetch', 'playClip'])
|
||||
@@ -1210,9 +1202,8 @@ export default {
|
||||
data.string('x00080030')
|
||||
)
|
||||
this.dicomInfo.series = data.string('x00200011')
|
||||
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${
|
||||
this.stack.imageIds.length
|
||||
}`
|
||||
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${this.stack.imageIds.length
|
||||
}`
|
||||
this.dicomInfo.size = `${data.uint16('x00280011')}*${data.uint16(
|
||||
'x00280010'
|
||||
)}`
|
||||
@@ -1392,9 +1383,9 @@ export default {
|
||||
var element = cornerstone.getEnabledElement(this.canvas)
|
||||
const { rowPixelSpacing, colPixelSpacing } = this.getPixelSpacing(element.image)
|
||||
const dx =
|
||||
(data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1)
|
||||
(data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1)
|
||||
const dy =
|
||||
(data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1)
|
||||
(data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1)
|
||||
const length = Math.sqrt(dx * dx + dy * dy)
|
||||
|
||||
return length.toFixed(this.digitPlaces)
|
||||
@@ -1408,9 +1399,9 @@ export default {
|
||||
if (imagePlane) {
|
||||
return {
|
||||
rowPixelSpacing:
|
||||
imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing,
|
||||
imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing,
|
||||
colPixelSpacing:
|
||||
imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing
|
||||
imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1462,7 +1453,7 @@ export default {
|
||||
},
|
||||
debounce(callback, delay) {
|
||||
let timerId
|
||||
return function() {
|
||||
return function () {
|
||||
clearTimeout(timerId)
|
||||
timerId = setTimeout(() => {
|
||||
callback.apply(this, arguments)
|
||||
@@ -1480,7 +1471,7 @@ export default {
|
||||
if (imageId) {
|
||||
ToolStateManager.clearImageIdToolState(imageId)
|
||||
let elements = cornerstone.getEnabledElementsByImageId(imageId)
|
||||
elements.map(el=>{
|
||||
elements.map(el => {
|
||||
cornerstone.updateImage(el.element)
|
||||
})
|
||||
}
|
||||
@@ -1766,7 +1757,7 @@ export default {
|
||||
this.activeToolName = toolName
|
||||
this.$nextTick(() => {
|
||||
// console.log(cornerstoneTools.isToolActiveForElement(this.canvas, 'Bidirectional'))
|
||||
|
||||
|
||||
if (toolName === 'Zoom') {
|
||||
cornerstoneTools.setToolActiveForElement(this.canvas, 'Zoom', {
|
||||
mouseButtonMask: [1, 2]
|
||||
@@ -1920,7 +1911,7 @@ export default {
|
||||
for (const [key, value] of searchParams.entries()) {
|
||||
params[key] = value
|
||||
}
|
||||
if (isNaN(params.frame)){
|
||||
if (isNaN(params.frame)) {
|
||||
params.frame = 0
|
||||
}
|
||||
return params
|
||||
@@ -1942,88 +1933,102 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.context-menu-wrapper{
|
||||
position: absolute;
|
||||
ul{
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
.context-menu-wrapper {
|
||||
position: absolute;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
background: #343333;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
border: 1px solid #2a2a2a;
|
||||
border-radius: 3px;
|
||||
height: auto;
|
||||
min-height: 50px;
|
||||
line-height: 1.5em;
|
||||
width: 80px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.menu {
|
||||
li {
|
||||
padding: 2px 5px;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #666;
|
||||
|
||||
div {
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.submenu {
|
||||
position: absolute;
|
||||
left: 77px;
|
||||
top: -1px;
|
||||
background: #343333;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
border: 1px solid #2a2a2a;
|
||||
border-radius: 3px;
|
||||
height: auto;
|
||||
min-height: 50px;
|
||||
line-height: 1.5em;
|
||||
width:80px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.menu{
|
||||
display: none;
|
||||
|
||||
li {
|
||||
padding: 2px 5px;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #666;
|
||||
div{
|
||||
|
||||
div {
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
.submenu{
|
||||
position: absolute;
|
||||
left: 77px;
|
||||
top: -1px;
|
||||
background: #343333;
|
||||
color: #fff;
|
||||
display: none;
|
||||
li {
|
||||
padding: 2px 5px;
|
||||
border-bottom: 1px solid #666;
|
||||
div{
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.menu li:hover{
|
||||
background-color: #ff5722;
|
||||
.submenu{
|
||||
display:block;
|
||||
}
|
||||
}
|
||||
.menu_active{
|
||||
cursor: pointer;
|
||||
}
|
||||
.menu_disabled{
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
}
|
||||
.info-visit{
|
||||
position: absolute;
|
||||
left:50%;
|
||||
top: 5px;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.arrw_div_wrapper{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #3f3f3f;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
border-radius: 10%;
|
||||
}
|
||||
.blind_name_wrapper{
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
background-color: #00000057;
|
||||
color: #fff;
|
||||
padding:0 10px;
|
||||
font-size: 14px;
|
||||
|
||||
.menu li:hover {
|
||||
background-color: #ff5722;
|
||||
|
||||
.submenu {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.info-cd{
|
||||
|
||||
.menu_active {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.menu_disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.info-visit {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 5px;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.arrw_div_wrapper {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #3f3f3f;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
border-radius: 10%;
|
||||
}
|
||||
|
||||
.blind_name_wrapper {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
background-color: #00000057;
|
||||
color: #fff;
|
||||
padding: 0 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.info-cd {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 5px;
|
||||
@@ -2032,6 +2037,7 @@ export default {
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.info-series {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
@@ -2041,6 +2047,7 @@ export default {
|
||||
font-size: 12px;
|
||||
/* z-index: 1; */
|
||||
}
|
||||
|
||||
.info-image {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
@@ -2060,6 +2067,7 @@ export default {
|
||||
font-size: 12px;
|
||||
/* z-index: 1; */
|
||||
}
|
||||
|
||||
.info-instance {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
@@ -2092,6 +2100,7 @@ export default {
|
||||
margin: 10px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.menu__item:hover {
|
||||
color: #ff0000;
|
||||
}
|
||||
@@ -2111,11 +2120,12 @@ li:hover {
|
||||
background-color: #e0e0e2;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.msg-div {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
color: #000;
|
||||
padding: 5px 20px;
|
||||
}
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
color: #000;
|
||||
padding: 5px 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { submitDicomVisitTask } from '@/api/trials'
|
||||
import { submitDicomVisitTask, verifyVisitTaskQuestions } from '@/api/trials'
|
||||
import { getCustomTag, submitCustomTag, resetReadingTask } from '@/api/reading'
|
||||
import { setSkipReadingCache } from '@/api/reading'
|
||||
import DicomEvent from './../components/DicomEvent'
|
||||
@@ -358,6 +358,7 @@ export default {
|
||||
async handleConfirm() {
|
||||
var res = await this.$refs['QuestionsPreview'].handleSave(false)
|
||||
if (res) {
|
||||
await verifyVisitTaskQuestions({ visitTaskId: this.visitTaskId })
|
||||
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||
this.signCode = ImageAssessmentReportConfirmation
|
||||
this.signVisible = true
|
||||
|
||||
+1
-1
@@ -353,7 +353,7 @@ export default {
|
||||
validatorNumberInput(rule, value, callback) {
|
||||
let reg = new RegExp(/^(?:-?(?:(?:0|[1-9]\d*)(?:\.\d+)?|\.\d+)|NE)$/, 'g')
|
||||
if (value === '') {
|
||||
callback(new Error(this.$t('common:ruleMessage:specify')));
|
||||
callback();
|
||||
} else {
|
||||
if (!reg.test(value)) {
|
||||
callback(new Error(this.$t('trials:reading:ruleMessage:validatorNumberInput')));
|
||||
|
||||
+2
-2
@@ -261,7 +261,7 @@ export default {
|
||||
validatorNumberInput(rule, value, callback) {
|
||||
let reg = new RegExp(/^(?:-?(?:(?:0|[1-9]\d*)(?:\.\d+)?|\.\d+)|NE)$/, 'g')
|
||||
if (value === '') {
|
||||
callback(new Error(this.$t('common:ruleMessage:specify')));
|
||||
callback();
|
||||
} else {
|
||||
if (!reg.test(value)) {
|
||||
callback(new Error(this.$t('trials:reading:ruleMessage:validatorNumberInput')));
|
||||
@@ -483,7 +483,7 @@ export default {
|
||||
var trialId = this.$route.query.trialId
|
||||
var subjectId = this.$route.query.trialId
|
||||
var file = await this.fileToBlob(param.file)
|
||||
const res = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${param.file.name}`, file)
|
||||
const res = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/${this.visitTaskId}/${param.file.name}`, file)
|
||||
console.log(res)
|
||||
this.fileList.push({ name: param.file.name, path: this.$getObjectName(res.url), url: this.$getObjectName(res.url) })
|
||||
this.urls.push(this.$getObjectName(res.url))
|
||||
|
||||
@@ -5,42 +5,22 @@
|
||||
<div class="related-study-wrapper">
|
||||
<div class="left">
|
||||
<div class="visit-name-wrapper">
|
||||
<div
|
||||
v-if="visitTaskList.length > 0"
|
||||
style="display: flex; flex-direction: row"
|
||||
>
|
||||
<div
|
||||
v-for="s in visitTaskList"
|
||||
:key="s.VisitTaskId"
|
||||
class="visit-item"
|
||||
:class="{
|
||||
'visit-item-active': activeTaskVisitId == s.VisitTaskId,
|
||||
}"
|
||||
@click.prevent="handleClick(s)"
|
||||
>
|
||||
<div v-if="visitTaskList.length > 0" style="display: flex; flex-direction: row">
|
||||
<div v-for="s in visitTaskList" :key="s.VisitTaskId" class="visit-item" :class="{
|
||||
'visit-item-active': activeTaskVisitId == s.VisitTaskId,
|
||||
}" @click.prevent="handleClick(s)">
|
||||
{{ s.TaskBlindName }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div
|
||||
v-for="s in visitTaskList"
|
||||
v-show="activeTaskVisitId === s.VisitTaskId"
|
||||
:key="s.VisitTaskId"
|
||||
class="study-wrapper"
|
||||
>
|
||||
<StudyList
|
||||
v-if="selectArr.includes(s.VisitTaskId)"
|
||||
:ref="s.VisitTaskId"
|
||||
:visit-task-id="s.VisitTaskId"
|
||||
:trial-id="trialId"
|
||||
:subject-visit-id="s.VisitId"
|
||||
:task-blind-name="s.TaskBlindName"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
@loadImageStack="loadImageStack"
|
||||
@previewNoneDicoms="previewNoneDicoms"
|
||||
/>
|
||||
<div v-for="s in visitTaskList" v-show="activeTaskVisitId === s.VisitTaskId" :key="s.VisitTaskId"
|
||||
class="study-wrapper">
|
||||
<StudyList v-if="selectArr.includes(s.VisitTaskId)" :ref="s.VisitTaskId" :visit-task-id="s.VisitTaskId"
|
||||
:trial-id="trialId" :subject-visit-id="s.VisitId" :task-blind-name="s.TaskBlindName"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo" @loadImageStack="loadImageStack"
|
||||
@previewNoneDicoms="previewNoneDicoms" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -48,21 +28,12 @@
|
||||
</div>
|
||||
<div class="dicom-viewer">
|
||||
<div class="container">
|
||||
<DicomViewer
|
||||
v-if="activeTaskVisitId"
|
||||
ref="dicomViewer"
|
||||
:trial-id="trialId"
|
||||
:trial-reading-criterion-id="trialReadingCriterionId"
|
||||
:subject-id="subjectId"
|
||||
:is-show="isShow"
|
||||
:is-exists-clinical-data="isExistsClinicalData"
|
||||
:is-exists-no-dicom-file="isExistsNoDicomFile"
|
||||
<DicomViewer v-if="activeTaskVisitId" ref="dicomViewer" :trial-id="trialId"
|
||||
:trial-reading-criterion-id="trialReadingCriterionId" :subject-id="subjectId" :is-show="isShow"
|
||||
:is-exists-clinical-data="isExistsClinicalData" :is-exists-no-dicom-file="isExistsNoDicomFile"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
:is-reading-task-view-in-order="isReadingTaskViewInOrder"
|
||||
:isExistsManual="isExistsManual"
|
||||
:IseCRFShowInDicomReading="IseCRFShowInDicomReading"
|
||||
@previewCD="previewCD"
|
||||
/>
|
||||
:is-reading-task-view-in-order="isReadingTaskViewInOrder" :isExistsManual="isExistsManual"
|
||||
:IseCRFShowInDicomReading="IseCRFShowInDicomReading" @previewCD="previewCD" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -77,6 +48,7 @@ import { mapGetters } from "vuex";
|
||||
import * as dicomParser from 'dicom-parser'
|
||||
import * as cornerstone from 'cornerstone-core'
|
||||
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
|
||||
import { workSpeedclose } from "@/utils"
|
||||
// import metaDataProvider from '@/utils/metaDataProvider'
|
||||
// cornerstone.metaData.addProvider(metaDataProvider, { priority: 10 });
|
||||
var config = {
|
||||
@@ -261,6 +233,7 @@ export default {
|
||||
DicomEvent.$off("addNoneDicomMeasureData");
|
||||
DicomEvent.$off("selectSeries");
|
||||
window.removeEventListener('beforeunload', e => { cornerstone.imageCache.purgeCache() })
|
||||
workSpeedclose(true)
|
||||
},
|
||||
methods: {
|
||||
async getVisitInfo() {
|
||||
@@ -547,7 +520,7 @@ export default {
|
||||
if (obj) {
|
||||
let index = Math.floor(
|
||||
obj.imageIds.length *
|
||||
((baseSeries.imageIdIndex + 1) / baseSeries.imageIds)
|
||||
((baseSeries.imageIdIndex + 1) / baseSeries.imageIds)
|
||||
);
|
||||
obj.imageIdIndex = index > 0 ? index - 1 : 0;
|
||||
}
|
||||
@@ -636,7 +609,7 @@ export default {
|
||||
// );
|
||||
let frame = this.visitTaskList[index].MeasureData[idx].MeasureData.frame
|
||||
// let filterStr = series.isExistMutiFrames ? `frame=${frame}&instanceId=${instanceId}` : `instanceId=${instanceId}`
|
||||
let n = series.instanceInfoList.findIndex(k=>k.Id === instanceId)
|
||||
let n = series.instanceInfoList.findIndex(k => k.Id === instanceId)
|
||||
let filterStr = ''
|
||||
if (n > -1 && series.isExistMutiFrames) {
|
||||
if (series.instanceInfoList[n].NumberOfFrames > 0) {
|
||||
@@ -683,12 +656,15 @@ export default {
|
||||
},
|
||||
cornerstoneimageloadprogress(e) {
|
||||
const imageId = e.detail.imageId
|
||||
console.log(imageId,'imageId')
|
||||
const params = {}
|
||||
const searchParams = new URLSearchParams(imageId.split('?')[1])
|
||||
for (const [key, value] of searchParams.entries()) {
|
||||
params[key] = value
|
||||
}
|
||||
params.percentComplete = e.detail.percentComplete
|
||||
params.FileTotal = e.detail.total
|
||||
params.imageId = imageId
|
||||
store.dispatch('reading/setImageLoadedProgress', params)
|
||||
}
|
||||
},
|
||||
@@ -699,22 +675,27 @@ export default {
|
||||
height: 100%;
|
||||
// background-color: #fff;
|
||||
background-color: #000;
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
|
||||
.report-header {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
background-color: #000;
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep .el-table,
|
||||
.el-table__expanded-cell {
|
||||
background-color: #000;
|
||||
@@ -728,19 +709,23 @@ export default {
|
||||
color: #fff;
|
||||
border-color: #444444;
|
||||
}
|
||||
::v-deep .el-table__body tr > td {
|
||||
|
||||
::v-deep .el-table__body tr>td {
|
||||
background-color: #000 !important;
|
||||
color: #fff;
|
||||
border-color: #444444;
|
||||
}
|
||||
::v-deep .el-table__body tr:hover > td {
|
||||
|
||||
::v-deep .el-table__body tr:hover>td {
|
||||
background-color: #858282 !important;
|
||||
color: #fff;
|
||||
border-color: #444444;
|
||||
}
|
||||
|
||||
::v-deep .el-table--border th.gutter:last-of-type {
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep .el-card__header {
|
||||
border: none;
|
||||
padding: 10px;
|
||||
@@ -753,10 +738,12 @@ export default {
|
||||
justify-content: flex-start;
|
||||
background-color: #000;
|
||||
box-sizing: border-box;
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
@@ -773,6 +760,7 @@ export default {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
.dicom-list {
|
||||
width: 200px;
|
||||
padding: 5px 0px;
|
||||
@@ -785,6 +773,7 @@ export default {
|
||||
border: 1px solid #727272;
|
||||
// border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.el-tabs {
|
||||
box-sizing: border-box;
|
||||
padding: 0 5px;
|
||||
@@ -793,24 +782,29 @@ export default {
|
||||
flex-direction: column;
|
||||
// justify-content: flex-start;
|
||||
border: 1px solid #727272;
|
||||
|
||||
.el-tabs__item {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep .el-tabs__header {
|
||||
height: 55px;
|
||||
margin: 0px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
::v-deep .el-tabs__content {
|
||||
flex: 1;
|
||||
margin: 0px;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
::v-deep .el-tabs__item {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.dicom-desc {
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
@@ -819,23 +813,28 @@ export default {
|
||||
color: #d0d0d0;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.ps {
|
||||
overflow-anchor: none;
|
||||
touch-action: auto;
|
||||
}
|
||||
|
||||
.series-active {
|
||||
background-color: #607d8b !important;
|
||||
border: 1px solid #607d8b !important;
|
||||
}
|
||||
|
||||
::v-deep .el-progress__text {
|
||||
color: #ccc;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.series {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
|
||||
.series-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -848,9 +847,11 @@ export default {
|
||||
border-radius: 2px;
|
||||
border: 1px solid #404040;
|
||||
background-color: #3a3a3a;
|
||||
|
||||
.el-progress__text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-progress-bar {
|
||||
padding-right: 0px;
|
||||
}
|
||||
@@ -861,8 +862,10 @@ export default {
|
||||
border: 2px solid #252525;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.image-desc {
|
||||
vertical-align: top;
|
||||
|
||||
p {
|
||||
width: 100px;
|
||||
white-space: nowrap;
|
||||
@@ -876,6 +879,7 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.related-study-wrapper {
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
@@ -891,6 +895,7 @@ export default {
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
|
||||
.visit-name-wrapper {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
@@ -906,6 +911,7 @@ export default {
|
||||
// flex-direction: row;
|
||||
// align-content: flex-start;
|
||||
}
|
||||
|
||||
.visit-item {
|
||||
margin-left: 10px;
|
||||
white-space: nowrap;
|
||||
@@ -918,17 +924,20 @@ export default {
|
||||
cursor: pointer;
|
||||
// margin-left: 10px;
|
||||
}
|
||||
|
||||
.visit-item-active {
|
||||
background-color: #607d8b;
|
||||
border: 1px solid #607d8b;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 170px;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
border-left: 1px solid #4a4a4a;
|
||||
color: #d5d5d5;
|
||||
|
||||
.study-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
</template>
|
||||
</el-select>
|
||||
<span
|
||||
v-else-if="questionForm[scope.row.QuestionId] instanceof Array && scope.row.Type === 'select' || scope.row.Type === 'radio'">
|
||||
v-else-if="questionForm[scope.row.QuestionId] instanceof Array && (scope.row.Type === 'select' || scope.row.Type === 'radio')">
|
||||
{{ questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId] }}
|
||||
</span>
|
||||
<el-select
|
||||
@@ -407,7 +407,8 @@ export default {
|
||||
// this.$set(v, 'xfIndex', i)
|
||||
}
|
||||
if (v.Type === 'number') {
|
||||
this.$set(this.questionForm, v.QuestionId, v.Answers[this.visitTaskId] === '' ? parseFloat(0).toFixed(this.digitPlaces) : v.Answers[this.visitTaskId])
|
||||
// this.$set(this.questionForm, v.QuestionId, v.Answers[this.visitTaskId] === '' ? parseFloat(0).toFixed(this.digitPlaces) : v.Answers[this.visitTaskId])
|
||||
this.$set(this.questionForm, v.QuestionId, v.Answers[this.visitTaskId])
|
||||
}
|
||||
if (v.Childrens.length > 0) {
|
||||
this.setChild(v.Childrens)
|
||||
@@ -425,7 +426,8 @@ export default {
|
||||
this.$set(this.questionForm, i.QuestionId, tableAnswers)
|
||||
}
|
||||
if (i.Type === 'number') {
|
||||
this.$set(this.questionForm, i.QuestionId, i.Answers[this.visitTaskId] === '' ? parseFloat(0).toFixed(this.digitPlaces) : i.Answers[this.visitTaskId])
|
||||
// this.$set(this.questionForm, i.QuestionId, i.Answers[this.visitTaskId] === '' ? parseFloat(0).toFixed(this.digitPlaces) : i.Answers[this.visitTaskId])
|
||||
this.$set(this.questionForm, i.QuestionId, i.Answers[this.visitTaskId])
|
||||
}
|
||||
if (i.Childrens && i.Childrens.length > 0 && i.Type !== 'table' && i.Type !== 'basicTable') {
|
||||
this.setChild(i.Childrens)
|
||||
|
||||
+1
-1
@@ -120,7 +120,7 @@ name: "CustomizeReportPageUpload",
|
||||
var trialId = this.$route.query.trialId
|
||||
var subjectId = this.$route.query.trialId
|
||||
var file = await this.fileToBlob(param.file)
|
||||
const res = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${param.file.name}`, file)
|
||||
const res = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/${this.visitTaskId}/${param.file.name}`, file)
|
||||
console.log(res)
|
||||
this.fileList.push({ name: param.file.name, path: this.$getObjectName(res.url), url: this.$getObjectName(res.url)})
|
||||
this.urls.push(this.$getObjectName(res.url))
|
||||
|
||||
@@ -1,57 +1,44 @@
|
||||
<template>
|
||||
<div ref="container" style="width:100%;height:100%" class="dicom-container">
|
||||
<!-- 访视阅片 -->
|
||||
<div v-if="readingCategory === 1 && (CriterionType === 7 || ((CriterionType === 1 || CriterionType === 0) && readingVersionEnum === 1)) " class="reading-wrapper">
|
||||
<div
|
||||
v-if="readingCategory === 1 && (CriterionType === 7 || ((CriterionType === 1 || CriterionType === 0) && readingVersionEnum === 1))"
|
||||
class="reading-wrapper">
|
||||
<VisitReview :reading-tool="readingTool" />
|
||||
</div>
|
||||
<div v-else-if="(isReadingTaskViewInOrder === 1 || ((isReadingTaskViewInOrder !== 1) && isShow)) && readingCategory=== 1 && CriterionType !== 0" class="reading-wrapper">
|
||||
<div
|
||||
v-else-if="(isReadingTaskViewInOrder === 1 || ((isReadingTaskViewInOrder !== 1) && isShow)) && readingCategory === 1 && CriterionType !== 0"
|
||||
class="reading-wrapper">
|
||||
<el-tabs v-model="activeName" v-loading="loading" :before-leave="beforeLeave">
|
||||
<!-- 阅片 -->
|
||||
<el-tab-pane :label="$t('trials:reading:tabTitle:review')" name="read">
|
||||
<ReadPage
|
||||
v-if="tabs.includes('read')"
|
||||
:trial-id="trialId"
|
||||
:visit-task-id="visitTaskId"
|
||||
:subject-id="subjectId"
|
||||
:subject-code="subjectCode"
|
||||
:is-show="isShow"
|
||||
:question-form-change-state="questionFormChangeState"
|
||||
:question-form-change-num="questionFormChangeNum"
|
||||
<ReadPage v-if="tabs.includes('read')" :trial-id="trialId" :visit-task-id="visitTaskId"
|
||||
:subject-id="subjectId" :subject-code="subjectCode" :is-show="isShow"
|
||||
:question-form-change-state="questionFormChangeState" :question-form-change-num="questionFormChangeNum"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
:is-reading-task-view-in-order="isReadingTaskViewInOrder"
|
||||
:is-exists-clinical-data="isExistsClinicalData"
|
||||
:is-exists-no-dicom-file="isExistsNoDicomFile"
|
||||
:is-exists-manual="isExistsManual"
|
||||
:ise-c-r-f-show-in-dicom-reading="IseCRFShowInDicomReading"
|
||||
@previewCD="previewCD"
|
||||
/>
|
||||
:is-reading-task-view-in-order="isReadingTaskViewInOrder" :is-exists-clinical-data="isExistsClinicalData"
|
||||
:is-exists-no-dicom-file="isExistsNoDicomFile" :is-exists-manual="isExistsManual"
|
||||
:ise-c-r-f-show-in-dicom-reading="IseCRFShowInDicomReading" @previewCD="previewCD" />
|
||||
</el-tab-pane>
|
||||
<!-- 报告 -->
|
||||
<el-tab-pane v-if="!IseCRFShowInDicomReading" :label="$t('trials:reading:tabTitle:report')" name="report">
|
||||
<ReportPage v-if="tabs.includes('report') && isShow" ref="reportPage" :question-form-change-state="questionFormChangeState" :visit-task-id="visitTaskId" />
|
||||
<ReportPage v-if="tabs.includes('report') && isShow" ref="reportPage"
|
||||
:question-form-change-state="questionFormChangeState" :visit-task-id="visitTaskId" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<div v-else-if="(isReadingTaskViewInOrder === 1 || ((isReadingTaskViewInOrder !== 1) && isShow)) && readingCategory=== 1 && CriterionType === 0" class="reading-wrapper">
|
||||
<div
|
||||
v-else-if="(isReadingTaskViewInOrder === 1 || ((isReadingTaskViewInOrder !== 1) && isShow)) && readingCategory === 1 && CriterionType === 0"
|
||||
class="reading-wrapper">
|
||||
<el-tabs v-model="activeName" v-loading="loading" :before-leave="beforeLeaveCustomize">
|
||||
<!-- 阅片 -->
|
||||
<el-tab-pane :label="$t('trials:reading:tabTitle:review')" name="read">
|
||||
<CustomizeReadPage
|
||||
v-if="tabs.includes('read')"
|
||||
:trial-id="trialId"
|
||||
:trial-reading-criterion-id="TrialReadingCriterionId"
|
||||
:visit-task-id="visitTaskId"
|
||||
:subject-id="subjectId"
|
||||
:subject-code="subjectCode"
|
||||
:is-show="isShow"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
<CustomizeReadPage v-if="tabs.includes('read')" :trial-id="trialId"
|
||||
:trial-reading-criterion-id="TrialReadingCriterionId" :visit-task-id="visitTaskId" :subject-id="subjectId"
|
||||
:subject-code="subjectCode" :is-show="isShow" :is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
:is-reading-task-view-in-order="isReadingTaskViewInOrder"
|
||||
:ise-c-r-f-show-in-dicom-reading="IseCRFShowInDicomReading"
|
||||
:is-exists-clinical-data="isExistsClinicalData"
|
||||
:is-exists-no-dicom-file="isExistsNoDicomFile"
|
||||
:is-exists-manual="isExistsManual"
|
||||
@previewCD="previewCD"
|
||||
/>
|
||||
:ise-c-r-f-show-in-dicom-reading="IseCRFShowInDicomReading" :is-exists-clinical-data="isExistsClinicalData"
|
||||
:is-exists-no-dicom-file="isExistsNoDicomFile" :is-exists-manual="isExistsManual" @previewCD="previewCD" />
|
||||
</el-tab-pane>
|
||||
<!-- 报告 -->
|
||||
<el-tab-pane v-if="!IseCRFShowInDicomReading" :label="$t('trials:reading:tabTitle:report')" name="report">
|
||||
@@ -60,70 +47,40 @@
|
||||
</el-tabs>
|
||||
</div>
|
||||
<!-- 全局阅片 -->
|
||||
<GlobalReview
|
||||
v-else-if="isShow && readingCategory === 2"
|
||||
:trial-id="trialId"
|
||||
:subject-id="subjectId"
|
||||
:visit-task-id="visitTaskId"
|
||||
:reading-category="readingCategory"
|
||||
:subject-code="subjectCode"
|
||||
:task-blind-name="taskBlindName"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
<GlobalReview v-else-if="isShow && readingCategory === 2" :trial-id="trialId" :subject-id="subjectId"
|
||||
:visit-task-id="visitTaskId" :reading-category="readingCategory" :subject-code="subjectCode"
|
||||
:task-blind-name="taskBlindName" :is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
:is-reading-show-previous-results="isReadingShowPreviousResults"
|
||||
:is-exists-clinical-data="isExistsClinicalData"
|
||||
/>
|
||||
:is-exists-clinical-data="isExistsClinicalData" />
|
||||
<!-- 裁判阅片 -->
|
||||
<AdReview
|
||||
v-else-if="isShow && readingCategory === 4"
|
||||
:trial-id="trialId"
|
||||
:subject-id="subjectId"
|
||||
:visit-task-id="visitTaskId"
|
||||
:reading-category="readingCategory"
|
||||
:subject-code="subjectCode"
|
||||
:task-blind-name="taskBlindName"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
<AdReview v-else-if="isShow && readingCategory === 4" :trial-id="trialId" :subject-id="subjectId"
|
||||
:visit-task-id="visitTaskId" :reading-category="readingCategory" :subject-code="subjectCode"
|
||||
:task-blind-name="taskBlindName" :is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
:is-reading-show-previous-results="isReadingShowPreviousResults"
|
||||
:is-exists-clinical-data="isExistsClinicalData"
|
||||
/>
|
||||
:is-exists-clinical-data="isExistsClinicalData" />
|
||||
|
||||
<!-- 肿瘤学阅片 -->
|
||||
<OncologyReview
|
||||
v-else-if="isShow && readingCategory === 5"
|
||||
:trial-id="trialId"
|
||||
:subject-id="subjectId"
|
||||
:visit-task-id="visitTaskId"
|
||||
:reading-category="readingCategory"
|
||||
:subject-code="subjectCode"
|
||||
:task-blind-name="taskBlindName"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
<OncologyReview v-else-if="isShow && readingCategory === 5" :trial-id="trialId" :subject-id="subjectId"
|
||||
:visit-task-id="visitTaskId" :reading-category="readingCategory" :subject-code="subjectCode"
|
||||
:task-blind-name="taskBlindName" :is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
:is-reading-show-previous-results="isReadingShowPreviousResults"
|
||||
:is-exists-clinical-data="isExistsClinicalData"
|
||||
/>
|
||||
:is-exists-clinical-data="isExistsClinicalData" />
|
||||
|
||||
<el-dialog
|
||||
:visible.sync="dialogVisible"
|
||||
:custom-class="isFullscreen?'full-dialog-container':'dialog-container'"
|
||||
:show-close="false"
|
||||
:close-on-click-modal="false"
|
||||
:fullscreen="isFullscreen"
|
||||
>
|
||||
<el-dialog :visible.sync="dialogVisible" :custom-class="isFullscreen ? 'full-dialog-container' : 'dialog-container'"
|
||||
:show-close="false" :close-on-click-modal="false" :fullscreen="isFullscreen">
|
||||
<span slot="title" class="dialog-footer">
|
||||
<!-- 当前阅片任务存在临床数据,请查看。若已查看,请点击“确认” -->
|
||||
<span v-if="!closeCDVisible">{{ $t('trials:reading:dagTitle:msg1') }}</span>
|
||||
<div style="position: absolute;right: 20px;top: 10px;">
|
||||
<svg-icon :icon-class="isFullscreen?'exit-fullscreen':'fullscreen'" style="cursor: pointer;font-size: 20px;" @click="isFullscreen=!isFullscreen" />
|
||||
<svg-icon v-if="closeCDVisible" icon-class="dClose" style="cursor: pointer;font-size: 25px;margin-left: 10px;" @click="dialogVisible = false" />
|
||||
<svg-icon :icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'"
|
||||
style="cursor: pointer;font-size: 20px;" @click="isFullscreen = !isFullscreen" />
|
||||
<svg-icon v-if="closeCDVisible" icon-class="dClose" style="cursor: pointer;font-size: 25px;margin-left: 10px;"
|
||||
@click="dialogVisible = false" />
|
||||
</div>
|
||||
</span>
|
||||
<div style="height: 100%;margin:0;display: flex;flex-direction: column;">
|
||||
<ClinicalData
|
||||
v-if="dialogVisible"
|
||||
style="flex: 1"
|
||||
:trial-id="trialId"
|
||||
:subject-id="subjectId"
|
||||
:visit-task-id="cdVisitTaskId"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
/>
|
||||
<ClinicalData v-if="dialogVisible" style="flex: 1" :trial-id="trialId" :subject-id="subjectId"
|
||||
:visit-task-id="cdVisitTaskId" :is-reading-show-subject-info="isReadingShowSubjectInfo" />
|
||||
<div v-if="!closeCDVisible" style="text-align:right">
|
||||
<!-- 确认 -->
|
||||
<el-button type="primary" @click="handleConfirmCD">{{ $t('trials:reading:button:confirm') }}</el-button>
|
||||
@@ -131,12 +88,7 @@
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
:visible.sync="tipVisible"
|
||||
:show-close="false"
|
||||
:close-on-click-modal="false"
|
||||
width="500px"
|
||||
>
|
||||
<el-dialog :visible.sync="tipVisible" :show-close="false" :close-on-click-modal="false" width="500px">
|
||||
<span slot="title" class="dialog-footer">
|
||||
<!-- 提示 -->
|
||||
{{ $t('trials:iRecist:warnning:msg44') }}
|
||||
@@ -169,11 +121,41 @@
|
||||
<el-button type="primary" @click="tipVisible = false">{{ $t('trials:reading:button:confirm') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :visible.sync="dialogBodyPartVisible"
|
||||
:custom-class="isFullscreen ? 'full-dialog-container' : 'dialog-container'" :show-close="false"
|
||||
:close-on-click-modal="false" :fullscreen="isFullscreen">
|
||||
<span slot="title" class="dialog-footer">
|
||||
<!-- <span>{{ $t('trials:reading:dagTitle:msg1') }}</span> -->
|
||||
<div style="position: absolute;right: 20px;top: 10px;">
|
||||
<svg-icon :icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'"
|
||||
style="cursor: pointer;font-size: 20px;" @click="isFullscreen = !isFullscreen" />
|
||||
<svg-icon icon-class="dClose" style="cursor: pointer;font-size: 25px;margin-left: 10px;"
|
||||
@click="dialogBodyPartVisible = false" />
|
||||
</div>
|
||||
</span>
|
||||
<div style="height: 100%;margin:0;display: flex;flex-direction: column;">
|
||||
<el-table :data="BodyPart" style="width: 100%">
|
||||
<el-table-column prop="StudyCode" :label="$t('trials:reading:table:StudyCode')">
|
||||
</el-table-column>
|
||||
<el-table-column prop="Modalities" :label="$t('trials:reading:table:Modalities')">
|
||||
</el-table-column>
|
||||
<el-table-column prop="BodyPart" :label="$t('trials:reading:table:BodyPart')">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ Array.isArray(scope.row.BodyPart) ? scope.row.BodyPart.join(" | ") : '' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div style="text-align:right;margin-top: 10px;">
|
||||
<!-- 确认 -->
|
||||
<el-button type="primary" @click="handleConfirmBP">{{ $t('trials:reading:button:confirm')
|
||||
}}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getNextTask, readClinicalData, verifyDefaultQuestionBeAnswer } from '@/api/trials'
|
||||
import { getNextTask, readClinicalData, verifyDefaultQuestionBeAnswer, viewstudyPart } from '@/api/trials'
|
||||
import VisitReview from './../dicoms3D/components/VisitReview'
|
||||
import ReadPage from './components/ReadPage'
|
||||
import CustomizeReadPage from './customize/CustomizeReadPage'
|
||||
@@ -188,6 +170,7 @@ import store from '@/store'
|
||||
// import { getToken } from '@/utils/auth'
|
||||
import { changeURLStatic } from '@/utils/history.js'
|
||||
import requestPoolManager from '@/utils/request-pool'
|
||||
import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
name: 'Reading',
|
||||
components: {
|
||||
@@ -235,9 +218,13 @@ export default {
|
||||
tipVisible: false,
|
||||
closeCDVisible: false,
|
||||
cdVisitTaskId: '',
|
||||
readingVersionEnum: null
|
||||
readingVersionEnum: null,
|
||||
dialogBodyPartVisible: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['BodyPart'])
|
||||
},
|
||||
mounted() {
|
||||
requestPoolManager.resetRequestPool()
|
||||
requestPoolManager.setSortType(0)
|
||||
@@ -264,6 +251,10 @@ export default {
|
||||
this.dialogVisible = true
|
||||
this.cdVisitTaskId = taskId
|
||||
})
|
||||
DicomEvent.$on('previewBP', (taskId) => {
|
||||
this.isFullscreen = false
|
||||
this.dialogBodyPartVisible = true
|
||||
})
|
||||
this.activeName = this.$router.currentRoute.query.tabName ? this.$router.currentRoute.query.tabName : 'read'
|
||||
this.tabs.push(this.activeName)
|
||||
this.trialId = this.$router.currentRoute.query.trialId
|
||||
@@ -294,6 +285,7 @@ export default {
|
||||
beforeDestroy() {
|
||||
DicomEvent.$off('getNextTask')
|
||||
DicomEvent.$off('previewCD')
|
||||
DicomEvent.$off('previewBP')
|
||||
DicomEvent.$emit('resetOpenWindow')
|
||||
window.removeEventListener('beforeunload', this.handleWindowClose)
|
||||
},
|
||||
@@ -336,6 +328,7 @@ export default {
|
||||
this.isExistsClinicalData = res.Result.IsExistsClinicalData
|
||||
this.isExistsManual = res.Result.ExistsManual
|
||||
this.isReadClinicalData = res.Result.IsReadClinicalData
|
||||
this.IsViewStudyPart = res.Result.IsViewStudyPart
|
||||
this.isNeedReadClinicalData = res.Result.IsNeedReadClinicalData
|
||||
this.CriterionType = res.Result.CriterionType
|
||||
this.digitPlaces = res.Result.DigitPlaces
|
||||
@@ -346,6 +339,7 @@ export default {
|
||||
localStorage.setItem('digitPlaces', res.Result.DigitPlaces)
|
||||
localStorage.setItem('IsExistUnprocessedFeedback', res.Result.IsExistUnprocessedFeedback)
|
||||
localStorage.setItem('taskInfo', JSON.stringify(res.Result))
|
||||
sessionStorage.setItem('taskInfo', JSON.stringify(res.Result))
|
||||
this.readingCategory = res.Result.ReadingCategory
|
||||
this.readingVersionEnum = res.Result.ReadingVersionEnum
|
||||
this.questionFormChangeState = false
|
||||
@@ -355,6 +349,10 @@ export default {
|
||||
this.dialogVisible = true
|
||||
this.cdVisitTaskId = this.visitTaskId
|
||||
}
|
||||
if ((this.CriterionType === 19 || this.CriterionType === 20) && !this.IsViewStudyPart) {
|
||||
this.isFullscreen = false
|
||||
this.dialogBodyPartVisible = true
|
||||
}
|
||||
if (res.Result.ReadingCategory === 1) {
|
||||
this.activeName = 'read'
|
||||
this.tabs = [this.activeName]
|
||||
@@ -500,6 +498,18 @@ export default {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
async handleConfirmBP() {
|
||||
this.loading = true
|
||||
var visitTaskId = this.visitTaskId
|
||||
try {
|
||||
await viewstudyPart({ visitTaskId })
|
||||
this.loading = false
|
||||
this.dialogBodyPartVisible = false
|
||||
this.IsViewStudyPart = true
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
previewCD() {
|
||||
this.closeCDVisible = true
|
||||
this.isFullscreen = false
|
||||
@@ -513,98 +523,115 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-message-box__headerbtn{
|
||||
::v-deep.el-message-box__headerbtn {
|
||||
display: none;
|
||||
}
|
||||
.dicom-container{
|
||||
.reading-wrapper{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 5px;
|
||||
box-sizing: border-box;
|
||||
background-color: #000;
|
||||
::v-deep.el-tabs{
|
||||
box-sizing: border-box;
|
||||
|
||||
.dicom-container {
|
||||
.reading-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.el-tabs__item{
|
||||
color: #fff;
|
||||
}
|
||||
.el-tabs__header{
|
||||
height: 50px;
|
||||
margin:0px;
|
||||
padding: 0 5px;
|
||||
box-sizing: border-box;
|
||||
background-color: #000;
|
||||
|
||||
::v-deep.el-tabs {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-tabs__content{
|
||||
flex: 1;
|
||||
margin:0px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-tabs__item{
|
||||
color: #fff;
|
||||
}
|
||||
.el-tab-pane{
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-tabs__item {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.el-tabs__header {
|
||||
height: 50px;
|
||||
margin: 0px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.el-tabs__content {
|
||||
flex: 1;
|
||||
margin: 0px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.el-tabs__item {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.el-tab-pane {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
::v-deep.hot-keys-label{
|
||||
color: #dfdfdf !important;
|
||||
}
|
||||
::v-deep.shortcut-key-input span{
|
||||
color: #dfdfdf !important;
|
||||
}
|
||||
// ::v-deep .el-dialog{
|
||||
// background: #1e1e1e;
|
||||
// ::v-deep .el-dialog__body{
|
||||
// padding: 10px;
|
||||
// }
|
||||
::v-deep.hot-keys-label {
|
||||
color: #dfdfdf !important;
|
||||
}
|
||||
|
||||
// }
|
||||
::v-deep.el-dialog{
|
||||
::v-deep.shortcut-key-input span {
|
||||
color: #dfdfdf !important;
|
||||
}
|
||||
|
||||
// ::v-deep .el-dialog{
|
||||
// background: #1e1e1e;
|
||||
// ::v-deep .el-dialog__body{
|
||||
// padding: 10px;
|
||||
// }
|
||||
|
||||
// }
|
||||
::v-deep.el-dialog {
|
||||
background: #1e1e1e;
|
||||
border: 1px solid #ddd;
|
||||
color: #ddd;
|
||||
.el-dialog__title{
|
||||
color:#fff;
|
||||
|
||||
.el-dialog__title {
|
||||
color: #fff;
|
||||
}
|
||||
.el-input .el-input__inner{
|
||||
|
||||
.el-input .el-input__inner {
|
||||
background-color: transparent;
|
||||
color: #ddd;
|
||||
border: 1px solid #5e5e5e;
|
||||
}
|
||||
.el-input.is-disabled .el-input__inner{
|
||||
|
||||
.el-input.is-disabled .el-input__inner {
|
||||
background-color: #646464a1;
|
||||
}
|
||||
.el-form-item__label{
|
||||
|
||||
.el-form-item__label {
|
||||
color: #dfdfdf
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
::v-deep.dialog-container{
|
||||
margin-top: 50px !important;
|
||||
width:75%;
|
||||
height:80%;
|
||||
}
|
||||
::v-deep.el-dialog__body{
|
||||
padding: 20px;
|
||||
height: calc(100% - 70px);
|
||||
}
|
||||
.el-dialog__header{
|
||||
|
||||
::v-deep.dialog-container {
|
||||
margin-top: 50px !important;
|
||||
width: 75%;
|
||||
height: 80%;
|
||||
}
|
||||
|
||||
::v-deep.el-dialog__body {
|
||||
padding: 20px;
|
||||
height: calc(100% - 70px);
|
||||
}
|
||||
|
||||
.el-dialog__header {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-radio__input.is-disabled.is-checked .el-radio__inner {
|
||||
background-color: #428bca;
|
||||
border-color: #428bca;
|
||||
}
|
||||
|
||||
.full-dialog-container{
|
||||
::v-deep.is-fullscreen .el-dialog__body{
|
||||
.full-dialog-container {
|
||||
::v-deep.is-fullscreen .el-dialog__body {
|
||||
height: calc(100% - 70px);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -7,33 +7,26 @@
|
||||
</div>
|
||||
<div style="height: 100%;" class="left-content">
|
||||
<!-- 检查层级 -->
|
||||
<div v-for="(study,i) in studyList" :key="study.CodeView">
|
||||
<div v-for="(study, i) in studyList" :key="study.CodeView">
|
||||
<div class="study-desc">
|
||||
<span>{{ study.CodeView }}</span>
|
||||
<span style="margin:0 5px">{{ study.Modality }}</span>
|
||||
<span>{{ getBodyPart(study.BodyPart) }}</span>
|
||||
<span>{{ getBodyPart(study.BodyPart, study.BodyPartForEditOther) }}</span>
|
||||
</div>
|
||||
<!-- 文件层级 -->
|
||||
<div v-if="study.NoneDicomStudyFileList.length === 0" class="empty-text">
|
||||
<slot name="empty">{{ $t('trials:audit:message:noData') }}</slot>
|
||||
</div>
|
||||
<div v-else id="imgList" style="height:100%;">
|
||||
<div
|
||||
v-for="(item,j) in study.NoneDicomStudyFileList"
|
||||
:id="`img${item.Id}`"
|
||||
:key="item.Id"
|
||||
:class="{
|
||||
'is-boxActive': item.Id === currentFileId
|
||||
}"
|
||||
class="img-box"
|
||||
@click="selected(item,i,j,true)"
|
||||
>
|
||||
<div v-for="(item, j) in study.NoneDicomStudyFileList" :id="`img${item.Id}`" :key="item.Id" :class="{
|
||||
'is-boxActive': item.Id === currentFileId
|
||||
}" class="img-box" @click="selected(item, i, j, true)">
|
||||
<div v-if="item.FileName.length < 15" class="img-text">
|
||||
{{ `${j+1}. ${item.FileName}` }}
|
||||
{{ `${j + 1}. ${item.FileName}` }}
|
||||
</div>
|
||||
<el-tooltip v-else :content="item.FileName" placement="bottom">
|
||||
<div class="img-text">
|
||||
{{ `${j+1}. ${item.FileName}` }}
|
||||
{{ `${j + 1}. ${item.FileName}` }}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
@@ -46,15 +39,9 @@
|
||||
<!-- 预览图像 -->
|
||||
<el-card class="box-card right">
|
||||
<div style="width:100%;height: 100%;">
|
||||
<NoneDicomsViewer
|
||||
v-if="previewImage.imgList.length > 0"
|
||||
ref="previewImage"
|
||||
style="width:100%;"
|
||||
:preview-image="previewImage"
|
||||
:value="currentStudyFileIndex"
|
||||
:reading-task-state="readingTaskState"
|
||||
@selectedImg="selectedImg"
|
||||
/>
|
||||
<NoneDicomsViewer v-if="previewImage.imgList.length > 0" ref="previewImage" style="width:100%;"
|
||||
:preview-image="previewImage" :value="currentStudyFileIndex" :reading-task-state="readingTaskState"
|
||||
@selectedImg="selectedImg" />
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
@@ -103,11 +90,11 @@ export default {
|
||||
visistTaskId: '',
|
||||
taskBlindName: '',
|
||||
readingTaskState: 2,
|
||||
bp: []
|
||||
BodyPart: {}
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
this.bp = await this.$getBodyPart(this.$route.query.trialId)
|
||||
this.BodyPart.Bodypart = await this.$getBodyPart(this.$route.query.trialId)
|
||||
if (this.$router.currentRoute.query.TokenKey) {
|
||||
store.dispatch('user/setToken', this.$router.currentRoute.query.TokenKey)
|
||||
changeURLStatic('TokenKey', '')
|
||||
@@ -183,8 +170,8 @@ export default {
|
||||
preview() {
|
||||
this.previewVisible = true
|
||||
},
|
||||
getBodyPart(bodyPart) {
|
||||
if (!bodyPart) return ''
|
||||
getBodyPart(bodyPart, other) {
|
||||
if (!bodyPart && !other) return ''
|
||||
var separator = ','
|
||||
if (bodyPart.indexOf('|') > -1) {
|
||||
separator = '|'
|
||||
@@ -194,51 +181,61 @@ export default {
|
||||
separator = ','
|
||||
}
|
||||
var arr = bodyPart.split(separator)
|
||||
var newArr = arr.map(i => {
|
||||
return this.$fd('Bodypart', i.trim(), 'Code', { Bodypart: this.bp }, 'Name')
|
||||
var newArr = arr.map((i) => {
|
||||
return this.$fd('Bodypart', i.trim(), 'Code', this.BodyPart, 'Name')
|
||||
})
|
||||
if (other) {
|
||||
newArr.push(other)
|
||||
}
|
||||
newArr = newArr.filter(Boolean)
|
||||
return newArr.join(' | ')
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.img-container{
|
||||
.img-container {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
::v-deep .el-card__body{
|
||||
|
||||
::v-deep .el-card__body {
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
.study-desc{
|
||||
|
||||
.study-desc {
|
||||
padding: 10px 5px;
|
||||
line-height: 1;
|
||||
background-color: #ebebeb;
|
||||
font-weight: 500;
|
||||
}
|
||||
.left{
|
||||
width:240px;
|
||||
|
||||
.left {
|
||||
width: 240px;
|
||||
height: 100%;
|
||||
|
||||
::v-deep .el-card__body{
|
||||
::v-deep .el-card__body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.title{
|
||||
|
||||
.title {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
border: 1ppx solid;
|
||||
@@ -247,27 +244,32 @@ export default {
|
||||
background-color: #4e4e4e;
|
||||
color: #ffffff;
|
||||
}
|
||||
.left-content{
|
||||
|
||||
.left-content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
::v-deep .el-tabs{
|
||||
|
||||
::v-deep .el-tabs {
|
||||
height: 100%;
|
||||
display:flex;
|
||||
display: flex;
|
||||
|
||||
flex-direction: column;
|
||||
}
|
||||
::v-deep .el-tabs__header{
|
||||
|
||||
::v-deep .el-tabs__header {
|
||||
height: 40px;
|
||||
padding: 0 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
::v-deep .el-tabs__content{
|
||||
|
||||
::v-deep .el-tabs__content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0 5px;
|
||||
}
|
||||
.img-box{
|
||||
|
||||
.img-box {
|
||||
// position: relative;
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
@@ -276,34 +278,40 @@ export default {
|
||||
// margin-bottom: 5px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
.img-text{
|
||||
|
||||
.img-text {
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis; /* 用省略号表示溢出的文本 */
|
||||
text-overflow: ellipsis;
|
||||
/* 用省略号表示溢出的文本 */
|
||||
white-space: nowrap;
|
||||
}
|
||||
.img-box:nth-last-child(1){
|
||||
|
||||
.img-box:nth-last-child(1) {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.is-boxActive {
|
||||
// border-color: #409eff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.is-boxActiv:after {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
.right{
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
margin-left: 10px;
|
||||
::v-deep .el-card__body{
|
||||
|
||||
::v-deep .el-card__body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div ref="viewport-fusion" class="viewport-wrapper" v-loading="loading" element-loading-text="Loading..."
|
||||
<div ref="viewport-fusion" class="viewport-wrapper" v-loading="loading" :element-loading-text="NSTip"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)" @mouseup="sliderMouseup" @mousemove="sliderMousemove"
|
||||
@mouseleave="sliderMouseleave" :style="{ color: series.Modality === 'PT' || isMip ? '#666' : '#ddd' }">
|
||||
<div v-if="series && taskInfo" class="left-top-text">
|
||||
@@ -190,7 +190,7 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
|
||||
this.taskInfo = JSON.parse(sessionStorage.getItem('taskInfo'))
|
||||
const digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
|
||||
this.$nextTick(() => {
|
||||
@@ -786,7 +786,12 @@ export default {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
NSTip() {
|
||||
return `NS: ${this.$store.state.trials.uploadTip}`
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -280,11 +280,11 @@
|
||||
>
|
||||
<svg-icon icon-class="refresh" class="svg-icon" />
|
||||
</div>
|
||||
<!-- 更多 -->
|
||||
<!-- 更多 :class="['tool-item', readingTaskState === 2 ? 'tool-disabled' : '']" -->
|
||||
<div
|
||||
v-if="criterionType === 0"
|
||||
:title="$t('trials:reading:button:more')"
|
||||
:class="['tool-item', readingTaskState === 2 ? 'tool-disabled' : '']"
|
||||
:class="['tool-item']"
|
||||
@click.stop="showPanel($event)"
|
||||
@mouseleave="toolMouseout"
|
||||
>
|
||||
@@ -297,7 +297,8 @@
|
||||
<i class="el-icon-arrow-down" style="color:#fff;" />
|
||||
</div>
|
||||
<div class="dropdown-content">
|
||||
<ul v-if="readingTaskState < 2" style="width:100px;">
|
||||
<!--v-if="readingTaskState < 2"-->
|
||||
<ul style="width:100px;">
|
||||
<li v-for="i in customizeStandards" :key="i.toolName" style="text-align:left;">
|
||||
<a href="#" @click.prevent="setMoreToolActive(i.toolName)">
|
||||
<svg-icon :icon-class="i.icon" class="svg-icon" style="margin-right: 5px;" />
|
||||
@@ -632,6 +633,7 @@ import colorMap from './colorMap.vue'
|
||||
import RectangleROITool from './tools/RectangleROITool'
|
||||
import uploadDicomAndNonedicom from '@/components/uploadDicomAndNonedicom'
|
||||
import downloadDicomAndNonedicom from '@/components/downloadDicomAndNonedicom'
|
||||
import { getNetWorkSpeed, setNetWorkSpeedSizeAll, workSpeedclose } from "@/utils"
|
||||
const { visibility } = annotation
|
||||
const { ViewportType, Events } = Enums
|
||||
const renderingEngineId = 'myRenderingEngine'
|
||||
@@ -783,8 +785,9 @@ export default {
|
||||
loadingText: null,
|
||||
toolNames: ['Length', 'Bidirectional', 'RectangleROI', 'ArrowAnnotate', 'CircleROI', 'Eraser'],
|
||||
// resetAnnotation: false , // 是否初始化标记 (融合时使用)
|
||||
saveCustomAnnotationTimer: null,
|
||||
|
||||
// 上传
|
||||
// 上传
|
||||
downloadImageVisible: false,
|
||||
uploadImageVisible: false,
|
||||
uploadSubjectId: null,
|
||||
@@ -871,7 +874,7 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
|
||||
this.taskInfo = JSON.parse(sessionStorage.getItem('taskInfo'))
|
||||
this.isReadingTaskViewInOrder = this.taskInfo.IsReadingTaskViewInOrder
|
||||
this.criterionType = this.taskInfo.CriterionType
|
||||
const digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||
@@ -880,6 +883,7 @@ export default {
|
||||
this.tools = getCustomizeStandardsTools(this.taskInfo.ReadingToolList)
|
||||
const toolNames = this.tools.map(i => i.toolName)
|
||||
this.customizeStandards = config.customizeStandards.filter(item => !toolNames.includes(item.toolName))
|
||||
console.log(this.customizeStandards,'this.customizeStandards')
|
||||
} else {
|
||||
this.tools = getTools(this.criterionType)
|
||||
}
|
||||
@@ -897,7 +901,7 @@ export default {
|
||||
this.initLoader()
|
||||
this.getWwcTpl()
|
||||
})
|
||||
|
||||
this.getTrialCriterion()
|
||||
DicomEvent.$on('isCanActiveNoneDicomTool', data => {
|
||||
this.open.postMessage({ type: 'isCanActiveNoneDicomTool', data: data }, window.location)
|
||||
})
|
||||
@@ -1053,6 +1057,7 @@ export default {
|
||||
i.MeasureData = JSON.parse(i.MeasureData)
|
||||
if (this.criterionType === 0) {
|
||||
i.MeasureData.id = i.Id
|
||||
i.MeasureData.markId = i.MarkId
|
||||
}
|
||||
annotationUIDs.push(i.MeasureData.annotationUID)
|
||||
}
|
||||
@@ -1360,6 +1365,16 @@ export default {
|
||||
const isCriticalSequence = this.visitTaskList[taskIndex].StudyList[studyIndex].IsCriticalSequence
|
||||
const keyImages = this.visitTaskList[taskIndex].KeyImages
|
||||
const series = this.visitTaskList[taskIndex].StudyList[studyIndex].SeriesList[seriesIndex]
|
||||
if (series && series.length > 0) {
|
||||
let file = series.find(item => item.ImageId === imageId)
|
||||
if (file) {
|
||||
getNetWorkSpeed()
|
||||
setNetWorkSpeedSizeAll(percentComplete, detail.total, imageId)
|
||||
}
|
||||
}
|
||||
if (percentComplete === 100) {
|
||||
workSpeedclose()
|
||||
}
|
||||
this.setImageLoadedProgress(series, percentComplete, instanceId)
|
||||
if (!isCriticalSequence && series.IsBeMark && keyImages.length > 0) {
|
||||
const i = keyImages.findIndex(i => i.Id === params.instanceId)
|
||||
@@ -1497,14 +1512,32 @@ export default {
|
||||
this.setToolsPassive()
|
||||
},
|
||||
annotationRemovedListener(e) {
|
||||
if (this.readingTaskState === 2) return
|
||||
const { annotation } = e.detail
|
||||
if (!annotation) return
|
||||
if (annotation.visitTaskId === this.taskInfo.VisitTaskId && annotation.seriesId) {
|
||||
const index = this.markedSeriesIds.indexOf(annotation.seriesId)
|
||||
if (index !== -1) {
|
||||
this.markedSeriesIds.splice(index, 1)
|
||||
try{
|
||||
if (!annotation) return
|
||||
if (this. readingTaskState === 2 && !annotation.data.label) return false
|
||||
if (this.readingTaskState === 2) {
|
||||
const errorMsg = { message: 'annotation Not allowed to operate' }
|
||||
throw errorMsg
|
||||
}
|
||||
if (annotation.visitTaskId === this.taskInfo.VisitTaskId && annotation.seriesId) {
|
||||
const index = this.markedSeriesIds.indexOf(annotation.seriesId)
|
||||
if (index !== -1) {
|
||||
this.markedSeriesIds.splice(index, 1)
|
||||
}
|
||||
} else {
|
||||
const errorMsg = { message: 'annotation Not allowed to operate' }
|
||||
throw errorMsg
|
||||
}
|
||||
} catch (e) {
|
||||
cornerstoneTools.annotation.state.addAnnotation(annotation)
|
||||
const renderingEngine = getRenderingEngine(renderingEngineId)
|
||||
for (let i = 0; i < this.cells.length; i++) {
|
||||
const viewportId = `${this.viewportKey}-${i}`
|
||||
const viewport = renderingEngine.getViewport(viewportId)
|
||||
viewport.render()
|
||||
}
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
async customAnnotationCompletedListener(e) {
|
||||
@@ -1540,8 +1573,16 @@ export default {
|
||||
if (this.isNumber(operateStateEnum)) {
|
||||
this.$refs[`ecrf_${series.TaskInfo.VisitTaskId}`][0].bindAnnotationToQuestion(annotation)
|
||||
} else {
|
||||
setTimeout(()=>{this.saveCustomAnnotation(annotation)},500)
|
||||
if (this.saveCustomAnnotationTimer) {
|
||||
clearTimeout(this.saveCustomAnnotationTimer)
|
||||
this.saveCustomAnnotationTimer = null
|
||||
}
|
||||
this.saveCustomAnnotationTimer = setTimeout(()=>{this.saveCustomAnnotation(annotation)},500)
|
||||
}
|
||||
} else {
|
||||
// if (this.isNumber(operateStateEnum)) {
|
||||
// this.removeAnnotation(annotation)
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1572,8 +1613,10 @@ export default {
|
||||
params.Id = annotation.id ? annotation.id : ''
|
||||
params.MeasureData = JSON.stringify(measureData)
|
||||
params.NumberOfFrames = annotation.numberOfFrames
|
||||
params.MarkId = annotation.annotationUID
|
||||
const res = await submitCustomTag(params)
|
||||
annotation.id = res.Result
|
||||
annotation.markId = params.MarkId
|
||||
})
|
||||
|
||||
} catch (e) {
|
||||
@@ -1600,7 +1643,11 @@ export default {
|
||||
if (isBound || this.isNumber(operateStateEnum)) {
|
||||
this.$refs[`ecrf_${series.TaskInfo.VisitTaskId}`][0].updateAnnotationToQuestion(annotation)
|
||||
} else {
|
||||
this.saveCustomAnnotation(annotation)
|
||||
if (this.saveCustomAnnotationTimer) {
|
||||
clearTimeout(this.saveCustomAnnotationTimer)
|
||||
this.saveCustomAnnotationTimer = null
|
||||
}
|
||||
this.saveCustomAnnotationTimer = setTimeout(()=>{this.saveCustomAnnotation(annotation)},1000)
|
||||
}
|
||||
}
|
||||
this.setToolsPassive()
|
||||
@@ -1610,6 +1657,7 @@ export default {
|
||||
try {
|
||||
// if ( this.resetAnnotation && this.isFusion ) return false
|
||||
if (!annotation) return false
|
||||
if (this.readingTaskState === 2 && !annotation.data.label) return false
|
||||
if (this.readingTaskState === 2) {
|
||||
const errorMsg = { message: 'annotation Not allowed to operate' }
|
||||
throw errorMsg
|
||||
@@ -1636,8 +1684,12 @@ export default {
|
||||
annotation.data.label +
|
||||
'?'
|
||||
)
|
||||
if (annotation.id) {
|
||||
deleteCustomTag(annotation.id)
|
||||
if (annotation.markId) {
|
||||
let res = await deleteCustomTag(annotation.markId)
|
||||
if (!res.IsSuccess) throw ''
|
||||
}else if (annotation.id) {
|
||||
let res = await deleteCustomTag(annotation.id)
|
||||
if (!res.IsSuccess) throw ''
|
||||
}
|
||||
}
|
||||
const index = this.markedSeriesIds.indexOf(annotation.seriesId)
|
||||
@@ -1706,6 +1758,7 @@ export default {
|
||||
i.MeasureData = JSON.parse(i.MeasureData)
|
||||
if (this.criterionType === 0) {
|
||||
i.MeasureData.id = i.Id
|
||||
i.MeasureData.markId = i.MarkId
|
||||
}
|
||||
annotationUIDs.push(i.MeasureData.annotationUID)
|
||||
}
|
||||
@@ -1731,6 +1784,7 @@ export default {
|
||||
i.MeasureData = JSON.parse(i.MeasureData)
|
||||
if (this.criterionType === 0) {
|
||||
i.MeasureData.id = i.Id
|
||||
i.MeasureData.markId = i.MarkId
|
||||
}
|
||||
}
|
||||
return i
|
||||
@@ -1919,7 +1973,7 @@ export default {
|
||||
if (area) {
|
||||
const areaLine = isEmptyArea
|
||||
? `Area: Oblique not supported`
|
||||
: `Area: ${parseFloat(area)} ${areaUnit}`
|
||||
: `Area: ${parseFloat(area).toFixed(2)} ${areaUnit}`
|
||||
textLines.push(areaLine)
|
||||
}
|
||||
|
||||
@@ -2007,7 +2061,7 @@ export default {
|
||||
},
|
||||
// 激活标注工具
|
||||
setAnnotateToolActive(toolName) {
|
||||
if (this.readingTaskState === 2) return
|
||||
// if (this.readingTaskState === 2) return
|
||||
const toolObj = this.tools.find(i => i.toolName === toolName)
|
||||
if (!toolObj || toolObj.isDisabled) return
|
||||
const series = this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series
|
||||
@@ -2060,7 +2114,7 @@ export default {
|
||||
}
|
||||
},
|
||||
setMoreToolActive(toolName) {
|
||||
if (this.readingTaskState === 2) return
|
||||
// if (this.readingTaskState === 2) return
|
||||
this.setToolsPassive()
|
||||
const series = this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series
|
||||
if (series && series.TaskInfo.VisitTaskId && series.TaskInfo.VisitTaskId === this.taskInfo.VisitTaskId) {
|
||||
@@ -2097,7 +2151,10 @@ export default {
|
||||
const series = this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series
|
||||
const isCurrentTask = series.TaskInfo.IsCurrentTask
|
||||
const readingTaskState = this.readingTaskState
|
||||
if (!isCurrentTask || readingTaskState >= 2) {
|
||||
if (isCurrentTask && readingTaskState >= 2) {
|
||||
this.tools[i].isDisabled = false
|
||||
e.target.style.cursor = 'pointer'
|
||||
} else if (!isCurrentTask || readingTaskState >= 2) {
|
||||
this.tools[i].isDisabled = true
|
||||
e.target.style.cursor = 'not-allowed'
|
||||
if (this.activeTool) {
|
||||
@@ -2914,9 +2971,25 @@ export default {
|
||||
try {
|
||||
const that = this
|
||||
// 请输入标记名称
|
||||
const { value } = await this.$prompt(this.$t('trials:noneDicom:message:msg1'), '', {
|
||||
let message = this.$t('trials:noneDicom:message:msg1')
|
||||
// if (isShowCancelButton) {
|
||||
// message = `<div><p>${this.$t('trials:noneDicom:message:msg1')}</p><p style='font-size:12px' class='customPromptTip'>${this.$t('trials:noneDicom:message:saveTip')}</p></div>`
|
||||
// }
|
||||
const { value } = await this.$prompt( message, '', {
|
||||
showClose: false,
|
||||
showCancelButton: isShowCancelButton,
|
||||
cancelButtonText: isShowCancelButton ? this.$t('trials:reading:button:temporarySave') : this.$t('common:button:cancel'),
|
||||
confirmButtonText: isShowCancelButton ? this.$t('trials:reading:button:enduringSave') : this.$t('trials:reading:button:relevancy'),
|
||||
// showCancelButton: isShowCancelButton,
|
||||
// dangerouslyUseHTMLString: isShowCancelButton,
|
||||
inputValidator: (res) => {
|
||||
if (!res) {
|
||||
return isShowCancelButton ? this.$t('trials:noneDicom:message:saveTip') : this.$t('trials:noneDicom:message:saveTipByRelevancy')
|
||||
}
|
||||
},
|
||||
inputErrorMessage: this.$t('trials:noneDicom:message:saveTip'),
|
||||
showCancelButton: true,
|
||||
closeOnClickModal: false,
|
||||
closeOnPressEscape: false,
|
||||
beforeClose: (action, instance, done) => {
|
||||
if (action === 'confirm') {
|
||||
const value = instance.inputValue
|
||||
@@ -2933,7 +3006,8 @@ export default {
|
||||
}
|
||||
})
|
||||
return value
|
||||
} catch {
|
||||
} catch(err) {
|
||||
console.log(err)
|
||||
return null
|
||||
}
|
||||
},
|
||||
@@ -3172,9 +3246,9 @@ export default {
|
||||
try {
|
||||
file = this.convertBase64ToBlob(file)
|
||||
const trialId = this.$route.query.trialId
|
||||
const taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
|
||||
const taskInfo = JSON.parse(sessionStorage.getItem('taskInfo'))
|
||||
const subjectId = taskInfo.SubjectId
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${fileName}.png`, file)
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/${this.visitTaskId}/${fileName}.png`, file)
|
||||
return { isSuccess: true, result: result }
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
@@ -3216,6 +3290,11 @@ export default {
|
||||
DicomEvent.$off('isCanActiveNoneDicomTool')
|
||||
DicomEvent.$off('removeNoneDicomMeasureData')
|
||||
DicomEvent.$off('addNoneDicomMeasureData')
|
||||
if (this.saveCustomAnnotationTimer) {
|
||||
clearTimeout(this.saveCustomAnnotationTimer)
|
||||
this.saveCustomAnnotationTimer = null
|
||||
}
|
||||
workSpeedclose(true)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -98,11 +98,11 @@
|
||||
<div
|
||||
style="display: inline-block;margin-left:5px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width:60px">
|
||||
<template
|
||||
v-if="innerFormData[`${table.Id}_${answer.RowIndex}`].IsLymphLesion && !isNaN(parseInt(innerFormData[`${table.Id}_${answer.RowIndex}`].LesionShort))">
|
||||
v-if="innerFormData[`${table.Id}_${answer.RowIndex}`].IsLymphNodes && !isNaN(parseInt(innerFormData[`${table.Id}_${answer.RowIndex}`].LesionShort))">
|
||||
{{ innerFormData[`${table.Id}_${answer.RowIndex}`].LesionShort }}mm
|
||||
</template>
|
||||
<template
|
||||
v-else-if="!innerFormData[`${table.Id}_${answer.RowIndex}`].IsLymphLesion && !isNaN(parseInt(innerFormData[`${table.Id}_${answer.RowIndex}`].LesionLength))">
|
||||
v-else-if="!innerFormData[`${table.Id}_${answer.RowIndex}`].IsLymphNodes && !isNaN(parseInt(innerFormData[`${table.Id}_${answer.RowIndex}`].LesionLength))">
|
||||
{{ innerFormData[`${table.Id}_${answer.RowIndex}`].LesionLength }}mm
|
||||
</template>
|
||||
</div>
|
||||
@@ -235,7 +235,7 @@ export default {
|
||||
mounted() {
|
||||
this.trialId = this.$route.query.trialId
|
||||
this.visitTaskId = this.visitInfo.VisitTaskId
|
||||
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
|
||||
this.taskInfo = JSON.parse(sessionStorage.getItem('taskInfo'))
|
||||
this.isBaseLineTask = this.taskInfo.IsBaseLine
|
||||
this.criterionType = this.taskInfo.CriterionType
|
||||
const digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||
@@ -1325,7 +1325,7 @@ export default {
|
||||
file = this.convertBase64ToBlob(file)
|
||||
const trialId = this.$route.query.trialId
|
||||
const subjectId = this.taskInfo.SubjectId
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${fileName}.png`, file)
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/${this.visitTaskId}/${fileName}.png`, file)
|
||||
return { isSuccess: true, result: result }
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
@@ -1489,6 +1489,7 @@ export default {
|
||||
this.getOuterQuestions()
|
||||
this.getTableQuestions()
|
||||
this.$emit('resetAnnotations', this.visitTaskId)
|
||||
DicomEvent.$emit('removeNoneDicomMeasureData', null)
|
||||
}
|
||||
loading.close()
|
||||
} catch (e) {
|
||||
@@ -1745,9 +1746,9 @@ export default {
|
||||
if (this.activeName) {
|
||||
return this.checkToolCanActive(toolName)
|
||||
} else {
|
||||
if (this.isBaseLineTask && (toolName === 'Bidirectional' || toolName === 'Length' || toolName === 'RectangleRoi')) {
|
||||
if (this.isBaseLineTask && (toolName === 'Bidirectional' || toolName === 'Length' || toolName === 'RectangleRoi' || toolName === 'RectangleROI')) {
|
||||
return { isCanActiveTool: true, reason: '' }
|
||||
} else if (!this.isBaseLineTask && (toolName === 'ArrowAnnotate' || toolName === 'Bidirectional' || toolName === 'Length' || toolName === 'RectangleRoi')) {
|
||||
} else if (!this.isBaseLineTask && (toolName === 'ArrowAnnotate' || toolName === 'Bidirectional' || toolName === 'Length' || toolName === 'RectangleRoi' || toolName === 'RectangleROI')) {
|
||||
return { isCanActiveTool: true, reason: '' }
|
||||
} else if (this.isBaseLineTask && toolName === 'ArrowAnnotate') {
|
||||
return { isCanActiveTool: false, reason: this.$t('trials:reading:warnning:msg54') }
|
||||
@@ -1770,10 +1771,10 @@ export default {
|
||||
} else if (innerForm.LesionType === 0 && isLymphNodes === 0 && toolName !== 'Length') {
|
||||
// '非淋巴结靶病灶需使用直径测量工具'
|
||||
return { isCanActiveTool: false, reason: this.$t('trials:reading:warnning:msg7') }
|
||||
} else if (innerForm.LesionType === 1 && isLymphNodes === 1 && toolName !== 'Bidirectional' && toolName !== 'RectangleRoi') {
|
||||
} else if (innerForm.LesionType === 1 && isLymphNodes === 1 && toolName !== 'Bidirectional' && toolName !== 'RectangleRoi' && toolName !== 'RectangleROI') {
|
||||
// '淋巴结非靶病灶需使用长短径测量工具或矩形工具'
|
||||
return { isCanActiveTool: false, reason: this.$t('trials:reading:warnning:msg8') }
|
||||
} else if (innerForm.LesionType === 1 && isLymphNodes === 0 && toolName !== 'Length' && toolName !== 'RectangleRoi') {
|
||||
} else if (innerForm.LesionType === 1 && isLymphNodes === 0 && toolName !== 'Length' && toolName !== 'RectangleRoi' && toolName !== 'RectangleROI') {
|
||||
// '非淋巴结非靶病灶需使用直径测量工具或矩形工具'
|
||||
return { isCanActiveTool: false, reason: this.$t('trials:reading:warnning:msg9') }
|
||||
} else if (toolName === 'ArrowAnnotate') {
|
||||
@@ -1788,10 +1789,10 @@ export default {
|
||||
} else if (innerForm.LesionType === 0 && isLymphNodes === 0 && toolName !== 'Length' && toolName !== 'ArrowAnnotate') {
|
||||
// 非淋巴结靶病灶需使用直径测量工具或箭头工具
|
||||
return { isCanActiveTool: false, reason: this.$t('trials:reading:warnning:msg11') }
|
||||
} else if (innerForm.LesionType === 1 && isLymphNodes === 1 && toolName !== 'Bidirectional' && toolName !== 'ArrowAnnotate' && toolName !== 'RectangleRoi') {
|
||||
} else if (innerForm.LesionType === 1 && isLymphNodes === 1 && toolName !== 'Bidirectional' && toolName !== 'ArrowAnnotate' && toolName !== 'RectangleRoi' && toolName !== 'RectangleROI') {
|
||||
// 淋巴结非靶病灶需使用长短径测量工具或矩形工具或矩形工具或箭头工具
|
||||
return { isCanActiveTool: false, reason: this.$t('trials:reading:warnning:msg52') }
|
||||
} else if (innerForm.LesionType === 1 && isLymphNodes === 0 && toolName !== 'Length' && toolName !== 'ArrowAnnotate' && toolName !== 'RectangleRoi') {
|
||||
} else if (innerForm.LesionType === 1 && isLymphNodes === 0 && toolName !== 'Length' && toolName !== 'ArrowAnnotate' && toolName !== 'RectangleRoi' && toolName !== 'RectangleROI') {
|
||||
// 非淋巴结非靶病灶需使用直径测量工具或矩形工具或矩形工具或箭头工具
|
||||
return { isCanActiveTool: false, reason: this.$t('trials:reading:warnning:msg53') }
|
||||
} else if (innerForm.LesionType === 2 && isLymphNodes === 1 && toolName !== 'Bidirectional' && toolName !== 'ArrowAnnotate') {
|
||||
|
||||
@@ -327,7 +327,7 @@ export default {
|
||||
},
|
||||
created() { this.getTableHeight() },
|
||||
mounted() {
|
||||
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
|
||||
this.taskInfo = JSON.parse(sessionStorage.getItem('taskInfo'))
|
||||
this.criterionType = this.taskInfo.CriterionType
|
||||
this.visitTaskId = this.taskInfo.VisitTaskId
|
||||
this.isBaselineTask = this.taskInfo.IsBaseLine
|
||||
@@ -367,7 +367,7 @@ export default {
|
||||
getTableHeight() {
|
||||
this.height = window.innerHeight - 170
|
||||
},
|
||||
async getReportInfo(IsCalculate) {
|
||||
async getReportInfo(IsCalculate = true) {
|
||||
this.loading = true
|
||||
try {
|
||||
var params = {
|
||||
|
||||
@@ -153,7 +153,7 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
|
||||
this.taskInfo = JSON.parse(sessionStorage.getItem('taskInfo'))
|
||||
const digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
|
||||
this.studyList = this.visitTaskInfo.StudyList
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
ref="viewport"
|
||||
class="viewport-wrapper"
|
||||
v-loading="loading"
|
||||
element-loading-text="Loading..."
|
||||
:element-loading-text="NSTip"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
||||
@mouseup="sliderMouseup"
|
||||
@mousemove="sliderMousemove"
|
||||
@@ -174,7 +174,7 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
|
||||
this.taskInfo = JSON.parse(sessionStorage.getItem('taskInfo'))
|
||||
const digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
|
||||
this.$nextTick(() => {
|
||||
@@ -539,7 +539,12 @@ export default {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
NSTip() {
|
||||
return `NS: ${this.$store.state.trials.downloadTip}`
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="visit-review-container">
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||
<!-- 阅片 -->
|
||||
<el-tab-pane v-if="taskInfo" :label="$t('trials:reading:tabTitle:review')" name="read">
|
||||
<read-page ref="readPage" :reading-tool="readingTool" />
|
||||
@@ -12,11 +12,13 @@
|
||||
name="report"
|
||||
>
|
||||
<report-page
|
||||
v-if="activeName === 'report' && taskInfo.CriterionType !== 0"
|
||||
v-if="taskInfo.CriterionType !== 0"
|
||||
ref="reportPage"
|
||||
@setReadingTaskState="setReadingTaskState"
|
||||
/>
|
||||
<customize-report-page
|
||||
v-if="activeName === 'report' && taskInfo.CriterionType === 0"
|
||||
v-if="taskInfo.CriterionType === 0"
|
||||
ref="reportPage"
|
||||
@setReadingTaskState="setReadingTaskState"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
@@ -47,12 +49,16 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.readingTool)
|
||||
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
|
||||
this.taskInfo = JSON.parse(sessionStorage.getItem('taskInfo'))
|
||||
},
|
||||
methods: {
|
||||
setReadingTaskState(state) {
|
||||
this.$refs['readPage'].setReadingTaskState(state)
|
||||
},
|
||||
handleClick(tab) {
|
||||
if (tab.name === 'report') {
|
||||
this.$refs['reportPage'].getReportInfo()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+90
-36
@@ -21,7 +21,7 @@
|
||||
<el-table-column :prop="item.Id" :label="item.QuestionName" :key="item.Id"
|
||||
v-for="item of question.TableQuestions.Questions" show-overflow-tooltip :render-header="renderHeader">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="item.Type === 'upload'">
|
||||
<span v-if="item.Type === 'upload' || item.Type === 'screenshot'">
|
||||
{{ scope.row[item.Id] === '' ? '' : scope.row[item.Id] ? scope.row[item.Id].split('|').length : '' }}
|
||||
</span>
|
||||
<span v-else-if="item.Type === 'number'">
|
||||
@@ -82,7 +82,8 @@
|
||||
validator: question.Type === 'number' && !question.TypeValue ? validatorNumberInput : (rule, value, callback) => { callback() },
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
]" :class="[question.Type === 'group' ? 'mb' : question.Type === 'upload' ? 'uploadWrapper' : '']">
|
||||
]"
|
||||
:class="[question.Type === 'group' ? 'mb' : question.Type === 'upload' || question.Type === 'screenshot' ? 'uploadWrapper' : '']">
|
||||
<!-- 输入框 -->
|
||||
<el-input v-if="question.Type === 'input'" v-model="questionForm[question.Id]"
|
||||
:disabled="question.TableQuestionType === 2 || readingTaskState === 2" />
|
||||
@@ -161,12 +162,13 @@
|
||||
</el-select>
|
||||
<template v-if="question.Type === 'number' && (question.ImageMarkEnum === 1 || question.ImageMarkEnum === 2)">
|
||||
<div style="display: flex;flex-direction: row;justify-content: flex-start;align-items: center;">
|
||||
<el-input type="number" @change="(val) => { formItemNumberChange(val, question) }"
|
||||
<el-input type="text" @change="(val) => { formItemNumberChange(val, question) }"
|
||||
@input="numberInput(question.Id)"
|
||||
@blur="questionsMarkStatus[question.Id] && questionsMarkStatus[question.Id].isMarked ? () => { } : handleMarkedQsBlur(questionForm[question.Id], questionForm, question.Id, question)"
|
||||
v-model="questionForm[question.Id]"
|
||||
:title="questionsMarkStatus[question.Id] ? questionsMarkStatus[question.Id].OrderMarkName : ''"
|
||||
:title="questionsMarkStatus[question.Id] ? questionsMarkStatus[question.Id].OrderMarkName : question.Remark"
|
||||
:disabled="(questionsMarkStatus[question.Id] && questionsMarkStatus[question.Id].isMarked && question.ImageMarkEnum === 2) || question.ImageMarkEnum === 1"
|
||||
style="width: 150px;">
|
||||
style="width: 150px;margin-right: 5px;">
|
||||
<template v-if="question.Unit !== 0" slot="append">
|
||||
{{ question.Unit !== 4 ? $fd('ValueUnit', question.Unit) : question.CustomUnit }}
|
||||
</template>
|
||||
@@ -236,18 +238,18 @@
|
||||
</el-input>
|
||||
</template>
|
||||
<!-- 上传图像 -->
|
||||
<el-upload v-if="question.Type === 'upload'" :disabled="readingTaskState === 2" action
|
||||
:accept="question.FileType" :limit="question.ImageCount === 0 ? 100 : question.ImageCount"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:before-upload="(file) => { return handleBeforeUpload(file, question.FileType) }"
|
||||
<el-upload v-if="question.Type === 'upload' || question.Type === 'screenshot'"
|
||||
:disabled="readingTaskState === 2" action :accept="question.FileType"
|
||||
:limit="question.ImageCount === 0 ? 100 : question.ImageCount" :on-preview="handlePictureCardPreview"
|
||||
:before-upload="(file) => { return handleBeforeUpload(file, question.FileType, question.Type) }"
|
||||
:http-request="uploadScreenshot" :on-remove="handleRemove" :file-list="fileList"
|
||||
:class="{ disabled: question.ImageCount === 0 ? false : fileList.length >= question.ImageCount }">
|
||||
<el-button slot="default" class="el-icon-plus" v-if="readingTaskState < 2">
|
||||
{{ this.$t('common:button:upload') }}
|
||||
</el-button>
|
||||
</el-upload>
|
||||
<viewer v-if="question.Type === 'upload' && imgVisible" :ref="imageUrl" style="margin:0 10px;"
|
||||
:images="[imageUrl]">
|
||||
<viewer v-if="(question.Type === 'upload' || question.Type === 'screenshot') && imgVisible" :ref="imageUrl"
|
||||
style="margin:0 10px;" :images="[imageUrl]">
|
||||
<img v-show="false" crossorigin="anonymous" :src="imageUrl" alt="Image">
|
||||
</viewer>
|
||||
</el-form-item>
|
||||
@@ -274,23 +276,28 @@
|
||||
|
||||
</base-model> -->
|
||||
<!-- 预览文件 -->
|
||||
<el-dialog v-if="previewVisible" :visible.sync="previewVisible" :title="$t('common:button:preview')"
|
||||
<!-- <el-dialog v-if="previewVisible" :visible.sync="previewVisible" :title="$t('common:button:preview')"
|
||||
:fullscreen="true" append-to-body custom-class="base-dialog-wrapper">
|
||||
<div class="base-modal-body" style="border: 2px solid #ccc; padding: 10px">
|
||||
<PreviewFile v-if="previewVisible" :file-path="currentPath" :file-type="currentType" />
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-dialog> -->
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { deleteReadingRowAnswer, getQuestionCalculateRelation, submitTableQuestion, deleteCustomTag } from '@/api/trials'
|
||||
import QuestionTableFormItem from './QuestionTableFormItem'
|
||||
import BaseModel from '@/components/BaseModel'
|
||||
import PreviewFile from '@/components/PreviewFile/index'
|
||||
// import PreviewFile from '@/components/PreviewFile/index'
|
||||
import { mapGetters } from 'vuex'
|
||||
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
|
||||
export default {
|
||||
name: 'QuestionFormItem',
|
||||
components: { QuestionTableFormItem, BaseModel, PreviewFile },
|
||||
components: {
|
||||
QuestionTableFormItem,
|
||||
BaseModel,
|
||||
// PreviewFile
|
||||
},
|
||||
props: {
|
||||
isBaseline: {
|
||||
type: Boolean,
|
||||
@@ -353,9 +360,9 @@ export default {
|
||||
digitPlaces: 2,
|
||||
CalculationTabelList: [],
|
||||
classArr: [],
|
||||
previewVisible: false,
|
||||
currentPath: '',
|
||||
currentType: '',
|
||||
// previewVisible: false,
|
||||
// currentPath: '',
|
||||
// currentType: '',
|
||||
markTableQuestions: [],
|
||||
parentQsId: ''
|
||||
}
|
||||
@@ -439,12 +446,14 @@ export default {
|
||||
// }
|
||||
// }
|
||||
// }, 300)
|
||||
if (this.question.Type === 'upload') {
|
||||
if (this.question.Type === 'upload' || this.question.Type === 'screenshot') {
|
||||
if (this.questionForm[this.question.Id]) {
|
||||
this.urls = this.questionForm[this.question.Id].split('|')
|
||||
this.fileList = []
|
||||
this.urls.map((url, index) => {
|
||||
this.fileList.push({ name: `${this.$t('trials:emailManageCfg:title:fileName')}${index + 1}`, url: `${url}` })
|
||||
var index = url.lastIndexOf('.')
|
||||
var suffix = url.substring(index + 1, url.length)
|
||||
this.fileList.push({ name: `${this.$t('trials:emailManageCfg:title:fileName')}${index + 1}(${suffix})`, url: `${url}` })
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -461,6 +470,22 @@ export default {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
DicomEvent.$on('openAddTableCol', (data) => {
|
||||
let { RowId } = data
|
||||
if (this.questionForm[this.question.Id] && Array.isArray(this.questionForm[this.question.Id]) && this.questionForm[this.question.Id].length > 0) {
|
||||
let index = this.questionForm[this.question.Id].findIndex(item => item.RowId === RowId)
|
||||
if (!!~index) {
|
||||
this.openAddTableCol(this.question, index)
|
||||
}
|
||||
}
|
||||
})
|
||||
DicomEvent.$on('operateImageMarker', (data) => {
|
||||
let { operateStateEnum, QuestionId, picturePath } = data
|
||||
if (this.question.Id === QuestionId) {
|
||||
this.operateImageMarker({ operateStateEnum, question: this.question, picturePath })
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
numberInput(id) {
|
||||
@@ -469,7 +494,7 @@ export default {
|
||||
validatorNumberInput(rule, value, callback) {
|
||||
let reg = new RegExp(/^(?:-?(?:(?:0|[1-9]\d*)(?:\.\d+)?|\.\d+)|NE)$/, 'g')
|
||||
if (value === '') {
|
||||
callback(new Error(this.$t('common:ruleMessage:specify')));
|
||||
callback();
|
||||
} else {
|
||||
if (!reg.test(value)) {
|
||||
callback(new Error(this.$t('trials:reading:ruleMessage:validatorNumberInput')));
|
||||
@@ -492,7 +517,7 @@ export default {
|
||||
}
|
||||
},
|
||||
handleMarkedQsBlur(value, a, b, question) {
|
||||
this.$set(a, b, parseFloat(value).toFixed(this.digitPlaces))
|
||||
this.$set(a, b, !isNaN(parseFloat(value)) ? parseFloat(value).toFixed(this.digitPlaces) : value)
|
||||
this.$emit('operateImageMarker', { operateStateEnum: 6, question })
|
||||
},
|
||||
async deleteTableCol(row, index) {
|
||||
@@ -694,7 +719,7 @@ export default {
|
||||
}
|
||||
}
|
||||
if (isExistUnSaved) {
|
||||
if (this.addOrEdit.type = 'add') {
|
||||
if (this.addOrEdit.type === 'add') {
|
||||
// 标记未保存是否确认关闭?
|
||||
const confirm = await this.$confirm(this.$t("dicom3D:CustomizeQuestionFormItem:confirm:markNoSaveAndclose"), {
|
||||
type: 'warning',
|
||||
@@ -1087,6 +1112,7 @@ export default {
|
||||
// },
|
||||
async operateImageMarker(obj) {
|
||||
// if (obj.question.IsTableQuestion && this.question.Id !== obj.question.ParentQsId) return
|
||||
if (obj.operateStateEnum === 5 && this.questionForm[obj.question.Id] && isNaN(parseFloat(this.questionForm[obj.question.Id])) && this.questionForm[obj.question.Id] !== 'NE') return false
|
||||
if (obj.operateStateEnum === 4) {
|
||||
// 移除问题标记值
|
||||
this.$set(this.questionForm, obj.question.Id, null)
|
||||
@@ -1193,7 +1219,7 @@ export default {
|
||||
}
|
||||
}
|
||||
if (isExistUnSaved) {
|
||||
if (this.addOrEdit.type = 'add') {
|
||||
if (this.addOrEdit.type === 'add') {
|
||||
//标记未保存是否确认关闭?
|
||||
const confirm = await this.$confirm(this.$t("dicom3D:CustomizeQuestionFormItem:confirm:markNoSaveAndclose"), {
|
||||
type: 'warning',
|
||||
@@ -1229,13 +1255,22 @@ export default {
|
||||
text: 'Loading',
|
||||
spinner: 'el-icon-loading'
|
||||
})
|
||||
var fileName = param.file.name
|
||||
let file = await this.fileToBlob(param.file)
|
||||
let res = await this.OSSclient.put(`/${this.$route.query.trialId}/Customize/${this.visitTaskId}/${fileName}`, file)
|
||||
this.fileList.push({ name: `${this.$t('trials:emailManageCfg:title:fileName')}${this.fileList.length + 1}`, url: this.$getObjectName(res.url) })
|
||||
this.urls.push(this.$getObjectName(res.url))
|
||||
this.$emit("setFormItemData", { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '', question: this.question })
|
||||
this.$set(this.QuestionsForm, this.question.Id, this.urls.length > 0 ? this.urls.join('|') : '')
|
||||
try {
|
||||
var fileName = param.file.name
|
||||
var index = fileName.lastIndexOf('.')
|
||||
var suffix = fileName.substring(index + 1, fileName.length)
|
||||
let file = await this.fileToBlob(param.file)
|
||||
// let res = await this.OSSclient.put(`/${this.$route.query.trialId}/Customize/${this.visitTaskId}/${fileName}`, file)
|
||||
const taskInfo = JSON.parse(sessionStorage.getItem('taskInfo'))
|
||||
const subjectId = taskInfo.SubjectId
|
||||
let res = await this.OSSclient.put(`/${this.$route.query.trialId}/Read/${subjectId}/${this.visitTaskId}/${fileName}`, file)
|
||||
this.fileList.push({ name: `${this.$t('trials:emailManageCfg:title:fileName')}${this.fileList.length + 1}(${suffix})`, url: this.$getObjectName(res.url) })
|
||||
this.urls.push(this.$getObjectName(res.url))
|
||||
this.$emit("setFormItemData", { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '', question: this.question })
|
||||
this.$set(this.QuestionsForm, this.question.Id, this.urls.length > 0 ? this.urls.join('|') : '')
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
loading.close()
|
||||
// uploadReadingAnswerImage(this.$route.query.trialId, this.visitTaskId, formData).then(res => {
|
||||
// if (res.IsSuccess) {
|
||||
@@ -1248,7 +1283,10 @@ export default {
|
||||
// loading.close()
|
||||
// })
|
||||
},
|
||||
handleBeforeUpload(file, accept) {
|
||||
handleBeforeUpload(file, accept, type) {
|
||||
if (type === 'screenshot') {
|
||||
accept = '.png,.jpeg,.jpg'
|
||||
}
|
||||
// 检测文件类型是否符合要求
|
||||
if (this.checkFileSuffix(file.name, accept) || accept === '-1') {
|
||||
return true
|
||||
@@ -1271,11 +1309,27 @@ export default {
|
||||
handlePictureCardPreview(file) {
|
||||
var suffix = file.url.substring(file.url.lastIndexOf(".") + 1)
|
||||
suffix = suffix ? suffix.toLowerCase() : ''
|
||||
if (suffix === 'doc' || suffix === 'docx' || suffix === 'pdf') {
|
||||
if (['ppt',
|
||||
'pptx',
|
||||
'doc',
|
||||
'docx',
|
||||
'xls',
|
||||
'xlsx'].includes(suffix)) {
|
||||
// window.open(this.OSSclientConfig.basePath + file.url,'_blank')
|
||||
this.currentPath = file.url
|
||||
this.currentType = suffix
|
||||
this.previewVisible = true
|
||||
this.$onlyOffice({
|
||||
path: file.url,
|
||||
type: suffix,
|
||||
title: file.name
|
||||
})
|
||||
// this.currentPath = file.url
|
||||
// this.currentType = suffix
|
||||
// this.previewVisible = true
|
||||
} else if (['pdf'].includes(suffix)) {
|
||||
this.$preview({
|
||||
path: file.url,
|
||||
type: 'pdf',
|
||||
title: file.name,
|
||||
})
|
||||
} else {
|
||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||
this.imgVisible = true
|
||||
|
||||
+77
-31
@@ -55,7 +55,7 @@
|
||||
|
||||
<script>
|
||||
|
||||
import { getCustomTableQuestionAnswer, changeDicomReadingQuestionAnswer, submitVisitTaskQuestionsInDto, getQuestionCalculateRelation, saveTaskQuestion } from '@/api/trials'
|
||||
import { getCustomTableQuestionAnswer, changeDicomReadingQuestionAnswer, submitVisitTaskQuestionsInDto, verifyVisitTaskQuestions, getQuestionCalculateRelation, saveTaskQuestion } from '@/api/trials'
|
||||
import { setSkipReadingCache, resetReadingTask, saveTableQuestionMark } from '@/api/reading'
|
||||
import const_ from '@/const/sign-code'
|
||||
import QuestionFormItem from './QuestionFormItem'
|
||||
@@ -114,7 +114,7 @@ export default {
|
||||
window.addEventListener('message', this.receiveMsg)
|
||||
this.trialId = this.$route.query.trialId
|
||||
this.visitTaskId = this.visitInfo.VisitTaskId
|
||||
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
|
||||
this.taskInfo = JSON.parse(sessionStorage.getItem('taskInfo'))
|
||||
this.isBaseLineTask = this.taskInfo.IsBaseLine
|
||||
this.criterionId = this.taskInfo.TrialReadingCriterionId
|
||||
const digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||
@@ -242,6 +242,8 @@ export default {
|
||||
async handleSubmit() {
|
||||
const valid = await this.$refs['questions'].validate()
|
||||
if (!valid) return
|
||||
await this.handleSave(false)
|
||||
await verifyVisitTaskQuestions({ visitTaskId: this.visitTaskId })
|
||||
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||
this.signCode = ImageAssessmentReportConfirmation
|
||||
this.signVisible = true
|
||||
@@ -577,7 +579,6 @@ export default {
|
||||
try {
|
||||
const answers = [{ id: obj.question.Id, answer: this.questionForm[obj.question.Id] }]
|
||||
const markInfo = []
|
||||
|
||||
const index = this.questionMarkInfoList.findIndex(
|
||||
item => item.QuestionId === this.operateQuestionId
|
||||
)
|
||||
@@ -594,16 +595,21 @@ export default {
|
||||
}
|
||||
annotation = this.getAnnotationByRow(obj.question.Id, false)
|
||||
// 截图上传
|
||||
let picturePath = ''
|
||||
let picturePath = obj.picturePath
|
||||
if (annotation) {
|
||||
const base64Str = await this.getScreenshots({
|
||||
visitTaskId: this.visitTaskId,
|
||||
annotation
|
||||
})
|
||||
const pictureObj = await this.uploadScreenshots(`${Date.now()}`, base64Str)
|
||||
picturePath = pictureObj.isSuccess ? this.$getObjectName(pictureObj.result.url) : ''
|
||||
if (!picturePath) {
|
||||
const pictureObj = await this.uploadScreenshots(`${Date.now()}`, base64Str)
|
||||
picturePath = pictureObj.isSuccess ? this.$getObjectName(pictureObj.result.url) : ''
|
||||
}
|
||||
markInfo[0].PicturePath = picturePath
|
||||
}
|
||||
if (markInfo && markInfo.length > 0) {
|
||||
markInfo[0].MarkId = annotation ? annotation.annotationUID : null
|
||||
}
|
||||
await saveTaskQuestion(-10, {
|
||||
visitTaskId: this.visitTaskId,
|
||||
answers,
|
||||
@@ -612,8 +618,20 @@ export default {
|
||||
this.$set(this.questionsMarkStatus, obj.question.Id, {
|
||||
isMarked: !!this.questionMarkInfoList[index]?.MeasureData,
|
||||
isSaved: true,
|
||||
OrderMarkName: this.questionMarkInfoList[index].OrderMarkName
|
||||
OrderMarkName: index > -1 ? this.questionMarkInfoList[index].OrderMarkName : ''
|
||||
})
|
||||
this.resetOperateState()
|
||||
if (annotation) {
|
||||
for (let i = 0; i < this.questionMarkInfoList.length; i++) {
|
||||
const item = this.questionMarkInfoList[i]
|
||||
if (!item.MeasureData || item.MeasureData.annotationUID !== annotation.annotationUID) continue
|
||||
const isTableMode = item.TableQuestionId
|
||||
if (!isTableMode && this.questionsMarkStatus[item.QuestionId] && !this.questionsMarkStatus[item.QuestionId].isSaved && this.questionsMarkStatus[item.QuestionId].isMarked) {
|
||||
DicomEvent.$emit('operateImageMarker', { QuestionId: item.QuestionId, operateStateEnum: 5, picturePath })
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('保存失败:', e)
|
||||
} finally {
|
||||
@@ -639,8 +657,8 @@ export default {
|
||||
}
|
||||
annotation = this.getAnnotationByRow(this.operateRowId)
|
||||
// 截图上传
|
||||
let picturePath = ''
|
||||
if (annotation) {
|
||||
let picturePath = obj.picturePath
|
||||
if (annotation && !picturePath) {
|
||||
const base64Str = await this.getScreenshots({
|
||||
visitTaskId: this.visitTaskId,
|
||||
annotation
|
||||
@@ -665,13 +683,25 @@ export default {
|
||||
QuestionType: 0,
|
||||
RowId: this.operateRowId,
|
||||
TableQuestionId: this.operateQuestionId,
|
||||
RowIndex: obj.rowIndex
|
||||
RowIndex: obj.rowIndex,
|
||||
MarkId: annotation ? annotation.annotationUID : null
|
||||
}, -10)
|
||||
this.$set(this.questionsMarkStatus,
|
||||
`${this.operateRowId}_${this.operateQuestionId}`,
|
||||
{ isMarked: !!annotation, isSaved: true, OrderMarkName: annotation.data.label }
|
||||
{ isMarked: !!annotation, isSaved: true, OrderMarkName: annotation ? annotation.data.label : '' }
|
||||
)
|
||||
this.resetOperateState()
|
||||
if (annotation) {
|
||||
for (let i = 0; i < this.questionMarkInfoList.length; i++) {
|
||||
const item = this.questionMarkInfoList[i]
|
||||
if (!item.MeasureData || item.MeasureData.annotationUID !== annotation.annotationUID) continue
|
||||
const isTableMode = item.TableQuestionId
|
||||
if (isTableMode && ((this.questionsMarkStatus[`${item.RowId}_${item.TableQuestionId}`] && !this.questionsMarkStatus[`${item.RowId}_${item.TableQuestionId}`].isSaved && this.questionsMarkStatus[`${item.RowId}_${item.TableQuestionId}`].isMarked) || (this.questionsMarkStatus[`${item.TableQuestionId}`] && !this.questionsMarkStatus[`${item.TableQuestionId}`].isSaved && this.questionsMarkStatus[`${item.TableQuestionId}`].isMarked))) {
|
||||
DicomEvent.$emit('operateImageMarkerTable', { QuestionId: item.TableQuestionId, operateStateEnum: 7, picturePath })
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('表格保存失败:', e)
|
||||
} finally {
|
||||
@@ -729,32 +759,45 @@ export default {
|
||||
return this.handleNullState(annotation)
|
||||
}
|
||||
if (!this.operateQuestionId) return
|
||||
if ([0, 3].includes(currentState)) {
|
||||
if ([0, 1, 3].includes(currentState)) {
|
||||
// 该标记不能与问题绑定!
|
||||
if (!annotation.data.label || annotation.markTool !== this.imageTool) {
|
||||
let message = this.$t("dicom3D:CustomizeQuestionList:alert:markNoSaveToQuestion").replace("xxx", this.$t(`dicom3D:mark:${this.imageTool}`))
|
||||
this.$alert(message)
|
||||
return
|
||||
}
|
||||
if (currentState === 3) {
|
||||
const conflictIndex = this.questionMarkInfoList.findIndex(
|
||||
item => item.MeasureData.annotationUID === annotation.annotationUID
|
||||
&& item.RowId !== this.operateRowId && this.operateRowId
|
||||
)
|
||||
if (conflictIndex > -1) {
|
||||
//该标记已绑定到其他行,不能更改绑定!
|
||||
this.$alert(this.$t("dicom3D:CustomizeQuestionList:alert:markIsbind"))
|
||||
return
|
||||
}
|
||||
// if (currentState === 3) {
|
||||
let conflictIndex = this.questionMarkInfoList.findIndex(
|
||||
item => item.MeasureData.annotationUID === annotation.annotationUID
|
||||
&& item.RowId !== this.operateRowId && item.RowId
|
||||
)
|
||||
// && this.operateRowId
|
||||
console.log(conflictIndex)
|
||||
if (conflictIndex > -1) {
|
||||
//该标记已绑定到其他行,不能更改绑定!
|
||||
this.$alert(this.$t("dicom3D:CustomizeQuestionList:alert:markIsbind"))
|
||||
return
|
||||
}
|
||||
conflictIndex = this.questionMarkInfoList.findIndex(
|
||||
item => item.MeasureData.annotationUID === annotation.annotationUID
|
||||
&& !item.TableQuestionId && this.isTableQuestion
|
||||
)
|
||||
if (conflictIndex > -1) {
|
||||
//该标记已绑定到外层问题,不能更改绑定!
|
||||
this.$alert(this.$t("dicom3D:CustomizeQuestionList:alert:markIsbind2"))
|
||||
return
|
||||
}
|
||||
// }
|
||||
// 是否确认绑定? 是否确认更改?
|
||||
const message = currentState === 0 ? this.$t("dicom3D:CustomizeQuestionList:confirm:bindYesOrNo") : this.$t("dicom3D:CustomizeQuestionList:confirm:updateYesOrNo")
|
||||
const result = await this.$confirm(message, {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
const isConfirmed = result === 'confirm'
|
||||
if (!isConfirmed) return
|
||||
const message = currentState === 0 ? this.$t("dicom3D:CustomizeQuestionList:confirm:bindYesOrNo") : currentState === 3 ? this.$t("dicom3D:CustomizeQuestionList:confirm:updateYesOrNo") : null
|
||||
if (message) {
|
||||
const result = await this.$confirm(message, {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
const isConfirmed = result === 'confirm'
|
||||
if (!isConfirmed) return
|
||||
}
|
||||
}
|
||||
const targetIndex = this.findTargetIndex()
|
||||
if (targetIndex === -1) {
|
||||
@@ -885,6 +928,9 @@ export default {
|
||||
qsArr.push({ ...item })
|
||||
const keyId = item.RowId ? `${item.RowId}_${item.TableQuestionId}` : item.TableQuestionId;
|
||||
this.$set(this.questionsMarkStatus, keyId, questionMarkInfo);
|
||||
if (item.RowId) {
|
||||
DicomEvent.$emit('openAddTableCol', { RowId: item.RowId })
|
||||
}
|
||||
}
|
||||
if (qsArr.length > 0) {
|
||||
store.dispatch('dicom3d/setOperateInfo', qsArr);
|
||||
@@ -926,7 +972,7 @@ export default {
|
||||
if ((TableQuestionId && QuestionId === questionId && markTableQuestions.includes(TableQuestionId)) && !RowId) {
|
||||
if (questionsMarkStatus && questionsMarkStatus[TableQuestionId]) {
|
||||
delete questionsMarkStatus[TableQuestionId]
|
||||
}else {
|
||||
} else {
|
||||
return item
|
||||
}
|
||||
} else {
|
||||
@@ -946,7 +992,7 @@ export default {
|
||||
const trialId = this.$route.query.trialId
|
||||
const taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
|
||||
const subjectId = taskInfo.SubjectId
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${fileName}.png`, file)
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/${this.visitTaskId}/${fileName}.png`, file)
|
||||
return { isSuccess: true, result: result }
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
|
||||
+84
-64
@@ -11,7 +11,8 @@
|
||||
validator: question.Type === 'number' && !question.TypeValue ? validatorNumberInput : (rule, value, callback) => { callback() },
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
]" :class="[question.Type === 'group' ? 'mb' : question.Type === 'upload' ? 'uploadWrapper' : '']">
|
||||
]"
|
||||
:class="[question.Type === 'group' ? 'mb' : question.Type === 'upload' || question.Type === 'screenshot' ? 'uploadWrapper' : '']">
|
||||
<!-- 输入框 -->
|
||||
<el-input v-if="question.Type === 'input'" v-model="questionForm[question.Id]"
|
||||
:disabled="question.TableQuestionType === 2 || (question.IsCopy && type === 'edit' && !isBaseline && questionForm.IsCurrentTaskAdd === 'False')" />
|
||||
@@ -80,12 +81,13 @@
|
||||
<!-- 数值 -->
|
||||
<template v-if="question.Type === 'number' && (question.ImageMarkEnum === 1 || question.ImageMarkEnum === 2)">
|
||||
<div style="display: flex;flex-direction: row;justify-content: flex-start;align-items: center;">
|
||||
<el-input type="number" @change="(val) => { formItemNumberChange(val, question) }"
|
||||
<el-input type="text" @change="(val) => { formItemNumberChange(val, question) }"
|
||||
@input="numberInput(question.Id)"
|
||||
@blur="questionsMarkStatus[question.Id] && questionsMarkStatus[question.Id].isMarked ? () => { } : handleMarkedQsBlur(questionForm[question.Id], questionForm, question.Id, question)"
|
||||
v-model="questionForm[question.Id]"
|
||||
:title="questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id] ? questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id].OrderMarkName : ''"
|
||||
:title="questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id] ? questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id].OrderMarkName : question.Remark"
|
||||
:disabled="(questionsMarkStatus[question.Id] && questionsMarkStatus[question.Id].isMarked && question.ImageMarkEnum === 2) || question.ImageMarkEnum === 1"
|
||||
style="width: 150px;">
|
||||
style="width: 150px;margin-right: 5px;">
|
||||
<template v-if="question.Unit !== 0" slot="append">
|
||||
{{ question.Unit !== 4 ? $fd('ValueUnit', question.Unit) : question.CustomUnit }}
|
||||
</template>
|
||||
@@ -156,45 +158,25 @@
|
||||
</el-input>
|
||||
</template>
|
||||
<!-- 上传图像 -->
|
||||
<el-upload v-if="question.Type === 'upload'" action :accept="question.FileType"
|
||||
:limit="question.ImageCount === 0 ? 100 : question.ImageCount" :on-preview="handlePictureCardPreview"
|
||||
:before-upload="handleBeforeUpload" :http-request="uploadScreenshot" list-type="picture-card"
|
||||
:on-remove="handleRemove" :file-list="fileList"
|
||||
<el-upload v-if="question.Type === 'upload' || question.Type === 'screenshot'" :disabled="readingTaskState === 2"
|
||||
action :accept="question.FileType" :limit="question.ImageCount === 0 ? 100 : question.ImageCount"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:before-upload="(file) => { return handleBeforeUpload(file, question.FileType, question.Type) }"
|
||||
:http-request="uploadScreenshot" :on-remove="handleRemove" :file-list="fileList"
|
||||
:class="{ disabled: question.ImageCount === 0 ? false : fileList.length >= question.ImageCount }">
|
||||
<i slot="default" class="el-icon-plus" />
|
||||
<div slot="file" slot-scope="{file}">
|
||||
<viewer :ref="file.url" :images="[imageUrl]" style="
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
">
|
||||
<img class="el-upload-list__item-thumbnail" :src="OSSclientConfig.basePath + file.url"
|
||||
crossOrigin="anonymous" alt="" style="max-width: 100%; max-height: 100%" />
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
|
||||
<i class="el-icon-zoom-in" />
|
||||
</span>
|
||||
|
||||
<span v-if="readingTaskState < 2" class="el-upload-list__item-delete" @click="handleRemove(file)">
|
||||
<i class="el-icon-delete" />
|
||||
</span>
|
||||
</span>
|
||||
</viewer>
|
||||
</div>
|
||||
<el-button slot="default" class="el-icon-plus" v-if="readingTaskState < 2">
|
||||
{{ this.$t('common:button:upload') }}
|
||||
</el-button>
|
||||
</el-upload>
|
||||
<el-dialog v-if="question.Type === 'upload'" append-to-body :visible.sync="imgVisible" width="600px">
|
||||
<el-image :src="imageUrl" width="100%">
|
||||
<div slot="placeholder" class="image-slot">
|
||||
{{ $t('trials:readingUnit:qsList:message:loading') }}<span class="dot">...</span>
|
||||
</div>
|
||||
</el-image>
|
||||
</el-dialog>
|
||||
<viewer v-if="(question.Type === 'upload' || question.Type === 'screenshot') && imgVisible" :ref="imageUrl"
|
||||
style="margin:0 10px;" :images="[imageUrl]">
|
||||
<img v-show="false" crossorigin="anonymous" :src="imageUrl" alt="Image">
|
||||
</viewer>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
|
||||
export default {
|
||||
name: 'QuestionTableFormItem',
|
||||
props: {
|
||||
@@ -294,18 +276,25 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
var digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
|
||||
if (this.question.Type === 'upload') {
|
||||
if (this.question.Type === 'upload' || this.question.Type === 'screenshot') {
|
||||
if (this.questionForm[this.question.Id]) {
|
||||
this.urls = this.questionForm[this.question.Id].split('|')
|
||||
this.fileList = []
|
||||
this.urls.map(url => {
|
||||
this.fileList.push({ name: '', url: `${url}` })
|
||||
this.urls.map((url, index) => {
|
||||
var index = url.lastIndexOf('.')
|
||||
var suffix = url.substring(index + 1, url.length)
|
||||
this.fileList.push({ name: `${this.$t('trials:emailManageCfg:title:fileName')}${index + 1}(${suffix})`, url: `${url}` })
|
||||
})
|
||||
}
|
||||
}
|
||||
DicomEvent.$on('operateImageMarkerTable', (data) => {
|
||||
let { operateStateEnum, QuestionId, picturePath } = data
|
||||
if (this.question.Id === QuestionId) {
|
||||
this.operateImageMarker({ operateStateEnum, question: this.question, picturePath })
|
||||
}
|
||||
})
|
||||
if (this.type === 'edit') return
|
||||
},
|
||||
methods: {
|
||||
@@ -319,7 +308,7 @@ export default {
|
||||
validatorNumberInput(rule, value, callback) {
|
||||
let reg = new RegExp(/^(?:-?(?:(?:0|[1-9]\d*)(?:\.\d+)?|\.\d+)|NE)$/, 'g')
|
||||
if (value === '') {
|
||||
callback(new Error(this.$t('common:ruleMessage:specify')));
|
||||
callback();
|
||||
} else {
|
||||
if (!reg.test(value)) {
|
||||
callback(new Error(this.$t('trials:reading:ruleMessage:validatorNumberInput')));
|
||||
@@ -355,6 +344,7 @@ export default {
|
||||
} else {
|
||||
this.$emit('setFormItemData', { key: question.Id, val: v, question: question })
|
||||
}
|
||||
this.$emit('formItemTableNumberChange', v, question)
|
||||
},
|
||||
handleBlur(value, a, b) {
|
||||
if (!value) return false
|
||||
@@ -363,7 +353,7 @@ export default {
|
||||
}
|
||||
},
|
||||
handleMarkedQsBlur(value, a, b, question) {
|
||||
this.$set(a, b, parseFloat(value).toFixed(this.digitPlaces))
|
||||
this.$set(a, b, !isNaN(parseFloat(value)) ? parseFloat(value).toFixed(this.digitPlaces) : value)
|
||||
question.IsTableQuestion = true
|
||||
// this.$emit('operateImageMarker', {operateStateEnum: 6, question})
|
||||
},
|
||||
@@ -529,6 +519,7 @@ export default {
|
||||
obj.question.IsTableQuestion = true
|
||||
obj.question.RowId = this.rowId
|
||||
obj.question.ParentQsId = this.parentQsId
|
||||
if (obj.operateStateEnum === 7 && this.questionForm[obj.question.Id] && isNaN(parseFloat(this.questionForm[obj.question.Id])) && this.questionForm[obj.question.Id] !== 'NE') return false
|
||||
if (obj.operateStateEnum === 7) {
|
||||
// 保存表格问题标记
|
||||
// if (!obj.question.RowId) {
|
||||
@@ -567,32 +558,36 @@ export default {
|
||||
text: 'Loading',
|
||||
spinner: 'el-icon-loading'
|
||||
})
|
||||
var trialId = this.$route.query.trialId
|
||||
var subjectId = this.$route.query.trialId
|
||||
var fileName = param.file.name
|
||||
var index = fileName.lastIndexOf('.')
|
||||
var suffix = fileName.substring(index + 1, fileName.length)
|
||||
var file = await this.fileToBlob(param.file)
|
||||
const res = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${param.file.name}`, file)
|
||||
this.fileList.push({ name: param.file.name, path: this.$getObjectName(res.url), url: this.$getObjectName(res.url) })
|
||||
// let res = await this.OSSclient.put(`/${this.$route.query.trialId}/Customize/${this.visitTaskId}/${fileName}`, file)
|
||||
const taskInfo = JSON.parse(sessionStorage.getItem('taskInfo'))
|
||||
const subjectId = taskInfo.SubjectId
|
||||
let res = await this.OSSclient.put(`/${this.$route.query.trialId}/Read/${subjectId}/${this.visitTaskId}/${fileName}`, file)
|
||||
this.fileList.push({ name: `${this.$t('trials:emailManageCfg:title:fileName')}${this.fileList.length + 1}(${suffix})`, url: this.$getObjectName(res.url) })
|
||||
this.urls.push(this.$getObjectName(res.url))
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '', question: this.question })
|
||||
loading.close()
|
||||
},
|
||||
handleBeforeUpload(file) {
|
||||
handleBeforeUpload(file, accept, type) {
|
||||
if (type === 'screenshot') {
|
||||
accept = '.png,.jpeg,.jpg'
|
||||
}
|
||||
// 检测文件类型是否符合要求
|
||||
if (this.checkFileSuffix(file.name)) {
|
||||
// this.fileList = []
|
||||
if (this.checkFileSuffix(file.name, accept) || accept === '-1') {
|
||||
return true
|
||||
} else {
|
||||
let msg = this.$t(
|
||||
"trials:readingUnit:qsList:message:imageFormat"
|
||||
).replace("xxx", this.question.FileType)
|
||||
const msg = this.$t('trials:adReview:title:msg4').replace('xxx', accept)
|
||||
this.$alert(msg)
|
||||
return false
|
||||
}
|
||||
},
|
||||
checkFileSuffix(fileName) {
|
||||
checkFileSuffix(fileName, accept) {
|
||||
var index = fileName.lastIndexOf('.')
|
||||
var suffix = fileName.substring(index + 1, fileName.length)
|
||||
if (this.question.FileType.toLocaleLowerCase().search(suffix.toLocaleLowerCase()) === -1) {
|
||||
if (accept.toLocaleLowerCase().search(suffix.toLocaleLowerCase()) === -1) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
@@ -602,21 +597,46 @@ export default {
|
||||
handlePictureCardPreview(file) {
|
||||
var suffix = file.url.substring(file.url.lastIndexOf(".") + 1)
|
||||
suffix = suffix ? suffix.toLowerCase() : ''
|
||||
if (suffix === 'doc' || suffix === 'docx' || suffix === 'pdf') {
|
||||
window.open(this.OSSclientConfig.basePath + file.url, '_blank')
|
||||
if (['ppt',
|
||||
'pptx',
|
||||
'doc',
|
||||
'docx',
|
||||
'xls',
|
||||
'xlsx'].includes(suffix)) {
|
||||
// window.open(this.OSSclientConfig.basePath + file.url,'_blank')
|
||||
this.$onlyOffice({
|
||||
path: file.url,
|
||||
type: suffix,
|
||||
title: file.name
|
||||
})
|
||||
// this.currentPath = file.url
|
||||
// this.currentType = suffix
|
||||
// this.previewVisible = true
|
||||
} else if (['pdf'].includes(suffix)) {
|
||||
this.$preview({
|
||||
path: file.url,
|
||||
type: 'pdf',
|
||||
title: file.name,
|
||||
})
|
||||
} else {
|
||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||
// this.imgVisible = true
|
||||
this.$refs[file.url].$viewer.show()
|
||||
this.imgVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs[this.imageUrl].$viewer.show()
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
// 删除图片
|
||||
handleRemove(file, fileList) {
|
||||
this.imageUrl = ''
|
||||
this.fileList.splice(this.fileList.findIndex(f => f.url === file.url), 1)
|
||||
this.urls.splice(this.fileList.findIndex(f => f === file.url), 1)
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '', question: this.question })
|
||||
if (file && file.status === "success") {
|
||||
this.imageUrl = ''
|
||||
this.fileList.splice(this.fileList.findIndex(f => f.url === file.url), 1)
|
||||
this.fileList.forEach((i, index) => {
|
||||
i.name = `${this.$t('trials:emailManageCfg:title:fileName')}${index + 1}`
|
||||
})
|
||||
this.urls.splice(this.fileList.findIndex(f => f === file.url), 1)
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '', question: this.question })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ export default {
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
|
||||
this.taskInfo = JSON.parse(sessionStorage.getItem('taskInfo'))
|
||||
this.trialId = this.$route.query.trialId
|
||||
this.visitTaskId = this.taskInfo.VisitTaskId
|
||||
this.subjectId = this.taskInfo.SubjectId
|
||||
|
||||
+1
-1
@@ -263,7 +263,7 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||
let digitPlaces = Number(sessionStorage.getItem('digitPlaces'))
|
||||
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -123,10 +123,10 @@
|
||||
</span>
|
||||
</div>
|
||||
<div style="display: inline-block;margin-left:5px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width:60px">
|
||||
<template v-if="innerFormData[`${table.Id}_${answer.RowIndex}`].IsLymphLesion && !isNaN(parseInt(innerFormData[`${table.Id}_${answer.RowIndex}`].LesionShort))">
|
||||
<template v-if="innerFormData[`${table.Id}_${answer.RowIndex}`].IsLymphNodes && !isNaN(parseInt(innerFormData[`${table.Id}_${answer.RowIndex}`].LesionShort))">
|
||||
{{ innerFormData[`${table.Id}_${answer.RowIndex}`].LesionShort }}mm
|
||||
</template>
|
||||
<template v-else-if="!innerFormData[`${table.Id}_${answer.RowIndex}`].IsLymphLesion && !isNaN(parseInt(innerFormData[`${table.Id}_${answer.RowIndex}`].LesionLength))">
|
||||
<template v-else-if="!innerFormData[`${table.Id}_${answer.RowIndex}`].IsLymphNodes && !isNaN(parseInt(innerFormData[`${table.Id}_${answer.RowIndex}`].LesionLength))">
|
||||
{{ innerFormData[`${table.Id}_${answer.RowIndex}`].LesionLength }}mm
|
||||
</template>
|
||||
</div>
|
||||
@@ -276,7 +276,7 @@ export default {
|
||||
mounted() {
|
||||
this.trialId = this.$route.query.trialId
|
||||
this.visitTaskId = this.visitInfo.VisitTaskId
|
||||
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
|
||||
this.taskInfo = JSON.parse(sessionStorage.getItem('taskInfo'))
|
||||
this.isBaseLineTask = this.taskInfo.IsBaseLine
|
||||
this.criterionType = this.taskInfo.CriterionType
|
||||
const digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||
@@ -536,7 +536,7 @@ export default {
|
||||
this.$set(this.innerFormData[`${tableId}_${rowIndex}`], stateId, 0)
|
||||
}
|
||||
|
||||
if (!(innerForm.IsCurrentTaskAdd === 'True')) {
|
||||
if (!(innerForm.IsCurrentTaskAdd === 'True') && lesionType !== 2) {
|
||||
// 非基线时,非淋巴结病灶长径>=10mm,自动给“存在”状态,如果淋巴结病灶短径>=10mm,自动给“存在”状态。
|
||||
if (!this.isBaseLineTask && ((obj.toolName === 'Length' && length >= 10) || (obj.toolName === 'Bidirectional' && short >= 10))) {
|
||||
this.$set(this.innerFormData[`${tableId}_${rowIndex}`], 'LesionState', 0)
|
||||
@@ -624,9 +624,10 @@ export default {
|
||||
this.$set(this.innerFormData[`${tableId}_${rowIndex}`], 'LesionState', 0)
|
||||
this.$set(this.innerFormData[`${tableId}_${rowIndex}`], stateId, 0)
|
||||
}
|
||||
const intrahepaticLesion = this.innerFormData[`${tableId}_${rowIndex}`].IntrahepaticLesion
|
||||
const isCurrentTaskAdd = this.innerFormData[`${tableId}_${rowIndex}`].IsCurrentTaskAdd
|
||||
const isLymphNodes = this.innerFormData[`${tableId}_${rowIndex}`].IsLymphNodes
|
||||
if (!(isCurrentTaskAdd === 'True')) {
|
||||
if (!(isCurrentTaskAdd === 'True') && lesionType !== 2) {
|
||||
// 非基线时,非淋巴结病灶长径>=10mm,自动给“存在”状态,如果淋巴结病灶短径>=10mm,自动给“存在”状态。
|
||||
if (!this.isBaseLineTask && ((toolName === 'Length' && length >= 10) || (toolName === 'Bidirectional' && short >= 10))) {
|
||||
this.$set(this.innerFormData[`${tableId}_${rowIndex}`], 'LesionState', 0)
|
||||
@@ -1428,7 +1429,7 @@ export default {
|
||||
file = this.convertBase64ToBlob(file)
|
||||
const trialId = this.$route.query.trialId
|
||||
const subjectId = this.taskInfo.SubjectId
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${fileName}.png`, file)
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/${this.visitTaskId}/${fileName}.png`, file)
|
||||
return { isSuccess: true, result: result }
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
|
||||
@@ -292,8 +292,82 @@ const config = {
|
||||
'i18nKey': 'trials:reading:button:CobbAngle',
|
||||
'isDisabled': false,
|
||||
'disabledReason': ''
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': '自由曲线',
|
||||
'icon': 'polygon',
|
||||
'toolName': 'PlanarFreehandROI',
|
||||
'props': ['radius', 'area', 'mean', 'max', 'stdDev'],
|
||||
'i18nKey': 'trials:reading:button:planarFreehandROI',
|
||||
'isDisabled': false,
|
||||
'disabledReason': ''
|
||||
},
|
||||
],
|
||||
'customizeStandardsNoneDicom': [
|
||||
{
|
||||
'name': '直径测量工具',
|
||||
'icon': 'length',
|
||||
'toolName': 'Length',
|
||||
'props': ['length'],
|
||||
'i18nKey': 'trials:reading:button:length',
|
||||
'isDisabled': false,
|
||||
'disabledReason': ''
|
||||
},
|
||||
{
|
||||
'name': '矩形工具',
|
||||
'icon': 'rectangle',
|
||||
'toolName': 'RectangleROI',
|
||||
'props': ['area', 'mean', 'max', 'stdDev'],
|
||||
'i18nKey': 'trials:reading:button:rectangle',
|
||||
'isDisabled': false,
|
||||
'disabledReason': ''
|
||||
},
|
||||
{
|
||||
'name': '箭头工具',
|
||||
'icon': 'arrow',
|
||||
'toolName': 'ArrowAnnotate',
|
||||
'props': [],
|
||||
'i18nKey': 'trials:reading:button:arrowAnnotate',
|
||||
'isDisabled': false,
|
||||
'disabledReason': ''
|
||||
},
|
||||
{
|
||||
'name': '圆形工具',
|
||||
'icon': 'oval',
|
||||
'toolName': 'CircleROI',
|
||||
'props': ['radius', 'area', 'mean', 'max', 'stdDev'],
|
||||
'i18nKey': 'trials:reading:button:Circle',
|
||||
'isDisabled': false,
|
||||
'disabledReason': ''
|
||||
},
|
||||
{
|
||||
'name': '椭圆工具',
|
||||
'icon': 'elliptical',
|
||||
'toolName': 'EllipticalROI',
|
||||
'props': ['radius', 'area', 'mean', 'max', 'stdDev'],
|
||||
'i18nKey': 'trials:reading:button:Elliptical',
|
||||
'isDisabled': false,
|
||||
'disabledReason': ''
|
||||
},
|
||||
{
|
||||
'name': '角度工具',
|
||||
'icon': 'angle',
|
||||
'toolName': 'Angle',
|
||||
'props': ['angle'],
|
||||
'i18nKey': 'trials:reading:button:Angle',
|
||||
'isDisabled': false,
|
||||
'disabledReason': ''
|
||||
},
|
||||
{
|
||||
'name': '自由曲线',
|
||||
'icon': 'polygon',
|
||||
'toolName': 'PlanarFreehandROI',
|
||||
'props': [],
|
||||
'i18nKey': 'trials:reading:button:planarFreehandROI',
|
||||
'isDisabled': false,
|
||||
'disabledReason': ''
|
||||
},
|
||||
],
|
||||
}
|
||||
const getTools = (criterionType) => {
|
||||
const standard = config.standards.find(s => s.type === criterionType)
|
||||
@@ -303,4 +377,8 @@ const getCustomizeStandardsTools = (toolNames) => {
|
||||
const filteredTools = config.customizeStandards.filter(item => toolNames.includes(item.toolName))
|
||||
return filteredTools || []
|
||||
}
|
||||
export { config, getTools, getCustomizeStandardsTools }
|
||||
const getCustomizeStandardsNoneDicomTools = (toolNames) => {
|
||||
const filteredTools = config.customizeStandardsNoneDicom.filter(item => toolNames.includes(item.toolName))
|
||||
return filteredTools || []
|
||||
}
|
||||
export { config, getTools, getCustomizeStandardsTools, getCustomizeStandardsNoneDicomTools }
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user