Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9ecaf5e267 | |||
| 1ca4fb7dd4 | |||
| cb2fed1ad2 | |||
| 4c642cd814 | |||
| 9dcbad7616 |
@@ -2,11 +2,7 @@
|
|||||||
ENV = 'usa'
|
ENV = 'usa'
|
||||||
NODE_ENV = 'usa'
|
NODE_ENV = 'usa'
|
||||||
# base public path
|
# base public path
|
||||||
# VUE_APP_BASE_PATH = 'https://d3taa4kz0xxv95.cloudfront.net/2025-10-31/'
|
VUE_APP_BASE_PATH = 'https://ei-code-prod.s3.amazonaws.com/2024-07-30/'
|
||||||
VUE_APP_BASE_PATH = '/'
|
|
||||||
|
|
||||||
# onlyoffice地址
|
|
||||||
VUE_APP_ONLYOFFICE_URL = "https://onlyoffice.uat.elevateimaging.ai"
|
|
||||||
|
|
||||||
# 是否开启登陆限制 true:是 false:否
|
# 是否开启登陆限制 true:是 false:否
|
||||||
VUE_APP_LOGIN_FOR_PERMISSION = true
|
VUE_APP_LOGIN_FOR_PERMISSION = true
|
||||||
|
|||||||
+1
-4
@@ -2,10 +2,7 @@
|
|||||||
ENV = 'usa'
|
ENV = 'usa'
|
||||||
NODE_ENV = 'usa'
|
NODE_ENV = 'usa'
|
||||||
# base public path
|
# base public path
|
||||||
VUE_APP_BASE_PATH = '/'
|
VUE_APP_BASE_PATH = 'https://ei-med-s3-code.s3.amazonaws.com/2024-07-30/'
|
||||||
|
|
||||||
# onlyoffice地址
|
|
||||||
VUE_APP_ONLYOFFICE_URL = "https://office.lili.elevateimaging.ai"
|
|
||||||
|
|
||||||
# 是否开启登陆限制 true:是 false:否
|
# 是否开启登陆限制 true:是 false:否
|
||||||
VUE_APP_LOGIN_FOR_PERMISSION = true
|
VUE_APP_LOGIN_FOR_PERMISSION = true
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
# just a flag
|
|
||||||
ENV = 'usa'
|
|
||||||
NODE_ENV = 'usa'
|
|
||||||
# base public path
|
|
||||||
VUE_APP_BASE_PATH = 'https://ei-code-prod.s3.amazonaws.com/2024-08-12/'
|
|
||||||
|
|
||||||
# 是否开启登陆限制 true:是 false:否
|
|
||||||
VUE_APP_LOGIN_FOR_PERMISSION = true
|
|
||||||
|
|
||||||
# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否
|
|
||||||
VUE_APP_LOCK_FOR_PERMISSION_MFA = true
|
|
||||||
|
|
||||||
# 是否开启长时间无操作锁定弹框 true:是 false:否
|
|
||||||
VUE_APP_LOCK_FOR_PERMISSION = true
|
|
||||||
|
|
||||||
# 无操作锁定弹框判断时间 单位:秒
|
|
||||||
VUE_APP_LOCK_FOR_TIME = 900
|
|
||||||
|
|
||||||
# 是否开启长时间无操作登出 true:是 false:否
|
|
||||||
VUE_APP_LOGOUT_FOR_PERMISSION = true
|
|
||||||
|
|
||||||
# 无操作锁定弹框判断时间 单位:秒
|
|
||||||
VUE_APP_LOGOUT_FOR_TIME = 1800
|
|
||||||
|
|
||||||
# 是否开启密码正则验证 true:是 false:否
|
|
||||||
VUE_APP_PASSWORD_FOR_PERMISSION = true
|
|
||||||
|
|
||||||
# 是否开启密码正则验证 true:是 false:否
|
|
||||||
VUE_APP_PASSWORD_FOR_REGULAR = ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[-_.@^+\$!%#*?&\$~])[A-Za-z0-9-~_.@^+\$~!%#*?&]{8,32}$
|
|
||||||
|
|
||||||
# 是否开启文档签署验证 true:是 false:否
|
|
||||||
VUE_APP_WORD_FOR_PERMISSION = true
|
|
||||||
|
|
||||||
# 公司名称
|
|
||||||
VUE_APP_COMPANY_NAME = "Elevate Imaging"
|
|
||||||
|
|
||||||
# dicom文件地址
|
|
||||||
VUE_APP_DICOM_PATH = 'https://zyypacs-uat.oss-cn-shanghai.aliyuncs.com'
|
|
||||||
|
|
||||||
VUE_APP_OSS_CONFIG_REGION = 'oss-cn-shanghai'
|
|
||||||
|
|
||||||
VUE_APP_OSS_CONFIG_BUCKET = 'zyypacs-uat'
|
|
||||||
|
|
||||||
VUE_APP_OSS_PATH = '/usa/dist'
|
|
||||||
Generated
-10
@@ -57,7 +57,6 @@
|
|||||||
"sortablejs": "^1.15.5",
|
"sortablejs": "^1.15.5",
|
||||||
"streamsaver": "^2.0.6",
|
"streamsaver": "^2.0.6",
|
||||||
"svgo": "^1.2.2",
|
"svgo": "^1.2.2",
|
||||||
"unzipit": "^2.0.3",
|
|
||||||
"v-viewer": "^1.7.4",
|
"v-viewer": "^1.7.4",
|
||||||
"vcrontab": "^0.3.5",
|
"vcrontab": "^0.3.5",
|
||||||
"vue": "2.7.16",
|
"vue": "2.7.16",
|
||||||
@@ -21836,15 +21835,6 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/unzipit": {
|
|
||||||
"version": "2.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/unzipit/-/unzipit-2.0.3.tgz",
|
|
||||||
"integrity": "sha512-e6+ftgSQRj9Hwf2mIWFwYIGqBoKV7AziG/d7pep2Uv3NCzHbhLO5d9dGRwpahVlnpQ7aQC+5kWk72dnWocdYyA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/unzipper": {
|
"node_modules/unzipper": {
|
||||||
"version": "0.10.14",
|
"version": "0.10.14",
|
||||||
"resolved": "https://registry.npmmirror.com/unzipper/-/unzipper-0.10.14.tgz",
|
"resolved": "https://registry.npmmirror.com/unzipper/-/unzipper-0.10.14.tgz",
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
"build": "vue-cli-service build",
|
"build": "vue-cli-service build",
|
||||||
"build:prod": "vue-cli-service build --mode prod",
|
"build:prod": "vue-cli-service build --mode prod",
|
||||||
"build:uat": "vue-cli-service build --mode uat",
|
"build:uat": "vue-cli-service build --mode uat",
|
||||||
"build:usa_test": "vue-cli-service build --mode usa_test",
|
|
||||||
"build:usa": "vue-cli-service build --mode usa",
|
"build:usa": "vue-cli-service build --mode usa",
|
||||||
"build:usa_prod": "vue-cli-service build --mode usa_prod",
|
"build:usa_prod": "vue-cli-service build --mode usa_prod",
|
||||||
"pre": "vue-cli-service build --mode pre",
|
"pre": "vue-cli-service build --mode pre",
|
||||||
@@ -64,7 +63,6 @@
|
|||||||
"sortablejs": "^1.15.5",
|
"sortablejs": "^1.15.5",
|
||||||
"streamsaver": "^2.0.6",
|
"streamsaver": "^2.0.6",
|
||||||
"svgo": "^1.2.2",
|
"svgo": "^1.2.2",
|
||||||
"unzipit": "^2.0.3",
|
|
||||||
"v-viewer": "^1.7.4",
|
"v-viewer": "^1.7.4",
|
||||||
"vcrontab": "^0.3.5",
|
"vcrontab": "^0.3.5",
|
||||||
"vue": "2.7.16",
|
"vue": "2.7.16",
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 7.7 KiB |
Binary file not shown.
@@ -316,30 +316,3 @@ export function GetReadingMedicineSystemQuestionList_Export(data) {
|
|||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 导出中心调研
|
|
||||||
export function getTrialSiteSurveyList_Export(data) {
|
|
||||||
return requestDownload({
|
|
||||||
url: `/ExcelExport/getTrialSiteSurveyList_Export`,
|
|
||||||
responseType: 'blob',
|
|
||||||
method: 'post',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 导出中心设备
|
|
||||||
export function getSiteSurveyEquipmentList_Export(data) {
|
|
||||||
return requestDownload({
|
|
||||||
url: `/ExcelExport/getSiteSurveyEquipmentList_Export`,
|
|
||||||
responseType: 'blob',
|
|
||||||
method: 'post',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 导出中心调研基本信息
|
|
||||||
export function getSiteSurveyInfoList_Export(data) {
|
|
||||||
return requestDownload({
|
|
||||||
url: `/ExcelExport/getSiteSurveyInfoList_Export`,
|
|
||||||
responseType: 'blob',
|
|
||||||
method: 'post',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -488,3 +488,24 @@ export function getFilterTableQuestion(data) {
|
|||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
export function deleteImageCache(params) {
|
||||||
|
return request({
|
||||||
|
url: `/Study/deleteImageCache`,
|
||||||
|
method: 'delete',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function getAnonymizeInfo(params) {
|
||||||
|
return request({
|
||||||
|
url: `/Study/getAnonymizeInfo`,
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function updateModality(params) {
|
||||||
|
return request({
|
||||||
|
url: `/Study/updateModality`,
|
||||||
|
method: 'put',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -129,31 +129,3 @@ export function getUserTypeList(userTypeEnum) {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getSiteSurveyLogList(param) {
|
|
||||||
return request({
|
|
||||||
url: `/TrialSiteSurvey/getSiteSurveyLogList`,
|
|
||||||
method: 'post',
|
|
||||||
data: param
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function getTrialIsSPMJoin(trialId) {
|
|
||||||
return request({
|
|
||||||
url: `/TrialSiteSurvey/getTrialIsSPMJoin?trialId=${trialId}`,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function getSiteSurveyEquipmentList(param) {
|
|
||||||
return request({
|
|
||||||
url: `/TrialSiteSurvey/getSiteSurveyEquipmentList`,
|
|
||||||
method: 'post',
|
|
||||||
data: param
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function getSiteSurveyInfoList(param) {
|
|
||||||
return request({
|
|
||||||
url: `/TrialSiteSurvey/getSiteSurveyInfoList`,
|
|
||||||
method: 'post',
|
|
||||||
data: param
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4523,3 +4523,23 @@ export function addOrUpdateCommonUploadRecord(data) {
|
|||||||
data,
|
data,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getInspectionById(data) {
|
||||||
|
return request({
|
||||||
|
url: `/Inspection/getInspectionById`,
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setJsonDetail(data) {
|
||||||
|
return request({
|
||||||
|
url: `/Inspection/setJsonDetail`,
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -488,67 +488,3 @@ export function setRandomTaskOrder(data) {
|
|||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getJudgeForm(data) {
|
|
||||||
return request({
|
|
||||||
url: `/ReadingImageTask/getJudgeForm`,
|
|
||||||
method: 'post',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setJudgeForm(data) {
|
|
||||||
return request({
|
|
||||||
url: `/ReadingImageTask/setJudgeForm`,
|
|
||||||
method: 'post',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getSingleVisitJudgeAnswer(data) {
|
|
||||||
return request({
|
|
||||||
url: `/ReadingImageTask/getSingleVisitJudgeAnswer`,
|
|
||||||
method: 'post',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function submitJudgeForm(data) {
|
|
||||||
return request({
|
|
||||||
url: `/Inspection/ReadingImageTask/SubmitJudgeForm`,
|
|
||||||
method: 'post',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getTrialQuestionVisitJudgeRule(data) {
|
|
||||||
return request({
|
|
||||||
url: `/ReadingQuestion/getTrialQuestionVisitJudgeRule`,
|
|
||||||
method: 'post',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setTrialQuestionVisitJudgeRule(data) {
|
|
||||||
return request({
|
|
||||||
url: `/ReadingQuestion/setTrialQuestionVisitJudgeRule`,
|
|
||||||
method: 'post',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function copyTrialQuestionVisitJudgeRule(data) {
|
|
||||||
return request({
|
|
||||||
url: `/ReadingQuestion/copyTrialQuestionVisitJudgeRule`,
|
|
||||||
method: 'post',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function applyBaseLineTrialQuestionVisitJudgeRule(data) {
|
|
||||||
return request({
|
|
||||||
url: `/ReadingQuestion/applyBaseLineTrialQuestionVisitJudgeRule`,
|
|
||||||
method: 'post',
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -94,14 +94,6 @@ export function getTrialJudgyInfo(params) {
|
|||||||
data: params
|
data: params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setTrialJudgeRuleInfo(params) {
|
|
||||||
return request({
|
|
||||||
url: `/ReadingQuestion/setTrialJudgeRuleInfo`,
|
|
||||||
method: 'post',
|
|
||||||
data: params
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 获取检查部位列表
|
// 获取检查部位列表
|
||||||
export function getTrialBodyPartList(params) {
|
export function getTrialBodyPartList(params) {
|
||||||
return request({
|
return request({
|
||||||
|
|||||||
@@ -213,6 +213,10 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
getInfo() {
|
||||||
|
var image = cornerstone.getImage(this.canvas)
|
||||||
|
return image
|
||||||
|
},
|
||||||
loadImageStack(dicomSeries, text = '') {
|
loadImageStack(dicomSeries, text = '') {
|
||||||
this.tip = text
|
this.tip = text
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
|||||||
@@ -296,6 +296,13 @@
|
|||||||
<option v-for="(item, index) in colormapsList" :key="index" :value="item.id">{{ item.name }}</option>
|
<option v-for="(item, index) in colormapsList" :key="index" :value="item.id">{{ item.name }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="sideTool-wrapper">
|
||||||
|
<label for="Replacement" style="display: inline-block;color: #fff;line-height: 20px;cursor: pointer;">
|
||||||
|
替换
|
||||||
|
</label>
|
||||||
|
<input type="file" id="Replacement" @change="beginScanFiles($event, 'replace')" style="display: none;">
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 患者信息 -->
|
<!-- 患者信息 -->
|
||||||
@@ -382,6 +389,7 @@ import {
|
|||||||
editPatientInfo
|
editPatientInfo
|
||||||
} from '@/api/trials'
|
} from '@/api/trials'
|
||||||
import { setPTClinicalDataForInstance, clearPTClinicalDataCache } from '@/utils/ptClinicalDataCache'
|
import { setPTClinicalDataForInstance, clearPTClinicalDataCache } from '@/utils/ptClinicalDataCache'
|
||||||
|
import { changeFile } from "@/views/trials/trials-panel/reading/dicoms/components/upload.js"
|
||||||
export default {
|
export default {
|
||||||
name: 'DicomsViewer',
|
name: 'DicomsViewer',
|
||||||
components: {
|
components: {
|
||||||
@@ -400,6 +408,14 @@ export default {
|
|||||||
modality: {
|
modality: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
|
},
|
||||||
|
SeriesList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
currentSeriesIndex: {
|
||||||
|
type: Number,
|
||||||
|
default: -1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -483,7 +499,9 @@ export default {
|
|||||||
},
|
},
|
||||||
formLoading: false,
|
formLoading: false,
|
||||||
type: '',
|
type: '',
|
||||||
isEdit: 0
|
isEdit: 0,
|
||||||
|
fileKey: null,
|
||||||
|
file: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -511,6 +529,19 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
beginScanFiles(e, key) {
|
||||||
|
this.fileKey = key
|
||||||
|
this.file = e.target.files[0]
|
||||||
|
let image = this.$refs[this.activeItem].getInfo()
|
||||||
|
let study = {
|
||||||
|
seriesList: this.SeriesList,
|
||||||
|
currentSeriesIndex: this.currentSeriesIndex
|
||||||
|
}
|
||||||
|
this.$emit("update:loading", true)
|
||||||
|
changeFile('CRC', this.file, study, image)
|
||||||
|
|
||||||
|
// DicomEvent.$emit('getStudyFile')
|
||||||
|
},
|
||||||
setToolsPassive() {
|
setToolsPassive() {
|
||||||
const elements = document.querySelectorAll('.dicom-item')
|
const elements = document.querySelectorAll('.dicom-item')
|
||||||
const scope = this
|
const scope = this
|
||||||
|
|||||||
@@ -336,14 +336,6 @@ export default {
|
|||||||
if (data.StudyList && data.StudyList.length > 0) {
|
if (data.StudyList && data.StudyList.length > 0) {
|
||||||
let StudyList = data.StudyList
|
let StudyList = data.StudyList
|
||||||
StudyList.forEach((study) => {
|
StudyList.forEach((study) => {
|
||||||
let arr = []
|
|
||||||
study.SeriesList.forEach(item => {
|
|
||||||
if (!arr.includes(item.Modality)) {
|
|
||||||
arr.push(item.Modality)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
let str = arr.join('_')
|
|
||||||
let time = study.StudyTime.split(' ')[0]
|
|
||||||
if (study.StudyDIRPath) {
|
if (study.StudyDIRPath) {
|
||||||
let obj = {
|
let obj = {
|
||||||
name: `${data.SubjectCode}/${data.TaskBlindName
|
name: `${data.SubjectCode}/${data.TaskBlindName
|
||||||
@@ -355,7 +347,7 @@ export default {
|
|||||||
obj = {
|
obj = {
|
||||||
name: `${data.SubjectCode}/${data.VisitName
|
name: `${data.SubjectCode}/${data.VisitName
|
||||||
}/${this.$fd('IsDicom', true)}/${study.StudyCode
|
}/${this.$fd('IsDicom', true)}/${study.StudyCode
|
||||||
}_${time}_${str}/DICOMDIR`,
|
}/DICOMDIR`,
|
||||||
url: this.OSSclientConfig.basePath + study.StudyDIRPath,
|
url: this.OSSclientConfig.basePath + study.StudyDIRPath,
|
||||||
}
|
}
|
||||||
} else if (this.IsReadingTaskViewInOrder === 0) {
|
} else if (this.IsReadingTaskViewInOrder === 0) {
|
||||||
@@ -388,7 +380,7 @@ export default {
|
|||||||
obj = {
|
obj = {
|
||||||
name: `${data.SubjectCode}/${data.VisitName
|
name: `${data.SubjectCode}/${data.VisitName
|
||||||
}/${this.$fd('IsDicom', true)}/${study.StudyCode
|
}/${this.$fd('IsDicom', true)}/${study.StudyCode
|
||||||
}_${time}_${str}/IMAGE/${fileName}`,
|
}/IMAGE/${fileName}`,
|
||||||
url: this.OSSclientConfig.basePath + instance.Path,
|
url: this.OSSclientConfig.basePath + instance.Path,
|
||||||
IsEncapsulated: instance.IsEncapsulated
|
IsEncapsulated: instance.IsEncapsulated
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,10 +61,8 @@
|
|||||||
scope.row.UploadStudyList.length <= 0
|
scope.row.UploadStudyList.length <= 0
|
||||||
" @click.stop="handleViewReadingImages(scope.row)" :title="$t('upload:dicom:button:preview')" />
|
" @click.stop="handleViewReadingImages(scope.row)" :title="$t('upload:dicom:button:preview')" />
|
||||||
<!--删除--->
|
<!--删除--->
|
||||||
<el-button circle :disabled="!scope.row.UploadStudyList ||
|
<el-button circle icon="el-icon-delete" :title="$t('upload:dicom:button:delete')"
|
||||||
scope.row.UploadStudyList.length <= 0 ||
|
@click.stop="remove(scope.row)" />
|
||||||
scope.row.ReadingTaskState === 2
|
|
||||||
" icon="el-icon-delete" :title="$t('upload:dicom:button:delete')" @click.stop="remove(scope.row)" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -383,6 +381,10 @@ export default {
|
|||||||
isReading: {
|
isReading: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
},
|
||||||
|
StudyInstanceUID: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
@@ -477,10 +479,7 @@ export default {
|
|||||||
let res = await getSubjectImageUploadList(params)
|
let res = await getSubjectImageUploadList(params)
|
||||||
this.loading = false
|
this.loading = false
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.isDownloaded = this.Criterion && this.Criterion.CriterionType && (
|
this.isDownloaded = res.OtherInfo.IsIRImageDownloaded
|
||||||
this.Criterion.CriterionType == 19 ||
|
|
||||||
this.Criterion.CriterionType == 20
|
|
||||||
) ? res.OtherInfo.IsIRImageDownloaded : true
|
|
||||||
this.TrialModality = res.OtherInfo.TrialModality.split('|')
|
this.TrialModality = res.OtherInfo.TrialModality.split('|')
|
||||||
this.IsReadingTaskViewInOrder = res.OtherInfo.IsReadingTaskViewInOrder || res.OtherInfo.IsReadingTaskViewInOrder === 0 ? res.OtherInfo.IsReadingTaskViewInOrder : 2
|
this.IsReadingTaskViewInOrder = res.OtherInfo.IsReadingTaskViewInOrder || res.OtherInfo.IsReadingTaskViewInOrder === 0 ? res.OtherInfo.IsReadingTaskViewInOrder : 2
|
||||||
this.StudyInstanceUidList = []
|
this.StudyInstanceUidList = []
|
||||||
@@ -958,7 +957,7 @@ export default {
|
|||||||
var instanceItem = instanceList.find(function (item) {
|
var instanceItem = instanceList.find(function (item) {
|
||||||
return item.instanceUid === instanceUid
|
return item.instanceUid === instanceUid
|
||||||
})
|
})
|
||||||
if (!instanceItem) {
|
if (!false) {
|
||||||
var date = data.string('x00080023')
|
var date = data.string('x00080023')
|
||||||
var time = data.string('x00080033')
|
var time = data.string('x00080033')
|
||||||
var instanceTime = ''
|
var instanceTime = ''
|
||||||
@@ -1087,11 +1086,12 @@ export default {
|
|||||||
async verifyStudy() {
|
async verifyStudy() {
|
||||||
this.btnLoading = true
|
this.btnLoading = true
|
||||||
var studyList = []
|
var studyList = []
|
||||||
|
let scope = this
|
||||||
this.selectArr.forEach((item) => {
|
this.selectArr.forEach((item) => {
|
||||||
item.dicomInfo.uploadFileSize = 0
|
item.dicomInfo.uploadFileSize = 0
|
||||||
if (!item.uploadState.selected) {
|
if (!item.uploadState.selected) {
|
||||||
studyList.push({
|
studyList.push({
|
||||||
studyInstanceUid: item.dicomInfo.studyUid,
|
studyInstanceUid: scope.isReading && scope.StudyInstanceUID ? scope.StudyInstanceUID : item.dicomInfo.studyUid,
|
||||||
studyDate: item.dicomInfo.studyTime,
|
studyDate: item.dicomInfo.studyTime,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1186,7 +1186,7 @@ export default {
|
|||||||
let t = setInterval(() => {
|
let t = setInterval(() => {
|
||||||
dicomUploadInProgress({
|
dicomUploadInProgress({
|
||||||
trialId: scope.trialId,
|
trialId: scope.trialId,
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.isReading && scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
VisitTaskId: dicomInfo.visitTaskId,
|
VisitTaskId: dicomInfo.visitTaskId,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
console.log(dicomInfo.visitTaskId)
|
console.log(dicomInfo.visitTaskId)
|
||||||
@@ -1213,7 +1213,7 @@ export default {
|
|||||||
dicomInfo.RadiopharmaceuticalStartTime,
|
dicomInfo.RadiopharmaceuticalStartTime,
|
||||||
|
|
||||||
studyId: dicomInfo.studyId,
|
studyId: dicomInfo.studyId,
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.isReading && scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
studyTime: dicomInfo.studyTime,
|
studyTime: dicomInfo.studyTime,
|
||||||
description: dicomInfo.description,
|
description: dicomInfo.description,
|
||||||
seriesCount: dicomInfo.seriesNum,
|
seriesCount: dicomInfo.seriesNum,
|
||||||
@@ -1254,58 +1254,60 @@ export default {
|
|||||||
try {
|
try {
|
||||||
let o = v.instanceList[ii]
|
let o = v.instanceList[ii]
|
||||||
let name = `${v.instanceList[ii].file.webkitRelativePath}_${v.instanceList[ii].instanceUid}`
|
let name = `${v.instanceList[ii].file.webkitRelativePath}_${v.instanceList[ii].instanceUid}`
|
||||||
if (o.isReUpload) {
|
// if (o.isReUpload) {
|
||||||
dicomInfo.failedFileCount++
|
// dicomInfo.failedFileCount++
|
||||||
dicomInfo.uploadFileSize += o.file.size
|
// dicomInfo.uploadFileSize += o.file.size
|
||||||
Record.Existed.push(name)
|
// Record.Existed.push(name)
|
||||||
Record.FileCount++
|
// Record.FileCount++
|
||||||
} else if (o.myPath) {
|
// }
|
||||||
instanceList.push({
|
// else if (o.myPath) {
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
// instanceList.push({
|
||||||
seriesInstanceUid: v.seriesUid,
|
// studyInstanceUid: dicomInfo.studyUid,
|
||||||
SOPClassUID: o.SOPClassUID,
|
// seriesInstanceUid: v.seriesUid,
|
||||||
TransferSytaxUID: o.TransferSytaxUID,
|
// SOPClassUID: o.SOPClassUID,
|
||||||
MediaStorageSOPInstanceUID:
|
// TransferSytaxUID: o.TransferSytaxUID,
|
||||||
o.MediaStorageSOPInstanceUID,
|
// MediaStorageSOPInstanceUID:
|
||||||
MediaStorageSOPClassUID:
|
// o.MediaStorageSOPInstanceUID,
|
||||||
o.MediaStorageSOPClassUID,
|
// MediaStorageSOPClassUID:
|
||||||
sopInstanceUid: o.instanceUid,
|
// o.MediaStorageSOPClassUID,
|
||||||
instanceNumber: o.instanceNumber,
|
// sopInstanceUid: o.instanceUid,
|
||||||
instanceTime: o.instanceTime,
|
// instanceNumber: o.instanceNumber,
|
||||||
imageRows: o.imageRows,
|
// instanceTime: o.instanceTime,
|
||||||
imageColumns: o.imageColumns,
|
// imageRows: o.imageRows,
|
||||||
sliceLocation: o.sliceLocation,
|
// imageColumns: o.imageColumns,
|
||||||
sliceThickness: o.sliceThickness,
|
// sliceLocation: o.sliceLocation,
|
||||||
numberOfFrames: o.numberOfFrames,
|
// sliceThickness: o.sliceThickness,
|
||||||
pixelSpacing: o.pixelSpacing,
|
// numberOfFrames: o.numberOfFrames,
|
||||||
imagerPixelSpacing: o.imagerPixelSpacing,
|
// pixelSpacing: o.pixelSpacing,
|
||||||
frameOfReferenceUID: o.frameOfReferenceUID,
|
// imagerPixelSpacing: o.imagerPixelSpacing,
|
||||||
windowCenter: o.windowCenter,
|
// frameOfReferenceUID: o.frameOfReferenceUID,
|
||||||
windowWidth: o.windowWidth,
|
// windowCenter: o.windowCenter,
|
||||||
path: o.myPath,
|
// windowWidth: o.windowWidth,
|
||||||
FileSize: o.FileSize,
|
// path: o.myPath,
|
||||||
|
// FileSize: o.FileSize,
|
||||||
|
|
||||||
PhotometricInterpretation:
|
// PhotometricInterpretation:
|
||||||
o.PhotometricInterpretation,
|
// o.PhotometricInterpretation,
|
||||||
BitsAllocated: o.BitsAllocated,
|
// BitsAllocated: o.BitsAllocated,
|
||||||
PixelRepresentation: o.PixelRepresentation,
|
// PixelRepresentation: o.PixelRepresentation,
|
||||||
RescaleIntercept: o.RescaleIntercept,
|
// RescaleIntercept: o.RescaleIntercept,
|
||||||
RescaleSlope: o.RescaleSlope,
|
// RescaleSlope: o.RescaleSlope,
|
||||||
ImagePositionPatient: o.ImagePositionPatient,
|
// ImagePositionPatient: o.ImagePositionPatient,
|
||||||
ImageOrientationPatient:
|
// ImageOrientationPatient:
|
||||||
o.ImageOrientationPatient,
|
// o.ImageOrientationPatient,
|
||||||
SequenceOfUltrasoundRegions:
|
// SequenceOfUltrasoundRegions:
|
||||||
o.SequenceOfUltrasoundRegions,
|
// o.SequenceOfUltrasoundRegions,
|
||||||
FrameTime: o.FrameTime,
|
// FrameTime: o.FrameTime,
|
||||||
CorrectedImage: o.CorrectedImage,
|
// CorrectedImage: o.CorrectedImage,
|
||||||
Units: o.Units,
|
// Units: o.Units,
|
||||||
DecayCorrection: o.DecayCorrection,
|
// DecayCorrection: o.DecayCorrection,
|
||||||
EncapsulatedDocument: o.EncapsulatedDocument,
|
// EncapsulatedDocument: o.EncapsulatedDocument,
|
||||||
})
|
// })
|
||||||
Record.Uploaded.push(name)
|
// Record.Uploaded.push(name)
|
||||||
dicomInfo.failedFileCount++
|
// dicomInfo.failedFileCount++
|
||||||
Record.FileCount++
|
// Record.FileCount++
|
||||||
} else {
|
// }
|
||||||
|
// else {
|
||||||
let path = `/${params.trialId}/Image/${params.subjectId
|
let path = `/${params.trialId}/Image/${params.subjectId
|
||||||
}/${params.subjectVisitId}/${dicomInfo.visitTaskId
|
}/${params.subjectVisitId}/${dicomInfo.visitTaskId
|
||||||
}/${scope.getGuid(
|
}/${scope.getGuid(
|
||||||
@@ -1331,7 +1333,18 @@ export default {
|
|||||||
file: o.file,
|
file: o.file,
|
||||||
speed: true,
|
speed: true,
|
||||||
},
|
},
|
||||||
null,
|
scope.isReading && scope.StudyInstanceUID ? {
|
||||||
|
AnonymizeFixedList: [
|
||||||
|
{
|
||||||
|
Element: '000D',
|
||||||
|
Group: '0020',
|
||||||
|
ReplaceValue: scope.StudyInstanceUID,
|
||||||
|
Id: 'StudyInstanceUID'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
AnonymizeNotFixedList: [],
|
||||||
|
DicomStoreInfo: {}
|
||||||
|
} : null,
|
||||||
(percentage, checkpoint, lastPer) => {
|
(percentage, checkpoint, lastPer) => {
|
||||||
dicomInfo.uploadFileSize +=
|
dicomInfo.uploadFileSize +=
|
||||||
checkpoint.size * (percentage - lastPer)
|
checkpoint.size * (percentage - lastPer)
|
||||||
@@ -1397,7 +1410,7 @@ export default {
|
|||||||
}
|
}
|
||||||
if (res && res.url) {
|
if (res && res.url) {
|
||||||
instanceList.push({
|
instanceList.push({
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.isReading && scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
seriesInstanceUid: v.seriesUid,
|
seriesInstanceUid: v.seriesUid,
|
||||||
sopInstanceUid: o.instanceUid,
|
sopInstanceUid: o.instanceUid,
|
||||||
SOPClassUID: o.SOPClassUID,
|
SOPClassUID: o.SOPClassUID,
|
||||||
@@ -1446,7 +1459,7 @@ export default {
|
|||||||
Record.Failed.push(name)
|
Record.Failed.push(name)
|
||||||
Record.FileCount++
|
Record.FileCount++
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
resolve1()
|
resolve1()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
@@ -1464,7 +1477,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
params.study.seriesList.push({
|
params.study.seriesList.push({
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.isReading && scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
seriesInstanceUid: v.seriesUid,
|
seriesInstanceUid: v.seriesUid,
|
||||||
seriesNumber: v.seriesNumber,
|
seriesNumber: v.seriesNumber,
|
||||||
seriesTime: v.seriesTime,
|
seriesTime: v.seriesTime,
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
:append-to-body="true" class="uploadDicomAndNonedicom">
|
:append-to-body="true" class="uploadDicomAndNonedicom">
|
||||||
<span slot="title">{{ title }}</span>
|
<span slot="title">{{ title }}</span>
|
||||||
<el-tabs type="border-card" v-model="activeName">
|
<el-tabs type="border-card" v-model="activeName">
|
||||||
<el-tab-pane :label="$t('uploadDicomAndNonedicom:label:dicom')" name="dicom" v-if="!IsImageSegment">
|
<el-tab-pane :label="$t('uploadDicomAndNonedicom:label:dicom')" name="dicom">
|
||||||
<dicomFile v-if="activeName === 'dicom'" :SubjectId="SubjectId" :SubjectCode="SubjectCode"
|
<dicomFile v-if="activeName === 'dicom'" :SubjectId="SubjectId" :SubjectCode="SubjectCode"
|
||||||
:Criterion="Criterion" :TaskId="VisitTaskId" :isUpload.sync="isUpload"
|
:Criterion="Criterion" :TaskId="VisitTaskId" :isUpload.sync="isUpload"
|
||||||
:isReadingTaskViewInOrder="isReadingTaskViewInOrder" :IsImageSegment="IsImageSegment" :forbid="forbid"
|
:isReadingTaskViewInOrder="isReadingTaskViewInOrder" :IsImageSegment="IsImageSegment" :forbid="forbid"
|
||||||
:isReading="isReading" />
|
:isReading="isReading" :StudyInstanceUID="StudyInstanceUID" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('uploadDicomAndNonedicom:label:nonedicom')" name="nonedicom">
|
<el-tab-pane :label="$t('uploadDicomAndNonedicom:label:nonedicom')" name="nonedicom">
|
||||||
<nonedicomFile v-if="activeName === 'nonedicom'" :SubjectId="SubjectId" :SubjectCode="SubjectCode"
|
<nonedicomFile v-if="activeName === 'nonedicom'" :SubjectId="SubjectId" :SubjectCode="SubjectCode"
|
||||||
@@ -63,6 +63,10 @@ export default {
|
|||||||
isReading: {
|
isReading: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
},
|
||||||
|
StudyInstanceUID: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -72,16 +76,10 @@ export default {
|
|||||||
isUpload: false,
|
isUpload: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
IsImageSegment() {
|
|
||||||
if (this.IsImageSegment) this.activeName = 'nonedicom'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.title = `Upload Images:${this.SubjectCode}(${this.Criterion.TrialReadingCriterionName})`
|
this.title = `Upload Images:${this.SubjectCode}(${this.Criterion.TrialReadingCriterionName})`
|
||||||
if (this.IsImageSegment) this.title = `Upload Images:${this.SubjectCode}`
|
if (this.IsImageSegment) this.title = `Upload Images:${this.SubjectCode}`
|
||||||
if (this.isReadingTaskViewInOrder === 0) this.title = ''
|
if (this.isReadingTaskViewInOrder === 0) this.title = ''
|
||||||
if (this.IsImageSegment) this.activeName = 'nonedicom'
|
|
||||||
store.dispatch('trials/setUnLock', true)
|
store.dispatch('trials/setUnLock', true)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -113,9 +113,7 @@
|
|||||||
<el-button circle icon="el-icon-upload2" :title="$t('upload:nonedicom:button:upload')" v-if="!forbid"
|
<el-button circle icon="el-icon-upload2" :title="$t('upload:nonedicom:button:upload')" v-if="!forbid"
|
||||||
@click.native.prevent="handleUpload(scope.row)" :disabled="isReading && !isDownloaded" />
|
@click.native.prevent="handleUpload(scope.row)" :disabled="isReading && !isDownloaded" />
|
||||||
<!--删除--->
|
<!--删除--->
|
||||||
<el-button :disabled="scope.row.UploadedFileCount <= 0 ||
|
<el-button circle icon="el-icon-delete" :title="$t('upload:nonedicom:button:delete')"
|
||||||
scope.row.ReadingTaskState === 2
|
|
||||||
" circle icon="el-icon-delete" :title="$t('upload:nonedicom:button:delete')"
|
|
||||||
@click.stop="remove(scope.row)" />
|
@click.stop="remove(scope.row)" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -224,7 +222,6 @@ import {
|
|||||||
import { preArchiveStudy, uploadNoneDicomFile } from '@/api/trials'
|
import { preArchiveStudy, uploadNoneDicomFile } from '@/api/trials'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
import { unzipRaw } from 'unzipit';
|
|
||||||
let defaultSearchData = () => {
|
let defaultSearchData = () => {
|
||||||
return {
|
return {
|
||||||
SubjectId: null,
|
SubjectId: null,
|
||||||
@@ -333,34 +330,6 @@ export default {
|
|||||||
store.dispatch('trials/setUnLock', false)
|
store.dispatch('trials/setUnLock', false)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async readZipFileListRaw(zipFile) {
|
|
||||||
try {
|
|
||||||
// 1. 使用 unzipRaw 读取原始条目列表
|
|
||||||
const { entries } = await unzipRaw(zipFile);
|
|
||||||
|
|
||||||
// 2. entries 是一个数组,需要手动处理
|
|
||||||
const fileList = entries.map(entry => {
|
|
||||||
// 3. 使用 TextDecoder 指定编码来解码文件名
|
|
||||||
// 例如,对于简体中文 ZIP 包,可以使用 'gbk'
|
|
||||||
const decoder = new TextDecoder('gbk'); // 或者 'big5'
|
|
||||||
const name = decoder.decode(entry.nameBytes);
|
|
||||||
|
|
||||||
return {
|
|
||||||
path: name,
|
|
||||||
name: name.split('/').pop(),
|
|
||||||
isDirectory: entry.isDirectory,
|
|
||||||
size: entry.size,
|
|
||||||
lastModified: entry.lastModDate
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('解码后的文件列表:', fileList);
|
|
||||||
return fileList;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('读取 ZIP 失败:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async getList() {
|
async getList() {
|
||||||
try {
|
try {
|
||||||
this.searchData.SubjectId = this.SubjectId
|
this.searchData.SubjectId = this.SubjectId
|
||||||
@@ -382,10 +351,7 @@ export default {
|
|||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.list = res.Result
|
this.list = res.Result
|
||||||
this.relationInfo = res.OtherInfo
|
this.relationInfo = res.OtherInfo
|
||||||
this.isDownloaded = this.Criterion && this.Criterion.CriterionType && (
|
this.isDownloaded = res.OtherInfo.IsIRImageDownloaded
|
||||||
this.Criterion.CriterionType == 19 ||
|
|
||||||
this.Criterion.CriterionType == 20
|
|
||||||
) ? res.OtherInfo.IsIRImageDownloaded : true
|
|
||||||
this.faccept = []
|
this.faccept = []
|
||||||
this.relationInfo.ImageFormatList.forEach((item) => {
|
this.relationInfo.ImageFormatList.forEach((item) => {
|
||||||
this.faccept.push(`.${item}`)
|
this.faccept.push(`.${item}`)
|
||||||
@@ -399,15 +365,11 @@ export default {
|
|||||||
// 扫描待上传文件
|
// 扫描待上传文件
|
||||||
beginScanFiles(e) {
|
beginScanFiles(e) {
|
||||||
var files = [...e.target.files]
|
var files = [...e.target.files]
|
||||||
var sameFiles = [], zipFiles = [], f = false
|
var sameFiles = []
|
||||||
files.forEach((file) => {
|
files.forEach((file) => {
|
||||||
var extendName = file.name
|
var extendName = file.name
|
||||||
.substring(file.name.lastIndexOf('.'))
|
.substring(file.name.lastIndexOf('.'))
|
||||||
.toLocaleLowerCase()
|
.toLocaleLowerCase()
|
||||||
if (extendName === '.zip' && this.IsImageSegment) {
|
|
||||||
if (file.name.indexOf('筛选期') > -1 || file.name.indexOf('研究结束') > -1) f = true
|
|
||||||
zipFiles.push(file)
|
|
||||||
}
|
|
||||||
if (
|
if (
|
||||||
this.faccept.indexOf(extendName) !== -1 &&
|
this.faccept.indexOf(extendName) !== -1 &&
|
||||||
this.fileList.findIndex((v) => v.name === file.name) > -1
|
this.fileList.findIndex((v) => v.name === file.name) > -1
|
||||||
@@ -415,16 +377,6 @@ export default {
|
|||||||
sameFiles.push(file.name)
|
sameFiles.push(file.name)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (zipFiles.length > 0) {
|
|
||||||
zipFiles.forEach(async file => {
|
|
||||||
let list = await this.readZipFileListRaw(file)
|
|
||||||
if (!f) f = list.some(i => i.path.indexOf('筛选期') > -1 || i.path.indexOf('研究结束') > -1)
|
|
||||||
list = null
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (f) return this.$confirm(this.$t("trials:uploadNonDicoms:confirm:zipNameNonCompliant"), '', {
|
|
||||||
type: "warning"
|
|
||||||
})
|
|
||||||
var scope = this
|
var scope = this
|
||||||
if (sameFiles.length > 0) {
|
if (sameFiles.length > 0) {
|
||||||
const h = this.$createElement
|
const h = this.$createElement
|
||||||
|
|||||||
@@ -228,12 +228,6 @@ export const constantRoutes = [
|
|||||||
component: () => import('@/views/research/form'),
|
component: () => import('@/views/research/form'),
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: '/researchLog',
|
|
||||||
name: 'researchLog',
|
|
||||||
component: () => import('@/views/research/form'),
|
|
||||||
hidden: true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/researchLogin_m',
|
path: '/researchLogin_m',
|
||||||
name: 'researchLogin_m',
|
name: 'researchLogin_m',
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export const anonymization = function (file, config) {
|
|||||||
try {
|
try {
|
||||||
const reader = new FileReader()
|
const reader = new FileReader()
|
||||||
let AnonymizeFixedList = config.AnonymizeFixedList
|
let AnonymizeFixedList = config.AnonymizeFixedList
|
||||||
|
console.log(AnonymizeFixedList, 'AnonymizeFixedList')
|
||||||
let AnonymizeNotFixedList = config.AnonymizeNotFixedList
|
let AnonymizeNotFixedList = config.AnonymizeNotFixedList
|
||||||
let DicomStoreInfo = config.DicomStoreInfo
|
let DicomStoreInfo = config.DicomStoreInfo
|
||||||
reader.onload = async (event) => {
|
reader.onload = async (event) => {
|
||||||
@@ -15,9 +16,11 @@ export const anonymization = function (file, config) {
|
|||||||
let dataset = dcmjs.data.DicomMessage.readFile(buffer)
|
let dataset = dcmjs.data.DicomMessage.readFile(buffer)
|
||||||
for (var i = 0; i < AnonymizeFixedList.length; i++) {
|
for (var i = 0; i < AnonymizeFixedList.length; i++) {
|
||||||
let AnonymizeFixed = AnonymizeFixedList[i]
|
let AnonymizeFixed = AnonymizeFixedList[i]
|
||||||
if (!dataset.dict.hasOwnProperty(`${AnonymizeFixed.Group + AnonymizeFixed.Element}`)) continue
|
if (!dataset.dict.hasOwnProperty(`${AnonymizeFixed.Group + AnonymizeFixed.Element}`) && !dataset.meta.hasOwnProperty(`${AnonymizeFixed.Group + AnonymizeFixed.Element}`)) continue
|
||||||
if (dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element]) {
|
if (dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element]) {
|
||||||
dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element].Value[0] = AnonymizeFixed.ReplaceValue
|
dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element].Value[0] = AnonymizeFixed.ReplaceValue
|
||||||
|
} else if (dataset.meta[AnonymizeFixed.Group + AnonymizeFixed.Element]) {
|
||||||
|
dataset.meta[AnonymizeFixed.Group + AnonymizeFixed.Element].Value[0] = AnonymizeFixed.ReplaceValue
|
||||||
} else {
|
} else {
|
||||||
dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element] = {
|
dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element] = {
|
||||||
vr: AnonymizeFixed.ValueRepresentation,
|
vr: AnonymizeFixed.ValueRepresentation,
|
||||||
@@ -60,7 +63,7 @@ export const anonymization = function (file, config) {
|
|||||||
let newDicomFile = dataset.write() // fragmentMultiframe 原始数据是否进行分割
|
let newDicomFile = dataset.write() // fragmentMultiframe 原始数据是否进行分割
|
||||||
const bufferArray = new Uint8Array(newDicomFile)
|
const bufferArray = new Uint8Array(newDicomFile)
|
||||||
const blob = new Blob([bufferArray], { type: 'application/octet-stream' })
|
const blob = new Blob([bufferArray], { type: 'application/octet-stream' })
|
||||||
resolve({ blob, pixelDataElement })
|
resolve({ blob, pixelDataElement, Modality: dataset.dict['00080060'].Value[0] })
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(file, 'warning')
|
console.log(file, 'warning')
|
||||||
console.log(err)
|
console.log(err)
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ export const dcmUpload = async function (data, config, progressFn, fileInfo) {
|
|||||||
let res = await Vue.prototype.OSSclient.multipartUpload(Object.assign(data, { file: blob.blob }), progressFn, fileInfo)
|
let res = await Vue.prototype.OSSclient.multipartUpload(Object.assign(data, { file: blob.blob }), progressFn, fileInfo)
|
||||||
resolve({
|
resolve({
|
||||||
...res,
|
...res,
|
||||||
image: blob.pixelDataElement
|
image: blob.pixelDataElement,
|
||||||
|
Modality: blob.Modality
|
||||||
})
|
})
|
||||||
// let OSSclientA = await OSSclient
|
// let OSSclientA = await OSSclient
|
||||||
// let blob = await encoder(file)
|
// let blob = await encoder(file)
|
||||||
|
|||||||
+4
-4
@@ -40,7 +40,7 @@ async function ossGenerateSTS() {
|
|||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
let _vm = router.default.app
|
let _vm = router.default.app
|
||||||
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload') {
|
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload' && _vm._route.path !== '/readingDicoms' && _vm._route.path !== '/showdicom') {
|
||||||
var objectItem = objectName.split('/')
|
var objectItem = objectName.split('/')
|
||||||
// objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
// objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
||||||
objectItem[objectItem.length - 1] = `${objectItem[objectItem.length - 1].substring(
|
objectItem[objectItem.length - 1] = `${objectItem[objectItem.length - 1].substring(
|
||||||
@@ -97,7 +97,7 @@ async function ossGenerateSTS() {
|
|||||||
OSSclient = new OSS(Vue.prototype.OSSclientConfig);
|
OSSclient = new OSS(Vue.prototype.OSSclientConfig);
|
||||||
}
|
}
|
||||||
let _vm = router.default.app
|
let _vm = router.default.app
|
||||||
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload') {
|
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload' && _vm._route.path !== '/readingDicoms' && _vm._route.path !== '/showdicom') {
|
||||||
var objectItem = data.path.split('/')
|
var objectItem = data.path.split('/')
|
||||||
// objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
// objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
||||||
objectItem[objectItem.length - 1] = `${objectItem[objectItem.length - 1].substring(
|
objectItem[objectItem.length - 1] = `${objectItem[objectItem.length - 1].substring(
|
||||||
@@ -151,7 +151,7 @@ async function ossGenerateSTS() {
|
|||||||
try {
|
try {
|
||||||
var name = objectName.split('/')[objectName.split('/').length - 1]
|
var name = objectName.split('/')[objectName.split('/').length - 1]
|
||||||
let _vm = router.default.app
|
let _vm = router.default.app
|
||||||
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload') {
|
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload' && _vm._route.path !== '/readingDicoms' && _vm._route.path !== '/showdicom') {
|
||||||
var objectItem = objectName.split('/')
|
var objectItem = objectName.split('/')
|
||||||
objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
||||||
objectName = objectItem.join('/')
|
objectName = objectItem.join('/')
|
||||||
@@ -225,7 +225,7 @@ function uploadAWS(aws, data, progress, fileInfo) {
|
|||||||
const { file, path } = data;
|
const { file, path } = data;
|
||||||
if (!file || !path) return reject('file and path be required');
|
if (!file || !path) return reject('file and path be required');
|
||||||
let _vm = router.default.app
|
let _vm = router.default.app
|
||||||
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload') {
|
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload' && _vm._route.path !== '/readingDicoms' && _vm._route.path !== '/showdicom') {
|
||||||
var objectItem = data.path.split('/')
|
var objectItem = data.path.split('/')
|
||||||
// objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
// objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
||||||
objectItem[objectItem.length - 1] = `${objectItem[objectItem.length - 1].substring(
|
objectItem[objectItem.length - 1] = `${objectItem[objectItem.length - 1].substring(
|
||||||
|
|||||||
+3
-9
@@ -11,10 +11,10 @@ function zipFiles(zipName, files) {
|
|||||||
store.dispatch('trials/setUnLock', true)
|
store.dispatch('trials/setUnLock', true)
|
||||||
files = formatFiles(files)
|
files = formatFiles(files)
|
||||||
// 创建压缩文件输出流
|
// 创建压缩文件输出流
|
||||||
let zipFileOutputStream = streamSaver.createWriteStream(zipName);
|
const zipFileOutputStream = streamSaver.createWriteStream(zipName);
|
||||||
// 创建下载文件流
|
// 创建下载文件流
|
||||||
const fileIterator = files.values();
|
const fileIterator = files.values();
|
||||||
let readableZipStream = new ZIP({
|
const readableZipStream = new ZIP({
|
||||||
async pull(ctrl) {
|
async pull(ctrl) {
|
||||||
const fileInfo = fileIterator.next();
|
const fileInfo = fileIterator.next();
|
||||||
if (fileInfo.done) {//迭代终止
|
if (fileInfo.done) {//迭代终止
|
||||||
@@ -41,13 +41,9 @@ function zipFiles(zipName, files) {
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
console.log("同步下载打包结束时间:" + new Date());
|
console.log("同步下载打包结束时间:" + new Date());
|
||||||
store.dispatch('trials/setUnLock', false)
|
store.dispatch('trials/setUnLock', false)
|
||||||
readableZipStream = null;
|
|
||||||
zipFileOutputStream = null;
|
|
||||||
resolve(true)
|
resolve(true)
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
readableZipStream = null;
|
|
||||||
zipFileOutputStream = null;
|
|
||||||
resolve(false)
|
resolve(false)
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -65,16 +61,14 @@ async function updateFile(file, name) {
|
|||||||
return new Promise(async resolve => {
|
return new Promise(async resolve => {
|
||||||
try {
|
try {
|
||||||
store.dispatch('trials/setUnLock', true)
|
store.dispatch('trials/setUnLock', true)
|
||||||
let fileOutputStream = streamSaver.createWriteStream(name);
|
const fileOutputStream = streamSaver.createWriteStream(name);
|
||||||
// file = decodeUtf8(file);
|
// file = decodeUtf8(file);
|
||||||
let res = await fetch(file);
|
let res = await fetch(file);
|
||||||
res.body.pipeTo(fileOutputStream).then(() => {
|
res.body.pipeTo(fileOutputStream).then(() => {
|
||||||
store.dispatch('trials/setUnLock', true)
|
store.dispatch('trials/setUnLock', true)
|
||||||
fileOutputStream = null;
|
|
||||||
resolve(true)
|
resolve(true)
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
fileOutputStream = null;
|
|
||||||
resolve(false)
|
resolve(false)
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
const WHITELIST = ['/', "/curriculumVitae", 'researchDetail_m', '/researchForm', '/ReviewersResearch', '/login', '/link_expired', '/error', '/resetpassword', '/recompose', '/email-recompose', '/trialStats', '/showdicom', '/imagesShare', '/audit', '/preview', '/researchLogin', '/researchLogin_m', '/blindResumeInfo', '/trialsResume', '/joinVerify', '/showNoneDicoms', '/noneDicomReading', '/clinicalData', '/readingDicoms', '/readingPage', '/visitDicomReview', '/visitNondicomReview', '/globalReview', '/adReview', '/oncologyReview', '/nonedicoms', '/ecrfList', '/researchLog']
|
const WHITELIST = ['/', "/curriculumVitae", 'researchDetail_m', '/researchForm', '/ReviewersResearch', '/login', '/link_expired', '/error', '/resetpassword', '/recompose', '/email-recompose', '/trialStats', '/showdicom', '/imagesShare', '/audit', '/preview', '/researchLogin', '/researchLogin_m', '/blindResumeInfo', '/trialsResume', '/joinVerify', '/showNoneDicoms', '/noneDicomReading', '/clinicalData', '/readingDicoms', '/readingPage', '/visitDicomReview', '/visitNondicomReview', '/globalReview', '/adReview', '/oncologyReview', '/nonedicoms', '/ecrfList']
|
||||||
export default WHITELIST
|
export default WHITELIST
|
||||||
|
|||||||
@@ -125,7 +125,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="viewerContent">
|
<div class="viewerContent">
|
||||||
<dicom-viewer id="dicomViewer" ref="dicomViewer" style="height:100%" :loading.sync="loading"
|
<dicom-viewer id="dicomViewer" ref="dicomViewer" style="height:100%" :loading.sync="loading"
|
||||||
:modality="modality" :Comparison.sync="isComparison" @loadStudy="loadStudy" />
|
:modality="modality" :Comparison.sync="isComparison" :SeriesList="seriesList"
|
||||||
|
:currentSeriesIndex="currentSeriesIndex" @loadStudy="loadStudy" />
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="viewerRightSidePanel">
|
<!-- <div class="viewerRightSidePanel">
|
||||||
<dicom-tools />
|
<dicom-tools />
|
||||||
@@ -179,7 +180,7 @@ export default {
|
|||||||
description: '',
|
description: '',
|
||||||
seriesCount: 0,
|
seriesCount: 0,
|
||||||
seriesList: [],
|
seriesList: [],
|
||||||
currentSeriesIndex: -1,
|
currentSeriesIndex: 0,
|
||||||
arr: [],
|
arr: [],
|
||||||
activeName: 'first',
|
activeName: 'first',
|
||||||
tpList: [],
|
tpList: [],
|
||||||
@@ -253,6 +254,11 @@ export default {
|
|||||||
})
|
})
|
||||||
workSpeedclose(true)
|
workSpeedclose(true)
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
currentSeriesIndex() {
|
||||||
|
console.log(this.currentSeriesIndex, 'currentSeriesIndex')
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async updateImageResizePath(data) {
|
async updateImageResizePath(data) {
|
||||||
try {
|
try {
|
||||||
@@ -353,13 +359,14 @@ export default {
|
|||||||
i.ImageId = imageId
|
i.ImageId = imageId
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId
|
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId ? this.$router.currentRoute.query.subjectVisitId : item.SubjectVisitId
|
||||||
var studyId = this.$router.currentRoute.query.studyId
|
var studyId = this.$router.currentRoute.query.studyId
|
||||||
var trialId = this.$router.currentRoute.query.trialId
|
var trialId = this.$router.currentRoute.query.trialId
|
||||||
seriesList.push({
|
seriesList.push({
|
||||||
trialId,
|
trialId,
|
||||||
subjectVisitId,
|
subjectVisitId,
|
||||||
studyId,
|
studyId,
|
||||||
|
subjectId: item.SubjectId,
|
||||||
imageIds: imageIds,
|
imageIds: imageIds,
|
||||||
instanceInfoList: item.InstanceInfoList,
|
instanceInfoList: item.InstanceInfoList,
|
||||||
seriesId: item.Id,
|
seriesId: item.Id,
|
||||||
@@ -415,12 +422,13 @@ export default {
|
|||||||
i.ImageId = imageId
|
i.ImageId = imageId
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId
|
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId ? this.$router.currentRoute.query.subjectVisitId : item.SubjectVisitId
|
||||||
var studyId = this.$router.currentRoute.query.studyId
|
var studyId = this.$router.currentRoute.query.studyId
|
||||||
var trialId = this.$router.currentRoute.query.trialId
|
var trialId = this.$router.currentRoute.query.trialId
|
||||||
seriesList.push({
|
seriesList.push({
|
||||||
trialId,
|
trialId,
|
||||||
subjectVisitId,
|
subjectVisitId,
|
||||||
|
subjectId: item.SubjectId,
|
||||||
studyId,
|
studyId,
|
||||||
imageIds: imageIds,
|
imageIds: imageIds,
|
||||||
instanceInfoList: item.InstanceInfoList,
|
instanceInfoList: item.InstanceInfoList,
|
||||||
@@ -1197,6 +1205,7 @@ export default {
|
|||||||
border-color: #213a54 !important;
|
border-color: #213a54 !important;
|
||||||
background-color: #213a54;
|
background-color: #213a54;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame_content_active {
|
.frame_content_active {
|
||||||
border-color: #213a54 !important;
|
border-color: #213a54 !important;
|
||||||
background-color: #213a54;
|
background-color: #213a54;
|
||||||
|
|||||||
@@ -6,7 +6,9 @@
|
|||||||
<div class="login-body">
|
<div class="login-body">
|
||||||
<div class="login-l">
|
<div class="login-l">
|
||||||
<div class="login-logo">
|
<div class="login-logo">
|
||||||
<img src="@/assets/zzlogo-usa.png" alt="" class="usa-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 src="@/assets/zzlogo4.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
<div :class="{
|
<div :class="{
|
||||||
'login-image': true,
|
'login-image': true,
|
||||||
@@ -19,14 +21,14 @@
|
|||||||
<div class="login-r">
|
<div class="login-r">
|
||||||
<div class="title-container">
|
<div class="title-container">
|
||||||
<!-- IRC Management System -->
|
<!-- IRC Management System -->
|
||||||
<!-- <div v-if="NODE_ENV === 'usa'"> -->
|
<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>
|
||||||
<!-- <div class="title" v-else>
|
<div class="title" v-else>
|
||||||
<img src="@/assets/system.png" alt=""
|
<img src="@/assets/system.png" alt=""
|
||||||
:style="{ width: isEN ? '180px' : '200px', height: isEN ? '60px' : '65px' }" />
|
:style="{ width: isEN ? '180px' : '200px', height: isEN ? '60px' : '65px' }" />
|
||||||
<div :style="`font-size:${isEN ? '28px' : '35px'}`">{{ $t('login:title:system') }}</div>
|
<div :style="`font-size:${isEN ? '28px' : '35px'}`">{{ $t('login:title:system') }}</div>
|
||||||
</div> -->
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on"
|
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on"
|
||||||
label-position="left">
|
label-position="left">
|
||||||
@@ -96,10 +98,10 @@
|
|||||||
$t('login:message:PrivacyPolicyName') }}</span>
|
$t('login:message:PrivacyPolicyName') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="text-align: right">
|
<div style="text-align: right">
|
||||||
<!-- <TopLang v-if="
|
<TopLang v-if="
|
||||||
VUE_APP_OSS_CONFIG_REGION !== 'oss-us-west-1' &&
|
VUE_APP_OSS_CONFIG_REGION !== 'oss-us-west-1' &&
|
||||||
NODE_ENV !== 'usa'
|
NODE_ENV !== 'usa'
|
||||||
" /> -->
|
" />
|
||||||
<!-- Forget password? -->
|
<!-- 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') }}
|
{{ $t('login:button:forgetPassword') }}
|
||||||
|
|||||||
@@ -1,93 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="log-list">
|
|
||||||
<el-table v-loading="loading" :data="tableData" v-adaptive="{ bottomOffset: 40 }" height="100" style="width: 100%">
|
|
||||||
<el-table-column prop="CreateTime" :label="$t('trials:researchForm:logList:label:CreateTime')" min-width="120"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ scope.row.CreateTime ? moment(scope.row.CreateTime).format('YYYY-MM-DD HH:mm:ss') : '' }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="Name" :label="$t('trials:researchForm:logList:label:Name')" min-width="100"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="UserType" :label="$t('trials:researchForm:logList:label:UserType')" min-width="100"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ scope.row.UserType && $fd('UserType', scope.row.UserType) ? $fd('UserType', scope.row.UserType) : '--' }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="OptType" :label="$t('trials:researchForm:logList:label:OptType')" min-width="100"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ $fd('SiteSurveyOptTyp', scope.row.OptType) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="Json" :label="$t('trials:researchForm:logList:label:Json')" min-width="100"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button v-if="scope.row.Json" type="text" @click="openLog(scope.row)">{{
|
|
||||||
$t('trials:researchForm:logList:label:SurveyForm') }}</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="Reason" :label="$t('trials:researchForm:logList:label:Reason')" min-width="140"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
import { getSiteSurveyLogList } from '@/api/research'
|
|
||||||
import moment from 'moment'
|
|
||||||
import { getToken } from '@/utils/auth'
|
|
||||||
export default {
|
|
||||||
name: 'LogList',
|
|
||||||
props: {
|
|
||||||
trialSiteSurveyId: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: false,
|
|
||||||
tableData: [],
|
|
||||||
moment,
|
|
||||||
openWindow: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.getList()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async getList() {
|
|
||||||
try {
|
|
||||||
this.loading = true
|
|
||||||
let res = await getSiteSurveyLogList({ trialSiteSurveyId: this.trialSiteSurveyId })
|
|
||||||
if (res.IsSuccess) {
|
|
||||||
this.tableData = res.Result
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
} finally {
|
|
||||||
this.loading = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
openLog(row) {
|
|
||||||
if (this.openWindow) {
|
|
||||||
this.openWindow.close()
|
|
||||||
}
|
|
||||||
var token = getToken()
|
|
||||||
var path = `/researchLog?trialId=${this.$route.query.trialId}&trialSiteSurveyId=${this.trialSiteSurveyId}&logId=${row.Id}&TokenKey=${token}`
|
|
||||||
|
|
||||||
this.openWindow = window.open(path, '_blank')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.log-list {
|
|
||||||
height: 100%;
|
|
||||||
min-height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
+7
-129
@@ -35,10 +35,6 @@
|
|||||||
<el-button v-if="userTypeEnumInt === 0" type="primary" size="small" @click="handleHistory">
|
<el-button v-if="userTypeEnumInt === 0" type="primary" size="small" @click="handleHistory">
|
||||||
{{ $t('trials:researchForm:button:historicalRecord') }}
|
{{ $t('trials:researchForm:button:historicalRecord') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- 操作日志 -->
|
|
||||||
<el-button type="primary" size="small" v-if="!isLog" @click="viewLog">
|
|
||||||
{{ $t('trials:researchForm:button:log') }}
|
|
||||||
</el-button>
|
|
||||||
<!-- 退出 -->
|
<!-- 退出 -->
|
||||||
<el-button v-if="userTypeEnumInt === 0" type="primary" size="small" @click="handleBack">
|
<el-button v-if="userTypeEnumInt === 0" type="primary" size="small" @click="handleBack">
|
||||||
{{ $t('trials:researchForm:button:loginOut') }}
|
{{ $t('trials:researchForm:button:loginOut') }}
|
||||||
@@ -137,37 +133,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<div class="history-dialog-content">
|
<div style="height:100%;margin:0;">
|
||||||
<HistoricalRecord :trial-id="trialId" :site-id="siteId" :trial-site-survey-id="trialSiteSurveyId" />
|
<HistoricalRecord :trial-id="trialId" :site-id="siteId" :trial-site-survey-id="trialSiteSurveyId" />
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<el-dialog v-if="logVisible" :visible.sync="logVisible"
|
|
||||||
:custom-class="isFullscreen ? 'full-log-dialog-container' : 'log-dialog-container'" :close-on-click-modal="false"
|
|
||||||
:fullscreen="isFullscreen" :show-close="false" width="60%" append-to-body>
|
|
||||||
<span slot="title" class="dialog-footer">
|
|
||||||
<div style="display: flex;flex-direction: row;justify-content: space-between;">
|
|
||||||
<div>
|
|
||||||
{{ $t('trials:researchForm:button:log') }}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<svg-icon :icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'"
|
|
||||||
style="vertical-align: baseline;cursor: pointer;font-size: 20px;" @click="toggleLogFullscreen" />
|
|
||||||
<svg-icon icon-class="dClose" style="cursor: pointer;font-size: 25px;margin-left: 10px;"
|
|
||||||
@click="logVisible = false" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
<div class="log-dialog-content">
|
|
||||||
<LogList :trial-site-survey-id="trialSiteSurveyId" />
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { getSiteSurveyInfo, trialSurveySubmit, submissionRejection, getSiteSurveyLogList } from '@/api/research'
|
import { getSiteSurveyInfo, trialSurveySubmit, submissionRejection } from '@/api/research'
|
||||||
import { getQueryString, changeURLStatic } from '@/utils/history.js'
|
import { getQueryString } from '@/utils/history.js'
|
||||||
import BaseInfo from './components/BaseInfo'
|
import BaseInfo from './components/BaseInfo'
|
||||||
import HistoricalParticipant from './components/HistoricalParticipant'
|
import HistoricalParticipant from './components/HistoricalParticipant'
|
||||||
import ParticipantList from './components/ParticipantList'
|
import ParticipantList from './components/ParticipantList'
|
||||||
@@ -175,11 +150,9 @@ import EquipmentList from './components/EquipmentList'
|
|||||||
import { mapMutations } from 'vuex'
|
import { mapMutations } from 'vuex'
|
||||||
import TopLang from './topLang'
|
import TopLang from './topLang'
|
||||||
import HistoricalRecord from './components/HistoricalRecord'
|
import HistoricalRecord from './components/HistoricalRecord'
|
||||||
import LogList from './components/LogList'
|
|
||||||
import store from '@/store'
|
|
||||||
export default {
|
export default {
|
||||||
name: 'QuestionForm',
|
name: 'QuestionForm',
|
||||||
components: { BaseInfo, HistoricalParticipant, ParticipantList, EquipmentList, TopLang, HistoricalRecord, LogList },
|
components: { BaseInfo, HistoricalParticipant, ParticipantList, EquipmentList, TopLang, HistoricalRecord },
|
||||||
props: {
|
props: {
|
||||||
isPreview: {
|
isPreview: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -202,10 +175,7 @@ export default {
|
|||||||
historyVisible: false,
|
historyVisible: false,
|
||||||
siteSurveyNoteInfo: {},
|
siteSurveyNoteInfo: {},
|
||||||
IsSupportUploadFile: false,
|
IsSupportUploadFile: false,
|
||||||
IsOnlyUploadFile: false,
|
IsOnlyUploadFile: false
|
||||||
logVisible: false,
|
|
||||||
isLog: false,
|
|
||||||
logId: null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -221,12 +191,6 @@ export default {
|
|||||||
this.setLanguage(lang)
|
this.setLanguage(lang)
|
||||||
this.$updateDictionary()
|
this.$updateDictionary()
|
||||||
this.trialSiteSurveyId = getQueryString('trialSiteSurveyId')
|
this.trialSiteSurveyId = getQueryString('trialSiteSurveyId')
|
||||||
this.logId = getQueryString('logId')
|
|
||||||
if (this.logId) this.isLog = true
|
|
||||||
if (this.$router.currentRoute.query.TokenKey) {
|
|
||||||
store.dispatch('user/setToken', this.$router.currentRoute.query.TokenKey)
|
|
||||||
changeURLStatic('TokenKey', '')
|
|
||||||
}
|
|
||||||
this.initPage()
|
this.initPage()
|
||||||
if (zzSessionStorage.getItem('userTypeEnumInt')) {
|
if (zzSessionStorage.getItem('userTypeEnumInt')) {
|
||||||
this.userTypeEnumInt = zzSessionStorage.getItem('userTypeEnumInt') * 1
|
this.userTypeEnumInt = zzSessionStorage.getItem('userTypeEnumInt') * 1
|
||||||
@@ -234,7 +198,7 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isPM() {
|
isPM() {
|
||||||
return this.hasPermi(['role:pm', 'role:spm', 'role:cpm', 'role:apm']) && this.state !== 3 && this.IsOnlyUploadFile
|
return this.hasPermi(['role:pm', 'role:spm', 'role:cpm', 'role:apm']) && this.state !== 3
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -242,43 +206,6 @@ export default {
|
|||||||
// 初始化页面
|
// 初始化页面
|
||||||
initPage() {
|
initPage() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
if (this.isLog) {
|
|
||||||
getSiteSurveyLogList({ trialSiteSurveyId: this.trialSiteSurveyId, Id: this.logId }).then(r => {
|
|
||||||
if (r.Result && r.Result[0].Json) {
|
|
||||||
let res = {
|
|
||||||
Result: JSON.parse(r.Result[0].Json)
|
|
||||||
}
|
|
||||||
if (res.Result) {
|
|
||||||
// this.trialSiteSurveyEquipmentType = res.Result.TrialInfo.TrialSiteSurveyEquipmentType
|
|
||||||
// this.trialSiteSurveyUserRoles = res.Result.TrialInfo.TrialSiteSurveyUserRoles
|
|
||||||
if (res.Result.SiteSurveyFiledConfig && res.Result.SiteSurveyFiledConfig.ModifyFiledList.length > 0) {
|
|
||||||
this.siteSurveyNoteInfo = res.Result.SiteSurveyFiledConfig.ModifyFiledList.find(i => i.NeedModifyFiled === 'SiteSurveyNote')
|
|
||||||
}
|
|
||||||
this.IsSupportUploadFile = res.Result.SiteSurveyFiledConfig.IsSupportUploadFile
|
|
||||||
this.IsOnlyUploadFile = res.Result.SiteSurveyFiledConfig.IsOnlyUploadFile
|
|
||||||
this.siteSurveyNoteInfo.IsCloseEquipmentSurvey = res.Result.SiteSurveyFiledConfig.IsCloseEquipmentSurvey
|
|
||||||
this.state = 3
|
|
||||||
this.siteId = res.Result.TrialSiteSurvey.TrialSiteId
|
|
||||||
this.$refs['baseResearchInfo'].initForm(res.Result.TrialInfo, res.Result.TrialSiteSurvey, res.Result.SiteSurveyFiledConfig ? res.Result.SiteSurveyFiledConfig.NotShowFieldList : null)
|
|
||||||
var historicalArr = []
|
|
||||||
var newArr = []
|
|
||||||
res.Result.TrialSiteUserSurveyList.map(i => {
|
|
||||||
if (i.IsHistoryUser) {
|
|
||||||
historicalArr.push(i)
|
|
||||||
} else {
|
|
||||||
newArr.push(i)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
this.$refs['historicalParticipant'].initList(historicalArr, res.Result.TrialSiteSurvey)
|
|
||||||
this.$refs['researchParticipants'].initList(newArr, res.Result.TrialSiteSurvey)
|
|
||||||
this.$refs['researchEquipments'].initList(res.Result.TrialSiteEquipmentSurveyList, res.Result.TrialSiteSurvey, res.Result.SiteSurveyFiledConfig.EquipmentControlFieldList)
|
|
||||||
this.isExistIncorrect = res.Result.TrialSiteUserSurveyList.every(item => item.IsCorrect === false)
|
|
||||||
}
|
|
||||||
this.loading = false
|
|
||||||
}
|
|
||||||
}).catch((err) => { console.log(err); this.loading = false })
|
|
||||||
} else {
|
|
||||||
getSiteSurveyInfo(this.trialId, this.trialSiteSurveyId).then(res => {
|
getSiteSurveyInfo(this.trialId, this.trialSiteSurveyId).then(res => {
|
||||||
if (res.Result) {
|
if (res.Result) {
|
||||||
// this.trialSiteSurveyEquipmentType = res.Result.TrialInfo.TrialSiteSurveyEquipmentType
|
// this.trialSiteSurveyEquipmentType = res.Result.TrialInfo.TrialSiteSurveyEquipmentType
|
||||||
@@ -309,8 +236,6 @@ export default {
|
|||||||
}
|
}
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}).catch(() => { this.loading = false })
|
}).catch(() => { this.loading = false })
|
||||||
}
|
|
||||||
|
|
||||||
},
|
},
|
||||||
// 提交
|
// 提交
|
||||||
handleSubmit(type) {
|
handleSubmit(type) {
|
||||||
@@ -422,14 +347,7 @@ export default {
|
|||||||
handleHistory() {
|
handleHistory() {
|
||||||
this.isFullscreen = false
|
this.isFullscreen = false
|
||||||
this.historyVisible = true
|
this.historyVisible = true
|
||||||
},
|
}
|
||||||
toggleLogFullscreen() {
|
|
||||||
this.isFullscreen = !this.isFullscreen
|
|
||||||
},
|
|
||||||
viewLog() {
|
|
||||||
this.isFullscreen = false
|
|
||||||
this.logVisible = true
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -481,45 +399,5 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.history-dialog-content,
|
|
||||||
.log-dialog-content {
|
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-dialog-content {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style lang="scss">
|
|
||||||
.full-log-dialog-container,
|
|
||||||
.log-dialog-container {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.full-log-dialog-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.full-log-dialog-container .el-dialog__body {
|
|
||||||
flex: 1;
|
|
||||||
min-height: 0;
|
|
||||||
padding: 10px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-dialog-container .el-dialog__body {
|
|
||||||
height: calc(100% - 80px);
|
|
||||||
padding: 10px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.full-log-dialog-container .log-dialog-content,
|
|
||||||
.log-dialog-container .log-dialog-content {
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -155,6 +155,17 @@ export default {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
IdCard: [
|
IdCard: [
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
let reg = new RegExp(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/, 'ig')
|
||||||
|
if (value && !reg.test(value)) {
|
||||||
|
callback(new Error(this.$t('common:ruleMessage:pattern')))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
max: 400,
|
max: 400,
|
||||||
message: this.$t('form:rules:maxLength:400'),
|
message: this.$t('form:rules:maxLength:400'),
|
||||||
@@ -162,6 +173,17 @@ export default {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
BankPhoneNum: [
|
BankPhoneNum: [
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
let reg = new RegExp(/^\d{11}$/, 'i')
|
||||||
|
if (value && !reg.test(value)) {
|
||||||
|
callback(new Error(this.$t('common:ruleMessage:pattern')))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
max: 400,
|
max: 400,
|
||||||
message: this.$t('form:rules:maxLength:400'),
|
message: this.$t('form:rules:maxLength:400'),
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
:maxlength="400"
|
:maxlength="400"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- <el-form-item
|
<el-form-item
|
||||||
:label="$t('system:Setting:label:Blind NameCN')"
|
:label="$t('system:Setting:label:Blind NameCN')"
|
||||||
prop="BlindNameCN"
|
prop="BlindNameCN"
|
||||||
>
|
>
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
style="width: 300px"
|
style="width: 300px"
|
||||||
:maxlength="400"
|
:maxlength="400"
|
||||||
/>
|
/>
|
||||||
</el-form-item> -->
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="$t('system:Setting:label:Blind Publications')"
|
:label="$t('system:Setting:label:Blind Publications')"
|
||||||
prop="BlindPublications"
|
prop="BlindPublications"
|
||||||
|
|||||||
@@ -211,6 +211,17 @@ export default {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
IdCard: [
|
IdCard: [
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
let reg = new RegExp(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/, 'ig')
|
||||||
|
if (value && !reg.test(value)) {
|
||||||
|
callback(new Error(this.$t('common:ruleMessage:pattern')))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
max: 400,
|
max: 400,
|
||||||
message: this.$t('form:rules:maxLength:400'),
|
message: this.$t('form:rules:maxLength:400'),
|
||||||
@@ -218,6 +229,17 @@ export default {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
BankPhoneNum: [
|
BankPhoneNum: [
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
let reg = new RegExp(/^\d{11}$/, 'i')
|
||||||
|
if (value && !reg.test(value)) {
|
||||||
|
callback(new Error(this.$t('common:ruleMessage:pattern')))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
max: 400,
|
max: 400,
|
||||||
message: this.$t('form:rules:maxLength:400'),
|
message: this.$t('form:rules:maxLength:400'),
|
||||||
|
|||||||
@@ -19,12 +19,12 @@
|
|||||||
>
|
>
|
||||||
{{ DATA.BlindName }}
|
{{ DATA.BlindName }}
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- <el-form-item
|
<el-form-item
|
||||||
:label="$t('system:Setting:label:Blind NameCN')"
|
:label="$t('system:Setting:label:Blind NameCN')"
|
||||||
style="width: 45%"
|
style="width: 45%"
|
||||||
>
|
>
|
||||||
{{ DATA.BlindNameCN }}
|
{{ DATA.BlindNameCN }}
|
||||||
</el-form-item> -->
|
</el-form-item>
|
||||||
<div style="display: flex; font-size: 14px; margin-bottom: 22px">
|
<div style="display: flex; font-size: 14px; margin-bottom: 22px">
|
||||||
<span style="display: inline-block; width: 120px; color: #000">{{
|
<span style="display: inline-block; width: 120px; color: #000">{{
|
||||||
$t('system:Setting:label:Blind Publications')
|
$t('system:Setting:label:Blind Publications')
|
||||||
@@ -109,8 +109,8 @@
|
|||||||
<div class="form_title">
|
<div class="form_title">
|
||||||
{{ $t('system:Setting:title:Blinded information') }}
|
{{ $t('system:Setting:title:Blinded information') }}
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-row>
|
<el-row>
|
||||||
<el-col :span="12"> -->
|
<el-col :span="12">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="$t('system:Setting:label:Blind Name')"
|
:label="$t('system:Setting:label:Blind Name')"
|
||||||
prop="BlindName"
|
prop="BlindName"
|
||||||
@@ -121,7 +121,7 @@
|
|||||||
:maxlength="400"
|
:maxlength="400"
|
||||||
></el-input>
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- </el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="$t('system:Setting:label:Blind NameCN')"
|
:label="$t('system:Setting:label:Blind NameCN')"
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
></el-input>
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row> -->
|
</el-row>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="$t('system:Setting:label:Blind Publications')"
|
:label="$t('system:Setting:label:Blind Publications')"
|
||||||
prop="BlindPublications"
|
prop="BlindPublications"
|
||||||
|
|||||||
@@ -591,9 +591,32 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="file" v-if="isAll && hasFile">
|
<div class="file" v-if="isAll && hasFile">
|
||||||
<div class="curriculum" v-if="resumeListEN && resumeListEN.length > 0">
|
<div
|
||||||
|
class="curriculum"
|
||||||
|
v-if="
|
||||||
|
(resumeListCN && resumeListCN.length > 0) ||
|
||||||
|
(resumeListEN && resumeListEN.length > 0)
|
||||||
|
"
|
||||||
|
>
|
||||||
<div class="title">{{ $t('curriculumVitae:curriculum:title') }}</div>
|
<div class="title">{{ $t('curriculumVitae:curriculum:title') }}</div>
|
||||||
<div class="fileBox">
|
<div class="fileBox">
|
||||||
|
<div
|
||||||
|
class="file_title"
|
||||||
|
v-if="resumeListCN && resumeListCN.length > 0"
|
||||||
|
>
|
||||||
|
{{ $t('curriculumVitae:curriculum:fileTitle:CN') }}
|
||||||
|
</div>
|
||||||
|
<template v-if="true">
|
||||||
|
<div class="file" v-for="item in resumeListCN" :key="item.Id">
|
||||||
|
<div class="name" :title="item.FileName">{{ item.FileName }}</div>
|
||||||
|
<i
|
||||||
|
class="el-icon-download"
|
||||||
|
:title="$t('common:button:download')"
|
||||||
|
@click.stop="handlePreview(item)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="noData" v-else>{{ $t('curriculumVitae:noData') }}</div>
|
||||||
<div
|
<div
|
||||||
class="file_title"
|
class="file_title"
|
||||||
v-if="resumeListEN && resumeListEN.length > 0"
|
v-if="resumeListEN && resumeListEN.length > 0"
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="trials-navbar" style="position: relative">
|
<div class="trials-navbar" style="position: relative">
|
||||||
<div class="leftMenu">
|
<div class="leftMenu">
|
||||||
<img src="@/assets/title-logo.png" alt="" class="title-logo" />
|
<img v-if="NODE_ENV === 'usa'" src="@/assets/title-logo.png" alt="" class="title-logo" />
|
||||||
<!-- <span style="white-space: nowrap" v-if="NODE_ENV !== 'usa'">
|
<img v-else src="@/assets/system.png" alt="" style="width: 150px;height: 50px;margin-bottom: -7px;" />
|
||||||
|
<span style="white-space: nowrap" v-if="NODE_ENV !== 'usa'">
|
||||||
|
<!-- 中心影像系统(EICS) -->
|
||||||
{{ $t('trials:trials:title:eics') }}
|
{{ $t('trials:trials:title:eics') }}
|
||||||
</span> -->
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="center-menu">
|
<div class="center-menu">
|
||||||
<NoticeMarquee />
|
<NoticeMarquee />
|
||||||
|
|||||||
@@ -1,311 +0,0 @@
|
|||||||
<template>
|
|
||||||
<BaseContainer>
|
|
||||||
<!-- 搜索框 -->
|
|
||||||
<template slot="search-container">
|
|
||||||
<el-form :inline="true">
|
|
||||||
<!-- 中心编号 -->
|
|
||||||
<el-form-item :label="$t('trials:researchStaff:table:siteId')">
|
|
||||||
<el-select v-model="searchData.TrialSiteId" clearable filterable style="width:120px;">
|
|
||||||
<el-option v-for="(item, index) of siteOptions" :key="index" :label="item.TrialSiteCode"
|
|
||||||
:value="item.TrialSiteId" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 中心名称 -->
|
|
||||||
<el-form-item :label="$t('trials:researchStaff:table:siteName')">
|
|
||||||
<el-input v-model="searchData.TrialSiteName" class="mr" clearable style="width:120px;" />
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 状态 -->
|
|
||||||
<el-form-item :label="$t('trials:researchRecord:table:status')">
|
|
||||||
<el-select v-model="searchData.State" clearable filterable style="width: 120px">
|
|
||||||
<el-option v-for="(item, index) of $d.ResearchRecord" :key="index" :label="item.label"
|
|
||||||
:value="item.value" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 是否废除 -->
|
|
||||||
<!-- <el-form-item :label="$t('trials:researchRecord:table:isDeleted')">
|
|
||||||
<el-select v-model="searchData.IsDeleted" clearable filterable style="width: 120px">
|
|
||||||
<el-option v-for="item of $d.YesOrNo" v-show="item.raw.ValueCN !== '无'" :key="`IsDeleted${item.value}`"
|
|
||||||
:label="item.label" :value="item.value" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item> -->
|
|
||||||
<el-form-item>
|
|
||||||
<!-- 查询 -->
|
|
||||||
<el-button type="primary" icon="el-icon-search" @click="handleSearch">
|
|
||||||
{{ $t('common:button:search') }}
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 重置 -->
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
|
|
||||||
{{ $t('common:button:reset') }}
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 导出 -->
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-download" :disabled="list.length === 0" @click="handleExport">
|
|
||||||
{{ $t('common:button:export') }}
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template slot="main-container">
|
|
||||||
<el-table ref="equipmentsList" v-loading="loading" v-adaptive="{ bottomOffset: 55 }" :data="list" stripe
|
|
||||||
height="100" @sort-change="handleSortByColumn">
|
|
||||||
<el-table-column type="index" width="50" />
|
|
||||||
<!-- 中心编号 -->
|
|
||||||
<el-table-column prop="TrialSiteCode" :label="$t('trials:researchStaff:table:siteId')" show-overflow-tooltip
|
|
||||||
sortable="custom" min-width="100">
|
|
||||||
</el-table-column>
|
|
||||||
<!-- 中心名称 -->
|
|
||||||
<el-table-column prop="TrialSiteName" :label="$t('trials:researchStaff:table:siteName')" show-overflow-tooltip
|
|
||||||
sortable="custom" min-width="120">
|
|
||||||
</el-table-column>
|
|
||||||
<!-- 状态 -->
|
|
||||||
<el-table-column prop="State" :label="$t('trials:researchRecord:table:status')" min-width="150"
|
|
||||||
sortable="custom" show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-tag v-if="scope.row.State === 0" type="primary">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
<el-tag v-if="scope.row.State === 1" type="info">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
<el-tag v-if="scope.row.State === 2" type="warning">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
<el-tag v-if="scope.row.State === 3" type="danger">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<!-- 是否废除 -->
|
|
||||||
<!-- <el-table-column prop="IsDeleted" :label="$t('trials:researchRecord:table:isDeleted')" min-width="100"
|
|
||||||
sortable="custom" show-overflow-tooltip>
|
|
||||||
<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="UserName" :label="$t('trials:researchForm:form:contactor')" show-overflow-tooltip
|
|
||||||
sortable="custom" min-width="100" />
|
|
||||||
<!-- 联系电话 -->
|
|
||||||
<el-table-column prop="Phone" :label="$t('trials:researchForm:form:contactorPhone')" show-overflow-tooltip
|
|
||||||
sortable="custom" min-width="100" />
|
|
||||||
<!-- 联系邮箱 -->
|
|
||||||
<el-table-column prop="Email" :label="$t('trials:researchForm:form:contactorEmail')" show-overflow-tooltip
|
|
||||||
sortable="custom" min-width="100" />
|
|
||||||
<template v-if="equipmentControlFieldList.includes('EquipmentTypeEnum')">
|
|
||||||
<!-- 扫描设备 -->
|
|
||||||
<el-table-column prop="EquipmentTypeEnum" :label="$t('trials:equiptResearch:form:equipment')" min-width="120"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ scope.row.OtherEquipmentType ? scope.row.OtherEquipmentType :
|
|
||||||
$fd('SiteSurvey_ScanEquipmentType', scope.row.EquipmentTypeEnum) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</template>
|
|
||||||
<template v-if="equipmentControlFieldList.includes('Parameters')">
|
|
||||||
<!-- 扫描参数 -->
|
|
||||||
<el-table-column prop="Parameters" :label="$t('trials:equiptResearch:form:param')" min-width="100"
|
|
||||||
show-overflow-tooltip />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="equipmentControlFieldList.includes('ManufacturerType')">
|
|
||||||
<!-- 扫描仪器制造商名称 -->
|
|
||||||
<el-table-column min-width="120" prop="ManufacturerType"
|
|
||||||
:label="$t('trials:equiptResearch:form:manufacturer')" show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ scope.row.ManufacturerName ? scope.row.ManufacturerName : $fd('ManufacturerType',
|
|
||||||
scope.row.ManufacturerType) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="equipmentControlFieldList.includes('ScannerType')">
|
|
||||||
<!-- 扫描仪型号 -->
|
|
||||||
<el-table-column min-width="120" prop="ScannerType" :label="$t('trials:equiptResearch:form:model')"
|
|
||||||
show-overflow-tooltip />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="equipmentControlFieldList.includes('MagneticFieldStrengthType')">
|
|
||||||
<!-- 磁场强度 -->
|
|
||||||
<el-table-column min-width="120" prop="MagneticFieldStrengthType"
|
|
||||||
:label="$t('trials:equiptResearch:form:MagneticFieldStrengthType')" show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ $fd('MagneticFieldStrengthType', scope.row.MagneticFieldStrengthType) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="equipmentControlFieldList.includes('BodyCoilChannelCount')">
|
|
||||||
<!-- 体部线圈通道数 -->
|
|
||||||
<el-table-column min-width="120" prop="BodyCoilChannelCount"
|
|
||||||
:label="$t('trials:equiptResearch:form:BodyCoilChannelCount')" show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ $fd('BodyCoilChannelCount', scope.row.BodyCoilChannelCount) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="equipmentControlFieldList.includes('HasDedicatedPdfFatQuantificationSequence')">
|
|
||||||
<!-- 是否具备专用的PDFF脂肪定量序列(CSE-MRI序列) -->
|
|
||||||
<el-table-column min-width="120" prop="HasDedicatedPdfFatQuantificationSequence"
|
|
||||||
:label="$t('trials:equiptResearch:form:HasDedicatedPdfFatQuantificationSequence')" show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ $fd('YesOrNo', scope.row.HasDedicatedPdfFatQuantificationSequence) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="equipmentControlFieldList.includes('PdfFatQuantificationSequenceType')">
|
|
||||||
<!-- 专用的PDFF脂肪定量序列类型 -->
|
|
||||||
<el-table-column min-width="120" prop="PdfFatQuantificationSequenceType"
|
|
||||||
:label="$t('trials:equiptResearch:form:PdfFatQuantificationSequenceType')" show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ scope.row.OtherSequenceSpecification ? scope.row.OtherSequenceSpecification :
|
|
||||||
$fd('PdfFatQuantificationSequenceType', scope.row.PdfFatQuantificationSequenceType) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="equipmentControlFieldList.includes('HasT2R2Correction')">
|
|
||||||
<!-- 是否包含 T2/R2 校正(用于铁沉积校正) -->
|
|
||||||
<el-table-column min-width="120" prop="HasT2R2Correction"
|
|
||||||
:label="$t('trials:equiptResearch:form:HasT2R2Correction')" show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ $fd('YesOrNo', scope.row.HasT2R2Correction) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="equipmentControlFieldList.includes('CanFullyExportPdfParameterMapsAndRawDicom')">
|
|
||||||
<!-- 是否可完整导出 PDFF 参数图及全部原始 DICOM 数据 -->
|
|
||||||
<el-table-column prop="CanFullyExportPdfParameterMapsAndRawDicom"
|
|
||||||
:label="$t('trials:equiptResearch:form:CanFullyExportPdfParameterMapsAndRawDicom')" min-width="120"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ $fd('YesOrNo', scope.row.CanFullyExportPdfParameterMapsAndRawDicom) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="equipmentControlFieldList.includes('Note')">
|
|
||||||
<!-- 备注 -->
|
|
||||||
<el-table-column min-width="120" prop="Note" :label="$t('trials:equiptResearch:form:remark')"
|
|
||||||
show-overflow-tooltip />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<!-- 分页组件 -->
|
|
||||||
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
|
|
||||||
@pagination="getList" />
|
|
||||||
</template>
|
|
||||||
</BaseContainer>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
import { getTrialSiteSelect } from '@/api/trials'
|
|
||||||
import { getSiteSurveyEquipmentList } from '@/api/research'
|
|
||||||
import BaseContainer from '@/components/BaseContainer'
|
|
||||||
import Pagination from '@/components/Pagination'
|
|
||||||
import { getSiteSurveyEquipmentList_Export } from '@/api/export'
|
|
||||||
const searchDataDefault = () => {
|
|
||||||
return {
|
|
||||||
SortField: '',
|
|
||||||
State: "",
|
|
||||||
Asc: true,
|
|
||||||
PageIndex: 1,
|
|
||||||
PageSize: 20,
|
|
||||||
TrialId: '',
|
|
||||||
TrialSiteId: '',
|
|
||||||
TrialSiteName: ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default {
|
|
||||||
name: 'Equipments',
|
|
||||||
components: { BaseContainer, Pagination },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
searchData: searchDataDefault(),
|
|
||||||
loading: false,
|
|
||||||
list: [],
|
|
||||||
total: 0,
|
|
||||||
trialId: '',
|
|
||||||
otherInfo: {},
|
|
||||||
siteOptions: [],
|
|
||||||
equipmentControlFieldList: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.trialId = this.$route.query.trialId
|
|
||||||
this.getList()
|
|
||||||
this.getSite()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async handleExport() {
|
|
||||||
await getSiteSurveyEquipmentList_Export(this.searchData)
|
|
||||||
},
|
|
||||||
async getList() {
|
|
||||||
try {
|
|
||||||
this.loading = true
|
|
||||||
this.searchData.TrialId = this.trialId
|
|
||||||
let res = await getSiteSurveyEquipmentList(this.searchData)
|
|
||||||
if (res.IsSuccess) {
|
|
||||||
this.list = res.Result.CurrentPageData
|
|
||||||
this.total = res.Result.TotalCount
|
|
||||||
this.otherInfo = res.OtherInfo
|
|
||||||
const { EquipmentControlFieldList } = res.OtherInfo
|
|
||||||
this.equipmentControlFieldList = []
|
|
||||||
EquipmentControlFieldList.forEach(item => {
|
|
||||||
this.equipmentControlFieldList.push(item.FiledName)
|
|
||||||
})
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.equipmentsList.doLayout()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
} finally {
|
|
||||||
this.loading = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 获取site下拉框数据
|
|
||||||
async getSite() {
|
|
||||||
try {
|
|
||||||
let res = await getTrialSiteSelect(this.trialId)
|
|
||||||
this.siteOptions = res.Result
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 重置
|
|
||||||
handleReset() {
|
|
||||||
this.searchData = searchDataDefault()
|
|
||||||
this.getList()
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.list.clearSort()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 查询
|
|
||||||
handleSearch() {
|
|
||||||
this.getList()
|
|
||||||
},
|
|
||||||
// 排序
|
|
||||||
handleSortByColumn(column) {
|
|
||||||
if (column.order === 'ascending') {
|
|
||||||
this.searchData.Asc = true
|
|
||||||
} else {
|
|
||||||
this.searchData.Asc = false
|
|
||||||
}
|
|
||||||
this.searchData.SortField = column.prop
|
|
||||||
this.getList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,356 +0,0 @@
|
|||||||
<template>
|
|
||||||
<BaseContainer>
|
|
||||||
<!-- 搜索框 -->
|
|
||||||
<template slot="search-container">
|
|
||||||
<el-form :inline="true">
|
|
||||||
<!-- 中心编号 -->
|
|
||||||
<el-form-item :label="$t('trials:researchStaff:table:siteId')">
|
|
||||||
<el-select v-model="searchData.TrialSiteId" clearable filterable style="width:120px;">
|
|
||||||
<el-option v-for="(item, index) of siteOptions" :key="index" :label="item.TrialSiteCode"
|
|
||||||
:value="item.TrialSiteId" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 中心名称 -->
|
|
||||||
<el-form-item :label="$t('trials:researchStaff:table:siteName')">
|
|
||||||
<el-input v-model="searchData.TrialSiteName" class="mr" clearable style="width:120px;" />
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 状态 -->
|
|
||||||
<el-form-item :label="$t('trials:researchRecord:table:status')">
|
|
||||||
<el-select v-model="searchData.State" clearable filterable style="width: 120px">
|
|
||||||
<el-option v-for="(item, index) of $d.ResearchRecord" :key="index" :label="item.label"
|
|
||||||
:value="item.value" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 是否废除 -->
|
|
||||||
<!-- <el-form-item :label="$t('trials:researchRecord:table:isDeleted')">
|
|
||||||
<el-select v-model="searchData.IsDeleted" clearable filterable style="width: 120px">
|
|
||||||
<el-option v-for="item of $d.YesOrNo" v-show="item.raw.ValueCN !== '无'" :key="`IsDeleted${item.value}`"
|
|
||||||
:label="item.label" :value="item.value" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item> -->
|
|
||||||
<el-form-item>
|
|
||||||
<!-- 查询 -->
|
|
||||||
<el-button type="primary" icon="el-icon-search" @click="handleSearch">
|
|
||||||
{{ $t('common:button:search') }}
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 重置 -->
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
|
|
||||||
{{ $t('common:button:reset') }}
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 导出 -->
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-download" :disabled="list.length === 0" @click="handleExport">
|
|
||||||
{{ $t('common:button:export') }}
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template slot="main-container">
|
|
||||||
<el-table ref="questionsList" v-loading="loading" v-adaptive="{ bottomOffset: 55 }" :data="list" stripe
|
|
||||||
height="100" @sort-change="handleSortByColumn">
|
|
||||||
<el-table-column type="index" width="50" />
|
|
||||||
|
|
||||||
<!-- 项目编号 -->
|
|
||||||
<!-- <el-table-column
|
|
||||||
prop="TrialCode"
|
|
||||||
:label="$t('trials:researchForm:form:trialId')"
|
|
||||||
show-overflow-tooltip
|
|
||||||
sortable="custom"
|
|
||||||
min-width="100"
|
|
||||||
/> -->
|
|
||||||
<!-- 试验方案号 -->
|
|
||||||
<!-- <el-table-column
|
|
||||||
prop="ResearchProgramNo"
|
|
||||||
:label="$t('trials:researchForm:form:researchNo')"
|
|
||||||
show-overflow-tooltip
|
|
||||||
sortable="custom"
|
|
||||||
min-width="100"
|
|
||||||
/> -->
|
|
||||||
<!-- 试验名称 -->
|
|
||||||
<!-- <el-table-column
|
|
||||||
prop="ExperimentName"
|
|
||||||
:label="$t('trials:researchForm:form:researchName')"
|
|
||||||
show-overflow-tooltip
|
|
||||||
sortable="custom"
|
|
||||||
min-width="100"
|
|
||||||
/> -->
|
|
||||||
<!-- 适应症类型 -->
|
|
||||||
<!-- <el-table-column
|
|
||||||
prop="IndicationType"
|
|
||||||
:label="$t('trials:researchForm:form:decleareType')"
|
|
||||||
show-overflow-tooltip
|
|
||||||
sortable="custom"
|
|
||||||
min-width="100"
|
|
||||||
/> -->
|
|
||||||
<!-- 适应症类型 -->
|
|
||||||
<!-- <el-table-column
|
|
||||||
prop="IndicationType"
|
|
||||||
:label="$t('trials:researchForm:form:decleareType')"
|
|
||||||
show-overflow-tooltip
|
|
||||||
sortable="custom"
|
|
||||||
min-width="100"
|
|
||||||
/> -->
|
|
||||||
|
|
||||||
<!-- 中心编号 -->
|
|
||||||
<el-table-column prop="TrialSiteCode" :label="$t('trials:researchStaff:table:siteId')" show-overflow-tooltip
|
|
||||||
sortable="custom" min-width="100" />
|
|
||||||
<!-- 中心名称 -->
|
|
||||||
<el-table-column prop="SiteName" :label="$t('trials:researchStaff:table:siteName')" show-overflow-tooltip
|
|
||||||
sortable="custom" min-width="100" />
|
|
||||||
<!-- 状态 -->
|
|
||||||
<el-table-column prop="State" :label="$t('trials:researchRecord:table:status')" min-width="150"
|
|
||||||
sortable="custom" show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-tag v-if="scope.row.State === 0" type="primary">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
<el-tag v-if="scope.row.State === 1" type="info">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
<el-tag v-if="scope.row.State === 2" type="warning">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
<el-tag v-if="scope.row.State === 3" type="danger">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<!-- 是否废除 -->
|
|
||||||
<!-- <el-table-column prop="IsDeleted" :label="$t('trials:researchRecord:table:isDeleted')" min-width="100"
|
|
||||||
sortable="custom" show-overflow-tooltip>
|
|
||||||
<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="UserName" :label="$t('trials:researchForm:form:contactor')" show-overflow-tooltip
|
|
||||||
sortable="custom" min-width="100" />
|
|
||||||
<!-- 联系电话 -->
|
|
||||||
<el-table-column prop="Phone" :label="$t('trials:researchForm:form:contactorPhone')" show-overflow-tooltip
|
|
||||||
sortable="custom" min-width="100" />
|
|
||||||
<!-- 联系邮箱 -->
|
|
||||||
<el-table-column prop="Email" :label="$t('trials:researchForm:form:contactorEmail')" show-overflow-tooltip
|
|
||||||
sortable="custom" min-width="100" />
|
|
||||||
<el-table-column v-show="otherInfo.IsSupportUploadFile" prop="SiteSurveyFile.FileName"
|
|
||||||
:label="$t('trials:researchForm:form:SiteSurveyFile')" show-overflow-tooltip min-width="100">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button v-if="scope.row.SiteSurveyFile && scope.row.SiteSurveyFile.FileName" type="text"
|
|
||||||
@click="viewFile(scope.row.SiteSurveyFile)">
|
|
||||||
{{ scope.row.SiteSurveyFile.FileName }}
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<template v-if="!notShowFieldList.includes('AverageEngravingCycle')">
|
|
||||||
<!-- 平均刻盘周期(天) -->
|
|
||||||
<el-table-column prop="AverageEngravingCycle" :label="$t('trials:researchForm:form:engravingCycle')"
|
|
||||||
show-overflow-tooltip />
|
|
||||||
</template>
|
|
||||||
<template v-if="!notShowFieldList.includes('IsRoutineMRIPDEE')">
|
|
||||||
<!-- MRI-PDFF 是否为本中心该适应症的常规诊疗检查项目? -->
|
|
||||||
<el-table-column prop="IsRoutineMRIPDEE" :label="$t('trials:researchForm:form:IsRoutineMRIPDEE')"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ $fd('YesOrNo', scope.row.IsRoutineMRIPDEE) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</template>
|
|
||||||
<template
|
|
||||||
v-if="!notShowFieldList.includes('MRIPDFFScanTime') || !notShowFieldList.includes('MRIPDFFLeadTime') || !notShowFieldList.includes('MRIPDFFOther')">
|
|
||||||
<!-- MRI-PDFF 检查的检测周期(含单次检查时长、预约等待时长等) -->
|
|
||||||
<!-- <el-table-column :label="$t('trials:researchForm:form:IsRoutineMRIPDEE')"> -->
|
|
||||||
<!-- 单次检查时长(分钟) -->
|
|
||||||
<el-table-column v-show="!notShowFieldList.includes('MRIPDFFScanTime')" prop="MRIPDFFScanTime"
|
|
||||||
:label="$t('trials:researchForm:form:MRIPDFFScanTime')" show-overflow-tooltip />
|
|
||||||
<!-- 平均预约等待时长(天) -->
|
|
||||||
<el-table-column v-show="!notShowFieldList.includes('MRIPDFFLeadTime')" prop="MRIPDFFLeadTime"
|
|
||||||
:label="$t('trials:researchForm:form:MRIPDFFLeadTime')" show-overflow-tooltip />
|
|
||||||
<!-- 特殊情况备注-->
|
|
||||||
<el-table-column v-show="!notShowFieldList.includes('MRIPDFFOther')" prop="MRIPDFFOther"
|
|
||||||
:label="$t('trials:researchForm:form:MRIPDFFOther')" show-overflow-tooltip />
|
|
||||||
<!-- </el-table-column> -->
|
|
||||||
</template>
|
|
||||||
<template
|
|
||||||
v-if="!notShowFieldList.includes('IsAuthorizeRadiologistsParticipate') || !notShowFieldList.includes('AssignFixedTechnologists')">
|
|
||||||
<!-- 如已选择研究者评估,项目是否会授权影像科老师参与本试验?如不单独授权,是否可在试验中保持 1-2 名固定技师操作? -->
|
|
||||||
<el-table-column prop="IsAuthorize" :label="$t('trials:researchForm:form:IsAuthorize')" show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span v-if="scope.row.IsAuthorizeRadiologistsParticipate">
|
|
||||||
{{ $t('trials:researchForm:form:IsAuthorizeRadiologistsParticipate') }}
|
|
||||||
</span>
|
|
||||||
<span v-else-if="scope.row.AssignFixedTechnologists">
|
|
||||||
{{ $t('trials:researchForm:form:AssignFixedTechnologists') }}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</template>
|
|
||||||
<template v-if="!notShowFieldList.includes('IsConfirmImagingTechnologist')">
|
|
||||||
<!-- 请确认参与本项目影像采集的影像技师具备对应的资质(如:“技师证”,对应设备的“大型设备上岗证”) -->
|
|
||||||
<el-table-column prop="IsConfirmImagingTechnologist" :label="$t('trials:researchForm:form:isQualified')"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ $fd('YesOrNo', scope.row.IsConfirmImagingTechnologist) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</template>
|
|
||||||
<template v-if="!notShowFieldList.includes('NotConfirmReson')">
|
|
||||||
<!-- 原因 -->
|
|
||||||
<el-table-column prop="NotConfirmReson" :label="$t('trials:researchForm:form:notQualifiedReason')"
|
|
||||||
show-overflow-tooltip />
|
|
||||||
</template>
|
|
||||||
<template v-if="!notShowFieldList.includes('EfficacyEvaluatorType')">
|
|
||||||
<!-- 研究单位疗效评估人员类型 -->
|
|
||||||
<el-table-column prop="EfficacyEvaluatorType" :label="$t('trials:researchForm:form:staffType')"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ $fd('EfficacyEvaluatorType', scope.row.EfficacyEvaluatorType) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</template>
|
|
||||||
<template v-if="!notShowFieldList.includes('IsFollowStudyParameters')">
|
|
||||||
<!-- 是否严格按照研究单位影像手册参数完成图像采集 -->
|
|
||||||
<el-table-column prop="IsFollowStudyParameters" :label="$t('trials:researchForm:form:isFollowStudyParam')"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ $fd('YesOrNo', scope.row.IsFollowStudyParameters) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</template>
|
|
||||||
<template v-if="!notShowFieldList.includes('NotFollowReson')">
|
|
||||||
<!-- 不能严格按照研究单位影像手册参数采集图像原因 -->
|
|
||||||
<el-table-column prop="NotFollowReson" :label="$t('trials:researchForm:form:notFollowStudyParam')"
|
|
||||||
show-overflow-tooltip />
|
|
||||||
</template>
|
|
||||||
<template v-if="!notShowFieldList.includes('ISStrictManualBurnFlag')">
|
|
||||||
<!-- 是否严格按照影像手册参数完成刻盘 -->
|
|
||||||
<el-table-column prop="ISStrictManualBurnFlag" :label="$t('trials:researchForm:form:ISStrictManualBurnFlag')"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ $fd('YesOrNo', scope.row.ISStrictManualBurnFlag) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</template>
|
|
||||||
<template v-if="!notShowFieldList.includes('NotStrictManualBurnFlagReason')">
|
|
||||||
<!-- 不能严格按照影像手册参数完成刻盘原因 -->
|
|
||||||
<el-table-column prop="NotStrictManualBurnFlagReason"
|
|
||||||
:label="$t('trials:researchForm:form:NotStrictManualBurnFlagReason')" show-overflow-tooltip />
|
|
||||||
</template>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<!-- 分页组件 -->
|
|
||||||
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
|
|
||||||
@pagination="getList" />
|
|
||||||
</template>
|
|
||||||
</BaseContainer>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
import { getTrialSiteSelect } from '@/api/trials'
|
|
||||||
import { getSiteSurveyInfoList } from '@/api/research'
|
|
||||||
import BaseContainer from '@/components/BaseContainer'
|
|
||||||
import Pagination from '@/components/Pagination'
|
|
||||||
import { getSiteSurveyInfoList_Export } from '@/api/export'
|
|
||||||
const searchDataDefault = () => {
|
|
||||||
return {
|
|
||||||
SortField: '',
|
|
||||||
Asc: true,
|
|
||||||
State: "",
|
|
||||||
PageIndex: 1,
|
|
||||||
PageSize: 20,
|
|
||||||
TrialId: '',
|
|
||||||
TrialSiteId: '',
|
|
||||||
TrialSiteName: ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default {
|
|
||||||
name: 'Equipments',
|
|
||||||
components: { BaseContainer, Pagination },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
searchData: searchDataDefault(),
|
|
||||||
loading: false,
|
|
||||||
list: [],
|
|
||||||
total: 0,
|
|
||||||
trialId: '',
|
|
||||||
otherInfo: {},
|
|
||||||
siteOptions: [],
|
|
||||||
notShowFieldList: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.trialId = this.$route.query.trialId
|
|
||||||
this.getList()
|
|
||||||
this.getSite()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async handleExport() {
|
|
||||||
await getSiteSurveyInfoList_Export(this.searchData)
|
|
||||||
},
|
|
||||||
async getList() {
|
|
||||||
try {
|
|
||||||
this.loading = true
|
|
||||||
this.searchData.TrialId = this.trialId
|
|
||||||
let res = await getSiteSurveyInfoList(this.searchData)
|
|
||||||
if (res.IsSuccess) {
|
|
||||||
this.list = res.Result.CurrentPageData
|
|
||||||
this.total = res.Result.TotalCount
|
|
||||||
this.otherInfo = res.OtherInfo
|
|
||||||
this.notShowFieldList = res.OtherInfo.NotShowFieldList
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.questionsList.doLayout()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
} finally {
|
|
||||||
this.loading = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 获取site下拉框数据
|
|
||||||
async getSite() {
|
|
||||||
try {
|
|
||||||
let res = await getTrialSiteSelect(this.trialId)
|
|
||||||
this.siteOptions = res.Result
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
viewFile(siteSurveyFile) {
|
|
||||||
this.$preview({
|
|
||||||
path: siteSurveyFile.Path,
|
|
||||||
type: siteSurveyFile.FileType,
|
|
||||||
title: siteSurveyFile.FileName,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 重置
|
|
||||||
handleReset() {
|
|
||||||
this.searchData = searchDataDefault()
|
|
||||||
this.getList()
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.list.clearSort()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 查询
|
|
||||||
handleSearch() {
|
|
||||||
this.getList()
|
|
||||||
},
|
|
||||||
// 排序
|
|
||||||
handleSortByColumn(column) {
|
|
||||||
if (column.order === 'ascending') {
|
|
||||||
this.searchData.Asc = true
|
|
||||||
} else {
|
|
||||||
this.searchData.Asc = false
|
|
||||||
}
|
|
||||||
this.searchData.SortField = column.prop
|
|
||||||
this.getList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,733 +0,0 @@
|
|||||||
<template>
|
|
||||||
<BaseContainer>
|
|
||||||
<!-- 搜索框 -->
|
|
||||||
<template slot="search-container">
|
|
||||||
<el-form :inline="true">
|
|
||||||
<!-- 中心 -->
|
|
||||||
<el-form-item :label="$t('trials:researchRecord:table:siteId')">
|
|
||||||
<el-select v-model="searchData.TrialSiteId" clearable filterable style="width: 120px">
|
|
||||||
<el-option v-for="(item, index) of siteOptions" :key="index" :label="item.TrialSiteCode"
|
|
||||||
:value="item.TrialSiteId" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 联系人 -->
|
|
||||||
<el-form-item :label="$t('trials:researchRecord:table:contactor')">
|
|
||||||
<el-input v-model="searchData.UserKeyInfo" class="mr" clearable :placeholder="`${$t(
|
|
||||||
'trials:researchRecord:placeholder:contactorInfo'
|
|
||||||
)}`" style="width: 140px" />
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 初审人 -->
|
|
||||||
<el-form-item :label="$t('trials:researchRecord:table:preliminaryUser')">
|
|
||||||
<el-input v-model="searchData.PreliminaryUserName" class="mr" clearable style="width: 140px" />
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 审核人 -->
|
|
||||||
<el-form-item :label="$t('trials:researchRecord:table:ReviewerUser')">
|
|
||||||
<el-input v-model="searchData.ReviewerUserName" class="mr" clearable style="width: 140px" />
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 状态 -->
|
|
||||||
<!-- <el-form-item :label="$t('trials:researchRecord:table:status')">
|
|
||||||
<el-select v-model="searchData.State" clearable filterable style="width: 120px">
|
|
||||||
<el-option v-for="(item, index) of $d.ResearchRecord" :key="index" :label="item.label"
|
|
||||||
:value="item.value" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item> -->
|
|
||||||
<!-- 是否废除 -->
|
|
||||||
<el-form-item :label="$t('trials:researchRecord:table:isDeleted')">
|
|
||||||
<el-select v-model="searchData.IsDeleted" clearable filterable style="width: 120px">
|
|
||||||
<el-option v-for="item of $d.YesOrNo" v-show="item.raw.ValueCN !== '无'" :key="`IsDeleted${item.value}`"
|
|
||||||
:label="item.label" :value="item.value" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 更新时间 -->
|
|
||||||
<el-form-item :label="$t('trials:researchRecord:table:updateTime')">
|
|
||||||
<el-date-picker v-model="searchData.DateRange" type="daterange" value-format="yyyy-MM-dd" format="yyyy-MM-dd"
|
|
||||||
style="width: 250px" />
|
|
||||||
</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-button type="primary" @click="handleExport">
|
|
||||||
{{ $t('common:button:export') }}
|
|
||||||
</el-button>
|
|
||||||
<!-- 中心人员 -->
|
|
||||||
<el-button v-show="searchData.State === 3"
|
|
||||||
v-hasPermi="['trials:trials-panel:attachments:site-research:summary-record']" type="primary"
|
|
||||||
icon="el-icon-info" @click="showResearchUser">
|
|
||||||
{{ $t('trials:researchRecord:button:researchData') }}
|
|
||||||
</el-button>
|
|
||||||
<!-- 调查表链接 -->
|
|
||||||
<el-button v-show="searchData.State === 0"
|
|
||||||
v-hasPermi="['trials:trials-panel:attachments:site-research:questionnaire-link']" type="primary"
|
|
||||||
icon="el-icon-link" @click="showResearchLink">
|
|
||||||
{{ $t('trials:researchRecord:button:questionLink') }}
|
|
||||||
</el-button>
|
|
||||||
</el-form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template slot="main-container">
|
|
||||||
<!-- 系统文件列表 -->
|
|
||||||
<el-table ref="siteResearchList" v-loading="loading" v-adaptive="{ bottomOffset: 60 }" :data="list" stripe
|
|
||||||
height="100" @sort-change="handleSortByColumn">
|
|
||||||
<el-table-column type="index" width="50" />
|
|
||||||
<!-- 中心编号 -->
|
|
||||||
<el-table-column prop="TrialSiteCode" :label="$t('trials:researchRecord:table:siteId')" min-width="100"
|
|
||||||
sortable="custom" show-overflow-tooltip />
|
|
||||||
<!-- 中心名称 -->
|
|
||||||
<el-table-column prop="SiteName" :label="$t('trials:researchRecord:table:siteName')" min-width="100"
|
|
||||||
sortable="custom" show-overflow-tooltip />
|
|
||||||
<!-- 联系人 -->
|
|
||||||
<el-table-column prop="UserName" :label="$t('trials:researchRecord:table:contactor')" min-width="100"
|
|
||||||
sortable="custom" show-overflow-tooltip />
|
|
||||||
<!-- 联系电话 -->
|
|
||||||
<el-table-column prop="Phone" :label="$t('trials:researchRecord:table:contactorPhone')" min-width="100"
|
|
||||||
show-overflow-tooltip />
|
|
||||||
<!-- 联系邮箱 -->
|
|
||||||
<el-table-column prop="Email" :label="$t('trials:researchRecord:table:contactorEmail')" min-width="150"
|
|
||||||
show-overflow-tooltip />
|
|
||||||
<!-- 初审人 -->
|
|
||||||
<el-table-column prop="preliminaryUser" :label="$t('trials:researchRecord:table:preliminaryUser')"
|
|
||||||
min-width="150" show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{
|
|
||||||
scope.row.PreliminaryUser
|
|
||||||
? scope.row.PreliminaryUser.RealName
|
|
||||||
: ''
|
|
||||||
}}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<!-- 审核人 -->
|
|
||||||
<el-table-column prop="ReviewerUser" :label="$t('trials:researchRecord:table:ReviewerUser')" min-width="150"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ scope.row.ReviewerUser ? scope.row.ReviewerUser.RealName : '' }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<!-- 状态 -->
|
|
||||||
<el-table-column prop="State" :label="$t('trials:researchRecord:table:status')" min-width="150"
|
|
||||||
sortable="custom" show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-tag v-if="scope.row.State === 0" type="primary">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
<el-tag v-if="scope.row.State === 1" type="info">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
<el-tag v-if="scope.row.State === 2" type="warning">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
<el-tag v-if="scope.row.State === 3" type="danger">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<!-- 是否废除 -->
|
|
||||||
<el-table-column prop="IsDeleted" :label="$t('trials:researchRecord:table:isDeleted')" min-width="100"
|
|
||||||
sortable="custom" show-overflow-tooltip>
|
|
||||||
<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('trials:researchRecord:table:updateTime')" min-width="150"
|
|
||||||
show-overflow-tooltip sortable="custom" />
|
|
||||||
<el-table-column width="150">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<!-- 查看 -->
|
|
||||||
<el-button v-show="searchData.State === 3" :disabled="scope.row.State !== 3" circle
|
|
||||||
:title="$t('common:button:view')" icon="el-icon-view" @click="handleViewResearchList(scope.row)" />
|
|
||||||
<!-- 审批 -->
|
|
||||||
<el-button v-show="(searchData.State === 1 || searchData.State === 2) && isAudit"
|
|
||||||
v-hasPermi="['trials:trials-panel:attachments:site-research:auidt']"
|
|
||||||
:disabled="scope.row.State === 0 || scope.row.State === 3 || scope.row.IsDeleted" circle
|
|
||||||
:title="$t('trials:researchRecord:action:view')" icon="el-icon-s-check"
|
|
||||||
@click="handleViewResearchList(scope.row)" />
|
|
||||||
<!-- 日志 -->
|
|
||||||
<el-button circle :title="$t('trials:researchRecord:action:log')" icon="el-icon-tickets"
|
|
||||||
@click="viewLog(scope.row)" />
|
|
||||||
<!-- 废除 -->
|
|
||||||
<el-button v-show="searchData.State === 0" v-hasPermi="[
|
|
||||||
'trials:trials-panel:attachments:site-research:abolish',
|
|
||||||
]" :disabled="scope.row.State !== 0 || scope.row.IsDeleted" circle
|
|
||||||
:title="$t('trials:researchRecord:action:abolish')" icon="el-icon-delete"
|
|
||||||
@click="handleRepealResearch(scope.row)" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
|
|
||||||
<!-- 分页组件 -->
|
|
||||||
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
|
|
||||||
@pagination="getList" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- 中心数据 trials:researchRecord:button:researchData-->
|
|
||||||
<!-- 中心人员 trials:researchRecord:dialogTitle:questionStaff-->
|
|
||||||
<el-dialog v-if="researchUserVisible" :visible.sync="researchUserVisible"
|
|
||||||
:title="$t('trials:researchRecord:button:researchData')" custom-class="base-dialog-wrapper" :fullscreen="true">
|
|
||||||
<div class="base-modal-body" style="border: 1px solid #ccc; padding: 10px">
|
|
||||||
<el-tabs v-model="activeName">
|
|
||||||
<el-tab-pane :label="$t('trials:researchRecord:dialogTitle:questionStaff')" name="first">
|
|
||||||
<Users v-if="activeName === 'first'" />
|
|
||||||
</el-tab-pane>
|
|
||||||
<el-tab-pane label="中心设备" name="second">
|
|
||||||
<Equipments v-if="activeName === 'second'" />
|
|
||||||
</el-tab-pane>
|
|
||||||
<el-tab-pane label="基本情况" name="third">
|
|
||||||
<Questions v-if="activeName === 'third'" />
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 调查表 -->
|
|
||||||
<el-dialog v-if="researchInfoVisible" :visible.sync="researchInfoVisible" :fullscreen="true"
|
|
||||||
:close-on-click-modal="false">
|
|
||||||
<research-form v-if="researchInfoVisible" @refreshPage="getList" />
|
|
||||||
</el-dialog>
|
|
||||||
<!-- 调查表编辑 -->
|
|
||||||
<el-dialog v-if="ImageManualVisible" :visible.sync="ImageManualVisible" :fullscreen="true"
|
|
||||||
:close-on-click-modal="false" :title="$t('trials:researchRecord:dialogTitle:ImageManualEdit')">
|
|
||||||
<ImageManual v-if="ImageManualVisible" :trialSiteSurveyId="trialSiteSurveyId" @getList="getList" />
|
|
||||||
</el-dialog>
|
|
||||||
<!-- 调查表链接 -->
|
|
||||||
<base-model :config="share_model">
|
|
||||||
<template slot="dialog-body" v-loading="shareLoading">
|
|
||||||
<el-button size="small" type="primary" style="margin-bottom: 10px;" @click.stop="openImageManual">{{
|
|
||||||
$t('trials:researchRecord:label:edit')
|
|
||||||
}}</el-button>
|
|
||||||
<div style="width: 100%; display: flex">
|
|
||||||
<div class="date">
|
|
||||||
<el-form :model="shareForm" :rules="rules" ref="shareForm" label-width="100px">
|
|
||||||
<el-form-item :label="$t('trials:researchRecord:label:ExpirationDays')" prop="ExpirationDays">
|
|
||||||
<el-radio-group v-model="shareForm.ExpirationDays" @input="shareForm.OtherExpirationDays = null">
|
|
||||||
<el-radio :label="1">{{ $t('trials:researchRecord:label:day1') }}</el-radio>
|
|
||||||
<el-radio :label="7">{{ $t('trials:researchRecord:label:day7') }}</el-radio>
|
|
||||||
<el-radio :label="15">{{ $t('trials:researchRecord:label:day15') }}</el-radio>
|
|
||||||
<el-radio :label="`default`">{{ $t('trials:researchRecord:label:default') }}
|
|
||||||
<el-input placeholder="" type="number" @input="handleInput" v-model="shareForm.OtherExpirationDays"
|
|
||||||
clearable size="mini" style="width: 60px;" class="dayInput" />
|
|
||||||
<span style="margin-left: 10px;">{{ $t('trials:researchRecord:label:day') }}</span>
|
|
||||||
</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item :label="$t('trials:researchRecord:label:LinkVerificationCode')" prop="LinkVerificationCode">
|
|
||||||
<el-radio-group v-model="shareForm.LinkVerificationCode"
|
|
||||||
@input="shareForm.OtherLinkVerificationCode = null">
|
|
||||||
<el-radio label="researchProgramNo">{{ $t('trials:researchRecord:label:researchProgramNo')
|
|
||||||
}}</el-radio>
|
|
||||||
<el-radio label="default">{{ $t('trials:researchRecord:label:default') }}
|
|
||||||
<el-input placeholder="" type="number" v-model="shareForm.OtherLinkVerificationCode" clearable
|
|
||||||
size="mini" style="width: 100px;" />
|
|
||||||
</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<el-button type="primary" round @click="setLink" style="float: right;">
|
|
||||||
{{ $t('trials:researchRecord:button:setLink') }}
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="share">
|
|
||||||
<div class="shareLink">
|
|
||||||
<h3>{{ $t('trials:researchRecord:label:link') }}</h3>
|
|
||||||
<el-input ref="shareLink" v-model="shareLink" readonly type="textarea" autosize :rows="3" />
|
|
||||||
<div class="dateBox">
|
|
||||||
<span>{{ $t('trials:researchRecord:label:linkVerificationCode') }}</span>
|
|
||||||
<span>{{ LinkVerificationCode }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="dateBox">
|
|
||||||
<span>{{ $t('trials:researchRecord:label:ValidityPeriod') }}</span>
|
|
||||||
<span>{{ validityPeriod }}</span>
|
|
||||||
<span style="color: red;" v-if="isExpired">({{ $t('trials:researchRecord:label:Expired') }})</span>
|
|
||||||
</div>
|
|
||||||
<el-button type="primary" round @click="copyLink" class="shareLinkBtn"
|
|
||||||
:disabled="!validityPeriod || isExpired">
|
|
||||||
{{ $t('trials:researchRecord:button:copyLink') }}
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="shareCode">
|
|
||||||
<h3>{{ $t('trials:researchRecord:label:shareCode') }}</h3>
|
|
||||||
<div style="display: flex;align-items: center;justify-content: space-between;">
|
|
||||||
<div class="qrCodeBox">
|
|
||||||
<div id="qrcode" ref="qrcode"></div>
|
|
||||||
</div>
|
|
||||||
<div class="codeBtnBox">
|
|
||||||
<el-button @click="handleCopyImg" type="primary" round :disabled="!validityPeriod || isExpired">{{
|
|
||||||
$t('trials:researchRecord:button:copyCode')
|
|
||||||
}}</el-button>
|
|
||||||
<el-button @click="savePic" round :disabled="!validityPeriod || isExpired">{{
|
|
||||||
$t('trials:researchRecord:button:savePic')
|
|
||||||
}}</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
</base-model>
|
|
||||||
<el-dialog v-if="logVisible" :visible.sync="logVisible"
|
|
||||||
:custom-class="isFullscreen ? 'full-log-dialog-container' : 'log-dialog-container'" :close-on-click-modal="false"
|
|
||||||
:fullscreen="isFullscreen" :show-close="false" width="60%" append-to-body>
|
|
||||||
<span slot="title" class="dialog-footer">
|
|
||||||
<div style="display: flex;flex-direction: row;justify-content: space-between;">
|
|
||||||
<div>
|
|
||||||
{{ $t('trials:researchForm:button:log') }}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<svg-icon :icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'"
|
|
||||||
style="vertical-align: baseline;cursor: pointer;font-size: 20px;" @click="toggleLogFullscreen" />
|
|
||||||
<svg-icon icon-class="dClose" style="cursor: pointer;font-size: 25px;margin-left: 10px;"
|
|
||||||
@click="logVisible = false" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
<div class="log-dialog-content">
|
|
||||||
<LogList :trial-site-survey-id="trialSiteSurveyId" />
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
</BaseContainer>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
getTrialSiteSurveyList,
|
|
||||||
getTrialSiteSelect,
|
|
||||||
abandonSiteSurvey,
|
|
||||||
setTrialLinkExpirationTime,
|
|
||||||
getTrialLinkExpirationTime,
|
|
||||||
getLinkLinkExpirationTime,
|
|
||||||
} from '@/api/trials'
|
|
||||||
import { changeURLStatic } from '@/utils/history.js'
|
|
||||||
import BaseContainer from '@/components/BaseContainer'
|
|
||||||
import Pagination from '@/components/Pagination'
|
|
||||||
import Users from './users'
|
|
||||||
import Equipments from './Equipments'
|
|
||||||
import Questions from './Questions'
|
|
||||||
import ResearchForm from '@/views/research/form'
|
|
||||||
import BaseModel from '@/components/BaseModel'
|
|
||||||
import ImageManual from './ImageManual'
|
|
||||||
import QRCode from 'qrcodejs2'
|
|
||||||
import LogList from '@/views/research/components/LogList'
|
|
||||||
import { getTrialSiteSurveyList_Export } from '@/api/export'
|
|
||||||
const searchDataDefault = () => {
|
|
||||||
return {
|
|
||||||
SortField: '',
|
|
||||||
Asc: true,
|
|
||||||
PageIndex: 1,
|
|
||||||
PageSize: 20,
|
|
||||||
TrialSiteId: '',
|
|
||||||
UserKeyInfo: '',
|
|
||||||
State: null,
|
|
||||||
IsDeleted: '',
|
|
||||||
DateRange: [],
|
|
||||||
PreliminaryUserName: null,
|
|
||||||
ReviewerUserName: null,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default {
|
|
||||||
name: 'ResearchList',
|
|
||||||
components: { BaseContainer, Pagination, Users, Equipments, Questions, ResearchForm, BaseModel, ImageManual, LogList },
|
|
||||||
props: {
|
|
||||||
isAudit: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
searchData: searchDataDefault(),
|
|
||||||
loading: false,
|
|
||||||
list: [],
|
|
||||||
total: 0,
|
|
||||||
trialId: this.$route.query.trialId,
|
|
||||||
siteOptions: [],
|
|
||||||
researchUserVisible: false,
|
|
||||||
researchInfoVisible: false,
|
|
||||||
share_model: {
|
|
||||||
visible: false,
|
|
||||||
title: this.$t('trials:researchRecord:title:shark'),
|
|
||||||
width: '1000px',
|
|
||||||
},
|
|
||||||
shareLink: '',
|
|
||||||
researchState: this.$d.ResearchRecord,
|
|
||||||
qrcode: null,
|
|
||||||
validityPeriod: null,
|
|
||||||
LinkVerificationCode: null,
|
|
||||||
isExpired: false,
|
|
||||||
shareLoading: false,
|
|
||||||
shareForm: {
|
|
||||||
ExpirationDays: null,
|
|
||||||
OtherExpirationDays: null,
|
|
||||||
LinkVerificationCode: null,
|
|
||||||
OtherLinkVerificationCode: null,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
ExpirationDays: [
|
|
||||||
{ required: true, message: this.$t("common:ruleMessage:select"), trigger: 'blur' },
|
|
||||||
{
|
|
||||||
validator: (rule, value, callback) => {
|
|
||||||
if (value === 'default' && !this.shareForm.OtherExpirationDays) {
|
|
||||||
callback(new Error(this.$t("common:ruleMessage:specify")));
|
|
||||||
} else {
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
|
|
||||||
}, trigger: 'blur'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
LinkVerificationCode: [
|
|
||||||
{ required: true, message: this.$t("common:ruleMessage:select"), trigger: 'blur' },
|
|
||||||
{
|
|
||||||
validator: (rule, value, callback) => {
|
|
||||||
if (value === 'default' && !this.shareForm.OtherLinkVerificationCode) {
|
|
||||||
callback(new Error(this.$t("common:ruleMessage:specify")));
|
|
||||||
} else {
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
|
|
||||||
}, trigger: 'blur'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
},
|
|
||||||
ImageManualVisible: false,
|
|
||||||
trialSiteSurveyId: null,
|
|
||||||
activeName: 'first',
|
|
||||||
isFullscreen: false,
|
|
||||||
logVisible: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
// this.getList()
|
|
||||||
this.getSite()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async handleExport() {
|
|
||||||
await getTrialSiteSurveyList_Export(this.searchData)
|
|
||||||
},
|
|
||||||
toggleLogFullscreen() {
|
|
||||||
this.isFullscreen = !this.isFullscreen
|
|
||||||
},
|
|
||||||
viewLog(row) {
|
|
||||||
this.trialSiteSurveyId = row.Id
|
|
||||||
this.isFullscreen = false
|
|
||||||
this.logVisible = true
|
|
||||||
},
|
|
||||||
async getLinkTimeIsExpired() {
|
|
||||||
try {
|
|
||||||
let data = {
|
|
||||||
TrialId: this.$route.query.trialId,
|
|
||||||
}
|
|
||||||
this.shareLoading = true
|
|
||||||
let res = await getLinkLinkExpirationTime(data)
|
|
||||||
this.shareLoading = false
|
|
||||||
if (res.IsSuccess) {
|
|
||||||
this.isExpired = res.Result.IsIsExpired
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
this.shareLoading = false
|
|
||||||
console.log(err)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async getLinkTime() {
|
|
||||||
try {
|
|
||||||
let data = {
|
|
||||||
TrialId: this.$route.query.trialId,
|
|
||||||
}
|
|
||||||
this.shareLoading = true
|
|
||||||
let res = await getTrialLinkExpirationTime(data)
|
|
||||||
this.shareLoading = false
|
|
||||||
if (res.IsSuccess) {
|
|
||||||
this.validityPeriod = res.Result.LinkExpirationTime
|
|
||||||
this.LinkVerificationCode = res.Result.LinkVerificationCode || res.Result.ResearchProgramNo
|
|
||||||
if (!this.validityPeriod) {
|
|
||||||
this.LinkVerificationCode = null
|
|
||||||
}
|
|
||||||
if (!this.validityPeriod) return false
|
|
||||||
this.getLinkTimeIsExpired()
|
|
||||||
this.shareLink = `${location.protocol}//${location.host}/researchLogin?trialId=${this.$route.query.trialId}`
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.creatQrCode()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
this.shareLoading = false
|
|
||||||
console.log(err)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async setLink() {
|
|
||||||
try {
|
|
||||||
let validate = await this.$refs.shareForm.validate()
|
|
||||||
if (!validate) return false
|
|
||||||
let data = {
|
|
||||||
TrialId: this.$route.query.trialId,
|
|
||||||
ExpirationDays: this.shareForm.ExpirationDays,
|
|
||||||
LinkVerificationCode: this.shareForm.LinkVerificationCode
|
|
||||||
}
|
|
||||||
if (this.shareForm.LinkVerificationCode === 'researchProgramNo') {
|
|
||||||
data.LinkVerificationCode = null
|
|
||||||
}
|
|
||||||
if (this.shareForm.LinkVerificationCode === 'default') {
|
|
||||||
data.LinkVerificationCode = this.shareForm.OtherLinkVerificationCode
|
|
||||||
}
|
|
||||||
if (this.shareForm.ExpirationDays === 'default') {
|
|
||||||
data.ExpirationDays = this.shareForm.OtherExpirationDays
|
|
||||||
}
|
|
||||||
this.shareLoading = true
|
|
||||||
let res = await setTrialLinkExpirationTime(data)
|
|
||||||
this.shareLoading = false
|
|
||||||
if (res.IsSuccess) {
|
|
||||||
this.getLinkTime()
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
this.shareLoading = false
|
|
||||||
console.log(err)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleInput(val) {
|
|
||||||
// 过滤掉非数字字符,并取整为正整数
|
|
||||||
this.shareForm.OtherExpirationDays = val.replace(/[^\d]/g, '').replace(/^0+/, '')
|
|
||||||
},
|
|
||||||
openImageManual() {
|
|
||||||
// if (!this.trialSiteSurveyId) return false
|
|
||||||
this.ImageManualVisible = true
|
|
||||||
},
|
|
||||||
// 获取系统文件数据
|
|
||||||
getList() {
|
|
||||||
this.loading = true
|
|
||||||
this.searchData.TrialId = this.trialId
|
|
||||||
if (this.searchData.DateRange && this.searchData.DateRange.length === 2) {
|
|
||||||
this.searchData.UpdateTimeBegin = this.searchData.DateRange[0]
|
|
||||||
this.searchData.updateTimeEnd = this.searchData.DateRange[1]
|
|
||||||
} else {
|
|
||||||
this.searchData.UpdateTimeBegin = ''
|
|
||||||
this.searchData.updateTimeEnd = ''
|
|
||||||
}
|
|
||||||
getTrialSiteSurveyList(this.searchData)
|
|
||||||
.then((res) => {
|
|
||||||
this.loading = false
|
|
||||||
this.list = res.Result.CurrentPageData
|
|
||||||
this.total = res.Result.TotalCount
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
this.loading = false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 查看调查表记录详情
|
|
||||||
handleViewResearchList(row) {
|
|
||||||
changeURLStatic('trialSiteSurveyId', row.Id)
|
|
||||||
this.researchInfoVisible = true
|
|
||||||
},
|
|
||||||
// 废除待提交的调查表
|
|
||||||
handleRepealResearch(row) {
|
|
||||||
// 是否确认废除?
|
|
||||||
this.$confirm(this.$t('trials:researchRecord:message:abolish'), {
|
|
||||||
type: 'warning',
|
|
||||||
distinguishCancelAndClose: true,
|
|
||||||
}).then(() => {
|
|
||||||
abandonSiteSurvey(this.trialId, row.Id).then((res) => {
|
|
||||||
if (res.IsSuccess) {
|
|
||||||
this.getList()
|
|
||||||
// 废除成功
|
|
||||||
this.$message.success(
|
|
||||||
this.$t('trials:researchRecord:message:abolishSuccessfully')
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 展示当前项目下所有调查表需生成账户的用户信息
|
|
||||||
showResearchUser() {
|
|
||||||
this.researchUserVisible = true
|
|
||||||
this.activeName = 'first'
|
|
||||||
},
|
|
||||||
// 复制链接
|
|
||||||
copyLink() {
|
|
||||||
// 中心调研表链接
|
|
||||||
this.$copyText(
|
|
||||||
`${this.$t('trials:researchRecord:message:researchFormLink')}: ${this.shareLink
|
|
||||||
}\n${this.$t('trials:researchRecord:label:linkVerificationCode')}${this.LinkVerificationCode}\n${this.$t('trials:researchRecord:label:ValidityPeriod')}${this.validityPeriod}`
|
|
||||||
)
|
|
||||||
.then((res) => {
|
|
||||||
// 复制成功
|
|
||||||
this.$message.success(
|
|
||||||
this.$t('trials:researchRecord:message:copySuccessfully')
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
// 复制失败
|
|
||||||
this.$alert(this.$t('trials:researchRecord:message:copyFailed'))
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 创建二维码
|
|
||||||
creatQrCode() {
|
|
||||||
this.$refs.qrcode.innerHTML = '' //清除二维码方法一
|
|
||||||
let text = this.shareLink
|
|
||||||
this.qrcode = new QRCode(this.$refs.qrcode, {
|
|
||||||
text: text, //页面地址 ,如果页面需要参数传递请注意哈希模式#
|
|
||||||
width: 200,
|
|
||||||
height: 200,
|
|
||||||
colorDark: '#000000',
|
|
||||||
colorLight: '#ffffff',
|
|
||||||
correctLevel: QRCode.CorrectLevel.H,
|
|
||||||
})
|
|
||||||
// qrcode.clear(); // 清除二维码方法二
|
|
||||||
},
|
|
||||||
// 下载二维码
|
|
||||||
savePic() {
|
|
||||||
let qrCodeCanvas = document
|
|
||||||
.getElementById('qrcode')
|
|
||||||
.getElementsByTagName('canvas')
|
|
||||||
let a = document.createElement('a')
|
|
||||||
a.href = qrCodeCanvas[0].toDataURL('image/url')
|
|
||||||
a.download = `${this.$route.query.researchProgramNo}${this.$t('trials:researchRecord:title:code')}.png`
|
|
||||||
a.click()
|
|
||||||
},
|
|
||||||
// 复制二维码
|
|
||||||
handleCopyImg() {
|
|
||||||
let qrCodeCanvas = document
|
|
||||||
.getElementById('qrcode')
|
|
||||||
.getElementsByTagName('canvas')
|
|
||||||
qrCodeCanvas[0].toBlob(async (blob) => {
|
|
||||||
console.log(blob)
|
|
||||||
const data = [
|
|
||||||
new ClipboardItem({
|
|
||||||
[blob.type]: blob,
|
|
||||||
}),
|
|
||||||
] // https://w3c.github.io/clipboard-apis/#dom-clipboard-write
|
|
||||||
await navigator.clipboard.write(data).then(
|
|
||||||
() => {
|
|
||||||
this.$message.success(
|
|
||||||
this.$t('trials:researchRecord:message:copySuccess')
|
|
||||||
)
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
this.$message.error(
|
|
||||||
this.$t('trials:researchRecord:message:UnableWrite')
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 获取site下拉框数据
|
|
||||||
getSite() {
|
|
||||||
getTrialSiteSelect(this.trialId).then((res) => {
|
|
||||||
this.siteOptions = res.Result
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 展示调查表链接
|
|
||||||
showResearchLink() {
|
|
||||||
this.shareForm = {
|
|
||||||
ExpirationDays: null,
|
|
||||||
OtherExpirationDays: null,
|
|
||||||
LinkVerificationCode: null,
|
|
||||||
OtherLinkVerificationCode: null,
|
|
||||||
}
|
|
||||||
this.validityPeriod = null
|
|
||||||
this.isExpired = false
|
|
||||||
this.share_model.visible = true
|
|
||||||
this.getLinkTime()
|
|
||||||
// &lang=${this.$i18n.locale}
|
|
||||||
// this.trialSiteSurveyId = this.list[0].Id
|
|
||||||
},
|
|
||||||
// 重置
|
|
||||||
handleReset() {
|
|
||||||
const state = this.searchData.State
|
|
||||||
this.searchData = searchDataDefault()
|
|
||||||
this.searchData.DateRange = []
|
|
||||||
if (this.searchData.DateRange && this.searchData.DateRange.length === 2) {
|
|
||||||
this.searchData.UpdateTimeBegin = this.searchData.DateRange[0]
|
|
||||||
this.searchData.updateTimeEnd = this.searchData.DateRange[1]
|
|
||||||
} else {
|
|
||||||
this.searchData.UpdateTimeBegin = ''
|
|
||||||
this.searchData.updateTimeEnd = ''
|
|
||||||
}
|
|
||||||
this.searchData.State = state
|
|
||||||
this.getList()
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.siteResearchList.clearSort()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 查询
|
|
||||||
handleSearch() {
|
|
||||||
this.getList()
|
|
||||||
},
|
|
||||||
// 排序
|
|
||||||
handleSortByColumn(column) {
|
|
||||||
if (column.order === 'ascending') {
|
|
||||||
this.searchData.Asc = true
|
|
||||||
} else {
|
|
||||||
this.searchData.Asc = false
|
|
||||||
}
|
|
||||||
this.searchData.SortField = column.prop
|
|
||||||
this.getList()
|
|
||||||
},
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
if (this.qrcode) {
|
|
||||||
this.qrcode = null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.date,
|
|
||||||
.share {
|
|
||||||
width: 55%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dayInput {
|
|
||||||
::v-deep .el-input__inner {
|
|
||||||
padding-left: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.date {
|
|
||||||
padding-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share {
|
|
||||||
width: 45%;
|
|
||||||
padding-left: 5%;
|
|
||||||
border-left: 1px solid #f0f0f0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shareLinkBtn {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.qrCodeBox {
|
|
||||||
width: 220px;
|
|
||||||
height: 220px;
|
|
||||||
display: flex;
|
|
||||||
border: 1px solid #c0c4cc;
|
|
||||||
border-radius: 5px;
|
|
||||||
box-shadow: 1px 1px 5px #c0c4cc;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dateBox {
|
|
||||||
margin: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codeBtnBox {
|
|
||||||
|
|
||||||
::v-deep .el-button {
|
|
||||||
display: block;
|
|
||||||
margin: 10px auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -6,33 +6,31 @@
|
|||||||
<!-- 中心编号 -->
|
<!-- 中心编号 -->
|
||||||
<el-form-item :label="$t('trials:researchStaff:table:siteId')">
|
<el-form-item :label="$t('trials:researchStaff:table:siteId')">
|
||||||
<el-select v-model="searchData.TrialSiteId" clearable filterable style="width:120px;">
|
<el-select v-model="searchData.TrialSiteId" clearable filterable style="width:120px;">
|
||||||
<el-option v-for="(item, index) of siteOptions" :key="index" :label="item.TrialSiteCode"
|
<el-option
|
||||||
:value="item.TrialSiteId" />
|
v-for="(item,index) of siteOptions"
|
||||||
|
:key="index"
|
||||||
|
:label="item.TrialSiteCode"
|
||||||
|
:value="item.TrialSiteId"
|
||||||
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 状态 -->
|
|
||||||
<el-form-item :label="$t('trials:researchRecord:table:status')">
|
|
||||||
<el-select v-model="searchData.State" clearable filterable style="width: 120px">
|
|
||||||
<el-option v-for="(item, index) of $d.ResearchRecord" :key="index" :label="item.label"
|
|
||||||
:value="item.value" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 是否废除 -->
|
|
||||||
<!-- <el-form-item :label="$t('trials:researchRecord:table:isDeleted')">
|
|
||||||
<el-select v-model="searchData.IsDeleted" clearable filterable style="width: 120px">
|
|
||||||
<el-option v-for="item of $d.YesOrNo" v-show="item.raw.ValueCN !== '无'" :key="`IsDeleted${item.value}`"
|
|
||||||
:label="item.label" :value="item.value" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item> -->
|
|
||||||
<!-- 姓名 -->
|
<!-- 姓名 -->
|
||||||
<el-form-item :label="$t('trials:researchStaff:table:Name')">
|
<el-form-item :label="$t('trials:researchStaff:table:Name')">
|
||||||
<el-input v-model="searchData.UserName" class="mr" clearable style="width:120px;" />
|
<el-input v-model="searchData.UserName" class="mr" clearable style="width:120px;" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 角色 -->
|
<!-- 角色 -->
|
||||||
<el-form-item :label="$t('trials:researchStaff:table:role')">
|
<el-form-item :label="$t('trials:researchStaff:table:role')">
|
||||||
<el-select v-model="searchData.TrialRoleCode" style="width:120px;" clearable>
|
<el-select
|
||||||
<el-option v-for="item of dict.type.SiteSurvey_UserRoles" :key="item.value" :label="item.label"
|
v-model="searchData.TrialRoleCode"
|
||||||
:value="parseInt(item.raw.Code)" />
|
style="width:120px;"
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item of dict.type.SiteSurvey_UserRoles"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="parseInt(item.raw.Code)"
|
||||||
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 单位 -->
|
<!-- 单位 -->
|
||||||
@@ -41,19 +39,42 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 是否生成账号 -->
|
<!-- 是否生成账号 -->
|
||||||
<el-form-item :label="$t('trials:researchStaff:table:isGenerateAccount')">
|
<el-form-item :label="$t('trials:researchStaff:table:isGenerateAccount')">
|
||||||
<el-select v-model="searchData.IsGenerateAccount" style="width:120px;" clearable>
|
<el-select
|
||||||
<el-option v-for="item of $d.YesOrNo" :key="`IsGenerateAccount${item.value}`" :label="item.label"
|
v-model="searchData.IsGenerateAccount"
|
||||||
:value="item.value" />
|
style="width:120px;"
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<el-option v-for="item of $d.YesOrNo" :key="`IsGenerateAccount${item.value}`" :label="item.label" :value="item.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 用户类型 -->
|
<!-- 用户类型 -->
|
||||||
<el-form-item :label="$t('trials:researchStaff:table:userType')">
|
<el-form-item :label="$t('trials:researchStaff:table:userType')">
|
||||||
<el-select v-model="searchData.UserTypeId" style="width:120px;" clearable>
|
<el-select
|
||||||
<el-option v-for="item of userTypeOptions" :key="item.Id" :label="item.UserTypeShortName" :value="item.Id">
|
v-model="searchData.UserTypeId"
|
||||||
|
style="width:120px;"
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item of userTypeOptions"
|
||||||
|
:key="item.Id"
|
||||||
|
:label="item.UserTypeShortName"
|
||||||
|
:value="item.Id"
|
||||||
|
>
|
||||||
<span>{{ item.UserType }}</span>
|
<span>{{ item.UserType }}</span>
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- 状态 -->
|
||||||
|
<!-- <el-form-item :label="$t('trials:researchStaff:table:status')">
|
||||||
|
<el-select v-model="searchData.State" clearable filterable style="width:120px;">
|
||||||
|
<el-option
|
||||||
|
v-for="(item,index) of researchUserState"
|
||||||
|
:key="index"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item> -->
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<!-- 查询 -->
|
<!-- 查询 -->
|
||||||
<el-button type="primary" icon="el-icon-search" @click="handleSearch">
|
<el-button type="primary" icon="el-icon-search" @click="handleSearch">
|
||||||
@@ -68,15 +89,25 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 发邮件 -->
|
<!-- 发邮件 -->
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button v-hasPermi="['trials:trials-panel:attachments:site-research:summary-record:sendEmail']"
|
<el-button
|
||||||
type="primary" icon="el-icon-message" :loading="sendEmailLoading" :disabled="selectArr.length === 0"
|
v-hasPermi="['trials:trials-panel:attachments:site-research:summary-record:sendEmail']"
|
||||||
@click="handleSendEmail">
|
type="primary"
|
||||||
|
icon="el-icon-message"
|
||||||
|
:loading="sendEmailLoading"
|
||||||
|
:disabled="selectArr.length === 0"
|
||||||
|
@click="handleSendEmail"
|
||||||
|
>
|
||||||
{{ $t('trials:researchRecord:dialogButton:sendEmail') }}
|
{{ $t('trials:researchRecord:dialogButton:sendEmail') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 导出 -->
|
<!-- 导出 -->
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-download" :disabled="list.length === 0" @click="handleExport">
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
icon="el-icon-download"
|
||||||
|
:disabled="list.length === 0"
|
||||||
|
@click="handleExport"
|
||||||
|
>
|
||||||
{{ $t('common:button:export') }}
|
{{ $t('common:button:export') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -85,74 +116,96 @@
|
|||||||
|
|
||||||
<template slot="main-container">
|
<template slot="main-container">
|
||||||
<!-- 系统文件列表 -->
|
<!-- 系统文件列表 -->
|
||||||
<el-table ref="researchUsers" v-loading="loading" v-adaptive="{ bottomOffset: 55 }" :data="list" stripe
|
<el-table
|
||||||
height="100" @selection-change="handleSelectChange" @sort-change="handleSortByColumn">
|
ref="researchUsers"
|
||||||
<el-table-column type="selection" width="50" :selectable="handleSelectTable" />
|
v-loading="loading"
|
||||||
|
v-adaptive="{bottomOffset:70}"
|
||||||
|
:data="list"
|
||||||
|
stripe
|
||||||
|
height="100"
|
||||||
|
@selection-change="handleSelectChange"
|
||||||
|
@sort-change="handleSortByColumn"
|
||||||
|
>
|
||||||
|
<el-table-column
|
||||||
|
type="selection"
|
||||||
|
width="50"
|
||||||
|
:selectable="handleSelectTable"
|
||||||
|
/>
|
||||||
<el-table-column type="index" width="50" />
|
<el-table-column type="index" width="50" />
|
||||||
<!-- 中心编号 -->
|
<!-- 中心编号 -->
|
||||||
<el-table-column prop="TrialSiteSurvey.TrialSiteCode" :label="$t('trials:researchStaff:table:siteId')"
|
<el-table-column
|
||||||
show-overflow-tooltip sortable="custom" min-width="100">
|
prop="TrialSiteSurvey.TrialSiteCode"
|
||||||
|
:label="$t('trials:researchStaff:table:siteId')"
|
||||||
|
show-overflow-tooltip
|
||||||
|
sortable="custom"
|
||||||
|
min-width="100"
|
||||||
|
>
|
||||||
<template slot-scope="scope">{{ `${scope.row.TrialSiteSurvey.TrialSiteCode}` }}</template>
|
<template slot-scope="scope">{{ `${scope.row.TrialSiteSurvey.TrialSiteCode}` }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!-- 中心名称 -->
|
<!-- 中心名称 -->
|
||||||
<el-table-column prop="TrialSiteSurvey.SiteName" :label="$t('trials:researchStaff:table:siteName')"
|
<el-table-column
|
||||||
show-overflow-tooltip sortable="custom" min-width="120">
|
prop="TrialSiteSurvey.SiteName"
|
||||||
|
:label="$t('trials:researchStaff:table:siteName')"
|
||||||
|
show-overflow-tooltip
|
||||||
|
sortable="custom"
|
||||||
|
min-width="120"
|
||||||
|
>
|
||||||
<template slot-scope="scope">{{ `${scope.row.TrialSiteSurvey.SiteName}` }}</template>
|
<template slot-scope="scope">{{ `${scope.row.TrialSiteSurvey.SiteName}` }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!-- 状态 -->
|
|
||||||
<el-table-column prop="State" :label="$t('trials:researchRecord:table:status')" min-width="150"
|
|
||||||
sortable="custom" show-overflow-tooltip>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-tag v-if="scope.row.State === 0" type="primary">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
<el-tag v-if="scope.row.State === 1" type="info">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
<el-tag v-if="scope.row.State === 2" type="warning">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
<el-tag v-if="scope.row.State === 3" type="danger">{{
|
|
||||||
$fd('ResearchRecord', scope.row.State)
|
|
||||||
}}</el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<!-- 是否废除 -->
|
|
||||||
<!-- <el-table-column prop="IsDeleted" :label="$t('trials:researchRecord:table:isDeleted')" min-width="100"
|
|
||||||
sortable="custom" show-overflow-tooltip>
|
|
||||||
<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="LastName" :label="$t('trials:researchStaff:table:Name')" show-overflow-tooltip
|
<el-table-column
|
||||||
sortable="custom" min-width="100">
|
prop="LastName"
|
||||||
|
:label="$t('trials:researchStaff:table:Name')"
|
||||||
|
show-overflow-tooltip
|
||||||
|
sortable="custom"
|
||||||
|
min-width="100"
|
||||||
|
>
|
||||||
<template slot-scope="scope">{{ `${scope.row.LastName} / ${scope.row.FirstName}` }}</template>
|
<template slot-scope="scope">{{ `${scope.row.LastName} / ${scope.row.FirstName}` }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!-- 角色 -->
|
<!-- 角色 -->
|
||||||
<el-table-column prop="TrialRoleCode" :label="$t('trials:researchStaff:table:role')" show-overflow-tooltip
|
<el-table-column
|
||||||
sortable="custom" min-width="100">
|
prop="TrialRoleCode"
|
||||||
|
:label="$t('trials:researchStaff:table:role')"
|
||||||
|
show-overflow-tooltip
|
||||||
|
sortable="custom"
|
||||||
|
min-width="100"
|
||||||
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
{{ $fd('SiteSurvey_UserRoles',scope.row.TrialRoleCode) }}
|
{{ $fd('SiteSurvey_UserRoles',scope.row.TrialRoleCode) }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!-- 电话号码 -->
|
<!-- 电话号码 -->
|
||||||
<el-table-column prop="Phone" :label="$t('trials:researchStaff:table:phone')" show-overflow-tooltip
|
<el-table-column
|
||||||
sortable="custom" min-width="120" />
|
prop="Phone"
|
||||||
|
:label="$t('trials:researchStaff:table:phone')"
|
||||||
|
show-overflow-tooltip
|
||||||
|
sortable="custom"
|
||||||
|
min-width="120"
|
||||||
|
/>
|
||||||
<!-- 邮箱 -->
|
<!-- 邮箱 -->
|
||||||
<el-table-column prop="Email" :label="$t('trials:researchStaff:table:email')" show-overflow-tooltip
|
<el-table-column
|
||||||
sortable="custom" min-width="150" />
|
prop="Email"
|
||||||
|
:label="$t('trials:researchStaff:table:email')"
|
||||||
|
show-overflow-tooltip
|
||||||
|
sortable="custom"
|
||||||
|
min-width="150"
|
||||||
|
/>
|
||||||
<!-- 单位 -->
|
<!-- 单位 -->
|
||||||
<el-table-column prop="OrganizationName" :label="$t('trials:researchStaff:table:organization')"
|
<el-table-column
|
||||||
show-overflow-tooltip sortable="custom" min-width="100" />
|
prop="OrganizationName"
|
||||||
|
:label="$t('trials:researchStaff:table:organization')"
|
||||||
|
show-overflow-tooltip
|
||||||
|
sortable="custom"
|
||||||
|
min-width="100"
|
||||||
|
/>
|
||||||
<!-- 是否生成账号 -->
|
<!-- 是否生成账号 -->
|
||||||
<el-table-column prop="IsGenerateAccount" :label="$t('trials:researchStaff:table:isGenerateAccount')"
|
<el-table-column
|
||||||
show-overflow-tooltip sortable="custom" min-width="130">
|
prop="IsGenerateAccount"
|
||||||
|
:label="$t('trials:researchStaff:table:isGenerateAccount')"
|
||||||
|
show-overflow-tooltip
|
||||||
|
sortable="custom"
|
||||||
|
min-width="130"
|
||||||
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
{{ $fd('YesOrNo', scope.row.IsGenerateAccount) }}
|
{{ $fd('YesOrNo', scope.row.IsGenerateAccount) }}
|
||||||
</template>
|
</template>
|
||||||
@@ -170,11 +223,21 @@
|
|||||||
<!-- </el-table-column>-->
|
<!-- </el-table-column>-->
|
||||||
|
|
||||||
<!-- 用户类型 -->
|
<!-- 用户类型 -->
|
||||||
<el-table-column prop="UserType" :label="$t('trials:researchStaff:table:userType')" show-overflow-tooltip
|
<el-table-column
|
||||||
sortable="custom" min-width="100" />
|
prop="UserType"
|
||||||
|
:label="$t('trials:researchStaff:table:userType')"
|
||||||
|
show-overflow-tooltip
|
||||||
|
sortable="custom"
|
||||||
|
min-width="100"
|
||||||
|
/>
|
||||||
<!-- 是否加入 -->
|
<!-- 是否加入 -->
|
||||||
<el-table-column prop="IsJoin" :label="$t('trials:researchStaff:table:isJoin')" show-overflow-tooltip
|
<el-table-column
|
||||||
sortable="custom" min-width="100">
|
prop="IsJoin"
|
||||||
|
:label="$t('trials:researchStaff:table:isJoin')"
|
||||||
|
show-overflow-tooltip
|
||||||
|
sortable="custom"
|
||||||
|
min-width="100"
|
||||||
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-tag v-if="scope.row.IsJoin" type="info">{{ $fd('IsJoin', scope.row.IsJoin) }}</el-tag>
|
<el-tag v-if="scope.row.IsJoin" type="info">{{ $fd('IsJoin', scope.row.IsJoin) }}</el-tag>
|
||||||
<el-tag v-else type="danger">{{ $fd('IsJoin', scope.row.IsJoin) }}</el-tag>
|
<el-tag v-else type="danger">{{ $fd('IsJoin', scope.row.IsJoin) }}</el-tag>
|
||||||
@@ -183,8 +246,7 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页组件 -->
|
<!-- 分页组件 -->
|
||||||
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
|
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize" @pagination="getList" />
|
||||||
@pagination="getList" />
|
|
||||||
</template>
|
</template>
|
||||||
</BaseContainer>
|
</BaseContainer>
|
||||||
</template>
|
</template>
|
||||||
@@ -234,6 +296,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
console.log(this.dict.type.SiteSurvey_UserRoles)
|
||||||
this.getList()
|
this.getList()
|
||||||
this.getSite()
|
this.getSite()
|
||||||
this.getUserType()
|
this.getUserType()
|
||||||
|
|||||||
@@ -1,208 +1,670 @@
|
|||||||
<template>
|
<template>
|
||||||
<BaseContainer>
|
<BaseContainer>
|
||||||
<div class="step-wrapper">
|
<!-- 搜索框 -->
|
||||||
<el-steps :active="activeStatus" align-center :space="300">
|
<template slot="search-container">
|
||||||
<!-- 中心填写 -->
|
<el-form :inline="true">
|
||||||
<el-step :title="$t('trials:siteResearch:timeline:step1')" class="click_cursor"
|
<!-- 中心 -->
|
||||||
@click.native="handleClick(0)" />
|
<el-form-item :label="$t('trials:researchRecord:table:siteId')">
|
||||||
<!-- SPM审核 -->
|
<el-select v-model="searchData.TrialSiteId" clearable filterable style="width: 120px">
|
||||||
<el-step v-if="isSPMJoin" :title="$t('trials:siteResearch:timeline:step2')" class="click_cursor"
|
<el-option v-for="(item, index) of siteOptions" :key="index" :label="item.TrialSiteCode"
|
||||||
@click.native="handleClick(1)" />
|
:value="item.TrialSiteId" />
|
||||||
<!-- PM审核 -->
|
</el-select>
|
||||||
<el-step :title="$t('trials:siteResearch:timeline:step3')" class="click_cursor"
|
</el-form-item>
|
||||||
@click.native="handleClick(2)" />
|
<!-- 联系人 -->
|
||||||
<!-- 审核完毕 -->
|
<el-form-item :label="$t('trials:researchRecord:table:contactor')">
|
||||||
<el-step :title="$t('trials:siteResearch:timeline:step14')" class="click_cursor"
|
<el-input v-model="searchData.UserKeyInfo" class="mr" clearable :placeholder="`${$t(
|
||||||
@click.native="handleClick(3)" />
|
'trials:researchRecord:placeholder:contactorInfo'
|
||||||
</el-steps>
|
)}`" style="width: 140px" />
|
||||||
<div class="step-content">
|
</el-form-item>
|
||||||
<ResearchList ref="researchList" :isAudit="isAudit" />
|
<!-- 初审人 -->
|
||||||
|
<el-form-item :label="$t('trials:researchRecord:table:preliminaryUser')">
|
||||||
|
<el-input v-model="searchData.PreliminaryUserName" class="mr" clearable style="width: 140px" />
|
||||||
|
</el-form-item>
|
||||||
|
<!-- 审核人 -->
|
||||||
|
<el-form-item :label="$t('trials:researchRecord:table:ReviewerUser')">
|
||||||
|
<el-input v-model="searchData.ReviewerUserName" class="mr" clearable style="width: 140px" />
|
||||||
|
</el-form-item>
|
||||||
|
<!-- 状态 -->
|
||||||
|
<el-form-item :label="$t('trials:researchRecord:table:status')">
|
||||||
|
<el-select v-model="searchData.State" clearable filterable style="width: 120px">
|
||||||
|
<el-option v-for="(item, index) of $d.ResearchRecord" :key="index" :label="item.label"
|
||||||
|
:value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- 是否废除 -->
|
||||||
|
<el-form-item :label="$t('trials:researchRecord:table:isDeleted')">
|
||||||
|
<el-select v-model="searchData.IsDeleted" clearable filterable style="width: 120px">
|
||||||
|
<el-option v-for="item of $d.YesOrNo" v-show="item.raw.ValueCN !== '无'" :key="`IsDeleted${item.value}`"
|
||||||
|
:label="item.label" :value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- 更新时间 -->
|
||||||
|
<el-form-item :label="$t('trials:researchRecord:table:updateTime')">
|
||||||
|
<el-date-picker v-model="searchData.DateRange" type="daterange" value-format="yyyy-MM-dd" format="yyyy-MM-dd"
|
||||||
|
style="width: 250px" />
|
||||||
|
</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-button v-hasPermi="[
|
||||||
|
'trials:trials-panel:attachments:site-research:summary-record',
|
||||||
|
]" type="primary" icon="el-icon-info" @click="showResearchUser">
|
||||||
|
{{ $t('trials:researchRecord:button:questionStaffs') }}
|
||||||
|
</el-button>
|
||||||
|
<!-- 调查表链接 -->
|
||||||
|
<el-button v-hasPermi="[
|
||||||
|
'trials:trials-panel:attachments:site-research:questionnaire-link',
|
||||||
|
]" type="primary" icon="el-icon-link" @click="showResearchLink">
|
||||||
|
{{ $t('trials:researchRecord:button:questionLink') }}
|
||||||
|
</el-button>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template slot="main-container">
|
||||||
|
<!-- 系统文件列表 -->
|
||||||
|
<el-table ref="siteResearchList" v-loading="loading" v-adaptive="{ bottomOffset: 60 }" :data="list" stripe
|
||||||
|
height="100" @sort-change="handleSortByColumn">
|
||||||
|
<el-table-column type="index" width="50" />
|
||||||
|
<!-- 中心编号 -->
|
||||||
|
<el-table-column prop="TrialSiteCode" :label="$t('trials:researchRecord:table:siteId')" min-width="100"
|
||||||
|
sortable="custom" show-overflow-tooltip />
|
||||||
|
<!-- 中心名称 -->
|
||||||
|
<el-table-column prop="SiteName" :label="$t('trials:researchRecord:table:siteName')" min-width="100"
|
||||||
|
sortable="custom" show-overflow-tooltip />
|
||||||
|
<!-- 联系人 -->
|
||||||
|
<el-table-column prop="UserName" :label="$t('trials:researchRecord:table:contactor')" min-width="100"
|
||||||
|
sortable="custom" show-overflow-tooltip />
|
||||||
|
<!-- 联系电话 -->
|
||||||
|
<el-table-column prop="Phone" :label="$t('trials:researchRecord:table:contactorPhone')" min-width="100"
|
||||||
|
show-overflow-tooltip />
|
||||||
|
<!-- 联系邮箱 -->
|
||||||
|
<el-table-column prop="Email" :label="$t('trials:researchRecord:table:contactorEmail')" min-width="150"
|
||||||
|
show-overflow-tooltip />
|
||||||
|
<!-- 初审人 -->
|
||||||
|
<el-table-column prop="preliminaryUser" :label="$t('trials:researchRecord:table:preliminaryUser')"
|
||||||
|
min-width="150" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{
|
||||||
|
scope.row.PreliminaryUser
|
||||||
|
? scope.row.PreliminaryUser.RealName
|
||||||
|
: ''
|
||||||
|
}}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- 审核人 -->
|
||||||
|
<el-table-column prop="ReviewerUser" :label="$t('trials:researchRecord:table:ReviewerUser')" min-width="150"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ scope.row.ReviewerUser ? scope.row.ReviewerUser.RealName : '' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- 状态 -->
|
||||||
|
<el-table-column prop="State" :label="$t('trials:researchRecord:table:status')" min-width="150"
|
||||||
|
sortable="custom" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag v-if="scope.row.State === 0" type="primary">{{
|
||||||
|
$fd('ResearchRecord', scope.row.State)
|
||||||
|
}}</el-tag>
|
||||||
|
<el-tag v-if="scope.row.State === 1" type="info">{{
|
||||||
|
$fd('ResearchRecord', scope.row.State)
|
||||||
|
}}</el-tag>
|
||||||
|
<el-tag v-if="scope.row.State === 2" type="warning">{{
|
||||||
|
$fd('ResearchRecord', scope.row.State)
|
||||||
|
}}</el-tag>
|
||||||
|
<el-tag v-if="scope.row.State === 3" type="danger">{{
|
||||||
|
$fd('ResearchRecord', scope.row.State)
|
||||||
|
}}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- 是否废除 -->
|
||||||
|
<el-table-column prop="IsDeleted" :label="$t('trials:researchRecord:table:isDeleted')" min-width="100"
|
||||||
|
sortable="custom" show-overflow-tooltip>
|
||||||
|
<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('trials:researchRecord:table:updateTime')" min-width="150"
|
||||||
|
show-overflow-tooltip sortable="custom" />
|
||||||
|
<el-table-column width="150">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<!-- 查看 -->
|
||||||
|
<el-button :disabled="scope.row.State !== 3" circle :title="$t('common:button:view')" icon="el-icon-view"
|
||||||
|
@click="handleViewResearchList(scope.row)" />
|
||||||
|
<!-- 审批 -->
|
||||||
|
<el-button v-hasPermi="[
|
||||||
|
'trials:trials-panel:attachments:site-research:auidt',
|
||||||
|
]" :disabled="scope.row.State === 0 || scope.row.State === 3 || scope.row.IsDeleted" circle
|
||||||
|
:title="$t('trials:researchRecord:action:view')" icon="el-icon-s-check"
|
||||||
|
@click="handleViewResearchList(scope.row)" />
|
||||||
|
<!-- 废除 -->
|
||||||
|
<el-button v-hasPermi="[
|
||||||
|
'trials:trials-panel:attachments:site-research:abolish',
|
||||||
|
]" :disabled="scope.row.State !== 0 || scope.row.IsDeleted" circle
|
||||||
|
:title="$t('trials:researchRecord:action:abolish')" icon="el-icon-delete"
|
||||||
|
@click="handleRepealResearch(scope.row)" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 分页组件 -->
|
||||||
|
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
|
||||||
|
@pagination="getList" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 中心人员 -->
|
||||||
|
<el-dialog v-if="researchUserVisible" :visible.sync="researchUserVisible"
|
||||||
|
:title="$t('trials:researchRecord:dialogTitle:questionStaff')" custom-class="base-dialog-wrapper"
|
||||||
|
:fullscreen="true">
|
||||||
|
<div class="base-modal-body" style="border: 1px solid #ccc; padding: 10px">
|
||||||
|
<Users v-if="researchUserVisible" />
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 调查表 -->
|
||||||
|
<el-dialog v-if="researchInfoVisible" :visible.sync="researchInfoVisible" :fullscreen="true"
|
||||||
|
:close-on-click-modal="false">
|
||||||
|
<research-form v-if="researchInfoVisible" @refreshPage="getList" />
|
||||||
|
</el-dialog>
|
||||||
|
<!-- 调查表编辑 -->
|
||||||
|
<el-dialog v-if="ImageManualVisible" :visible.sync="ImageManualVisible" :fullscreen="true"
|
||||||
|
:close-on-click-modal="false" :title="$t('trials:researchRecord:dialogTitle:ImageManualEdit')">
|
||||||
|
<ImageManual v-if="ImageManualVisible" :trialSiteSurveyId="trialSiteSurveyId" @getList="getList" />
|
||||||
|
</el-dialog>
|
||||||
|
<!-- 调查表链接 -->
|
||||||
|
<base-model :config="share_model">
|
||||||
|
<template slot="dialog-body" v-loading="shareLoading">
|
||||||
|
<el-button size="small" type="primary" style="margin-bottom: 10px;" @click.stop="openImageManual">{{
|
||||||
|
$t('trials:researchRecord:label:edit')
|
||||||
|
}}</el-button>
|
||||||
|
<div style="width: 100%; display: flex">
|
||||||
|
<div class="date">
|
||||||
|
<el-form :model="shareForm" :rules="rules" ref="shareForm" label-width="100px">
|
||||||
|
<el-form-item :label="$t('trials:researchRecord:label:ExpirationDays')" prop="ExpirationDays">
|
||||||
|
<el-radio-group v-model="shareForm.ExpirationDays" @input="shareForm.OtherExpirationDays = null">
|
||||||
|
<el-radio :label="1">{{ $t('trials:researchRecord:label:day1') }}</el-radio>
|
||||||
|
<el-radio :label="7">{{ $t('trials:researchRecord:label:day7') }}</el-radio>
|
||||||
|
<el-radio :label="15">{{ $t('trials:researchRecord:label:day15') }}</el-radio>
|
||||||
|
<el-radio :label="`default`">{{ $t('trials:researchRecord:label:default') }}
|
||||||
|
<el-input placeholder="" type="number" @input="handleInput" v-model="shareForm.OtherExpirationDays"
|
||||||
|
clearable size="mini" style="width: 60px;" class="dayInput" />
|
||||||
|
<span style="margin-left: 10px;">{{ $t('trials:researchRecord:label:day') }}</span>
|
||||||
|
</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('trials:researchRecord:label:LinkVerificationCode')" prop="LinkVerificationCode">
|
||||||
|
<el-radio-group v-model="shareForm.LinkVerificationCode"
|
||||||
|
@input="shareForm.OtherLinkVerificationCode = null">
|
||||||
|
<el-radio label="researchProgramNo">{{ $t('trials:researchRecord:label:researchProgramNo')
|
||||||
|
}}</el-radio>
|
||||||
|
<el-radio label="default">{{ $t('trials:researchRecord:label:default') }}
|
||||||
|
<el-input placeholder="" type="number" v-model="shareForm.OtherLinkVerificationCode" clearable
|
||||||
|
size="mini" style="width: 100px;" />
|
||||||
|
</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-button type="primary" round @click="setLink" style="float: right;">
|
||||||
|
{{ $t('trials:researchRecord:button:setLink') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="share">
|
||||||
|
<div class="shareLink">
|
||||||
|
<h3>{{ $t('trials:researchRecord:label:link') }}</h3>
|
||||||
|
<el-input ref="shareLink" v-model="shareLink" readonly type="textarea" autosize :rows="3" />
|
||||||
|
<div class="dateBox">
|
||||||
|
<span>{{ $t('trials:researchRecord:label:linkVerificationCode') }}</span>
|
||||||
|
<span>{{ LinkVerificationCode }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="dateBox">
|
||||||
|
<span>{{ $t('trials:researchRecord:label:ValidityPeriod') }}</span>
|
||||||
|
<span>{{ validityPeriod }}</span>
|
||||||
|
<span style="color: red;" v-if="isExpired">({{ $t('trials:researchRecord:label:Expired') }})</span>
|
||||||
|
</div>
|
||||||
|
<el-button type="primary" round @click="copyLink" class="shareLinkBtn"
|
||||||
|
:disabled="!validityPeriod || isExpired">
|
||||||
|
{{ $t('trials:researchRecord:button:copyLink') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="shareCode">
|
||||||
|
<h3>{{ $t('trials:researchRecord:label:shareCode') }}</h3>
|
||||||
|
<div style="display: flex;align-items: center;justify-content: space-between;">
|
||||||
|
<div class="qrCodeBox">
|
||||||
|
<div id="qrcode" ref="qrcode"></div>
|
||||||
|
</div>
|
||||||
|
<div class="codeBtnBox">
|
||||||
|
<el-button @click="handleCopyImg" type="primary" round :disabled="!validityPeriod || isExpired">{{
|
||||||
|
$t('trials:researchRecord:button:copyCode')
|
||||||
|
}}</el-button>
|
||||||
|
<el-button @click="savePic" round :disabled="!validityPeriod || isExpired">{{
|
||||||
|
$t('trials:researchRecord:button:savePic')
|
||||||
|
}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</base-model>
|
||||||
</BaseContainer>
|
</BaseContainer>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { getTrialIsSPMJoin } from '@/api/research'
|
import {
|
||||||
|
getTrialSiteSurveyList,
|
||||||
|
getTrialSiteSelect,
|
||||||
|
abandonSiteSurvey,
|
||||||
|
setTrialLinkExpirationTime,
|
||||||
|
getTrialLinkExpirationTime,
|
||||||
|
getLinkLinkExpirationTime,
|
||||||
|
} from '@/api/trials'
|
||||||
|
import { changeURLStatic } from '@/utils/history.js'
|
||||||
import BaseContainer from '@/components/BaseContainer'
|
import BaseContainer from '@/components/BaseContainer'
|
||||||
import ResearchList from './components/ResearchList'
|
import Pagination from '@/components/Pagination'
|
||||||
|
import Users from './components/users'
|
||||||
|
import ResearchForm from '@/views/research/form'
|
||||||
|
import BaseModel from '@/components/BaseModel'
|
||||||
|
import ImageManual from './components/ImageManual'
|
||||||
|
import QRCode from 'qrcodejs2'
|
||||||
|
|
||||||
|
const searchDataDefault = () => {
|
||||||
|
return {
|
||||||
|
SortField: '',
|
||||||
|
Asc: true,
|
||||||
|
PageIndex: 1,
|
||||||
|
PageSize: 20,
|
||||||
|
TrialSiteId: '',
|
||||||
|
UserKeyInfo: '',
|
||||||
|
State: null,
|
||||||
|
IsDeleted: '',
|
||||||
|
DateRange: [],
|
||||||
|
PreliminaryUserName: null,
|
||||||
|
ReviewerUserName: null,
|
||||||
|
}
|
||||||
|
}
|
||||||
export default {
|
export default {
|
||||||
name: 'SiteResearch',
|
name: 'SiteResearchList',
|
||||||
components: {
|
components: { BaseContainer, Pagination, Users, ResearchForm, BaseModel, ImageManual },
|
||||||
BaseContainer,
|
|
||||||
ResearchList
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isSPMJoin: true,
|
searchData: searchDataDefault(),
|
||||||
activeStatus: 0
|
loading: false,
|
||||||
}
|
list: [],
|
||||||
|
total: 0,
|
||||||
|
trialId: this.$route.query.trialId,
|
||||||
|
siteOptions: [],
|
||||||
|
researchUserVisible: false,
|
||||||
|
researchInfoVisible: false,
|
||||||
|
share_model: {
|
||||||
|
visible: false,
|
||||||
|
title: this.$t('trials:researchRecord:title:shark'),
|
||||||
|
width: '1000px',
|
||||||
},
|
},
|
||||||
watch: {
|
shareLink: '',
|
||||||
activeStatus: {
|
researchState: this.$d.ResearchRecord,
|
||||||
deep: true,
|
qrcode: null,
|
||||||
immediate: true,
|
validityPeriod: null,
|
||||||
handler(v) {
|
LinkVerificationCode: null,
|
||||||
this.$nextTick(() => {
|
isExpired: false,
|
||||||
if (!this.isSPMJoin && v > 0) {
|
shareLoading: false,
|
||||||
this.$refs['researchList'].searchData.State = v + 1
|
shareForm: {
|
||||||
|
ExpirationDays: null,
|
||||||
|
OtherExpirationDays: null,
|
||||||
|
LinkVerificationCode: null,
|
||||||
|
OtherLinkVerificationCode: null,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
ExpirationDays: [
|
||||||
|
{ required: true, message: this.$t("common:ruleMessage:select"), trigger: 'blur' },
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (value === 'default' && !this.shareForm.OtherExpirationDays) {
|
||||||
|
callback(new Error(this.$t("common:ruleMessage:specify")));
|
||||||
} else {
|
} else {
|
||||||
this.$refs['researchList'].searchData.State = v
|
callback()
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$refs['researchList'].getList()
|
}, trigger: 'blur'
|
||||||
})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
],
|
||||||
},
|
LinkVerificationCode: [
|
||||||
computed: {
|
{ required: true, message: this.$t("common:ruleMessage:select"), trigger: 'blur' },
|
||||||
isAudit() {
|
{
|
||||||
if (this.isSPMJoin) {
|
validator: (rule, value, callback) => {
|
||||||
return (this.hasPermi(['role:spm', 'role:cpm', 'role:apm']) && this.activeStatus === 1) || (this.hasPermi(['role:pm']) && this.activeStatus === 2)
|
if (value === 'default' && !this.shareForm.OtherLinkVerificationCode) {
|
||||||
|
callback(new Error(this.$t("common:ruleMessage:specify")));
|
||||||
} else {
|
} else {
|
||||||
return this.hasPermi(['role:pm']) && this.activeStatus === 1
|
callback()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}, trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
ImageManualVisible: false,
|
||||||
|
trialSiteSurveyId: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getTrialIsSPMJoin()
|
this.getList()
|
||||||
|
this.getSite()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getTrialIsSPMJoin() {
|
async getLinkTimeIsExpired() {
|
||||||
try {
|
try {
|
||||||
let trialId = this.$route.query.trialId
|
let data = {
|
||||||
if (!trialId) return
|
TrialId: this.$route.query.trialId,
|
||||||
let res = await getTrialIsSPMJoin(trialId)
|
}
|
||||||
this.isSPMJoin = res.Result
|
this.shareLoading = true
|
||||||
if (this.isSPMJoin) {
|
let res = await getLinkLinkExpirationTime(data)
|
||||||
if (this.hasPermi(['role:pm'])) this.activeStatus = 2
|
this.shareLoading = false
|
||||||
if (this.hasPermi(['role:spm', 'role:cpm', 'role:apm'])) this.activeStatus = 1
|
if (res.IsSuccess) {
|
||||||
|
this.isExpired = res.Result.IsIsExpired
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
this.shareLoading = false
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getLinkTime() {
|
||||||
|
try {
|
||||||
|
let data = {
|
||||||
|
TrialId: this.$route.query.trialId,
|
||||||
|
}
|
||||||
|
this.shareLoading = true
|
||||||
|
let res = await getTrialLinkExpirationTime(data)
|
||||||
|
this.shareLoading = false
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
this.validityPeriod = res.Result.LinkExpirationTime
|
||||||
|
this.LinkVerificationCode = res.Result.LinkVerificationCode || res.Result.ResearchProgramNo
|
||||||
|
if (!this.validityPeriod) {
|
||||||
|
this.LinkVerificationCode = null
|
||||||
|
}
|
||||||
|
if (!this.validityPeriod) return false
|
||||||
|
this.getLinkTimeIsExpired()
|
||||||
|
this.shareLink = `${location.protocol}//${location.host}/researchLogin?trialId=${this.$route.query.trialId}`
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.creatQrCode()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
this.shareLoading = false
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async setLink() {
|
||||||
|
try {
|
||||||
|
let validate = await this.$refs.shareForm.validate()
|
||||||
|
if (!validate) return false
|
||||||
|
let data = {
|
||||||
|
TrialId: this.$route.query.trialId,
|
||||||
|
ExpirationDays: this.shareForm.ExpirationDays,
|
||||||
|
LinkVerificationCode: this.shareForm.LinkVerificationCode
|
||||||
|
}
|
||||||
|
if (this.shareForm.LinkVerificationCode === 'researchProgramNo') {
|
||||||
|
data.LinkVerificationCode = null
|
||||||
|
}
|
||||||
|
if (this.shareForm.LinkVerificationCode === 'default') {
|
||||||
|
data.LinkVerificationCode = this.shareForm.OtherLinkVerificationCode
|
||||||
|
}
|
||||||
|
if (this.shareForm.ExpirationDays === 'default') {
|
||||||
|
data.ExpirationDays = this.shareForm.OtherExpirationDays
|
||||||
|
}
|
||||||
|
this.shareLoading = true
|
||||||
|
let res = await setTrialLinkExpirationTime(data)
|
||||||
|
this.shareLoading = false
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
this.getLinkTime()
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
this.shareLoading = false
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleInput(val) {
|
||||||
|
// 过滤掉非数字字符,并取整为正整数
|
||||||
|
this.shareForm.OtherExpirationDays = val.replace(/[^\d]/g, '').replace(/^0+/, '')
|
||||||
|
},
|
||||||
|
openImageManual() {
|
||||||
|
// if (!this.trialSiteSurveyId) return false
|
||||||
|
this.ImageManualVisible = true
|
||||||
|
},
|
||||||
|
// 获取系统文件数据
|
||||||
|
getList() {
|
||||||
|
this.loading = true
|
||||||
|
this.searchData.TrialId = this.trialId
|
||||||
|
if (this.searchData.DateRange && this.searchData.DateRange.length === 2) {
|
||||||
|
this.searchData.UpdateTimeBegin = this.searchData.DateRange[0]
|
||||||
|
this.searchData.updateTimeEnd = this.searchData.DateRange[1]
|
||||||
} else {
|
} else {
|
||||||
if (this.hasPermi(['role:pm'])) this.activeStatus = 1
|
this.searchData.UpdateTimeBegin = ''
|
||||||
if (this.hasPermi(['role:spm', 'role:cpm', 'role:apm'])) this.activeStatus = 0
|
this.searchData.updateTimeEnd = ''
|
||||||
}
|
}
|
||||||
} catch (e) {
|
getTrialSiteSurveyList(this.searchData)
|
||||||
console.log(e)
|
.then((res) => {
|
||||||
}
|
this.loading = false
|
||||||
|
this.list = res.Result.CurrentPageData
|
||||||
|
this.total = res.Result.TotalCount
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
handleClick(step) {
|
// 查看调查表记录详情
|
||||||
this.activeStatus = step
|
handleViewResearchList(row) {
|
||||||
if (!this.isSPMJoin && step > 0) this.activeStatus = step - 1
|
changeURLStatic('trialSiteSurveyId', row.Id)
|
||||||
|
this.researchInfoVisible = true
|
||||||
},
|
},
|
||||||
|
// 废除待提交的调查表
|
||||||
|
handleRepealResearch(row) {
|
||||||
|
// 是否确认废除?
|
||||||
|
this.$confirm(this.$t('trials:researchRecord:message:abolish'), {
|
||||||
|
type: 'warning',
|
||||||
|
distinguishCancelAndClose: true,
|
||||||
|
}).then(() => {
|
||||||
|
abandonSiteSurvey(this.trialId, row.Id).then((res) => {
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
this.getList()
|
||||||
|
// 废除成功
|
||||||
|
this.$message.success(
|
||||||
|
this.$t('trials:researchRecord:message:abolishSuccessfully')
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 展示当前项目下所有调查表需生成账户的用户信息
|
||||||
|
showResearchUser() {
|
||||||
|
this.researchUserVisible = true
|
||||||
|
},
|
||||||
|
// 复制链接
|
||||||
|
copyLink() {
|
||||||
|
// 中心调研表链接
|
||||||
|
this.$copyText(
|
||||||
|
`${this.$t('trials:researchRecord:message:researchFormLink')}: ${this.shareLink
|
||||||
|
}\n${this.$t('trials:researchRecord:label:linkVerificationCode')}${this.LinkVerificationCode}\n${this.$t('trials:researchRecord:label:ValidityPeriod')}${this.validityPeriod}`
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
// 复制成功
|
||||||
|
this.$message.success(
|
||||||
|
this.$t('trials:researchRecord:message:copySuccessfully')
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
// 复制失败
|
||||||
|
this.$alert(this.$t('trials:researchRecord:message:copyFailed'))
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 创建二维码
|
||||||
|
creatQrCode() {
|
||||||
|
this.$refs.qrcode.innerHTML = '' //清除二维码方法一
|
||||||
|
let text = this.shareLink
|
||||||
|
this.qrcode = new QRCode(this.$refs.qrcode, {
|
||||||
|
text: text, //页面地址 ,如果页面需要参数传递请注意哈希模式#
|
||||||
|
width: 200,
|
||||||
|
height: 200,
|
||||||
|
colorDark: '#000000',
|
||||||
|
colorLight: '#ffffff',
|
||||||
|
correctLevel: QRCode.CorrectLevel.H,
|
||||||
|
})
|
||||||
|
// qrcode.clear(); // 清除二维码方法二
|
||||||
|
},
|
||||||
|
// 下载二维码
|
||||||
|
savePic() {
|
||||||
|
let qrCodeCanvas = document
|
||||||
|
.getElementById('qrcode')
|
||||||
|
.getElementsByTagName('canvas')
|
||||||
|
let a = document.createElement('a')
|
||||||
|
a.href = qrCodeCanvas[0].toDataURL('image/url')
|
||||||
|
a.download = `${this.$route.query.researchProgramNo}${this.$t('trials:researchRecord:title:code')}.png`
|
||||||
|
a.click()
|
||||||
|
},
|
||||||
|
// 复制二维码
|
||||||
|
handleCopyImg() {
|
||||||
|
let qrCodeCanvas = document
|
||||||
|
.getElementById('qrcode')
|
||||||
|
.getElementsByTagName('canvas')
|
||||||
|
qrCodeCanvas[0].toBlob(async (blob) => {
|
||||||
|
console.log(blob)
|
||||||
|
const data = [
|
||||||
|
new ClipboardItem({
|
||||||
|
[blob.type]: blob,
|
||||||
|
}),
|
||||||
|
] // https://w3c.github.io/clipboard-apis/#dom-clipboard-write
|
||||||
|
await navigator.clipboard.write(data).then(
|
||||||
|
() => {
|
||||||
|
this.$message.success(
|
||||||
|
this.$t('trials:researchRecord:message:copySuccess')
|
||||||
|
)
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
this.$message.error(
|
||||||
|
this.$t('trials:researchRecord:message:UnableWrite')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 获取site下拉框数据
|
||||||
|
getSite() {
|
||||||
|
getTrialSiteSelect(this.trialId).then((res) => {
|
||||||
|
this.siteOptions = res.Result
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 展示调查表链接
|
||||||
|
showResearchLink() {
|
||||||
|
this.shareForm = {
|
||||||
|
ExpirationDays: null,
|
||||||
|
OtherExpirationDays: null,
|
||||||
|
LinkVerificationCode: null,
|
||||||
|
OtherLinkVerificationCode: null,
|
||||||
|
}
|
||||||
|
this.validityPeriod = null
|
||||||
|
this.isExpired = false
|
||||||
|
this.share_model.visible = true
|
||||||
|
this.getLinkTime()
|
||||||
|
// &lang=${this.$i18n.locale}
|
||||||
|
// this.trialSiteSurveyId = this.list[0].Id
|
||||||
|
},
|
||||||
|
// 重置
|
||||||
|
handleReset() {
|
||||||
|
this.searchData = searchDataDefault()
|
||||||
|
this.searchData.DateRange = []
|
||||||
|
if (this.searchData.DateRange && this.searchData.DateRange.length === 2) {
|
||||||
|
this.searchData.UpdateTimeBegin = this.searchData.DateRange[0]
|
||||||
|
this.searchData.updateTimeEnd = this.searchData.DateRange[1]
|
||||||
|
} else {
|
||||||
|
this.searchData.UpdateTimeBegin = ''
|
||||||
|
this.searchData.updateTimeEnd = ''
|
||||||
|
}
|
||||||
|
this.getList()
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.siteResearchList.clearSort()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 查询
|
||||||
|
handleSearch() {
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
// 排序
|
||||||
|
handleSortByColumn(column) {
|
||||||
|
if (column.order === 'ascending') {
|
||||||
|
this.searchData.Asc = true
|
||||||
|
} else {
|
||||||
|
this.searchData.Asc = false
|
||||||
|
}
|
||||||
|
this.searchData.SortField = column.prop
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.qrcode) {
|
||||||
|
this.qrcode = null
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.step-wrapper {
|
.date,
|
||||||
|
.share {
|
||||||
|
width: 55%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-steps {
|
.dayInput {
|
||||||
height: 80px;
|
::v-deep .el-input__inner {
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.date {
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share {
|
||||||
|
width: 45%;
|
||||||
|
padding-left: 5%;
|
||||||
|
border-left: 1px solid #f0f0f0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shareLinkBtn {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qrCodeBox {
|
||||||
|
width: 220px;
|
||||||
|
height: 220px;
|
||||||
|
display: flex;
|
||||||
|
border: 1px solid #c0c4cc;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 1px 1px 5px #c0c4cc;
|
||||||
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.step-content {
|
.dateBox {
|
||||||
flex: 1;
|
margin: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.codeBtnBox {
|
||||||
height: 40px;
|
|
||||||
line-height: 40px;
|
|
||||||
padding-left: 5px;
|
|
||||||
background: #e4ebf1;
|
|
||||||
border-left: 3px solid #0fc8e0;
|
|
||||||
font-size: 13px;
|
|
||||||
|
|
||||||
p {
|
::v-deep .el-button {
|
||||||
padding: 0;
|
display: block;
|
||||||
margin: 0;
|
margin: 10px auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.trial-wrapper {
|
|
||||||
height: 60px;
|
|
||||||
|
|
||||||
.div-row {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin: 10px 20px !important;
|
|
||||||
font-size: 13px;
|
|
||||||
|
|
||||||
.div-col {
|
|
||||||
flex: 1;
|
|
||||||
width: 100px;
|
|
||||||
white-space: nowrap !important;
|
|
||||||
text-overflow: ellipsis !important;
|
|
||||||
word-break: break-word !important;
|
|
||||||
overflow: hidden !important;
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.div-textarea {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-step__head.is-process {
|
|
||||||
color: #428bca;
|
|
||||||
border-color: #428bca;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-step__title.is-process {
|
|
||||||
color: #428bca;
|
|
||||||
border-color: #428bca;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-step__description.is-process {
|
|
||||||
color: #428bca;
|
|
||||||
border-color: #428bca;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-step__head.is-process .el-step__line {
|
|
||||||
background-color: #428bca;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-step__head.is-finish {
|
|
||||||
color: #303133;
|
|
||||||
border-color: #303133;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-step__title.is-finish {
|
|
||||||
color: #303133;
|
|
||||||
border-color: #303133;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-step__description.is-finish {
|
|
||||||
color: #303133;
|
|
||||||
border-color: #303133;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-step__title.is-process {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-step__title.is-finish {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-step__head.is-finish .el-step__line {
|
|
||||||
background-color: #303133;
|
|
||||||
}
|
|
||||||
|
|
||||||
.click_cursor {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1675,7 +1675,10 @@ export default {
|
|||||||
cornerstone.getDefaultViewportForImage(this.canvas, image)
|
cornerstone.getDefaultViewportForImage(this.canvas, image)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
getInfo() {
|
||||||
|
var image = cornerstone.getImage(this.canvas)
|
||||||
|
return image
|
||||||
|
},
|
||||||
toggleDicomInfo() {
|
toggleDicomInfo() {
|
||||||
this.toolState.dicomInfoVisible = !this.toolState.dicomInfoVisible
|
this.toolState.dicomInfoVisible = !this.toolState.dicomInfoVisible
|
||||||
if (this.toolState.dicomInfoVisible) {
|
if (this.toolState.dicomInfoVisible) {
|
||||||
|
|||||||
@@ -422,7 +422,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-tooltip v-if="trialCriterion.ImageUploadEnum > 0 && currentReadingTaskState < 2" v-hasPermi="['role:ir']"
|
<el-tooltip v-if="trialCriterion.ImageUploadEnum > 0"
|
||||||
class="item" effect="dark" :content="$t('trials:reading:button:upload')" placement="bottom">
|
class="item" effect="dark" :content="$t('trials:reading:button:upload')" placement="bottom">
|
||||||
<div class="tool-wrapper">
|
<div class="tool-wrapper">
|
||||||
<div class="icon" @click.prevent="openUploadImage('upload')">
|
<div class="icon" @click.prevent="openUploadImage('upload')">
|
||||||
@@ -431,15 +431,7 @@
|
|||||||
<div class="text">{{ $t('trials:reading:button:upload') }}</div>
|
<div class="text">{{ $t('trials:reading:button:upload') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip v-if="trialCriterion.ImageDownloadEnum > 0" v-hasPermi="[
|
<el-tooltip v-if="trialCriterion.ImageDownloadEnum > 0" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
||||||
'role:ir',
|
|
||||||
'role:mim',
|
|
||||||
'role:mc',
|
|
||||||
'role:pm',
|
|
||||||
'role:apm',
|
|
||||||
'role:ea',
|
|
||||||
'role:qa',
|
|
||||||
]" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
|
||||||
<div class="tool-wrapper">
|
<div class="tool-wrapper">
|
||||||
<div class="icon" @click.prevent="openUploadImage('download')">
|
<div class="icon" @click.prevent="openUploadImage('download')">
|
||||||
<i class="el-icon-download svg-icon" />
|
<i class="el-icon-download svg-icon" />
|
||||||
@@ -447,6 +439,10 @@
|
|||||||
<div class="text">{{ $t('trials:reading:button:download') }}</div>
|
<div class="text">{{ $t('trials:reading:button:download') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
<label for="Replacement" style="color: #fff;cursor: pointer;">
|
||||||
|
替换
|
||||||
|
</label>
|
||||||
|
<input type="file" id="Replacement" @change="beginScanFiles($event, 'replace')" style="display: none;">
|
||||||
<div style="margin-left:auto;">
|
<div style="margin-left:auto;">
|
||||||
<div style="padding:5px;display: flex;">
|
<div style="padding:5px;display: flex;">
|
||||||
<!-- 手册 -->
|
<!-- 手册 -->
|
||||||
@@ -708,7 +704,8 @@
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
<upload-dicom-and-nonedicom v-if="uploadImageVisible" :subject-id="uploadSubjectId"
|
<upload-dicom-and-nonedicom v-if="uploadImageVisible" :subject-id="uploadSubjectId"
|
||||||
:subject-code="uploadSubjectCode" :criterion="uploadTrialCriterion" :visible.sync="uploadImageVisible"
|
:subject-code="uploadSubjectCode" :criterion="uploadTrialCriterion" :visible.sync="uploadImageVisible"
|
||||||
:visit-task-id="taskId" :is-reading-task-view-in-order="isReadingTaskViewInOrder" :isReading="true" />
|
:visit-task-id="taskId" :is-reading-task-view-in-order="isReadingTaskViewInOrder" :isReading="true"
|
||||||
|
:StudyInstanceUID="StudyInstanceUID" />
|
||||||
<download-dicom-and-nonedicom v-if="downloadImageVisible" :subject-id="uploadSubjectId"
|
<download-dicom-and-nonedicom v-if="downloadImageVisible" :subject-id="uploadSubjectId"
|
||||||
:subject-code="uploadSubjectCode" :criterion="uploadTrialCriterion" :task-id="taskId"
|
:subject-code="uploadSubjectCode" :criterion="uploadTrialCriterion" :task-id="taskId"
|
||||||
:visible.sync="downloadImageVisible" :isReading="true" />
|
:visible.sync="downloadImageVisible" :isReading="true" />
|
||||||
@@ -767,6 +764,8 @@ import const_ from '@/const/sign-code'
|
|||||||
import { changeURLStatic } from '@/utils/history.js'
|
import { changeURLStatic } from '@/utils/history.js'
|
||||||
import SystemInfo from "@/utils/systemInfo";
|
import SystemInfo from "@/utils/systemInfo";
|
||||||
import md5 from 'js-md5'
|
import md5 from 'js-md5'
|
||||||
|
import { changeFile } from "./upload.js"
|
||||||
|
import dcmjs from '@/utils/dcmUpload/dcmjs'
|
||||||
export default {
|
export default {
|
||||||
name: 'DicomViewer',
|
name: 'DicomViewer',
|
||||||
components: {
|
components: {
|
||||||
@@ -845,6 +844,10 @@ export default {
|
|||||||
default() {
|
default() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
Loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -978,7 +981,10 @@ export default {
|
|||||||
fullScreenWidth: window.innerWidth - 570 + 'px',
|
fullScreenWidth: window.innerWidth - 570 + 'px',
|
||||||
fullScreenHeight: window.innerHeight - 130 + 'px',
|
fullScreenHeight: window.innerHeight - 130 + 'px',
|
||||||
|
|
||||||
ManualsClose: false
|
ManualsClose: false,
|
||||||
|
fileKey: null,
|
||||||
|
file: null,
|
||||||
|
StudyInstanceUID: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1213,6 +1219,12 @@ export default {
|
|||||||
this.AspectRatio = windowWidth / windowHeight
|
this.AspectRatio = windowWidth / windowHeight
|
||||||
};
|
};
|
||||||
this.getSystemInfoReading()
|
this.getSystemInfoReading()
|
||||||
|
DicomEvent.$on('sendStudyFile', (study) => {
|
||||||
|
let image = this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].getInfo()
|
||||||
|
study.visitTaskList = this.visitTaskList
|
||||||
|
this.$emit("update:Loading", true)
|
||||||
|
changeFile('IR', this.file, study, image)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
DicomEvent.$off('updateImage')
|
DicomEvent.$off('updateImage')
|
||||||
@@ -1236,6 +1248,11 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
beginScanFiles(e, key) {
|
||||||
|
this.fileKey = key
|
||||||
|
this.file = e.target.files[0]
|
||||||
|
DicomEvent.$emit('getStudyFile')
|
||||||
|
},
|
||||||
handleReadingChart(e) {
|
handleReadingChart(e) {
|
||||||
this.$emit('handleReadingChart', e)
|
this.$emit('handleReadingChart', e)
|
||||||
},
|
},
|
||||||
@@ -1283,6 +1300,10 @@ export default {
|
|||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
this.taskId = this.visitTaskList[idx].VisitTaskId
|
this.taskId = this.visitTaskList[idx].VisitTaskId
|
||||||
}
|
}
|
||||||
|
let image = this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].getInfo()
|
||||||
|
let dataset = dcmjs.data.DicomMessage.readFile(image.data.byteArray.buffer)
|
||||||
|
this.StudyInstanceUID = dataset.dict['0020000D'].Value[0]
|
||||||
|
dataset = null
|
||||||
this.uploadSubjectCode = localStorage.getItem("subjectCode")
|
this.uploadSubjectCode = localStorage.getItem("subjectCode")
|
||||||
this.uploadSubjectId = localStorage.getItem("subjectId")
|
this.uploadSubjectId = localStorage.getItem("subjectId")
|
||||||
this.uploadTrialCriterion = this.trialCriterion
|
this.uploadTrialCriterion = this.trialCriterion
|
||||||
|
|||||||
@@ -189,22 +189,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 计算值 -->
|
<!-- 计算值 -->
|
||||||
<Questions
|
<Questions ref="ecrf2" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
|
||||||
ref="ecrf2"
|
:group-classify="4" style="margin-top:20px" />
|
||||||
:question-form-change-state="true"
|
|
||||||
:question-form-change-num="0"
|
|
||||||
:is-qulity-issues="false"
|
|
||||||
:group-classify="4"
|
|
||||||
:question-type="12"
|
|
||||||
style="margin-top:20px" />
|
|
||||||
|
|
||||||
<!-- 评估结果 -->
|
<!-- 评估结果 -->
|
||||||
<Questions
|
<Questions ref="ecrf3" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
|
||||||
ref="ecrf3"
|
|
||||||
:question-form-change-state="true"
|
|
||||||
:question-form-change-num="0"
|
|
||||||
:is-qulity-issues="false"
|
|
||||||
:question-type="12"
|
|
||||||
:group-classify="5" />
|
:group-classify="5" />
|
||||||
<!-- 新增、编辑弹窗 -->
|
<!-- 新增、编辑弹窗 -->
|
||||||
<el-dialog v-if="addOrEdit.visible" :visible.sync="addOrEdit.visible" :close-on-click-modal="false"
|
<el-dialog v-if="addOrEdit.visible" :visible.sync="addOrEdit.visible" :close-on-click-modal="false"
|
||||||
@@ -633,7 +622,7 @@ export default {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async handleSave(index, options = {}) {
|
async handleSave(index) {
|
||||||
if (this.rowSaveLoadingMap[index]) return
|
if (this.rowSaveLoadingMap[index]) return
|
||||||
const refName = `questions${index}`
|
const refName = `questions${index}`
|
||||||
this.$set(this.rowSaveLoadingMap, index, true)
|
this.$set(this.rowSaveLoadingMap, index, true)
|
||||||
@@ -651,13 +640,9 @@ export default {
|
|||||||
answers: answers
|
answers: answers
|
||||||
}
|
}
|
||||||
await saveTaskQuestion(12, params)
|
await saveTaskQuestion(12, params)
|
||||||
if (!options.silentSuccess) {
|
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
}
|
|
||||||
DicomEvent.$emit('getReportInfo', true)
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
if (!options.skipRefresh) {
|
this.refreshQuestions()
|
||||||
await this.refreshQuestions()
|
|
||||||
}
|
|
||||||
this.formChanged = false
|
this.formChanged = false
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
@@ -873,29 +858,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async uploadDlgClose() {
|
async uploadDlgClose() {
|
||||||
try {
|
this.refreshQuestions()
|
||||||
await this.refreshQuestions()
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
const saveTasks = []
|
|
||||||
for (let index = 0; index < this.questions.length; index++) {
|
|
||||||
const qs = this.questions[index]
|
|
||||||
if (qs.GroupClassify === 6) {
|
|
||||||
saveTasks.push(() => this.handleSave(index, { silentSuccess: true, skipRefresh: true }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
saveTasks.push(() => this.$refs['ecrf2'] && this.$refs['ecrf2'].handleSave({ silentSuccess: true, skipRefresh: true }))
|
|
||||||
saveTasks.push(() => this.$refs['ecrf3'] && this.$refs['ecrf3'].handleSave({ silentSuccess: true, skipRefresh: true }))
|
|
||||||
for (const saveTask of saveTasks) {
|
|
||||||
try {
|
|
||||||
await saveTask()
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
} finally {
|
|
||||||
this.upload.visible = false
|
this.upload.visible = false
|
||||||
}
|
|
||||||
},
|
},
|
||||||
renderHeader(h, { column, $index }) {
|
renderHeader(h, { column, $index }) {
|
||||||
const span = document.createElement('span')
|
const span = document.createElement('span')
|
||||||
|
|||||||
@@ -30,12 +30,12 @@
|
|||||||
<div class="image-viewer__actions__inner">
|
<div class="image-viewer__actions__inner">
|
||||||
<i class="el-icon-zoom-out" @click="handleActions('zoomOut')" />
|
<i class="el-icon-zoom-out" @click="handleActions('zoomOut')" />
|
||||||
<i class="el-icon-zoom-in" @click="handleActions('zoomIn')" />
|
<i class="el-icon-zoom-in" @click="handleActions('zoomIn')" />
|
||||||
<!-- <i class="el-image-viewer__actions__divider" /> -->
|
<i class="el-image-viewer__actions__divider" />
|
||||||
<i class="el-icon-c-scale-to-original" @click="toggleMode" />
|
<i class="el-icon-c-scale-to-original" @click="toggleMode" />
|
||||||
<!-- <i class="el-image-viewer__actions__divider" /> -->
|
<i class="el-image-viewer__actions__divider" />
|
||||||
<i class="el-icon-refresh-left" @click="handleActions('anticlocelise')" />
|
<i class="el-icon-refresh-left" @click="handleActions('anticlocelise')" />
|
||||||
<i class="el-icon-refresh-right" @click="handleActions('clocelise')" />
|
<i class="el-icon-refresh-right" @click="handleActions('clocelise')" />
|
||||||
<i v-if="readingTaskState < 2 && taskInfo.CriterionType !== 19 && taskInfo.CriterionType !== 20" class="el-icon-bottom-right"
|
<i v-if="readingTaskState < 2" class="el-icon-bottom-right"
|
||||||
:style="{ cursor: isToolDisabled || readingTaskState >= 2 ? 'not-allowed' : 'pointer' }"
|
:style="{ cursor: isToolDisabled || readingTaskState >= 2 ? 'not-allowed' : 'pointer' }"
|
||||||
@click="handleDrawArrow" />
|
@click="handleDrawArrow" />
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
:style="{cursor:isToolDisabled || readingTaskState >=2 ?'not-allowed':'pointer'}"
|
:style="{cursor:isToolDisabled || readingTaskState >=2 ?'not-allowed':'pointer'}"
|
||||||
@click="handleDrawRectangle"
|
@click="handleDrawRectangle"
|
||||||
/> -->
|
/> -->
|
||||||
<svg-icon v-if="readingTaskState < 2 && taskInfo.CriterionType !== 19 && taskInfo.CriterionType !== 20" icon-class="rectangle" class="svg-icon"
|
<svg-icon v-if="readingTaskState < 2" icon-class="rectangle" class="svg-icon"
|
||||||
:style="{ cursor: isToolDisabled || readingTaskState >= 2 ? 'not-allowed' : 'pointer' }"
|
:style="{ cursor: isToolDisabled || readingTaskState >= 2 ? 'not-allowed' : 'pointer' }"
|
||||||
@click="handleDrawRectangle" />
|
@click="handleDrawRectangle" />
|
||||||
</div>
|
</div>
|
||||||
@@ -109,7 +109,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const taskInfo = JSON.parse(localStorage.getItem('taskInfo') || '{}')
|
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
index: this.initialIndex,
|
index: this.initialIndex,
|
||||||
@@ -138,13 +137,11 @@ export default {
|
|||||||
currentDrawData: {},
|
currentDrawData: {},
|
||||||
canvasData: [],
|
canvasData: [],
|
||||||
imgZoom: 1,
|
imgZoom: 1,
|
||||||
isDragging: false,
|
|
||||||
isToolDisabled: false,
|
isToolDisabled: false,
|
||||||
lesionName: '',
|
lesionName: '',
|
||||||
visitTaskId: '',
|
visitTaskId: '',
|
||||||
isInit: false,
|
isInit: false,
|
||||||
imgSize: { height: '', width: '' }, // 图片原始尺寸
|
imgSize: { height: '', width: '' } // 图片原始尺寸
|
||||||
taskInfo
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -212,10 +209,6 @@ export default {
|
|||||||
}
|
}
|
||||||
this.deviceSupportInstall()
|
this.deviceSupportInstall()
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
|
||||||
window.removeEventListener('message', this.receiveMsg)
|
|
||||||
this.stopDragging()
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
getCanvasData() {
|
getCanvasData() {
|
||||||
return new Promise(async resolve => {
|
return new Promise(async resolve => {
|
||||||
@@ -344,55 +337,25 @@ export default {
|
|||||||
// 初始化画布
|
// 初始化画布
|
||||||
initCanvas(img) {
|
initCanvas(img) {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
this.canvasSize.height = img.height
|
||||||
|
this.canvasSize.width = img.width
|
||||||
|
|
||||||
this.imgSize.height = img.height
|
this.imgSize.height = img.height
|
||||||
this.imgSize.width = img.width
|
this.imgSize.width = img.width
|
||||||
|
|
||||||
const canvasDiv = document.getElementsByClassName('image-viewer__canvas')[0]
|
const canvasDiv = document.getElementsByClassName('image-viewer__canvas')[0]
|
||||||
const widthRatio = canvasDiv && canvasDiv.offsetWidth ? canvasDiv.offsetWidth / img.width : 1
|
|
||||||
const heightRatio = canvasDiv && canvasDiv.offsetHeight ? canvasDiv.offsetHeight / img.height : 1
|
|
||||||
this.imgZoom = Math.min(widthRatio, heightRatio, 1)
|
|
||||||
this.canvasSize.height = Math.round(img.height * this.imgZoom)
|
|
||||||
this.canvasSize.width = Math.round(img.width * this.imgZoom)
|
|
||||||
this.canvasPosition = {
|
this.canvasPosition = {
|
||||||
x: canvasDiv.offsetWidth / 2 - this.canvasSize.width / 2,
|
x: canvasDiv.offsetWidth / 2 - img.width / 2,
|
||||||
y: canvasDiv.offsetHeight / 2 - this.canvasSize.height / 2 - 25
|
y: canvasDiv.offsetHeight / 2 - img.height / 2 - 25
|
||||||
} // 背景居中
|
} // 背景居中
|
||||||
|
|
||||||
this.$nextTick(async () => {
|
this.$nextTick(async () => {
|
||||||
ctx = document.getElementById('canvas').getContext('2d') // 获取上下文
|
ctx = document.getElementById('canvas').getContext('2d') // 获取上下文
|
||||||
await ctx.drawImage(img, 0, 0, this.canvasSize.width, this.canvasSize.height) // 在canvas中绘制图片(图片、起始位置、绘图尺寸)
|
await ctx.drawImage(img, 0, 0, img.width, img.height) // 在canvas中绘制图片(图片、起始位置、绘图尺寸)
|
||||||
this.drawToArr()
|
this.drawToArr()
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
scalePoint(point) {
|
|
||||||
return {
|
|
||||||
x: point.x * this.imgZoom,
|
|
||||||
y: point.y * this.imgZoom
|
|
||||||
}
|
|
||||||
},
|
|
||||||
startDragging(e) {
|
|
||||||
const { offsetX, offsetY } = this.transform
|
|
||||||
const startX = e.pageX
|
|
||||||
const startY = e.pageY
|
|
||||||
this.isDragging = true
|
|
||||||
this._dragHandler = rafThrottle((ev) => {
|
|
||||||
this.transform.offsetX = offsetX + ev.pageX - startX
|
|
||||||
this.transform.offsetY = offsetY + ev.pageY - startY
|
|
||||||
})
|
|
||||||
this._dragEndHandler = () => {
|
|
||||||
this.stopDragging()
|
|
||||||
}
|
|
||||||
on(document, 'mousemove', this._dragHandler)
|
|
||||||
on(document, 'mouseup', this._dragEndHandler)
|
|
||||||
},
|
|
||||||
stopDragging() {
|
|
||||||
off(document, 'mousemove', this._dragHandler)
|
|
||||||
off(document, 'mouseup', this._dragEndHandler)
|
|
||||||
this._dragHandler = null
|
|
||||||
this._dragEndHandler = null
|
|
||||||
this.isDragging = false
|
|
||||||
},
|
|
||||||
|
|
||||||
// 清空画布
|
// 清空画布
|
||||||
clearCanvas() {
|
clearCanvas() {
|
||||||
@@ -418,11 +381,6 @@ export default {
|
|||||||
if (e.button !== 0) {
|
if (e.button !== 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!this.model) {
|
|
||||||
this.startDragging(e)
|
|
||||||
e.preventDefault()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.isMouseDown = true // 打开鼠标状态
|
this.isMouseDown = true // 打开鼠标状态
|
||||||
// 获取画布中鼠标开始点击位置
|
// 获取画布中鼠标开始点击位置
|
||||||
this.canvasMouseStart = {
|
this.canvasMouseStart = {
|
||||||
@@ -433,9 +391,6 @@ export default {
|
|||||||
|
|
||||||
// 鼠标移动事件
|
// 鼠标移动事件
|
||||||
async handleMouseMove(e) {
|
async handleMouseMove(e) {
|
||||||
if (!this.model || this.isDragging) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 获取屏幕中鼠标位置(显示实时坐标)
|
// 获取屏幕中鼠标位置(显示实时坐标)
|
||||||
this.mousePosition = {
|
this.mousePosition = {
|
||||||
x: e.pageX,
|
x: e.pageX,
|
||||||
@@ -482,12 +437,10 @@ export default {
|
|||||||
var headlen = 10// 自定义箭头线的长度
|
var headlen = 10// 自定义箭头线的长度
|
||||||
var theta = 45// 自定义箭头线与直线的夹角
|
var theta = 45// 自定义箭头线与直线的夹角
|
||||||
var arrowX, arrowY// 箭头线终点坐标
|
var arrowX, arrowY// 箭头线终点坐标
|
||||||
var start = this.scalePoint(e.data.handles.start)
|
var fromX = e.data.handles.start.x
|
||||||
var end = this.scalePoint(e.data.handles.end)
|
var fromY = e.data.handles.start.y
|
||||||
var fromX = start.x
|
var toX = e.data.handles.end.x
|
||||||
var fromY = start.y
|
var toY = e.data.handles.end.y
|
||||||
var toX = end.x
|
|
||||||
var toY = end.y
|
|
||||||
// 计算各角度和对应的箭头终点坐标
|
// 计算各角度和对应的箭头终点坐标
|
||||||
var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI
|
var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI
|
||||||
var angle1 = (angle + theta) * Math.PI / 180
|
var angle1 = (angle + theta) * Math.PI / 180
|
||||||
@@ -500,8 +453,8 @@ export default {
|
|||||||
// 画直线
|
// 画直线
|
||||||
ctx.lineWidth = this.lineWidth
|
ctx.lineWidth = this.lineWidth
|
||||||
ctx.beginPath()
|
ctx.beginPath()
|
||||||
ctx.moveTo(fromX, fromY)
|
ctx.moveTo(fromX * this.imgZoom, fromY * this.imgZoom)
|
||||||
ctx.lineTo(toX, toY)
|
ctx.lineTo(toX * this.imgZoom, toY * this.imgZoom)
|
||||||
|
|
||||||
arrowX = toX + topX
|
arrowX = toX + topX
|
||||||
arrowY = toY + topY
|
arrowY = toY + topY
|
||||||
@@ -520,16 +473,18 @@ export default {
|
|||||||
ctx.lineWidth = this.lineWidth
|
ctx.lineWidth = this.lineWidth
|
||||||
ctx.beginPath()
|
ctx.beginPath()
|
||||||
ctx.strokeStyle = this.color
|
ctx.strokeStyle = this.color
|
||||||
const start = this.scalePoint(e.data.handles.start)
|
|
||||||
const end = this.scalePoint(e.data.handles.end)
|
|
||||||
// 绘制矩形边框
|
// 绘制矩形边框
|
||||||
ctx.strokeRect(
|
ctx.strokeRect(
|
||||||
start.x,
|
// this.canvasMouseStart.x,
|
||||||
start.y,
|
// this.canvasMouseStart.y,
|
||||||
end.x - start.x,
|
// e.offsetX - this.canvasMouseStart.x,
|
||||||
end.y - start.y
|
// e.offsetY - this.canvasMouseStart.y
|
||||||
|
e.data.handles.start.x,
|
||||||
|
e.data.handles.start.y,
|
||||||
|
e.data.handles.end.x - e.data.handles.start.x,
|
||||||
|
e.data.handles.end.y - e.data.handles.start.y
|
||||||
)
|
)
|
||||||
this.drawText(ctx, start, end, e.data.remark, this.color)
|
this.drawText(ctx, { x: e.data.handles.start.x, y: e.data.handles.start.y }, { x: e.data.handles.end.x, y: e.data.handles.end.y }, e.data.remark, this.color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -540,10 +495,6 @@ export default {
|
|||||||
if (e.button !== 0) {
|
if (e.button !== 0) {
|
||||||
return // 非左键松开
|
return // 非左键松开
|
||||||
}
|
}
|
||||||
if (this.isDragging) {
|
|
||||||
this.stopDragging()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 左键松开
|
// 左键松开
|
||||||
if (this.model === 'ArrowAnnotate' || this.model === 'RectangleRoi') {
|
if (this.model === 'ArrowAnnotate' || this.model === 'RectangleRoi') {
|
||||||
|
|||||||
@@ -189,22 +189,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 计算值 -->
|
<!-- 计算值 -->
|
||||||
<Questions
|
<Questions ref="ecrf2" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
|
||||||
ref="ecrf2"
|
:group-classify="4" style="margin-top:20px" />
|
||||||
:question-form-change-state="true"
|
|
||||||
:question-form-change-num="0"
|
|
||||||
:is-qulity-issues="false"
|
|
||||||
:group-classify="4"
|
|
||||||
:question-type="12"
|
|
||||||
style="margin-top:20px" />
|
|
||||||
|
|
||||||
<!-- 评估结果 -->
|
<!-- 评估结果 -->
|
||||||
<Questions
|
<Questions ref="ecrf3" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
|
||||||
ref="ecrf3"
|
|
||||||
:question-form-change-state="true"
|
|
||||||
:question-form-change-num="0"
|
|
||||||
:is-qulity-issues="false"
|
|
||||||
:question-type="12"
|
|
||||||
:group-classify="5" />
|
:group-classify="5" />
|
||||||
<el-dialog v-if="addOrEdit.visible" :visible.sync="addOrEdit.visible" :close-on-click-modal="false"
|
<el-dialog v-if="addOrEdit.visible" :visible.sync="addOrEdit.visible" :close-on-click-modal="false"
|
||||||
:title="addOrEdit.title" width="500px">
|
:title="addOrEdit.title" width="500px">
|
||||||
@@ -628,7 +617,7 @@ export default {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async handleSave(index, options = {}) {
|
async handleSave(index) {
|
||||||
if (this.rowSaveLoadingMap[index]) return
|
if (this.rowSaveLoadingMap[index]) return
|
||||||
const refName = `questions${index}`
|
const refName = `questions${index}`
|
||||||
this.$set(this.rowSaveLoadingMap, index, true)
|
this.$set(this.rowSaveLoadingMap, index, true)
|
||||||
@@ -646,13 +635,9 @@ export default {
|
|||||||
answers: answers
|
answers: answers
|
||||||
}
|
}
|
||||||
await saveTaskQuestion(12, params)
|
await saveTaskQuestion(12, params)
|
||||||
if (!options.silentSuccess) {
|
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
}
|
|
||||||
DicomEvent.$emit('getReportInfo', true)
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
if (!options.skipRefresh) {
|
this.refreshQuestions()
|
||||||
await this.refreshQuestions()
|
|
||||||
}
|
|
||||||
this.formChanged = false
|
this.formChanged = false
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
@@ -899,29 +884,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async uploadDlgClose() {
|
async uploadDlgClose() {
|
||||||
try {
|
this.refreshQuestions()
|
||||||
await this.refreshQuestions()
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
const saveTasks = []
|
|
||||||
for (let index = 0; index < this.questions.length; index++) {
|
|
||||||
const qs = this.questions[index]
|
|
||||||
if (qs.GroupClassify === 6) {
|
|
||||||
saveTasks.push(() => this.handleSave(index, { silentSuccess: true, skipRefresh: true }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
saveTasks.push(() => this.$refs['ecrf2'] && this.$refs['ecrf2'].handleSave({ silentSuccess: true, skipRefresh: true }))
|
|
||||||
saveTasks.push(() => this.$refs['ecrf3'] && this.$refs['ecrf3'].handleSave({ silentSuccess: true, skipRefresh: true }))
|
|
||||||
for (const saveTask of saveTasks) {
|
|
||||||
try {
|
|
||||||
await saveTask()
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
} finally {
|
|
||||||
this.upload.visible = false
|
this.upload.visible = false
|
||||||
}
|
|
||||||
},
|
},
|
||||||
renderHeader(h, { column, $index }) {
|
renderHeader(h, { column, $index }) {
|
||||||
const span = document.createElement('span')
|
const span = document.createElement('span')
|
||||||
|
|||||||
@@ -279,24 +279,22 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async handleSave(options = {}) {
|
handleSave() {
|
||||||
if (this.saveLoading) return false
|
if (this.saveLoading) return
|
||||||
this.saveLoading = true
|
this.saveLoading = true
|
||||||
const valid = await new Promise(resolve => {
|
this.$refs['questions'].validate(async (valid) => {
|
||||||
this.$refs['questions'].validate(v => resolve(v))
|
|
||||||
})
|
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
// lugano标准校验脾脏状态是否符合要求
|
// lugano标准校验脾脏状态是否符合要求
|
||||||
if ((this.criterionType === 2 || this.criterionType === 18) && this.groupClassify === 3) {
|
if ((this.criterionType === 2 || this.criterionType === 18) && this.groupClassify === 3) {
|
||||||
// 是否有标记未保存
|
// 是否有标记未保存
|
||||||
var existUnSave = this.checkAnnotationStatus(this.questions)
|
var existUnSave = this.checkAnnotationStatus(this.questions)
|
||||||
if (existUnSave) {
|
if (existUnSave) {
|
||||||
await this.$alert(this.$t('trials:lugano:message:saveWarning'), this.$t('trials:lugano:fusionDialog:warning'))
|
this.$alert(this.$t('trials:lugano:message:saveWarning'), this.$t('trials:lugano:fusionDialog:warning'))
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentSpleenStatus = this.questionForm[this.spleenStatusId]
|
var currentSpleenStatus = this.questionForm[this.spleenStatusId]
|
||||||
@@ -307,26 +305,24 @@ export default {
|
|||||||
|
|
||||||
if (currentSpleenLength && currentSpleenStatus === 5) {
|
if (currentSpleenLength && currentSpleenStatus === 5) {
|
||||||
// '脾脏状态为不可评估,不需要添加标记!'
|
// '脾脏状态为不可评估,不需要添加标记!'
|
||||||
await this.$alert(this.$t('trials:lugano:message:validSpleen1'), this.$t('trials:lugano:fusionDialog:warning'), {
|
this.$alert(this.$t('trials:lugano:message:validSpleen1'), this.$t('trials:lugano:fusionDialog:warning'), {
|
||||||
callback: _ => { }
|
callback: _ => { }
|
||||||
})
|
})
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
return false
|
|
||||||
} else if (currentSpleenStatus === 5 && ((stIdx > -1 && this.measurements[stIdx].MeasureData) || (slIdx > -1 && this.measurements[slIdx].MeasureData))) {
|
} else if (currentSpleenStatus === 5 && ((stIdx > -1 && this.measurements[stIdx].MeasureData) || (slIdx > -1 && this.measurements[slIdx].MeasureData))) {
|
||||||
// 若有标记,状态不可为“无法评估”
|
// 若有标记,状态不可为“无法评估”
|
||||||
await this.$alert(this.$t('trials:lugano:message:validSpleen1'), this.$t('trials:lugano:fusionDialog:warning'), {
|
this.$alert(this.$t('trials:lugano:message:validSpleen1'), this.$t('trials:lugano:fusionDialog:warning'), {
|
||||||
callback: _ => { }
|
callback: _ => { }
|
||||||
})
|
})
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
return false
|
|
||||||
} else if (((stIdx > -1 && this.measurements[stIdx].MeasureData) || (slIdx > -1 && this.measurements[slIdx].MeasureData)) && !currentSpleenLength) {
|
} else if (((stIdx > -1 && this.measurements[stIdx].MeasureData) || (slIdx > -1 && this.measurements[slIdx].MeasureData)) && !currentSpleenLength) {
|
||||||
await this.$alert(this.$t('trials:lugano:message:validSpleen2'), this.$t('trials:lugano:fusionDialog:warning'), {
|
this.$alert(this.$t('trials:lugano:message:validSpleen2'), this.$t('trials:lugano:fusionDialog:warning'), {
|
||||||
callback: _ => { }
|
callback: _ => { }
|
||||||
})
|
})
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
return false
|
} else {
|
||||||
|
this.saveQuestionsList()
|
||||||
}
|
}
|
||||||
return await this.saveQuestionsList(options)
|
|
||||||
} else if ((this.criterionType === 2 || this.criterionType === 18) && this.groupClassify === 1 && this.questionForm[this.imageQualityIssuesId] && parseInt(this.questionForm[this.imageQualityIssuesId]) === 6) {
|
} else if ((this.criterionType === 2 || this.criterionType === 18) && this.groupClassify === 1 && this.questionForm[this.imageQualityIssuesId] && parseInt(this.questionForm[this.imageQualityIssuesId]) === 6) {
|
||||||
// 保存影响质量问题分组,如果质量问题为PET-CT影像无法融合则验证是否可以保存
|
// 保存影响质量问题分组,如果质量问题为PET-CT影像无法融合则验证是否可以保存
|
||||||
let res = null
|
let res = null
|
||||||
@@ -337,28 +333,30 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (res.IsSuccess && !res.Result.IsCanChooseNotMerge) {
|
if (res.IsSuccess && !res.Result.IsCanChooseNotMerge) {
|
||||||
await this.$alert(this.$t('trials:lugano:saveQuestions:warning1'), this.$t('trials:lugano:fusionDialog:warning'), {
|
// this.$alert(this.$t('trials:lugano:saveQuestions:warning1'), this.$t('trials:lugano:fusionDialog:warning'), {showCancelButton: false})
|
||||||
|
this.$alert(this.$t('trials:lugano:saveQuestions:warning1'), this.$t('trials:lugano:fusionDialog:warning'), {
|
||||||
showCancelButton: false,
|
showCancelButton: false,
|
||||||
callback: action => { }
|
callback: action => { }
|
||||||
})
|
})
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
return false
|
return
|
||||||
}
|
} else {
|
||||||
// 如果设置为PET-CT影像无法融合,则FDG-PET评估会被设置为NE。
|
// 如果设置为PET-CT影像无法融合,则FDG-PET评估会被设置为NE。
|
||||||
const confirm = await this.$confirm(this.$t('trials:lugano:saveQuestions:warning2'), {
|
this.$confirm(this.$t('trials:lugano:saveQuestions:warning2'), {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
distinguishCancelAndClose: true
|
distinguishCancelAndClose: true
|
||||||
}).then(() => true).catch(() => false)
|
})
|
||||||
if (!confirm) {
|
.then(() => {
|
||||||
this.saveLoading = false
|
this.saveQuestionsList()
|
||||||
return false
|
})
|
||||||
}
|
}
|
||||||
return await this.saveQuestionsList(options)
|
|
||||||
} else {
|
} else {
|
||||||
return await this.saveQuestionsList(options)
|
this.saveQuestionsList()
|
||||||
}
|
}
|
||||||
|
// this.saveQuestionsList()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
async saveQuestionsList(options = {}) {
|
async saveQuestionsList() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
var answers = []
|
var answers = []
|
||||||
var imageQuality = null
|
var imageQuality = null
|
||||||
@@ -384,22 +382,18 @@ export default {
|
|||||||
// })
|
// })
|
||||||
// params.questionMarkInfoList = questionMarkInfoList
|
// params.questionMarkInfoList = questionMarkInfoList
|
||||||
// }
|
// }
|
||||||
try {
|
|
||||||
const res = await saveTaskQuestion(this.questionType, params)
|
saveTaskQuestion(this.questionType, params).then(async res => {
|
||||||
if (this.imageQualityIssuesId) {
|
if (this.imageQualityIssuesId) {
|
||||||
store.dispatch('reading/setImageQualityIssues', this.questionForm[this.imageQualityIssuesId])
|
store.dispatch('reading/setImageQualityIssues', this.questionForm[this.imageQualityIssuesId])
|
||||||
if (this.questionForm[this.imageQualityIssuesId] && parseInt(this.questionForm[this.imageQualityIssuesId]) === 6) {
|
if (this.questionForm[this.imageQualityIssuesId] && parseInt(this.questionForm[this.imageQualityIssuesId]) === 6) {
|
||||||
DicomEvent.$emit('closePetct')
|
DicomEvent.$emit('closePetct')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!options.silentSuccess) {
|
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
}
|
|
||||||
if (!options.skipRefresh) {
|
|
||||||
var trialId = this.$route.query.trialId
|
var trialId = this.$route.query.trialId
|
||||||
await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: trialId, visitTaskId: this.visitTaskId })
|
await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: trialId, visitTaskId: this.visitTaskId })
|
||||||
this.getQuestions(this.visitTaskId, true)
|
this.getQuestions(this.visitTaskId, true)
|
||||||
}
|
|
||||||
this.loading = false
|
this.loading = false
|
||||||
if (this.isQulityIssues) {
|
if (this.isQulityIssues) {
|
||||||
DicomEvent.$emit('questionFormChange', false)
|
DicomEvent.$emit('questionFormChange', false)
|
||||||
@@ -423,12 +417,10 @@ export default {
|
|||||||
}
|
}
|
||||||
this.formChanged = false
|
this.formChanged = false
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
return res
|
}).catch(() => {
|
||||||
} catch (e) {
|
|
||||||
this.loading = false
|
this.loading = false
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
throw e
|
})
|
||||||
}
|
|
||||||
},
|
},
|
||||||
checkAnnotationStatus(obj) {
|
checkAnnotationStatus(obj) {
|
||||||
for (let i = 0; i < obj.length; i++) {
|
for (let i = 0; i < obj.length; i++) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="dicom-container">
|
<div class="dicom-container" v-loading="loading">
|
||||||
<div :class="{ 'dicom-list': true, studyHide: !studyShow }">
|
<div :class="{ 'dicom-list': true, studyHide: !studyShow }">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="related-study-wrapper">
|
<div class="related-study-wrapper">
|
||||||
@@ -27,7 +27,8 @@
|
|||||||
class="study-wrapper">
|
class="study-wrapper">
|
||||||
<StudyList v-if="selectArr.includes(s.VisitTaskId)" :ref="s.VisitTaskId" :visit-task-id="s.VisitTaskId"
|
<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"
|
:trial-id="trialId" :subject-visit-id="s.VisitId" :task-blind-name="s.TaskBlindName"
|
||||||
:is-reading-show-subject-info="isReadingShowSubjectInfo" :is-reading-task-view-in-order="isReadingTaskViewInOrder" @loadImageStack="loadImageStack"
|
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||||
|
:is-reading-task-view-in-order="isReadingTaskViewInOrder" @loadImageStack="loadImageStack"
|
||||||
@previewNoneDicoms="previewNoneDicoms" />
|
@previewNoneDicoms="previewNoneDicoms" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -38,7 +39,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="dicom-viewer">
|
<div class="dicom-viewer">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<DicomViewer v-if="activeTaskVisitId" ref="dicomViewer" :is-show="isShow"
|
<DicomViewer v-if="activeTaskVisitId" ref="dicomViewer" :is-show="isShow" :Loading.sync="loading"
|
||||||
:question-form-change-state="questionFormChangeState" :question-form-change-num="questionFormChangeNum"
|
:question-form-change-state="questionFormChangeState" :question-form-change-num="questionFormChangeNum"
|
||||||
:is-exists-clinical-data="isExistsClinicalData" :is-exists-no-dicom-file="isExistsNoDicomFile"
|
:is-exists-clinical-data="isExistsClinicalData" :is-exists-no-dicom-file="isExistsNoDicomFile"
|
||||||
:is-reading-show-subject-info="isReadingShowSubjectInfo" :studyShow="studyShow"
|
:is-reading-show-subject-info="isReadingShowSubjectInfo" :studyShow="studyShow"
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-loading="loading" class="study-wrapper">
|
<div v-loading="loading" class="study-wrapper">
|
||||||
<h4 v-if="isReadingShowSubjectInfo" style="color: #ddd;padding: 5px 0px;margin: 0;text-align: center;background-color: #4c4c4c;">
|
<h4 v-if="isReadingShowSubjectInfo"
|
||||||
|
style="color: #ddd;padding: 5px 0px;margin: 0;text-align: center;background-color: #4c4c4c;">
|
||||||
{{ subjectCode }}
|
{{ subjectCode }}
|
||||||
</h4>
|
</h4>
|
||||||
<h4 v-if="isReadingShowSubjectInfo" style="color: #ddd;padding: 5px 0px;margin: 0;text-align: center;background-color: #4c4c4c;margin-bottom: 5px;">
|
<h4 v-if="isReadingShowSubjectInfo"
|
||||||
|
style="color: #ddd;padding: 5px 0px;margin: 0;text-align: center;background-color: #4c4c4c;margin-bottom: 5px;">
|
||||||
{{ taskBlindName }}
|
{{ taskBlindName }}
|
||||||
</h4>
|
</h4>
|
||||||
<div class="ps">
|
<div class="ps">
|
||||||
@@ -14,11 +16,7 @@
|
|||||||
<!-- 关键序列 -->
|
<!-- 关键序列 -->
|
||||||
{{ $t('trials:reading:title:keySeries') }}
|
{{ $t('trials:reading:title:keySeries') }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-else class="dicom-desc" style="white-space: normal;">
|
||||||
v-else
|
|
||||||
class="dicom-desc"
|
|
||||||
style="white-space: normal;"
|
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<div style="text-overflow: ellipsis;overflow: hidden;">
|
<div style="text-overflow: ellipsis;overflow: hidden;">
|
||||||
|
|
||||||
@@ -28,7 +26,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="study-meta-line" :title="study.Modalities">
|
<span class="study-meta-line" :title="study.Modalities">
|
||||||
<span v-if="isReadingTaskViewInOrder !== 0" class="study-code" :title="study.StudyCode">{{ study.StudyCode }}</span>
|
<span v-if="isReadingTaskViewInOrder !== 0" class="study-code" :title="study.StudyCode">{{
|
||||||
|
study.StudyCode }}</span>
|
||||||
<span class="study-modality">{{ study.Modalities }}({{ study.SeriesCount }})</span>
|
<span class="study-modality">{{ study.Modalities }}({{ study.SeriesCount }})</span>
|
||||||
<span class="patient-info" v-if="['PT、CT', 'CT、PT', 'PET-CT'].includes(study.Modalities)">
|
<span class="patient-info" v-if="['PT、CT', 'CT、PT', 'PET-CT'].includes(study.Modalities)">
|
||||||
<el-popover placement="right-start" trigger="hover" popper-class="patient-info-popper">
|
<el-popover placement="right-start" trigger="hover" popper-class="patient-info-popper">
|
||||||
@@ -63,67 +62,57 @@
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="study.Description" class="study-desc-text" :title="study.Description">{{ study.Description }}</div>
|
<div v-if="study.Description" class="study-desc-text" :title="study.Description">{{ study.Description }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="series">
|
<div class="series">
|
||||||
<div
|
<div v-for="(series, i) in study.SeriesList" :key="i" style="position:relative;margin-top:5px;"
|
||||||
v-for="(series, i) in study.SeriesList"
|
series-type="current" @click="showSeriesImage(index, i, series)">
|
||||||
:key="i"
|
|
||||||
style="position:relative;margin-top:5px;"
|
|
||||||
series-type="current"
|
|
||||||
@click="showSeriesImage(index,i,series)"
|
|
||||||
>
|
|
||||||
|
|
||||||
<div
|
<div :class="{ 'series-active': i == seriesIndex && index === studyIndex }" class="series-wrapper">
|
||||||
:class="{'series-active': i==seriesIndex && index === studyIndex}"
|
<el-image class="image-preview" :src="series.previewImageUrl" fit="fill" crossorigin="anonymous" />
|
||||||
class="series-wrapper"
|
|
||||||
>
|
|
||||||
<el-image
|
|
||||||
class="image-preview"
|
|
||||||
:src="series.previewImageUrl"
|
|
||||||
fit="fill"
|
|
||||||
crossorigin="anonymous"
|
|
||||||
/>
|
|
||||||
<div class="image-desc">
|
<div class="image-desc">
|
||||||
<div class="flex-div">
|
<div class="flex-div">
|
||||||
<div style="width: 40px;display: flex;flex-direction: row;justify-content: space-between;">
|
<div style="width: 40px;display: flex;flex-direction: row;justify-content: space-between;">
|
||||||
<div v-if="!study.IsCriticalSequence">#{{ series.seriesNumber }}</div>
|
<div v-if="!study.IsCriticalSequence">#{{ series.seriesNumber }}</div>
|
||||||
<div v-if="series.isDicom && series.prefetchInstanceCount<series.instanceCount * 100 && series.modality!== 'SR'">
|
<div
|
||||||
|
v-if="series.isDicom && series.prefetchInstanceCount < series.instanceCount * 100 && series.modality !== 'SR'">
|
||||||
<!-- 下载 -->
|
<!-- 下载 -->
|
||||||
<el-tooltip v-if="!series.isLoading" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
<el-tooltip v-if="!series.isLoading" class="item" effect="dark"
|
||||||
<i class="el-icon-video-play" style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;" @click.stop="loadSeries(series,index,i)" />
|
:content="$t('trials:reading:button:download')" placement="bottom">
|
||||||
|
<i class="el-icon-video-play"
|
||||||
|
style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;"
|
||||||
|
@click.stop="loadSeries(series, index, i)" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<el-tooltip v-else-if="series.isDicom && series.prefetchInstanceCount === 0 &&series.modality!== 'SR'" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
<el-tooltip
|
||||||
<i class="el-icon-video-play" style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;" @click.stop="loadSeries(series,index,i)" />
|
v-else-if="series.isDicom && series.prefetchInstanceCount === 0 && series.modality !== 'SR'"
|
||||||
|
class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
||||||
|
<i class="el-icon-video-play"
|
||||||
|
style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;"
|
||||||
|
@click.stop="loadSeries(series, index, i)" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="series.isExistMutiFrames && series.instanceCount > 1">
|
<div v-if="series.isExistMutiFrames && series.instanceCount > 1">
|
||||||
<el-popover
|
<el-popover placement="right" trigger="hover" popper-class="instance_frame_wrapper">
|
||||||
placement="right"
|
|
||||||
trigger="hover"
|
|
||||||
popper-class="instance_frame_wrapper"
|
|
||||||
>
|
|
||||||
<div class="frame_list">
|
<div class="frame_list">
|
||||||
<div
|
<div v-for="(instance, idx) in series.instanceInfoList" :key="instance.Id"
|
||||||
v-for="(instance, idx) in series.instanceInfoList"
|
class="frame_content" :class="{ 'frame_content_active': activeInstanceId === instance.Id }"
|
||||||
:key="instance.Id"
|
|
||||||
class="frame_content"
|
|
||||||
:class="{ 'frame_content_active': activeInstanceId === instance.Id }"
|
|
||||||
:style="{ 'margin-bottom': idx < series.instanceInfoList.length - 1 ? '5px' : '0px' }"
|
:style="{ 'margin-bottom': idx < series.instanceInfoList.length - 1 ? '5px' : '0px' }"
|
||||||
@click.stop="showMultiFrames(index,series, i, instance)"
|
@click.stop="showMultiFrames(index, series, i, instance)">
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<div>{{ instance.InstanceNumber }}</div>
|
<div>{{ instance.InstanceNumber }}</div>
|
||||||
<div>{{ `${instance.NumberOfFrames > 0 ? instance.KeyFramesList.length > 0 ? instance.KeyFramesList.length : instance.NumberOfFrames : 1} frame` }}</div>
|
<div>{{ `${instance.NumberOfFrames > 0 ? instance.KeyFramesList.length > 0 ?
|
||||||
|
instance.KeyFramesList.length : instance.NumberOfFrames : 1} frame` }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;color: #ffeb3b;" />
|
<i slot="reference" class="el-icon-connection"
|
||||||
|
style="font-size: 15px;cursor: pointer;color: #ffeb3b;" />
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -145,9 +134,11 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="flex-div">
|
<div class="flex-div">
|
||||||
<div v-if="measureData && measureData.findIndex(v=>v.SeriesId === series.seriesId && v.MeasureData) > -1">
|
<div
|
||||||
|
v-if="measureData && measureData.findIndex(v => v.SeriesId === series.seriesId && v.MeasureData) > -1">
|
||||||
<!-- 有标注 -->
|
<!-- 有标注 -->
|
||||||
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:marked')" placement="right">
|
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:marked')"
|
||||||
|
placement="right">
|
||||||
<i class="el-icon-star-on" style="font-size: 16px;color: #ff5722;" />
|
<i class="el-icon-star-on" style="font-size: 16px;color: #ff5722;" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
@@ -155,10 +146,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="series.isDicom && series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount * 100" style="width: 100%;">
|
<div
|
||||||
<el-progress
|
v-if="series.isDicom && series.prefetchInstanceCount > 0 && series.prefetchInstanceCount < series.instanceCount * 100"
|
||||||
:percentage="parseInt((series.prefetchInstanceCount / series.instanceCount).toFixed(2))"
|
style="width: 100%;">
|
||||||
/>
|
<el-progress :percentage="parseInt((series.prefetchInstanceCount / series.instanceCount).toFixed(2))" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -168,24 +159,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sr-wrapper">
|
<div class="sr-wrapper">
|
||||||
<el-dialog
|
<el-dialog :visible.sync="srDialogVisible"
|
||||||
:visible.sync="srDialogVisible"
|
:custom-class="isSrFullscreen ? 'sr-full-dialog-container' : 'sr-dialog-container'" :show-close="false"
|
||||||
:custom-class="isSrFullscreen?'sr-full-dialog-container':'sr-dialog-container'"
|
:close-on-click-modal="false" :fullscreen="isSrFullscreen">
|
||||||
:show-close="false"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
:fullscreen="isSrFullscreen"
|
|
||||||
>
|
|
||||||
<span slot="title" class="dialog-footer">
|
<span slot="title" class="dialog-footer">
|
||||||
<div style="position: absolute;right: 20px;top: 10px;">
|
<div style="position: absolute;right: 20px;top: 10px;">
|
||||||
<svg-icon :icon-class="isSrFullscreen?'exit-fullscreen':'fullscreen'" style="cursor: pointer;font-size: 20px;color:#000;" @click="isSrFullscreen=!isSrFullscreen" />
|
<svg-icon :icon-class="isSrFullscreen ? 'exit-fullscreen' : 'fullscreen'"
|
||||||
<svg-icon icon-class="dClose" style="cursor: pointer;font-size: 25px;margin-left: 10px;" @click="srDialogVisible = false" />
|
style="cursor: pointer;font-size: 20px;color:#000;" @click="isSrFullscreen = !isSrFullscreen" />
|
||||||
|
<svg-icon icon-class="dClose" style="cursor: pointer;font-size: 25px;margin-left: 10px;"
|
||||||
|
@click="srDialogVisible = false" />
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<div style="height: 100%;margin:0;">
|
<div style="height: 100%;margin:0;">
|
||||||
<SrList
|
<SrList v-if="srDialogVisible" :sr-info="srInfo" />
|
||||||
v-if="srDialogVisible"
|
|
||||||
:sr-info="srInfo"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
@@ -296,6 +282,9 @@ export default {
|
|||||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||||
this.measureData = this.visitTaskList[idx].MeasureData
|
this.measureData = this.visitTaskList[idx].MeasureData
|
||||||
})
|
})
|
||||||
|
DicomEvent.$on("getStudyFile", () => {
|
||||||
|
DicomEvent.$emit('sendStudyFile', { studyList: this.studyList, studyIndex: this.studyIndex, seriesIndex: this.seriesIndex, visitTaskId: this.visitTaskId })
|
||||||
|
})
|
||||||
|
|
||||||
// DicomEvent.$on('setReadingState', readingTaskState => {
|
// DicomEvent.$on('setReadingState', readingTaskState => {
|
||||||
// var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
// var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||||
@@ -972,10 +961,12 @@ export default {
|
|||||||
::v-deep .el-progress-bar__inner {
|
::v-deep .el-progress-bar__inner {
|
||||||
transition: width 0s ease;
|
transition: width 0s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
width:100%;
|
width:100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|
||||||
.dicom-desc {
|
.dicom-desc {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
@@ -985,6 +976,7 @@ export default {
|
|||||||
white-space: normal;
|
white-space: normal;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
.study-meta-line {
|
.study-meta-line {
|
||||||
// display: grid;
|
// display: grid;
|
||||||
// grid-template-columns: minmax(0, 1fr) auto;
|
// grid-template-columns: minmax(0, 1fr) auto;
|
||||||
@@ -994,6 +986,7 @@ export default {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.study-meta-main {
|
.study-meta-main {
|
||||||
display: block;
|
display: block;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
@@ -1001,11 +994,13 @@ export default {
|
|||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.study-code,
|
.study-code,
|
||||||
.study-modality {
|
.study-modality {
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
margin: 0 2px;
|
margin: 0 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.study-desc-text {
|
.study-desc-text {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -1017,19 +1012,23 @@ export default {
|
|||||||
overflow-anchor: none;
|
overflow-anchor: none;
|
||||||
touch-action: auto;
|
touch-action: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.series-active {
|
.series-active {
|
||||||
background-color: #607d8b !important;
|
background-color: #607d8b !important;
|
||||||
border: 1px solid #607d8b !important;
|
border: 1px solid #607d8b !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-progress__text {
|
::v-deep .el-progress__text {
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.series {
|
.series {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
|
|
||||||
.series-wrapper {
|
.series-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -1042,9 +1041,11 @@ export default {
|
|||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
border: 1px solid #404040;
|
border: 1px solid #404040;
|
||||||
background-color: #3a3a3a;
|
background-color: #3a3a3a;
|
||||||
|
|
||||||
.el-progress__text {
|
.el-progress__text {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-progress-bar {
|
.el-progress-bar {
|
||||||
padding-right: 0px;
|
padding-right: 0px;
|
||||||
}
|
}
|
||||||
@@ -1055,8 +1056,10 @@ export default {
|
|||||||
border: 2px solid #252525;
|
border: 2px solid #252525;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-desc {
|
.image-desc {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
|
|
||||||
p {
|
p {
|
||||||
width: 95px;
|
width: 95px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -1066,6 +1069,7 @@ export default {
|
|||||||
color: #ddd;
|
color: #ddd;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
|
||||||
div {
|
div {
|
||||||
width: 95px;
|
width: 95px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -1074,6 +1078,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-div {
|
.flex-div {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -1091,17 +1096,21 @@ export default {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-collapse {
|
::v-deep .el-collapse {
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
.el-collapse-item {
|
.el-collapse-item {
|
||||||
background-color: #000 !important;
|
background-color: #000 !important;
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-collapse-item__content {
|
.el-collapse-item__content {
|
||||||
padding-bottom: 5px;
|
padding-bottom: 5px;
|
||||||
background-color: #000 !important;
|
background-color: #000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-collapse-item__header {
|
.el-collapse-item__header {
|
||||||
background-color: #000 !important;
|
background-color: #000 !important;
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
@@ -1114,33 +1123,40 @@ export default {
|
|||||||
padding-top: 6px;
|
padding-top: 6px;
|
||||||
padding-bottom: 6px;
|
padding-bottom: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-collapse-item__arrow {
|
.el-collapse-item__arrow {
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sr-wrapper {
|
.sr-wrapper {
|
||||||
::v-deep .el-dialog {
|
::v-deep .el-dialog {
|
||||||
background: #fff !important;
|
background: #fff !important;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
|
|
||||||
// color: #ddd;
|
// color: #ddd;
|
||||||
.el-dialog__title {
|
.el-dialog__title {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .sr-dialog-container {
|
::v-deep .sr-dialog-container {
|
||||||
margin-top: 50px !important;
|
margin-top: 50px !important;
|
||||||
width: 75%;
|
width: 75%;
|
||||||
height: 80%;
|
height: 80%;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-dialog__body {
|
::v-deep .el-dialog__body {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
height: calc(100% - 50px);
|
height: calc(100% - 50px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-dialog__header {
|
.el-dialog__header {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sr-full-dialog-container {
|
.sr-full-dialog-container {
|
||||||
::v-deep .is-fullscreen .el-dialog__body {
|
::v-deep .is-fullscreen .el-dialog__body {
|
||||||
height: calc(100% - 50px);
|
height: calc(100% - 50px);
|
||||||
@@ -1156,18 +1172,22 @@ export default {
|
|||||||
border: 1px solid #2c2c2c;
|
border: 1px solid #2c2c2c;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame_list {
|
.frame_list {
|
||||||
max-height: 500px;
|
max-height: 500px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.instance_frame_wrapper ::-webkit-scrollbar {
|
.instance_frame_wrapper ::-webkit-scrollbar {
|
||||||
width: 7px;
|
width: 7px;
|
||||||
height: 7px;
|
height: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: #d0d0d0;
|
background: #d0d0d0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame_content {
|
.frame_content {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
@@ -1177,6 +1197,7 @@ export default {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
border: 1px solid #404040;
|
border: 1px solid #404040;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame_content:hover {
|
.frame_content:hover {
|
||||||
/* font-weight: bold; */
|
/* font-weight: bold; */
|
||||||
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
||||||
@@ -1185,6 +1206,7 @@ export default {
|
|||||||
border-color: #213a54 !important;
|
border-color: #213a54 !important;
|
||||||
background-color: #213a54;
|
background-color: #213a54;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame_content_active {
|
.frame_content_active {
|
||||||
border-color: #213a54 !important;
|
border-color: #213a54 !important;
|
||||||
background-color: #213a54;
|
background-color: #213a54;
|
||||||
@@ -1197,6 +1219,7 @@ export default {
|
|||||||
line-height: 1;
|
line-height: 1;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.patient-info-popper {
|
.patient-info-popper {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
|
|||||||
@@ -0,0 +1,205 @@
|
|||||||
|
import { dcmUpload } from '@/utils/dcmUpload/dcmUpload'
|
||||||
|
import dcmjs from '@/utils/dcmUpload/dcmjs'
|
||||||
|
import { deleteImageCache, getAnonymizeInfo, updateModality } from '@/api/reading'
|
||||||
|
import * as dicomParser from 'dicom-parser'
|
||||||
|
import * as cornerstone from 'cornerstone-core'
|
||||||
|
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
|
||||||
|
var config = {
|
||||||
|
maxWebWorkers: 4,
|
||||||
|
startWebWorkersOnDemand: true,
|
||||||
|
taskConfiguration: {
|
||||||
|
decodeTask: {
|
||||||
|
initializeCodecsOnStartup: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cornerstoneWADOImageLoader.webWorkerManager.initialize(config)
|
||||||
|
cornerstoneWADOImageLoader.external.dicomParser = dicomParser
|
||||||
|
cornerstoneWADOImageLoader.external.cornerstone = cornerstone
|
||||||
|
import Vue from 'vue'
|
||||||
|
function dicomToPng(imageId, width, height) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
cornerstone.loadImage(imageId).then(async (image) => {
|
||||||
|
let canvas = document.createElement('canvas')
|
||||||
|
canvas.width = (width * 60) / height
|
||||||
|
canvas.height = 60
|
||||||
|
if (image) {
|
||||||
|
cornerstone.renderToCanvas(canvas, image)
|
||||||
|
// 将 Canvas 图像对象转换为 PNG 格式
|
||||||
|
let blob = await canvasToBlob(canvas)
|
||||||
|
resolve(blob)
|
||||||
|
} else {
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch((reason) => {
|
||||||
|
reason()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function canvasToBlob(canvas) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
canvas.toBlob((blob) => {
|
||||||
|
resolve(blob)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function UpdateModality(params) {
|
||||||
|
try {
|
||||||
|
let res = await updateModality(params)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function getAnonymize(VisitTaskId, SubjectVisitId) {
|
||||||
|
try {
|
||||||
|
let params = {}
|
||||||
|
if (VisitTaskId) {
|
||||||
|
params.VisitTaskId = VisitTaskId
|
||||||
|
} else {
|
||||||
|
params.SubjectVisitId = SubjectVisitId
|
||||||
|
}
|
||||||
|
let res = await getAnonymizeInfo(params)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
return res.Result
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function deleteCache(path) {
|
||||||
|
try {
|
||||||
|
let params = {
|
||||||
|
path
|
||||||
|
}
|
||||||
|
let res = await deleteImageCache(params)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 0002,0003 MediaStorageSOPInstanceUID
|
||||||
|
* 0008,0018 SOPInstanceUID
|
||||||
|
* 0020,000D StudyInstanceUID
|
||||||
|
* 0020,000E SeriesInstanceUID
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export async function changeFile(key, file, study, image) {
|
||||||
|
// console.log(image, 'image')
|
||||||
|
// return console.log(study, 'study')
|
||||||
|
let dataset = dcmjs.data.DicomMessage.readFile(image.data.byteArray.buffer)
|
||||||
|
// console.log(dataset, 'dataset')
|
||||||
|
let MediaStorageSOPInstanceUID = dataset.meta['00020003'].Value[0]
|
||||||
|
let SOPInstanceUID = dataset.dict['00080018'].Value[0]
|
||||||
|
let StudyInstanceUID = dataset.dict['0020000D'].Value[0]
|
||||||
|
let SeriesInstanceUID = dataset.dict['0020000E'].Value[0]
|
||||||
|
// let Modality = dataset.dict['00080060'].Value[0]
|
||||||
|
let { visitTaskId, visitTaskList = [], studyList, studyIndex, seriesIndex, seriesList, currentSeriesIndex } = study
|
||||||
|
let series = key === 'IR' ? studyList[studyIndex].SeriesList[seriesIndex] : seriesList[currentSeriesIndex]
|
||||||
|
console.log(series, 'seriesId')
|
||||||
|
let index = visitTaskList.findIndex(i => i.VisitTaskId === visitTaskId)
|
||||||
|
let config = null
|
||||||
|
if (key === 'IR') {
|
||||||
|
config = await getAnonymize(visitTaskId)
|
||||||
|
} else {
|
||||||
|
config = await getAnonymize(null, series.subjectVisitId)
|
||||||
|
}
|
||||||
|
if (!config) return false
|
||||||
|
config.AnonymizeFixedList.push({
|
||||||
|
Element: '0003',
|
||||||
|
Group: '0002',
|
||||||
|
ReplaceValue: MediaStorageSOPInstanceUID,
|
||||||
|
Id: 'MediaStorageSOPInstanceUID'
|
||||||
|
})
|
||||||
|
config.AnonymizeFixedList.push({
|
||||||
|
Element: '0018',
|
||||||
|
Group: '0008',
|
||||||
|
ReplaceValue: SOPInstanceUID,
|
||||||
|
Id: 'SOPInstanceUID'
|
||||||
|
})
|
||||||
|
config.AnonymizeFixedList.push({
|
||||||
|
Element: '000D',
|
||||||
|
Group: '0020',
|
||||||
|
ReplaceValue: StudyInstanceUID,
|
||||||
|
Id: 'StudyInstanceUID'
|
||||||
|
})
|
||||||
|
config.AnonymizeFixedList.push({
|
||||||
|
Element: '000E',
|
||||||
|
Group: '0020',
|
||||||
|
ReplaceValue: SeriesInstanceUID,
|
||||||
|
Id: 'SeriesInstanceUID'
|
||||||
|
})
|
||||||
|
let uploadBatchId = Vue.prototype.$guid()
|
||||||
|
let path = image.imageId.split(`wadouri:${Vue.prototype.OSSclientConfig.basePath}`)[1].split("?")[0]
|
||||||
|
let res = await dcmUpload(
|
||||||
|
{
|
||||||
|
path: path,
|
||||||
|
file: file,
|
||||||
|
speed: true,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
(percentage, checkpoint, lastPer) => {
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fileName: file.name,
|
||||||
|
fileSize: file.size,
|
||||||
|
fileType: 'application/dicom',
|
||||||
|
uploadBatchId: uploadBatchId,
|
||||||
|
batchDataType: 1,
|
||||||
|
// trialId: params.trialId,
|
||||||
|
subjectId: key === 'IR' ? localStorage.getItem("subjectId") : series.subjectId,
|
||||||
|
subjectVisitId: key === 'IR' ? visitTaskList[index].VisitId : series.subjectVisitId,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (!res || !res.url) return false
|
||||||
|
let Modality = res.Modality
|
||||||
|
let fileId =
|
||||||
|
cornerstoneWADOImageLoader.wadouri.fileManager.add(
|
||||||
|
file
|
||||||
|
)
|
||||||
|
let blob = await dicomToPng(
|
||||||
|
fileId,
|
||||||
|
image.columns,
|
||||||
|
image.rows
|
||||||
|
)
|
||||||
|
let thumbnailPath = series.previewImageUrl.split(Vue.prototype.OSSclientConfig.basePath)[1]
|
||||||
|
let OSSclient = Vue.prototype.OSSclient
|
||||||
|
try {
|
||||||
|
let seriesRes = await OSSclient.put(thumbnailPath, blob, {
|
||||||
|
fileName: thumbnailPath.split('/')[thumbnailPath.split('/').length - 1],
|
||||||
|
fileSize: blob.size,
|
||||||
|
fileType: 'image/jpeg',
|
||||||
|
uploadBatchId: uploadBatchId,
|
||||||
|
batchDataType: 2,
|
||||||
|
// trialId: params.trialId,
|
||||||
|
subjectId: key === 'IR' ? localStorage.getItem("subjectId") : series.subjectId,
|
||||||
|
subjectVisitId: key === 'IR' ? visitTaskList[index].VisitId : series.subjectVisitId,
|
||||||
|
})
|
||||||
|
console.log(seriesRes, 'seriesRes')
|
||||||
|
if (!seriesRes || !seriesRes.url) return false
|
||||||
|
res = await Promise.all([deleteCache(path), deleteCache(thumbnailPath)])
|
||||||
|
if (!res) return false
|
||||||
|
let params = {
|
||||||
|
Modality,
|
||||||
|
SeriesId: series.seriesId,
|
||||||
|
IsCRCReplace: key === 'IR' ? false : true
|
||||||
|
}
|
||||||
|
res = await UpdateModality(params)
|
||||||
|
if (!res) return false
|
||||||
|
window.location.reload(true)
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -477,6 +477,10 @@ export default {
|
|||||||
DicomEvent.$off('updateImage')
|
DicomEvent.$off('updateImage')
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getInfo() {
|
||||||
|
var image = cornerstone.getImage(this.canvas)
|
||||||
|
return image
|
||||||
|
},
|
||||||
goViewer(e) {
|
goViewer(e) {
|
||||||
console.log(this.$refs['sliderBox'].clientHeight)
|
console.log(this.$refs['sliderBox'].clientHeight)
|
||||||
var height = e.offsetY * 100 / this.$refs['sliderBox'].clientHeight
|
var height = e.offsetY * 100 / this.$refs['sliderBox'].clientHeight
|
||||||
|
|||||||
@@ -309,10 +309,8 @@
|
|||||||
<div class="text">{{ $t('trials:reading:button:reset') }}</div>
|
<div class="text">{{ $t('trials:reading:button:reset') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip v-if="
|
<el-tooltip v-if="trialCriterion.ImageUploadEnum > 0" class="item" effect="dark"
|
||||||
trialCriterion.ImageUploadEnum > 0 && currentReadingTaskState < 2
|
:content="$t('trials:reading:button:upload')" placement="bottom">
|
||||||
" v-hasPermi="['role:ir']" class="item" effect="dark" :content="$t('trials:reading:button:upload')"
|
|
||||||
placement="bottom">
|
|
||||||
<div class="tool-wrapper">
|
<div class="tool-wrapper">
|
||||||
<div class="icon" @click.prevent="openUploadImage('upload')">
|
<div class="icon" @click.prevent="openUploadImage('upload')">
|
||||||
<i class="el-icon-upload2 svg-icon" />
|
<i class="el-icon-upload2 svg-icon" />
|
||||||
@@ -320,15 +318,8 @@
|
|||||||
<div class="text">{{ $t('trials:reading:button:upload') }}</div>
|
<div class="text">{{ $t('trials:reading:button:upload') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip v-if="trialCriterion.ImageDownloadEnum > 0" v-hasPermi="[
|
<el-tooltip v-if="trialCriterion.ImageDownloadEnum > 0" class="item" effect="dark"
|
||||||
'role:ir',
|
:content="$t('trials:reading:button:download')" placement="bottom">
|
||||||
'role:mim',
|
|
||||||
'role:mc',
|
|
||||||
'role:pm',
|
|
||||||
'role:apm',
|
|
||||||
'role:ea',
|
|
||||||
'role:qa',
|
|
||||||
]" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
|
||||||
<div class="tool-wrapper">
|
<div class="tool-wrapper">
|
||||||
<div class="icon" @click.prevent="openUploadImage('download')">
|
<div class="icon" @click.prevent="openUploadImage('download')">
|
||||||
<i class="el-icon-download svg-icon" />
|
<i class="el-icon-download svg-icon" />
|
||||||
@@ -336,7 +327,10 @@
|
|||||||
<div class="text">{{ $t('trials:reading:button:download') }}</div>
|
<div class="text">{{ $t('trials:reading:button:download') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
<label for="Replacement" style="color: #fff;cursor: pointer;">
|
||||||
|
替换
|
||||||
|
</label>
|
||||||
|
<input type="file" id="Replacement" @change="beginScanFiles($event, 'replace')" style="display: none;">
|
||||||
<div style="margin-left: auto">
|
<div style="margin-left: auto">
|
||||||
<div style="display: flex;">
|
<div style="display: flex;">
|
||||||
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:handbooks')" placement="bottom"
|
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:handbooks')" placement="bottom"
|
||||||
@@ -448,7 +442,7 @@
|
|||||||
/> -->
|
/> -->
|
||||||
<upload-dicom-and-nonedicom v-if="uploadImageVisible" :SubjectId="uploadSubjectId" :SubjectCode="uploadSubjectCode"
|
<upload-dicom-and-nonedicom v-if="uploadImageVisible" :SubjectId="uploadSubjectId" :SubjectCode="uploadSubjectCode"
|
||||||
:Criterion="uploadTrialCriterion" :visible.sync="uploadImageVisible" :VisitTaskId="taskId"
|
:Criterion="uploadTrialCriterion" :visible.sync="uploadImageVisible" :VisitTaskId="taskId"
|
||||||
:isReadingTaskViewInOrder="isReadingTaskViewInOrder" :isReading="true" />
|
:isReadingTaskViewInOrder="isReadingTaskViewInOrder" :StudyInstanceUID="StudyInstanceUID" :isReading="true" />
|
||||||
<download-dicom-and-nonedicom v-if="downloadImageVisible" :SubjectId="uploadSubjectId"
|
<download-dicom-and-nonedicom v-if="downloadImageVisible" :SubjectId="uploadSubjectId"
|
||||||
:SubjectCode="uploadSubjectCode" :Criterion="uploadTrialCriterion" :TaskId="taskId"
|
:SubjectCode="uploadSubjectCode" :Criterion="uploadTrialCriterion" :TaskId="taskId"
|
||||||
:visible.sync="downloadImageVisible" :isReading="true" />
|
:visible.sync="downloadImageVisible" :isReading="true" />
|
||||||
@@ -478,6 +472,8 @@ import { getDoctorShortcutKey, getUserWLTemplateList } from '@/api/user'
|
|||||||
import uploadDicomAndNonedicom from '@/components/uploadDicomAndNonedicom'
|
import uploadDicomAndNonedicom from '@/components/uploadDicomAndNonedicom'
|
||||||
import downloadDicomAndNonedicom from '@/components/downloadDicomAndNonedicom'
|
import downloadDicomAndNonedicom from '@/components/downloadDicomAndNonedicom'
|
||||||
import { getCriterionReadingInfo, setReadKeyFile } from '@/api/trials'
|
import { getCriterionReadingInfo, setReadKeyFile } from '@/api/trials'
|
||||||
|
import { changeFile } from "@/views/trials/trials-panel/reading/dicoms/components/upload.js"
|
||||||
|
import dcmjs from '@/utils/dcmUpload/dcmjs'
|
||||||
export default {
|
export default {
|
||||||
name: 'DicomViewer',
|
name: 'DicomViewer',
|
||||||
components: {
|
components: {
|
||||||
@@ -683,7 +679,10 @@ export default {
|
|||||||
fullScreenWidth: window.innerWidth - 570 + 'px',
|
fullScreenWidth: window.innerWidth - 570 + 'px',
|
||||||
fullScreenHeight: window.innerHeight - 128 + 'px',
|
fullScreenHeight: window.innerHeight - 128 + 'px',
|
||||||
|
|
||||||
ManualsClose: false
|
ManualsClose: false,
|
||||||
|
fileKey: null,
|
||||||
|
file: null,
|
||||||
|
StudyInstanceUID: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -856,6 +855,12 @@ export default {
|
|||||||
this.loadLinkedImageStack(seriesInfo)
|
this.loadLinkedImageStack(seriesInfo)
|
||||||
console.log('loadLinkedImageStack')
|
console.log('loadLinkedImageStack')
|
||||||
})
|
})
|
||||||
|
DicomEvent.$on('sendStudyFile', (study) => {
|
||||||
|
let image = this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].getInfo()
|
||||||
|
study.visitTaskList = this.visitTaskList
|
||||||
|
this.$emit("update:Loading", true)
|
||||||
|
changeFile('IR', this.file, study, image)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
DicomEvent.$off('updateImage')
|
DicomEvent.$off('updateImage')
|
||||||
@@ -866,6 +871,11 @@ export default {
|
|||||||
DicomEvent.$off('loadLinkedImageStack')
|
DicomEvent.$off('loadLinkedImageStack')
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
beginScanFiles(e, key) {
|
||||||
|
this.fileKey = key
|
||||||
|
this.file = e.target.files[0]
|
||||||
|
DicomEvent.$emit('getStudyFile')
|
||||||
|
},
|
||||||
handleReadingChart(e) {
|
handleReadingChart(e) {
|
||||||
this.$emit('handleReadingChart', e)
|
this.$emit('handleReadingChart', e)
|
||||||
},
|
},
|
||||||
@@ -898,6 +908,11 @@ export default {
|
|||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
this.taskId = this.visitTaskList[idx].VisitTaskId
|
this.taskId = this.visitTaskList[idx].VisitTaskId
|
||||||
}
|
}
|
||||||
|
let image = this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].getInfo()
|
||||||
|
let dataset = dcmjs.data.DicomMessage.readFile(image.data.byteArray.buffer)
|
||||||
|
this.StudyInstanceUID = dataset.dict['0020000D'].Value[0]
|
||||||
|
dataset = null
|
||||||
|
console.log(this.StudyInstanceUID, 'StudyInstanceUID')
|
||||||
this.uploadSubjectCode = localStorage.getItem("subjectCode")
|
this.uploadSubjectCode = localStorage.getItem("subjectCode")
|
||||||
this.uploadSubjectId = localStorage.getItem("subjectId")
|
this.uploadSubjectId = localStorage.getItem("subjectId")
|
||||||
this.uploadTrialCriterion = this.trialCriterion
|
this.uploadTrialCriterion = this.trialCriterion
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ export default {
|
|||||||
immediate: true,
|
immediate: true,
|
||||||
handler(val) {
|
handler(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
this.readingTaskState = val
|
this.readingTaskState = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,7 +169,7 @@ export default {
|
|||||||
if (i > -1) {
|
if (i > -1) {
|
||||||
this.visitTaskId = this.visitTaskList[i].VisitTaskId
|
this.visitTaskId = this.visitTaskList[i].VisitTaskId
|
||||||
this.taskBlindName = this.visitTaskList[i].TaskBlindName
|
this.taskBlindName = this.visitTaskList[i].TaskBlindName
|
||||||
this.readingTaskState = this.visitTaskList[i].ReadingTaskState
|
this.readingTaskState = 1
|
||||||
console.log(this.visitTaskList[i].IsInit)
|
console.log(this.visitTaskList[i].IsInit)
|
||||||
if (!this.visitTaskList[i].IsInit) {
|
if (!this.visitTaskList[i].IsInit) {
|
||||||
var loading = this.$loading({ fullscreen: true })
|
var loading = this.$loading({ fullscreen: true })
|
||||||
@@ -306,9 +306,9 @@ export default {
|
|||||||
}
|
}
|
||||||
this.signVisible = false
|
this.signVisible = false
|
||||||
// 设置当前任务阅片状态为已读
|
// 设置当前任务阅片状态为已读
|
||||||
this.readingTaskState = 2
|
this.readingTaskState = 1
|
||||||
store.dispatch('reading/setVisitTaskReadingTaskState', { visitTaskId: this.visitTaskId, readingTaskState: 2 })
|
store.dispatch('reading/setVisitTaskReadingTaskState', { visitTaskId: this.visitTaskId, readingTaskState: 1 })
|
||||||
DicomEvent.$emit('setReadingState', 2)
|
DicomEvent.$emit('setReadingState', 1)
|
||||||
window.opener.postMessage('refreshTaskList', window.location)
|
window.opener.postMessage('refreshTaskList', window.location)
|
||||||
this.$confirm(this.$t('trials:oncologyReview:title:msg2'), {
|
this.$confirm(this.$t('trials:oncologyReview:title:msg2'), {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-loading="loading" style="min-height: 500px;">
|
<div v-loading="loading" style="min-height: 500px;">
|
||||||
<el-form v-if="isRender" ref="questions" size="small" :model="questionForm" :disabled="readingTaskState >= 2">
|
<el-form v-if="isRender" ref="questions" size="small" :model="questionForm">
|
||||||
<template>
|
<template>
|
||||||
<QuestionFormItem v-for="question of questions" :key="question.Id" :visitTaskId="visitTaskId"
|
<QuestionFormItem v-for="question of questions" :key="question.Id" :visitTaskId="visitTaskId"
|
||||||
:question="question" :question-form="questionForm" :reading-task-state="readingTaskState"
|
:question="question" :question-form="questionForm" :reading-task-state="readingTaskState"
|
||||||
@@ -112,8 +112,8 @@ export default {
|
|||||||
VisitTaskId: visitTaskId ? visitTaskId : this.visitTaskId
|
VisitTaskId: visitTaskId ? visitTaskId : this.visitTaskId
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
this.IsBaseline = res.OtherInfo.IsBaseline
|
this.IsBaseline = res.OtherInfo.IsBaseline
|
||||||
this.readingTaskState = res.OtherInfo.ReadingTaskState
|
this.readingTaskState = 1
|
||||||
DicomEvent.$emit('setReadingState', res.OtherInfo.ReadingTaskState)
|
DicomEvent.$emit('setReadingState', 1)
|
||||||
res.Result.SinglePage.map((v) => {
|
res.Result.SinglePage.map((v) => {
|
||||||
if (v.Type === 'group' && v.Childrens.length === 0) return
|
if (v.Type === 'group' && v.Childrens.length === 0) return
|
||||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary' && v.Type !== 'table' && v.Type !== 'basicTable' && v.Type !== 'number') {
|
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary' && v.Type !== 'table' && v.Type !== 'basicTable' && v.Type !== 'number') {
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-loading="loading" class="study-wrapper">
|
<div v-loading="loading" class="study-wrapper">
|
||||||
<h4 v-if="isReadingShowSubjectInfo" style="color: #ddd;padding: 5px 0px;margin: 0;text-align: center;background-color: #4c4c4c;">
|
<h4 v-if="isReadingShowSubjectInfo"
|
||||||
|
style="color: #ddd;padding: 5px 0px;margin: 0;text-align: center;background-color: #4c4c4c;">
|
||||||
{{ subjectCode }}
|
{{ subjectCode }}
|
||||||
</h4>
|
</h4>
|
||||||
<h4 v-if="isReadingShowSubjectInfo" style="color: #ddd;padding: 5px 0px;margin: 0;text-align: center;background-color: #4c4c4c;margin-bottom: 5px;">
|
<h4 v-if="isReadingShowSubjectInfo"
|
||||||
|
style="color: #ddd;padding: 5px 0px;margin: 0;text-align: center;background-color: #4c4c4c;margin-bottom: 5px;">
|
||||||
{{ taskBlindName }}
|
{{ taskBlindName }}
|
||||||
</h4>
|
</h4>
|
||||||
<div class="ps">
|
<div class="ps">
|
||||||
@@ -14,11 +16,8 @@
|
|||||||
<!-- 关键序列 -->
|
<!-- 关键序列 -->
|
||||||
{{ $t('trials:reading:title:keySeries') }}
|
{{ $t('trials:reading:title:keySeries') }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-else class="dicom-desc"
|
||||||
v-else
|
style="width: 150px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;">
|
||||||
class="dicom-desc"
|
|
||||||
style="width: 150px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;"
|
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<div style="text-overflow: ellipsis;overflow: hidden;" v-if="!study.StudyName">
|
<div style="text-overflow: ellipsis;overflow: hidden;" v-if="!study.StudyName">
|
||||||
<span :title="study.StudyCode">{{ study.StudyCode }}</span>
|
<span :title="study.StudyCode">{{ study.StudyCode }}</span>
|
||||||
@@ -31,59 +30,47 @@
|
|||||||
</span>
|
</span>
|
||||||
<div>{{ study.Modalities }} ({{ study.SeriesCount }})</div>
|
<div>{{ study.Modalities }} ({{ study.SeriesCount }})</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="text-overflow: ellipsis;overflow: hidden;" :title="study.Description">{{ study.Description }}</div>
|
<div style="text-overflow: ellipsis;overflow: hidden;" :title="study.Description">{{ study.Description
|
||||||
|
}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="series">
|
<div class="series">
|
||||||
<div
|
<div v-for="(series, i) in study.SeriesList" :key="i" style="position:relative;margin-top:5px;"
|
||||||
v-for="(series, i) in study.SeriesList"
|
series-type="current" @click="showSeriesImage(index, i, series)">
|
||||||
:key="i"
|
|
||||||
style="position:relative;margin-top:5px;"
|
|
||||||
series-type="current"
|
|
||||||
@click="showSeriesImage(index,i,series)"
|
|
||||||
>
|
|
||||||
|
|
||||||
<div
|
<div :class="{ 'series-active': i == seriesIndex && index === studyIndex }" class="series-wrapper">
|
||||||
:class="{'series-active': i==seriesIndex && index === studyIndex}"
|
<el-image class="image-preview" :src="series.previewImageUrl" fit="fill" crossorigin="anonymous" />
|
||||||
class="series-wrapper"
|
|
||||||
>
|
|
||||||
<el-image
|
|
||||||
class="image-preview"
|
|
||||||
:src="series.previewImageUrl"
|
|
||||||
fit="fill"
|
|
||||||
crossorigin="anonymous"
|
|
||||||
/>
|
|
||||||
<div class="image-desc">
|
<div class="image-desc">
|
||||||
<div class="flex-div">
|
<div class="flex-div">
|
||||||
<div style="width: 40px;display: flex;flex-direction: row;justify-content: space-between;">
|
<div style="width: 40px;display: flex;flex-direction: row;justify-content: space-between;">
|
||||||
<div v-if="!study.IsCriticalSequence">#{{ series.seriesNumber }}</div>
|
<div v-if="!study.IsCriticalSequence">#{{ series.seriesNumber }}</div>
|
||||||
<div v-if="series.isDicom && series.prefetchInstanceCount<series.instanceCount * 100 && series.modality!== 'SR'">
|
<div
|
||||||
|
v-if="series.isDicom && series.prefetchInstanceCount < series.instanceCount * 100 && series.modality !== 'SR'">
|
||||||
<!-- 下载 -->
|
<!-- 下载 -->
|
||||||
<el-tooltip v-if="!series.isLoading" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
<el-tooltip v-if="!series.isLoading" class="item" effect="dark"
|
||||||
<i class="el-icon-video-play" style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;" @click.stop="loadSeries(series,index,i)" />
|
:content="$t('trials:reading:button:download')" placement="bottom">
|
||||||
|
<i class="el-icon-video-play"
|
||||||
|
style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;"
|
||||||
|
@click.stop="loadSeries(series, index, i)" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<el-tooltip v-else-if="series.isDicom && series.prefetchInstanceCount === 0 &&series.modality!== 'SR'" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
<el-tooltip
|
||||||
<i class="el-icon-video-play" style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;" @click.stop="loadSeries(series,index,i)" />
|
v-else-if="series.isDicom && series.prefetchInstanceCount === 0 && series.modality !== 'SR'"
|
||||||
|
class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
||||||
|
<i class="el-icon-video-play"
|
||||||
|
style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;"
|
||||||
|
@click.stop="loadSeries(series, index, i)" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="series.isExistMutiFrames && series.instanceCount > 1">
|
<div v-if="series.isExistMutiFrames && series.instanceCount > 1">
|
||||||
<el-popover
|
<el-popover placement="right" trigger="hover" popper-class="instance_frame_wrapper">
|
||||||
placement="right"
|
|
||||||
trigger="hover"
|
|
||||||
popper-class="instance_frame_wrapper"
|
|
||||||
>
|
|
||||||
<div class="frame_list">
|
<div class="frame_list">
|
||||||
<div
|
<div v-for="(instance, idx) in series.instanceInfoList" :key="instance.Id"
|
||||||
v-for="(instance, idx) in series.instanceInfoList"
|
class="frame_content" :class="{ 'frame_content_active': activeInstanceId === instance.Id }"
|
||||||
:key="instance.Id"
|
|
||||||
class="frame_content"
|
|
||||||
:class="{ 'frame_content_active': activeInstanceId === instance.Id }"
|
|
||||||
:style="{ 'margin-bottom': idx < series.instanceInfoList.length - 1 ? '5px' : '0px' }"
|
:style="{ 'margin-bottom': idx < series.instanceInfoList.length - 1 ? '5px' : '0px' }"
|
||||||
@click.stop="showMultiFrames(index,series, i, instance)"
|
@click.stop="showMultiFrames(index, series, i, instance)">
|
||||||
>
|
|
||||||
<!-- <div>
|
<!-- <div>
|
||||||
<img
|
<img
|
||||||
class="image-preview"
|
class="image-preview"
|
||||||
@@ -96,12 +83,14 @@
|
|||||||
</div> -->
|
</div> -->
|
||||||
<div>
|
<div>
|
||||||
<div>{{ instance.InstanceNumber }}</div>
|
<div>{{ instance.InstanceNumber }}</div>
|
||||||
<div>{{ `${instance.NumberOfFrames > 0 ? instance.KeyFramesList.length > 0 ? instance.KeyFramesList.length : instance.NumberOfFrames : 1} frame` }}</div>
|
<div>{{ `${instance.NumberOfFrames > 0 ? instance.KeyFramesList.length > 0 ?
|
||||||
|
instance.KeyFramesList.length : instance.NumberOfFrames : 1} frame` }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;color: #ffeb3b;" />
|
<i slot="reference" class="el-icon-connection"
|
||||||
|
style="font-size: 15px;cursor: pointer;color: #ffeb3b;" />
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -121,9 +110,11 @@
|
|||||||
{{ series.modality }}: {{ series.instanceCount }} image
|
{{ series.modality }}: {{ series.instanceCount }} image
|
||||||
</p>
|
</p>
|
||||||
<div class="flex-div">
|
<div class="flex-div">
|
||||||
<div v-if="measureData && measureData.findIndex(v=>v.SeriesId === series.seriesId && v.MeasureData) > -1">
|
<div
|
||||||
|
v-if="measureData && measureData.findIndex(v => v.SeriesId === series.seriesId && v.MeasureData) > -1">
|
||||||
<!-- 有标注 -->
|
<!-- 有标注 -->
|
||||||
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:marked')" placement="right">
|
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:marked')"
|
||||||
|
placement="right">
|
||||||
<i class="el-icon-star-on" style="font-size: 16px;color: #ff5722;" />
|
<i class="el-icon-star-on" style="font-size: 16px;color: #ff5722;" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
@@ -131,10 +122,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="series.isDicom && series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount * 100" style="width: 100%;">
|
<div
|
||||||
<el-progress
|
v-if="series.isDicom && series.prefetchInstanceCount > 0 && series.prefetchInstanceCount < series.instanceCount * 100"
|
||||||
:percentage="parseInt((series.prefetchInstanceCount / series.instanceCount).toFixed(2))"
|
style="width: 100%;">
|
||||||
/>
|
<el-progress :percentage="parseInt((series.prefetchInstanceCount / series.instanceCount).toFixed(2))" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -144,24 +135,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sr-wrapper">
|
<div class="sr-wrapper">
|
||||||
<el-dialog
|
<el-dialog :visible.sync="srDialogVisible"
|
||||||
:visible.sync="srDialogVisible"
|
:custom-class="isSrFullscreen ? 'sr-full-dialog-container' : 'sr-dialog-container'" :show-close="false"
|
||||||
:custom-class="isSrFullscreen?'sr-full-dialog-container':'sr-dialog-container'"
|
:close-on-click-modal="false" :fullscreen="isSrFullscreen">
|
||||||
:show-close="false"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
:fullscreen="isSrFullscreen"
|
|
||||||
>
|
|
||||||
<span slot="title" class="dialog-footer">
|
<span slot="title" class="dialog-footer">
|
||||||
<div style="position: absolute;right: 20px;top: 10px;">
|
<div style="position: absolute;right: 20px;top: 10px;">
|
||||||
<svg-icon :icon-class="isSrFullscreen?'exit-fullscreen':'fullscreen'" style="cursor: pointer;font-size: 20px;color:#000;" @click="isSrFullscreen=!isSrFullscreen" />
|
<svg-icon :icon-class="isSrFullscreen ? 'exit-fullscreen' : 'fullscreen'"
|
||||||
<svg-icon icon-class="dClose" style="cursor: pointer;font-size: 25px;margin-left: 10px;" @click="srDialogVisible = false" />
|
style="cursor: pointer;font-size: 20px;color:#000;" @click="isSrFullscreen = !isSrFullscreen" />
|
||||||
|
<svg-icon icon-class="dClose" style="cursor: pointer;font-size: 25px;margin-left: 10px;"
|
||||||
|
@click="srDialogVisible = false" />
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<div style="height: 100%;margin:0;">
|
<div style="height: 100%;margin:0;">
|
||||||
<SrList
|
<SrList v-if="srDialogVisible" :sr-info="srInfo" />
|
||||||
v-if="srDialogVisible"
|
|
||||||
:sr-info="srInfo"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
@@ -266,6 +252,9 @@ export default {
|
|||||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||||
this.measureData = this.visitTaskList[idx].MeasureData
|
this.measureData = this.visitTaskList[idx].MeasureData
|
||||||
})
|
})
|
||||||
|
DicomEvent.$on("getStudyFile", () => {
|
||||||
|
DicomEvent.$emit('sendStudyFile', { studyList: this.studyList, studyIndex: this.studyIndex, seriesIndex: this.seriesIndex, visitTaskId: this.visitTaskId })
|
||||||
|
})
|
||||||
// DicomEvent.$on('setReadingState', readingTaskState => {
|
// DicomEvent.$on('setReadingState', readingTaskState => {
|
||||||
// var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
// var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||||
// if (idx > -1) {
|
// if (idx > -1) {
|
||||||
@@ -871,10 +860,12 @@ export default {
|
|||||||
::v-deep .el-progress-bar__inner {
|
::v-deep .el-progress-bar__inner {
|
||||||
transition: width 0s ease;
|
transition: width 0s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
width:100%;
|
width:100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|
||||||
.dicom-desc {
|
.dicom-desc {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
@@ -887,19 +878,23 @@ export default {
|
|||||||
overflow-anchor: none;
|
overflow-anchor: none;
|
||||||
touch-action: auto;
|
touch-action: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.series-active {
|
.series-active {
|
||||||
background-color: #607d8b !important;
|
background-color: #607d8b !important;
|
||||||
border: 1px solid #607d8b !important;
|
border: 1px solid #607d8b !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-progress__text {
|
::v-deep .el-progress__text {
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.series {
|
.series {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
|
|
||||||
.series-wrapper {
|
.series-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -912,9 +907,11 @@ export default {
|
|||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
border: 1px solid #404040;
|
border: 1px solid #404040;
|
||||||
background-color: #3a3a3a;
|
background-color: #3a3a3a;
|
||||||
|
|
||||||
.el-progress__text {
|
.el-progress__text {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-progress-bar {
|
.el-progress-bar {
|
||||||
padding-right: 0px;
|
padding-right: 0px;
|
||||||
}
|
}
|
||||||
@@ -925,8 +922,10 @@ export default {
|
|||||||
border: 2px solid #252525;
|
border: 2px solid #252525;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-desc {
|
.image-desc {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
|
|
||||||
p {
|
p {
|
||||||
width: 95px;
|
width: 95px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -936,6 +935,7 @@ export default {
|
|||||||
color: #ddd;
|
color: #ddd;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
|
||||||
div {
|
div {
|
||||||
width: 95px;
|
width: 95px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -944,6 +944,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-div {
|
.flex-div {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -960,17 +961,21 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-collapse {
|
::v-deep .el-collapse {
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
.el-collapse-item {
|
.el-collapse-item {
|
||||||
background-color: #000 !important;
|
background-color: #000 !important;
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-collapse-item__content {
|
.el-collapse-item__content {
|
||||||
padding-bottom: 5px;
|
padding-bottom: 5px;
|
||||||
background-color: #000 !important;
|
background-color: #000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-collapse-item__header {
|
.el-collapse-item__header {
|
||||||
background-color: #000 !important;
|
background-color: #000 !important;
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
@@ -980,27 +985,33 @@ export default {
|
|||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sr-wrapper {
|
.sr-wrapper {
|
||||||
::v-deep .el-dialog {
|
::v-deep .el-dialog {
|
||||||
background: #fff !important;
|
background: #fff !important;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
|
|
||||||
// color: #ddd;
|
// color: #ddd;
|
||||||
.el-dialog__title {
|
.el-dialog__title {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .sr-dialog-container {
|
::v-deep .sr-dialog-container {
|
||||||
margin-top: 50px !important;
|
margin-top: 50px !important;
|
||||||
width: 75%;
|
width: 75%;
|
||||||
height: 80%;
|
height: 80%;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-dialog__body {
|
::v-deep .el-dialog__body {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
height: calc(100% - 50px);
|
height: calc(100% - 50px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-dialog__header {
|
.el-dialog__header {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sr-full-dialog-container {
|
.sr-full-dialog-container {
|
||||||
::v-deep .is-fullscreen .el-dialog__body {
|
::v-deep .is-fullscreen .el-dialog__body {
|
||||||
height: calc(100% - 50px);
|
height: calc(100% - 50px);
|
||||||
@@ -1008,7 +1019,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<style>
|
<style>
|
||||||
.instance_frame_wrapper {
|
.instance_frame_wrapper {
|
||||||
@@ -1017,18 +1027,22 @@ export default {
|
|||||||
border: 1px solid #2c2c2c;
|
border: 1px solid #2c2c2c;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame_list {
|
.frame_list {
|
||||||
max-height: 500px;
|
max-height: 500px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.instance_frame_wrapper ::-webkit-scrollbar {
|
.instance_frame_wrapper ::-webkit-scrollbar {
|
||||||
width: 7px;
|
width: 7px;
|
||||||
height: 7px;
|
height: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: #d0d0d0;
|
background: #d0d0d0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame_content {
|
.frame_content {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
@@ -1038,6 +1052,7 @@ export default {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
border: 1px solid #404040;
|
border: 1px solid #404040;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame_content:hover {
|
.frame_content:hover {
|
||||||
/* font-weight: bold; */
|
/* font-weight: bold; */
|
||||||
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
||||||
@@ -1046,6 +1061,7 @@ export default {
|
|||||||
border-color: #213a54 !important;
|
border-color: #213a54 !important;
|
||||||
background-color: #213a54;
|
background-color: #213a54;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame_content_active {
|
.frame_content_active {
|
||||||
border-color: #213a54 !important;
|
border-color: #213a54 !important;
|
||||||
background-color: #213a54;
|
background-color: #213a54;
|
||||||
|
|||||||
@@ -147,7 +147,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<div style="text-align:right;margin-top: 10px;" v-if="!IsViewStudyPart">
|
<div style="text-align:right;margin-top: 10px;">
|
||||||
<!-- 确认 -->
|
<!-- 确认 -->
|
||||||
<el-button type="primary" @click="handleConfirmBP">{{ $t('trials:reading:button:confirm')
|
<el-button type="primary" @click="handleConfirmBP">{{ $t('trials:reading:button:confirm')
|
||||||
}}</el-button>
|
}}</el-button>
|
||||||
@@ -223,8 +223,7 @@ export default {
|
|||||||
readingVersionEnum: null,
|
readingVersionEnum: null,
|
||||||
dialogBodyPartVisible: false,
|
dialogBodyPartVisible: false,
|
||||||
isReadKeyFile: true,
|
isReadKeyFile: true,
|
||||||
isHaveKeyFile: false,
|
isHaveKeyFile: false
|
||||||
IsViewStudyPart: true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
@@ -320,7 +320,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tool-item" :title="$t('trials:reading:button:upload')"
|
<div class="tool-item" :title="$t('trials:reading:button:upload')"
|
||||||
v-if="trialCriterion.ImageUploadEnum > 0 && readingTaskState < 2" v-hasPermi="['role:ir']">
|
v-if="trialCriterion.ImageUploadEnum > 0" v-hasPermi="['role:ir']">
|
||||||
<div class="tool-wrapper">
|
<div class="tool-wrapper">
|
||||||
<div class="icon" @click.prevent="openUploadImage('upload')">
|
<div class="icon" @click.prevent="openUploadImage('upload')">
|
||||||
<i class="el-icon-upload2 svg-icon" />
|
<i class="el-icon-upload2 svg-icon" />
|
||||||
|
|||||||
@@ -150,19 +150,13 @@ export default {
|
|||||||
this.handleClear(e, key)
|
this.handleClear(e, key)
|
||||||
if (key === 'study') {
|
if (key === 'study') {
|
||||||
this.seriesList = this.studyList.find(item => item.StudyId === this.form.studyId).SeriesArr
|
this.seriesList = this.studyList.find(item => item.StudyId === this.form.studyId).SeriesArr
|
||||||
this.form.seriesId = null
|
|
||||||
this.form.segmentGroupId = null
|
|
||||||
this.form.segmentId = null
|
|
||||||
}
|
}
|
||||||
if (key === 'series') {
|
if (key === 'series') {
|
||||||
this.segmentGroupList = this.segmentionList.filter(item => item.SeriesId === this.form.seriesId)
|
this.segmentGroupList = this.segmentionList.filter(item => item.SeriesId === this.form.seriesId)
|
||||||
this.form.segmentGroupId = null
|
|
||||||
this.form.segmentId = null
|
|
||||||
}
|
}
|
||||||
if (key === 'segmentGroup') {
|
if (key === 'segmentGroup') {
|
||||||
let list = await this.getSegmentList(this.form.segmentGroupId)
|
let list = await this.getSegmentList(this.form.segmentGroupId)
|
||||||
this.segmentList = list.filter(item => item.SegmentJson)
|
this.segmentList = list.filter(item => item.SegmentJson)
|
||||||
this.form.segmentId = null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleClear(e, key) {
|
handleClear(e, key) {
|
||||||
|
|||||||
@@ -804,16 +804,12 @@ export default {
|
|||||||
toolGroup.setToolPassive(this.activeTool)
|
toolGroup.setToolPassive(this.activeTool)
|
||||||
}
|
}
|
||||||
this.$emit('update:activeTool', '')
|
this.$emit('update:activeTool', '')
|
||||||
} else if (this.activeTool === name) {
|
|
||||||
toolGroup.setToolPassive(this.ThresholdTools[1])
|
|
||||||
this.$emit('update:activeTool', '')
|
|
||||||
} else {
|
} else {
|
||||||
if (this.activeTool) {
|
if (this.activeTool) {
|
||||||
if (toolName === CrosshairsTool.toolName) {
|
if (toolName === CrosshairsTool.toolName) {
|
||||||
toolGroup.setToolDisabled(this.activeTool)
|
toolGroup.setToolDisabled(this.activeTool)
|
||||||
} else {
|
} else {
|
||||||
toolGroup.setToolPassive(this.activeTool)
|
toolGroup.setToolPassive(this.activeTool)
|
||||||
toolGroup.setToolPassive(this.ThresholdTools[1])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
toolGroup.setToolActive(toolName, {
|
toolGroup.setToolActive(toolName, {
|
||||||
|
|||||||
+2
-2
@@ -24,7 +24,7 @@
|
|||||||
<template v-if="rerender">
|
<template v-if="rerender">
|
||||||
<QuestionFormItem v-for="question of questions" :key="question.Id" :visit-task-id="visitTaskId"
|
<QuestionFormItem v-for="question of questions" :key="question.Id" :visit-task-id="visitTaskId"
|
||||||
:isNoneDicom="isNoneDicom" :question="question" :question-form="questionForm"
|
:isNoneDicom="isNoneDicom" :question="question" :question-form="questionForm"
|
||||||
:reading-task-state="readingTaskState" :criterion-id="criterionId" :calculation-list="calculationList"
|
:reading-task-state="1" :criterion-id="criterionId" :calculation-list="calculationList"
|
||||||
:question-mark-info-list="questionMarkInfoList" :questions-mark-status="questionsMarkStatus"
|
:question-mark-info-list="questionMarkInfoList" :questions-mark-status="questionsMarkStatus"
|
||||||
:questionsSegmentMarkStatus="questionsSegmentMarkStatus" :is-baseline="isBaseLineTask"
|
:questionsSegmentMarkStatus="questionsSegmentMarkStatus" :is-baseline="isBaseLineTask"
|
||||||
@resetFormItemData="resetFormItemData" @setFormItemData="setFormItemData" @getQuestions="getQuestions"
|
@resetFormItemData="resetFormItemData" @setFormItemData="setFormItemData" @getQuestions="getQuestions"
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
@handleReadingChart="handleReadingChart" @saveSegmentBindingAndAnswer="saveSegmentBindingAndAnswer" />
|
@handleReadingChart="handleReadingChart" @saveSegmentBindingAndAnswer="saveSegmentBindingAndAnswer" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-form-item v-if="readingTaskState < 2">
|
<el-form-item>
|
||||||
<div class="action-bar">
|
<div class="action-bar">
|
||||||
<!-- <i class="el-icon-warning feedback-icon" @click="openFeedBackTable"
|
<!-- <i class="el-icon-warning feedback-icon" @click="openFeedBackTable"
|
||||||
:style="{ color: taskInfo && taskInfo.IsExistUnprocessedFeedback ? '#ffeb3b' : '#fff' }" /> -->
|
:style="{ color: taskInfo && taskInfo.IsExistUnprocessedFeedback ? '#ffeb3b' : '#fff' }" /> -->
|
||||||
|
|||||||
+23
-70
@@ -35,9 +35,7 @@
|
|||||||
scope.row.QuestionName }}
|
scope.row.QuestionName }}
|
||||||
<svg-icon
|
<svg-icon
|
||||||
v-if="scope.row.ShowChartTypeEnum > 0 || (scope.row.LesionType === 0 && scope.row.ReportLayType === 1)"
|
v-if="scope.row.ShowChartTypeEnum > 0 || (scope.row.LesionType === 0 && scope.row.ReportLayType === 1)"
|
||||||
icon-class="readingChart"
|
icon-class="readingChart" class="svg-icon svg-readingChart-mini" @click.stop="(e) => handleReadingChart({
|
||||||
class="svg-icon svg-readingChart-mini"
|
|
||||||
@click.stop="(e) => handleReadingChart({
|
|
||||||
e,
|
e,
|
||||||
data: {
|
data: {
|
||||||
QuestionId: scope.row.RowIndex ? null : scope.row.QuestionId,
|
QuestionId: scope.row.RowIndex ? null : scope.row.QuestionId,
|
||||||
@@ -51,13 +49,8 @@
|
|||||||
<span v-else style="font-weight: bold;font-size: 16px;color: #f44336;">{{ scope.row.GroupName }}</span>
|
<span v-else style="font-weight: bold;font-size: 16px;color: #f44336;">{{ scope.row.GroupName }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column v-for="task in visitTaskList" :key="task.VisitTaskId" prop="date" show-overflow-tooltip
|
||||||
v-for="task in visitTaskList"
|
width="200px">
|
||||||
:key="task.VisitTaskId"
|
|
||||||
prop="date"
|
|
||||||
show-overflow-tooltip
|
|
||||||
width="200px"
|
|
||||||
>
|
|
||||||
<template slot="header">
|
<template slot="header">
|
||||||
<div v-if="task.IsCurrentTask">{{ task.BlindName }}</div>
|
<div v-if="task.IsCurrentTask">{{ task.BlindName }}</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
@@ -71,18 +64,15 @@
|
|||||||
</template>
|
</template>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<template
|
<template
|
||||||
v-if="readingTaskState < 2 && task.VisitTaskId === visitTaskId && (scope.row.Type === 'input' || scope.row.Type === 'number' || scope.row.Type === 'select' || scope.row.Type === 'textarea' || scope.row.Type === 'radio')"
|
v-if="readingTaskState < 2 && task.VisitTaskId === visitTaskId && (scope.row.Type === 'input' || scope.row.Type === 'number' || scope.row.Type === 'select' || scope.row.Type === 'textarea' || scope.row.Type === 'radio')">
|
||||||
>
|
|
||||||
<!-- 输入框 -->
|
<!-- 输入框 -->
|
||||||
<div>
|
<div>
|
||||||
<template
|
<template
|
||||||
v-if="!((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
v-if="!((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)" />
|
||||||
/>
|
|
||||||
<el-input
|
<el-input
|
||||||
v-else-if="questionForm[scope.row.QuestionId] instanceof Array && (scope.row.Type === 'input' || scope.row.Type === 'textarea') && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
v-else-if="questionForm[scope.row.QuestionId] instanceof Array && (scope.row.Type === 'input' || scope.row.Type === 'textarea') && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
||||||
v-model="questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]"
|
v-model="questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]"
|
||||||
size="mini"
|
size="mini" />
|
||||||
/>
|
|
||||||
<span
|
<span
|
||||||
v-else-if="questionForm[scope.row.QuestionId] instanceof Array && (scope.row.Type === 'input' || scope.row.Type === 'textarea')">{{
|
v-else-if="questionForm[scope.row.QuestionId] instanceof Array && (scope.row.Type === 'input' || scope.row.Type === 'textarea')">{{
|
||||||
questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId] }}</span>
|
questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId] }}</span>
|
||||||
@@ -94,22 +84,13 @@
|
|||||||
<el-select
|
<el-select
|
||||||
v-else-if="questionForm[scope.row.QuestionId] instanceof Array && (scope.row.Type === 'select' || scope.row.Type === 'radio') && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
v-else-if="questionForm[scope.row.QuestionId] instanceof Array && (scope.row.Type === 'select' || scope.row.Type === 'radio') && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
||||||
v-model="questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]"
|
v-model="questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]"
|
||||||
size="mini"
|
size="mini" clearable :multiple="scope.row.OptionTypeEnum === 1">
|
||||||
clearable
|
|
||||||
:multiple="scope.row.OptionTypeEnum === 1"
|
|
||||||
>
|
|
||||||
<template>
|
<template>
|
||||||
<el-option
|
<el-option v-for="val in scope.row.TypeValue.split('|')" :key="val" :label="val" :value="val" />
|
||||||
v-for="val in scope.row.TypeValue.split('|')"
|
|
||||||
:key="val"
|
|
||||||
:label="val"
|
|
||||||
:value="val"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-select>
|
</el-select>
|
||||||
<span
|
<span
|
||||||
v-else-if="questionForm[scope.row.QuestionId] instanceof Array && questionForm[scope.row.QuestionId][scope.row.xfIndex] && (scope.row.Type === 'select' || scope.row.Type === 'radio')"
|
v-else-if="questionForm[scope.row.QuestionId] instanceof Array && questionForm[scope.row.QuestionId][scope.row.xfIndex] && (scope.row.Type === 'select' || scope.row.Type === 'radio')">
|
||||||
>
|
|
||||||
{{
|
{{
|
||||||
Array.isArray(questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId])
|
Array.isArray(questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId])
|
||||||
?
|
?
|
||||||
@@ -119,18 +100,10 @@
|
|||||||
</span>
|
</span>
|
||||||
<el-select
|
<el-select
|
||||||
v-else-if="(scope.row.Type === 'select' || scope.row.Type === 'radio') && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
v-else-if="(scope.row.Type === 'select' || scope.row.Type === 'radio') && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
||||||
v-model="questionForm[scope.row.QuestionId]"
|
v-model="questionForm[scope.row.QuestionId]" size="mini" clearable
|
||||||
size="mini"
|
:multiple="scope.row.OptionTypeEnum === 1">
|
||||||
clearable
|
|
||||||
:multiple="scope.row.OptionTypeEnum === 1"
|
|
||||||
>
|
|
||||||
<template>
|
<template>
|
||||||
<el-option
|
<el-option v-for="val in scope.row.TypeValue.split('|')" :key="val" :label="val" :value="val" />
|
||||||
v-for="val in scope.row.TypeValue.split('|')"
|
|
||||||
:key="val"
|
|
||||||
:label="val"
|
|
||||||
:value="val"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-select>
|
</el-select>
|
||||||
<span v-else-if="scope.row.Type === 'select' || scope.row.Type === 'radio'">
|
<span v-else-if="scope.row.Type === 'select' || scope.row.Type === 'radio'">
|
||||||
@@ -143,8 +116,7 @@
|
|||||||
<el-input
|
<el-input
|
||||||
v-else-if="scope.row.DataSource !== 1 && questionForm[scope.row.QuestionId] instanceof Array && scope.row.Type === 'number' && (scope.row.xfIndex || scope.row.xfIndex === 0) && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
v-else-if="scope.row.DataSource !== 1 && questionForm[scope.row.QuestionId] instanceof Array && scope.row.Type === 'number' && (scope.row.xfIndex || scope.row.xfIndex === 0) && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
||||||
v-model="questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]"
|
v-model="questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]"
|
||||||
:disabled="scope.row.DataSource === 1"
|
:disabled="scope.row.DataSource === 1" size="mini"
|
||||||
size="mini"
|
|
||||||
@blur="limitBlur(questionForm[scope.row.QuestionId][scope.row.xfIndex], scope.row.TableQuestionId, scope.row.ValueType)"
|
@blur="limitBlur(questionForm[scope.row.QuestionId][scope.row.xfIndex], scope.row.TableQuestionId, scope.row.ValueType)"
|
||||||
@focus="() => { questionId = scope.row.QuestionId }">
|
@focus="() => { questionId = scope.row.QuestionId }">
|
||||||
<template v-if="scope.row.Unit !== 0" slot="append">
|
<template v-if="scope.row.Unit !== 0" slot="append">
|
||||||
@@ -154,11 +126,8 @@
|
|||||||
<template v-else-if="scope.row.ValueType === 2" slot="append">%</template>
|
<template v-else-if="scope.row.ValueType === 2" slot="append">%</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<span
|
<span
|
||||||
v-else-if="questionForm[scope.row.QuestionId] instanceof Array && scope.row.Type === 'number' && (scope.row.xfIndex || scope.row.xfIndex === 0)"
|
v-else-if="questionForm[scope.row.QuestionId] instanceof Array && scope.row.Type === 'number' && (scope.row.xfIndex || scope.row.xfIndex === 0)">
|
||||||
>
|
<template v-if="(scope.row.ValueType === 0 || scope.row.ValueType === 1) && scope.row.Unit">
|
||||||
<template
|
|
||||||
v-if="(scope.row.ValueType === 0 || scope.row.ValueType === 1) && scope.row.Unit"
|
|
||||||
>
|
|
||||||
{{
|
{{
|
||||||
isNaN(parseInt(questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]))
|
isNaN(parseInt(questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]))
|
||||||
?
|
?
|
||||||
@@ -185,9 +154,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<el-input
|
<el-input
|
||||||
v-else-if="scope.row.DataSource !== 1 && scope.row.Type === 'number' && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
v-else-if="scope.row.DataSource !== 1 && scope.row.Type === 'number' && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
||||||
v-model="questionForm[scope.row.QuestionId]"
|
v-model="questionForm[scope.row.QuestionId]" :disabled="scope.row.DataSource === 1" size="mini"
|
||||||
:disabled="scope.row.DataSource === 1"
|
|
||||||
size="mini"
|
|
||||||
@blur="limitBlur(questionForm, scope.row.QuestionId, scope.row.ValueType)"
|
@blur="limitBlur(questionForm, scope.row.QuestionId, scope.row.ValueType)"
|
||||||
@focus="() => { questionId = scope.row.QuestionId }">
|
@focus="() => { questionId = scope.row.QuestionId }">
|
||||||
<template v-if="scope.row.Unit !== 0" slot="append">
|
<template v-if="scope.row.Unit !== 0" slot="append">
|
||||||
@@ -197,9 +164,7 @@
|
|||||||
<template v-else-if="scope.row.ValueType === 2" slot="append">%</template>
|
<template v-else-if="scope.row.ValueType === 2" slot="append">%</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<span v-else-if="scope.row.Type === 'number'">
|
<span v-else-if="scope.row.Type === 'number'">
|
||||||
<template
|
<template v-if="(scope.row.ValueType === 0 || scope.row.ValueType === 1) && scope.row.Unit">
|
||||||
v-if="(scope.row.ValueType === 0 || scope.row.ValueType === 1) && scope.row.Unit"
|
|
||||||
>
|
|
||||||
{{ isNaN(parseInt(questionForm[scope.row.QuestionId])) ?
|
{{ isNaN(parseInt(questionForm[scope.row.QuestionId])) ?
|
||||||
questionForm[scope.row.QuestionId] : `${questionForm[scope.row.QuestionId]} ${scope.row.Unit !== 4
|
questionForm[scope.row.QuestionId] : `${questionForm[scope.row.QuestionId]} ${scope.row.Unit !== 4
|
||||||
?
|
?
|
||||||
@@ -236,11 +201,8 @@
|
|||||||
}}
|
}}
|
||||||
</template>
|
</template>
|
||||||
<template
|
<template
|
||||||
v-else-if="!((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
v-else-if="!((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)" />
|
||||||
/>
|
<template v-else-if="(scope.row.ValueType === 0 || scope.row.ValueType === 1) && scope.row.Unit">
|
||||||
<template
|
|
||||||
v-else-if="(scope.row.ValueType === 0 || scope.row.ValueType === 1) && scope.row.Unit"
|
|
||||||
>
|
|
||||||
{{
|
{{
|
||||||
isNaN(parseInt(scope.row.Answers[task.VisitTaskId])) ? scope.row.Answers[task.VisitTaskId] :
|
isNaN(parseInt(scope.row.Answers[task.VisitTaskId])) ? scope.row.Answers[task.VisitTaskId] :
|
||||||
`${scope.row.Answers[task.VisitTaskId]}
|
`${scope.row.Answers[task.VisitTaskId]}
|
||||||
@@ -259,26 +221,17 @@
|
|||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- 签名框 -->
|
<!-- 签名框 -->
|
||||||
<el-dialog
|
<el-dialog v-if="signVisible" :visible.sync="signVisible" :close-on-click-modal="false" width="600px"
|
||||||
v-if="signVisible"
|
custom-class="base-dialog-wrapper">
|
||||||
:visible.sync="signVisible"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
width="600px"
|
|
||||||
custom-class="base-dialog-wrapper"
|
|
||||||
>
|
|
||||||
<div slot="title">
|
<div slot="title">
|
||||||
<span style="font-size:18px;">{{ $t('common:dialogTitle:sign') }}</span>
|
<span style="font-size:18px;">{{ $t('common:dialogTitle:sign') }}</span>
|
||||||
<span
|
<span style="font-size:12px;margin-left:5px">{{ `(${$t('common:label:sign')}${currentUser})` }}</span>
|
||||||
style="font-size:12px;margin-left:5px"
|
|
||||||
>{{ `(${$t('common:label:sign')}${currentUser})` }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<SignForm ref="signForm" :sign-code-enum="signCode" @closeDialog="closeSignDialog" />
|
<SignForm ref="signForm" :sign-code-enum="signCode" @closeDialog="closeSignDialog" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 预览文件 -->
|
<!-- 预览文件 -->
|
||||||
<viewer
|
<viewer ref="picture_perview_customizeReportPage" style="margin: 0 10px"
|
||||||
ref="picture_perview_customizeReportPage"
|
|
||||||
style="margin: 0 10px"
|
|
||||||
v-if="currentType && ['png', 'jpg', 'jpeg'].includes(currentType.toLowerCase())"
|
v-if="currentType && ['png', 'jpg', 'jpeg'].includes(currentType.toLowerCase())"
|
||||||
:images="[`${OSSclientConfig.basePath}${currentPath}`]" :options="viewerOptions">
|
:images="[`${OSSclientConfig.basePath}${currentPath}`]" :options="viewerOptions">
|
||||||
<img v-show="false" :src="`${OSSclientConfig.basePath}${currentPath}`" alt="Image" />
|
<img v-show="false" :src="`${OSSclientConfig.basePath}${currentPath}`" alt="Image" />
|
||||||
|
|||||||
@@ -221,7 +221,6 @@ export default {
|
|||||||
Object.keys(this.seriesData).forEach(key => {
|
Object.keys(this.seriesData).forEach(key => {
|
||||||
if (key !== 'default' || this.isNeedDefault) seriesData.push(this.seriesData[key])
|
if (key !== 'default' || this.isNeedDefault) seriesData.push(this.seriesData[key])
|
||||||
})
|
})
|
||||||
console.log(seriesData, 'seriesData')
|
|
||||||
this.chart.clear();
|
this.chart.clear();
|
||||||
const option = {
|
const option = {
|
||||||
useUTC: true,
|
useUTC: true,
|
||||||
@@ -298,10 +297,10 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
res = await this.getCurrentSliceValuesFromVoxelManager(this.renderingEngineId, `${this.viewportKey}-${this.activeViewportIndex}`)
|
res = await this.getCurrentSliceValuesFromVoxelManager(this.renderingEngineId, `${this.viewportKey}-${this.activeViewportIndex}`)
|
||||||
}
|
}
|
||||||
|
if (res) {
|
||||||
let obj = {
|
let obj = {
|
||||||
|
|
||||||
}
|
}
|
||||||
if (res) {
|
|
||||||
res.values.forEach(item => {
|
res.values.forEach(item => {
|
||||||
if (obj[item]) {
|
if (obj[item]) {
|
||||||
obj[item]++
|
obj[item]++
|
||||||
@@ -324,24 +323,10 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
seriesData.sort((a, b) => a[0] - b[0])
|
seriesData.sort((a, b) => a[0] - b[0])
|
||||||
let MIN = seriesData[0][0]
|
|
||||||
let MAX = seriesData[seriesData.length - 1][0]
|
|
||||||
seriesData = []
|
|
||||||
for (let i = MIN; i <= MAX; i++) {
|
|
||||||
if (obj[i]) {
|
|
||||||
let arr = [i, obj[i]]
|
|
||||||
seriesData.push(arr)
|
|
||||||
} else {
|
|
||||||
let arr = [i, 0]
|
|
||||||
seriesData.push(arr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
seriesData.sort((a, b) => a[0] - b[0])
|
|
||||||
return {
|
return {
|
||||||
seriesData: {
|
seriesData: {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
symbolSize: 0,
|
symbolSize: 0,
|
||||||
stack: 'Total',
|
|
||||||
data: seriesData
|
data: seriesData
|
||||||
},
|
},
|
||||||
min: min,
|
min: min,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<BaseContainer class="medical-feedback-ir">
|
<BaseContainer class="medical-feedback-ir">
|
||||||
<el-tabs v-if="TrialReadingCriterionId" v-model="TrialReadingCriterionId" type="border-card">
|
<el-tabs v-model="TrialReadingCriterionId" type="border-card">
|
||||||
<el-tab-pane v-for="i of trialCriterionList" :key="i.TrialReadingCriterionId" :label="i.TrialReadingCriterionName" :name="i.TrialReadingCriterionId">
|
<el-tab-pane v-for="i of trialCriterionList" :key="i.TrialReadingCriterionId" :label="i.TrialReadingCriterionName" :name="i.TrialReadingCriterionId">
|
||||||
<div v-if="TrialReadingCriterionId === i.TrialReadingCriterionId">
|
<div v-if="TrialReadingCriterionId === i.TrialReadingCriterionId">
|
||||||
<div slot="search-container">
|
<div slot="search-container">
|
||||||
@@ -148,7 +148,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div slot="main-container">
|
<div slot="main-container">
|
||||||
<el-table
|
<el-table
|
||||||
:ref="TrialReadingCriterionId"
|
|
||||||
v-adaptive="{bottomOffset:75}"
|
v-adaptive="{bottomOffset:75}"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:data="list"
|
:data="list"
|
||||||
@@ -410,7 +409,7 @@ export default {
|
|||||||
chatForm: { visible: false, title: '' }, // 质询记录
|
chatForm: { visible: false, title: '' }, // 质询记录
|
||||||
auditVisible: false,
|
auditVisible: false,
|
||||||
trialCriterionList: [],
|
trialCriterionList: [],
|
||||||
TrialReadingCriterionId: '',
|
TrialReadingCriterionId: '0',
|
||||||
otherInfo: null
|
otherInfo: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -442,9 +441,6 @@ export default {
|
|||||||
this.total = res.Result.TotalCount
|
this.total = res.Result.TotalCount
|
||||||
this.otherInfo = res.OtherInfo
|
this.otherInfo = res.OtherInfo
|
||||||
this.loading = false
|
this.loading = false
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs[this.TrialReadingCriterionId][0].doLayout()
|
|
||||||
})
|
|
||||||
}).catch(() => { this.loading = false })
|
}).catch(() => { this.loading = false })
|
||||||
},
|
},
|
||||||
handleSearch() {
|
handleSearch() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<BaseContainer v-loading="loading" class="read-task">
|
<BaseContainer v-loading="loading" class="read-task">
|
||||||
<el-tabs v-if="TrialReadingCriterionId" v-model="TrialReadingCriterionId" type="border-card">
|
<el-tabs v-model="TrialReadingCriterionId" type="border-card">
|
||||||
<el-tab-pane v-for="item of trialCriterionList" :key="item.TrialReadingCriterionId"
|
<el-tab-pane v-for="item of trialCriterionList" :key="item.TrialReadingCriterionId"
|
||||||
:label="item.TrialReadingCriterionName" :name="item.TrialReadingCriterionId">
|
:label="item.TrialReadingCriterionName" :name="item.TrialReadingCriterionId">
|
||||||
<div v-if="TrialReadingCriterionId === item.TrialReadingCriterionId">
|
<div v-if="TrialReadingCriterionId === item.TrialReadingCriterionId">
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div slot="main-container">
|
<div slot="main-container">
|
||||||
<el-table :ref="TrialReadingCriterionId" v-adaptive="{ bottomOffset: 75 }" :data="list" stripe height="100"
|
<el-table v-adaptive="{ bottomOffset: 75 }" :data="list" stripe height="100"
|
||||||
@sort-change="handleSortChange">
|
@sort-change="handleSortChange">
|
||||||
<el-table-column type="index" width="40" align="left" />
|
<el-table-column type="index" width="40" align="left" />
|
||||||
<!-- 是否加急 -->
|
<!-- 是否加急 -->
|
||||||
@@ -206,7 +206,7 @@
|
|||||||
<!-- 是否复制阅片表单 -->
|
<!-- 是否复制阅片表单 -->
|
||||||
<el-form-item :label="$t('trials:readTask:title:copyForm')" prop="IsCopyOrigenalForms" :rules="[
|
<el-form-item :label="$t('trials:readTask:title:copyForm')" prop="IsCopyOrigenalForms" :rules="[
|
||||||
{ required: true, message: $t('common:ruleMessage:select') },
|
{ required: true, message: $t('common:ruleMessage:select') },
|
||||||
]" v-if="rowData.ReadingTool !== 3">
|
]">
|
||||||
<el-radio-group v-model="ApplyforReasonForm.IsCopyOrigenalForms">
|
<el-radio-group v-model="ApplyforReasonForm.IsCopyOrigenalForms">
|
||||||
<el-radio v-for="item of $d.YesOrNo" :key="`IsCopyOrigenalForms${item.raw.Id}`" :label="item.value">{{
|
<el-radio v-for="item of $d.YesOrNo" :key="`IsCopyOrigenalForms${item.raw.Id}`" :label="item.value">{{
|
||||||
item.label }}</el-radio>
|
item.label }}</el-radio>
|
||||||
@@ -371,7 +371,7 @@ export default {
|
|||||||
RequestReReadingReason: [{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' }]
|
RequestReReadingReason: [{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' }]
|
||||||
},
|
},
|
||||||
trialCriterionList: [],
|
trialCriterionList: [],
|
||||||
TrialReadingCriterionId: '',
|
TrialReadingCriterionId: '0',
|
||||||
openWindow: null,
|
openWindow: null,
|
||||||
otherInfo: null
|
otherInfo: null
|
||||||
}
|
}
|
||||||
@@ -423,9 +423,6 @@ export default {
|
|||||||
this.total = res.Result.TotalCount
|
this.total = res.Result.TotalCount
|
||||||
this.otherInfo = res.OtherInfo
|
this.otherInfo = res.OtherInfo
|
||||||
this.loading = false
|
this.loading = false
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs[this.TrialReadingCriterionId][0].doLayout()
|
|
||||||
})
|
|
||||||
}).catch(() => { this.loading = false })
|
}).catch(() => { this.loading = false })
|
||||||
},
|
},
|
||||||
handleSearch() {
|
handleSearch() {
|
||||||
@@ -483,8 +480,7 @@ export default {
|
|||||||
this.ApplyforReasonVisible = true
|
this.ApplyforReasonVisible = true
|
||||||
this.ApplyforReasonForm = {
|
this.ApplyforReasonForm = {
|
||||||
Type: null,
|
Type: null,
|
||||||
Remake: null,
|
Remake: null
|
||||||
IsCopyOrigenalForms: this.rowData.ReadingTool === 3 ? false : null
|
|
||||||
}
|
}
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}).catch(() => { this.loading = false })
|
}).catch(() => { this.loading = false })
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<BaseContainer>
|
||||||
<el-tabs type="border-card" v-model="activeName">
|
|
||||||
<template v-for="item in tabPaneList">
|
|
||||||
<el-tab-pane :label="$t(`uploadDicomAndNonedicom:label:TargetSection_${item}`)" :name="item">
|
|
||||||
<BaseContainer v-if="activeName == item">
|
|
||||||
<div slot="search-container">
|
<div slot="search-container">
|
||||||
<el-form :inline="true">
|
<el-form :inline="true">
|
||||||
<!-- 受试者编号 -->
|
<!-- 受试者编号 -->
|
||||||
@@ -23,8 +19,8 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
<div slot="main-container">
|
<div slot="main-container">
|
||||||
<el-table v-adaptive="{ bottomOffset: 85 }" :data="list" stripe height="100"
|
<el-table v-adaptive="{ bottomOffset: 75 }" :data="list" stripe height="100" @sort-change="handleSortChange"
|
||||||
@sort-change="handleSortChange" v-loading="loading">
|
v-loading="loading">
|
||||||
<el-table-column type="index" width="40" align="left" />
|
<el-table-column type="index" width="40" align="left" />
|
||||||
<el-table-column prop="IsUrgent" :label="$t('trials:consistencyCheck:table:isUrgent')"
|
<el-table-column prop="IsUrgent" :label="$t('trials:consistencyCheck:table:isUrgent')"
|
||||||
show-overflow-tooltip min-width="100">
|
show-overflow-tooltip min-width="100">
|
||||||
@@ -39,9 +35,8 @@
|
|||||||
:label="$t('trials:pendingReadingTasks:table:subjectCode')" show-overflow-tooltip
|
:label="$t('trials:pendingReadingTasks:table:subjectCode')" show-overflow-tooltip
|
||||||
sortable="custom" />
|
sortable="custom" />
|
||||||
<!-- 访视数量 -->
|
<!-- 访视数量 -->
|
||||||
<el-table-column prop="VisitCount"
|
<el-table-column prop="VisitCount" :label="$t('trials:pendingReadingTasks:table:VisitCount')"
|
||||||
:label="$t('trials:pendingReadingTasks:table:VisitCount')" show-overflow-tooltip
|
show-overflow-tooltip sortable="custom" />
|
||||||
sortable="custom" />
|
|
||||||
<!-- dicom检查数量 -->
|
<!-- dicom检查数量 -->
|
||||||
<!-- <el-table-column prop="DicomStudyCount" :label="$t('trials:pendingReadingTasks:table:DicomStudyCount')"
|
<!-- <el-table-column prop="DicomStudyCount" :label="$t('trials:pendingReadingTasks:table:DicomStudyCount')"
|
||||||
show-overflow-tooltip sortable="custom" /> -->
|
show-overflow-tooltip sortable="custom" /> -->
|
||||||
@@ -50,22 +45,10 @@
|
|||||||
:label="$t('trials:pendingReadingTasks:table:NoneDicomStudyCount')" show-overflow-tooltip
|
:label="$t('trials:pendingReadingTasks:table:NoneDicomStudyCount')" show-overflow-tooltip
|
||||||
sortable="custom" /> -->
|
sortable="custom" /> -->
|
||||||
<!-- 标记访视数量 -->
|
<!-- 标记访视数量 -->
|
||||||
<el-table-column prop="MarkVisitCount"
|
<el-table-column prop="MarkVisitCount" :label="$t('trials:pendingReadingTasks:table:MarkVisitCount')"
|
||||||
:label="$t('trials:pendingReadingTasks:table:MarkVisitCount')" show-overflow-tooltip
|
show-overflow-tooltip>
|
||||||
sortable="custom">
|
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ scope.row.MarkIVUSVisitCount || 0
|
<span>{{ `${scope.row.MarkIVUSVisitCount || 0}/${scope.row.MarkOCTVisitCount || 0}` }}</span>
|
||||||
}}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<!-- 标记访视数量 -->
|
|
||||||
<el-table-column prop="MarkVisitCount"
|
|
||||||
:label="$t('trials:pendingReadingTasks:table:MarkOCTVisitCount')"
|
|
||||||
show-overflow-tooltip sortable="custom">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ scope.row.MarkOCTVisitCount ||
|
|
||||||
0
|
|
||||||
}}</span>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!-- 标记dicom检查数量 -->
|
<!-- 标记dicom检查数量 -->
|
||||||
@@ -76,14 +59,6 @@
|
|||||||
<!-- <el-table-column prop="MarkNoneDicomStudyCount"
|
<!-- <el-table-column prop="MarkNoneDicomStudyCount"
|
||||||
:label="$t('trials:pendingReadingTasks:table:MarkNoneDicomStudyCount')" show-overflow-tooltip
|
:label="$t('trials:pendingReadingTasks:table:MarkNoneDicomStudyCount')" show-overflow-tooltip
|
||||||
sortable="custom" /> -->
|
sortable="custom" /> -->
|
||||||
<!-- 下载时间 -->
|
|
||||||
<el-table-column prop="LatestDownloadTime" min-width="100"
|
|
||||||
:label="$t('trials:pendingReadingTasks:table:latestDownloadTime')"
|
|
||||||
show-overflow-tooltip sortable="custom" />
|
|
||||||
<!-- 上传时间 -->
|
|
||||||
<el-table-column prop="LatestUploadTime" min-width="100"
|
|
||||||
:label="$t('trials:pendingReadingTasks:table:latestUploadTime')"
|
|
||||||
show-overflow-tooltip sortable="custom" />
|
|
||||||
<el-table-column :label="$t('common:action:action')" width="100" fixed="right">
|
<el-table-column :label="$t('common:action:action')" width="100" fixed="right">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<!-- 阅片 -->
|
<!-- 阅片 -->
|
||||||
@@ -94,34 +69,26 @@
|
|||||||
: $t('trials:pendingReadingTasks:button:review')
|
: $t('trials:pendingReadingTasks:button:review')
|
||||||
" icon="el-icon-edit-outline" @click="handleReadImage(scope.row)" /> -->
|
" icon="el-icon-edit-outline" @click="handleReadImage(scope.row)" /> -->
|
||||||
<!-- 上传 -->
|
<!-- 上传 -->
|
||||||
<el-button v-hasPermi="['role:ir', 'role:pm', 'role:apm']" circle
|
<el-button v-hasPermi="['role:ir', 'role:pm', 'role:apm']" circle icon="el-icon-upload2"
|
||||||
icon="el-icon-upload2"
|
|
||||||
:title="$t('trials:pendingReadingTasks:button:upload')"
|
:title="$t('trials:pendingReadingTasks:button:upload')"
|
||||||
@click="openUploadImage(scope.row, 'upload')" />
|
@click="openUploadImage(scope.row, 'upload')" />
|
||||||
<!-- 下载 -->
|
<!-- 下载 -->
|
||||||
<el-button v-hasPermi="['role:ir', 'role:pm', 'role:apm']" circle
|
<el-button v-hasPermi="['role:ir', 'role:pm', 'role:apm']" circle icon="el-icon-download"
|
||||||
icon="el-icon-download"
|
|
||||||
:title="$t('trials:pendingReadingTasks:button:download')"
|
:title="$t('trials:pendingReadingTasks:button:download')"
|
||||||
@click="openUploadImage(scope.row, 'download')" />
|
@click="openUploadImage(scope.row, 'download')" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<pagination class="page" :total="total" :page.sync="searchData.PageIndex"
|
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
|
||||||
:limit.sync="searchData.PageSize" @pagination="getList" />
|
@pagination="getList" />
|
||||||
</div>
|
</div>
|
||||||
<upload-dicom-and-nonedicom v-if="uploadImageVisible" :SubjectId="uploadSubjectId"
|
<upload-dicom-and-nonedicom v-if="uploadImageVisible" :SubjectId="uploadSubjectId"
|
||||||
:SubjectCode="uploadSubjectCode" :Criterion="uploadTrialCriterion"
|
:SubjectCode="uploadSubjectCode" :Criterion="uploadTrialCriterion" :visible.sync="uploadImageVisible"
|
||||||
:visible.sync="uploadImageVisible" :IsImageSegment="true" :forbid="forbid" />
|
:IsImageSegment="true" :forbid="forbid" />
|
||||||
<download-dicom-and-nonedicom v-if="downloadImageVisible" :SubjectId="uploadSubjectId"
|
<download-dicom-and-nonedicom v-if="downloadImageVisible" :SubjectId="uploadSubjectId"
|
||||||
:SubjectCode="uploadSubjectCode" :Criterion="uploadTrialCriterion"
|
:SubjectCode="uploadSubjectCode" :Criterion="uploadTrialCriterion" :visible.sync="downloadImageVisible"
|
||||||
:visible.sync="downloadImageVisible" :IsImageSegment="true" :forbid="forbid" />
|
:IsImageSegment="true" :forbid="forbid" />
|
||||||
</BaseContainer>
|
</BaseContainer>
|
||||||
</el-tab-pane>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
</el-tabs>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import BaseContainer from '@/components/BaseContainer'
|
import BaseContainer from '@/components/BaseContainer'
|
||||||
@@ -132,7 +99,6 @@ import { getTrialSubjectVisitMarkList } from "@/api/trials"
|
|||||||
const searchDataDefault = () => {
|
const searchDataDefault = () => {
|
||||||
return {
|
return {
|
||||||
SubjectCode: '',
|
SubjectCode: '',
|
||||||
State: 0,
|
|
||||||
PageIndex: 1,
|
PageIndex: 1,
|
||||||
PageSize: 20,
|
PageSize: 20,
|
||||||
}
|
}
|
||||||
@@ -163,8 +129,6 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
activeName: '0',
|
|
||||||
tabPaneList: ['0', '1', '2'],
|
|
||||||
searchData: searchDataDefault(),
|
searchData: searchDataDefault(),
|
||||||
loading: false,
|
loading: false,
|
||||||
list: [],
|
list: [],
|
||||||
@@ -189,9 +153,6 @@ export default {
|
|||||||
if (!v) {
|
if (!v) {
|
||||||
this.getList()
|
this.getList()
|
||||||
}
|
}
|
||||||
},
|
|
||||||
activeName() {
|
|
||||||
this.getList()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -210,7 +171,6 @@ export default {
|
|||||||
try {
|
try {
|
||||||
this.searchData.TrialId = this.$route.query.trialId
|
this.searchData.TrialId = this.$route.query.trialId
|
||||||
this.searchData.TrialReadingCriterionId = this.TrialReadingCriterionId
|
this.searchData.TrialReadingCriterionId = this.TrialReadingCriterionId
|
||||||
this.searchData.State = this.activeName
|
|
||||||
this.loading = true
|
this.loading = true
|
||||||
let res = await getTrialSubjectVisitMarkList(this.searchData)
|
let res = await getTrialSubjectVisitMarkList(this.searchData)
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
|||||||
@@ -88,21 +88,21 @@
|
|||||||
: $t('trials:pendingReadingTasks:button:review')
|
: $t('trials:pendingReadingTasks:button:review')
|
||||||
" icon="el-icon-edit-outline" @click="handleReadImage(scope.row)" />
|
" icon="el-icon-edit-outline" @click="handleReadImage(scope.row)" />
|
||||||
<!-- 上传 -->
|
<!-- 上传 -->
|
||||||
<!-- <el-button v-if="
|
<el-button v-if="
|
||||||
item.ImageUploadEnum > 0 &&
|
item.ImageUploadEnum > 0 &&
|
||||||
item.IsReadingTaskViewInOrder > 1 &&
|
item.IsReadingTaskViewInOrder > 1 &&
|
||||||
!scope.row.IsSubjectJudge
|
!scope.row.IsSubjectJudge
|
||||||
" v-hasPermi="['role:ir']" circle icon="el-icon-upload2"
|
" v-hasPermi="['role:ir']" circle icon="el-icon-upload2"
|
||||||
:title="$t('trials:pendingReadingTasks:button:upload')"
|
:title="$t('trials:pendingReadingTasks:button:upload')"
|
||||||
@click="openUploadImage(scope.row, item, 'upload')" /> -->
|
@click="openUploadImage(scope.row, item, 'upload')" />
|
||||||
<!-- 下载 -->
|
<!-- 下载 -->
|
||||||
<!-- <el-button v-if="
|
<el-button v-if="
|
||||||
item.ImageDownloadEnum > 0 &&
|
item.ImageDownloadEnum > 0 &&
|
||||||
item.IsReadingTaskViewInOrder > 1 &&
|
item.IsReadingTaskViewInOrder > 1 &&
|
||||||
!scope.row.IsSubjectJudge
|
!scope.row.IsSubjectJudge
|
||||||
" v-hasPermi="['role:ir']" circle icon="el-icon-download"
|
" v-hasPermi="['role:ir']" circle icon="el-icon-download"
|
||||||
:title="$t('trials:pendingReadingTasks:button:download')"
|
:title="$t('trials:pendingReadingTasks:button:download')"
|
||||||
@click="openUploadImage(scope.row, item, 'download')" /> -->
|
@click="openUploadImage(scope.row, item, 'download')" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<BaseContainer class="reread-task">
|
<BaseContainer class="reread-task">
|
||||||
<el-tabs v-if="TrialReadingCriterionId" v-model="TrialReadingCriterionId" type="border-card">
|
<el-tabs v-model="TrialReadingCriterionId" type="border-card">
|
||||||
<el-tab-pane v-for="item of trialCriterionList" :key="item.TrialReadingCriterionId" :label="item.TrialReadingCriterionName" :name="item.TrialReadingCriterionId">
|
<el-tab-pane v-for="item of trialCriterionList" :key="item.TrialReadingCriterionId" :label="item.TrialReadingCriterionName" :name="item.TrialReadingCriterionId">
|
||||||
<div v-if="TrialReadingCriterionId === item.TrialReadingCriterionId">
|
<div v-if="TrialReadingCriterionId === item.TrialReadingCriterionId">
|
||||||
<div slot="search-container">
|
<div slot="search-container">
|
||||||
@@ -82,7 +82,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div slot="main-container">
|
<div slot="main-container">
|
||||||
<el-table
|
<el-table
|
||||||
:ref="TrialReadingCriterionId"
|
|
||||||
v-adaptive="{bottomOffset:75}"
|
v-adaptive="{bottomOffset:75}"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:data="list"
|
:data="list"
|
||||||
@@ -333,7 +332,7 @@ export default {
|
|||||||
},
|
},
|
||||||
ConfirmReReadingVisible: false,
|
ConfirmReReadingVisible: false,
|
||||||
trialCriterionList: [],
|
trialCriterionList: [],
|
||||||
TrialReadingCriterionId: '',
|
TrialReadingCriterionId: '0',
|
||||||
otherInfo: null
|
otherInfo: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -380,9 +379,6 @@ export default {
|
|||||||
this.total = res.Result.TotalCount
|
this.total = res.Result.TotalCount
|
||||||
this.otherInfo = res.OtherInfo
|
this.otherInfo = res.OtherInfo
|
||||||
this.loading = false
|
this.loading = false
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs[this.TrialReadingCriterionId][0].doLayout()
|
|
||||||
})
|
|
||||||
}).catch(() => { this.loading = false })
|
}).catch(() => { this.loading = false })
|
||||||
},
|
},
|
||||||
handleSearch() {
|
handleSearch() {
|
||||||
|
|||||||
+107
-200
@@ -1,60 +1,18 @@
|
|||||||
<!-- eslint-disable -->
|
|
||||||
<!-- eslint-disable vue/no-unused-vars -->
|
<!-- eslint-disable vue/no-unused-vars -->
|
||||||
<!-- eslint-disable vue/no-template-shadow -->
|
<!-- eslint-disable vue/no-template-shadow -->
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
<template>
|
<template>
|
||||||
<el-form v-loading="loading" :label-width="'100px'">
|
<el-form v-loading="loading">
|
||||||
<!-- 仲裁对象 -->
|
<!-- 仲裁对象 -->
|
||||||
<el-form-item :label="$t('trials:adRules:title:arbitrationRule')">
|
<el-form-item :label="$t('trials:adRules:title:arbitrationRule')" :label-width="'180px'">
|
||||||
<el-radio-group v-model="JudgyInfo.ArbitrationRule" :disabled="isSign">
|
<el-radio-group v-model="JudgyInfo.ArbitrationRule" :disabled="OtherInfo.IsSign">
|
||||||
<el-radio v-for="item of $d.ArbitrationRule" :key="item.id"
|
<el-radio v-for="item of $d.ArbitrationRule" :key="item.id"
|
||||||
:disabled="!JudgyInfo.IsReadingTaskViewInOrder || true" :label="item.value" @change="changeArbitrationRule">
|
:disabled="!JudgyInfo.IsReadingTaskViewInOrder || true" :label="item.value" @change="changeArbitrationRule">
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</el-radio>
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 仲裁模式JudgeModeEnum 整体结果择一判定;指标组合判定-->
|
<el-collapse v-model="activeNames" style="border-top:none;">
|
||||||
<el-form-item :label="$t('trials:adRules:title:judgeMode')">
|
|
||||||
<el-radio-group v-model="JudgyInfo.JudgeModeEnum" :disabled="isSign">
|
|
||||||
<el-radio
|
|
||||||
v-for="item of $d.JudgeMode"
|
|
||||||
:key="item.id"
|
|
||||||
:disabled="JudgyInfo.ArbitrationRule !== 1"
|
|
||||||
:label="item.value"
|
|
||||||
>
|
|
||||||
{{ item.label }}
|
|
||||||
</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 裁判规则JudgeRuleEnum 访视一致规则;访视差异规则-->
|
|
||||||
<el-form-item :label="$t('trials:adRules:title:judgeRule')">
|
|
||||||
<el-radio-group v-model="JudgyInfo.JudgeRuleEnum" :disabled="isSign">
|
|
||||||
<el-radio
|
|
||||||
v-for="item of $d.JudgeRule"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.value"
|
|
||||||
>
|
|
||||||
{{ item.label }}
|
|
||||||
</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button
|
|
||||||
v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
@click="saveJugeRule"
|
|
||||||
v-show="!isSign">
|
|
||||||
{{ $t('common:button:save') }}
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
<ArbitrationRulesByVisit
|
|
||||||
v-if="judgeRuleEnum === 1"
|
|
||||||
ref="visitRules"
|
|
||||||
:trial-reading-criterion-id="trialReadingCriterionId"
|
|
||||||
:isSign="isSign"
|
|
||||||
/>
|
|
||||||
<el-collapse v-else-if="judgeRuleEnum === 0" v-model="activeNames" style="border-top:none;">
|
|
||||||
<el-collapse-item v-for="(item, index) of QuestionList" :key="item.ReadingQuestionTrialId"
|
<el-collapse-item v-for="(item, index) of QuestionList" :key="item.ReadingQuestionTrialId"
|
||||||
style="position: relative;padding:0 10px;" :name="item.ReadingQuestionTrialId">
|
style="position: relative;padding:0 10px;" :name="item.ReadingQuestionTrialId">
|
||||||
<div slot="title">
|
<div slot="title">
|
||||||
@@ -63,28 +21,24 @@
|
|||||||
<div style="position: relative">
|
<div style="position: relative">
|
||||||
<el-button v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
<el-button v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
||||||
style="position: absolute; right: 0; top: 0; z-index: 10" size="mini" type="primary"
|
style="position: absolute; right: 0; top: 0; z-index: 10" size="mini" type="primary"
|
||||||
:disabled="isSign" @click="apply(item.ReadingQuestionTrialId, index)">{{ $t('common:button:save')
|
:disabled="OtherInfo.IsSign" @click="apply(item.ReadingQuestionTrialId, index)">{{ $t('common:button:save')
|
||||||
}}</el-button>
|
}}</el-button>
|
||||||
<el-button v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
<el-button v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
||||||
style="position: absolute; right: 60px; top: 0; z-index: 10" size="mini" type="primary"
|
style="position: absolute; right: 60px; top: 0; z-index: 10" size="mini" type="primary"
|
||||||
:disabled="isSign" @click="reset(item.ReadingQuestionTrialId, index)">{{ $t('common:button:reset')
|
:disabled="OtherInfo.IsSign" @click="reset(item.ReadingQuestionTrialId, index)">{{ $t('common:button:reset')
|
||||||
}}</el-button>
|
}}</el-button>
|
||||||
<!-- 产生裁判阅片的条件 -->
|
<!-- 产生裁判阅片的条件 -->
|
||||||
<el-form-item :label-width="'280px'" :label="$t('trials:adRules:title:judgeTypeEnum')" style="width: 95%">
|
<el-form-item :label-width="'280px'" :label="$t('trials:adRules:title:judgeTypeEnum')" style="width: 95%">
|
||||||
<el-radio-group v-model="QuestionList[index].JudgeType" @input="(val) => JudgeTypeChange(val, index)">
|
<el-radio-group v-model="QuestionList[index].JudgeType" @input="(val) => JudgeTypeChange(val, index)">
|
||||||
<template v-for="item of $d.JudgeTypeEnum">
|
<template v-for="item of $d.JudgeTypeEnum">
|
||||||
<el-radio
|
<el-radio style="margin-bottom: 5px" :key="item.id" :disabled="OtherInfo.IsSign ||
|
||||||
style="margin-bottom: 5px"
|
!hasPermi(['trials:trials-panel:setting:reading-unit:edit'])
|
||||||
:key="item.id"
|
" :label="item.value" v-if="
|
||||||
:disabled="isSign || !hasPermi(['trials:trials-panel:setting:reading-unit:edit'])"
|
item.value < 4 ||
|
||||||
:label="item.value"
|
(item.value > 3 &&
|
||||||
v-if="
|
(QuestionList[index].Type === 'number' ||
|
||||||
(['number', 'calculation'].includes(QuestionList[index].Type)
|
QuestionList[index].Type === 'calculation'))
|
||||||
? [1, 4, 5]
|
">
|
||||||
: [1, 2, 3]
|
|
||||||
).includes(item.value)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</el-radio>
|
</el-radio>
|
||||||
</template>
|
</template>
|
||||||
@@ -94,7 +48,7 @@
|
|||||||
<div v-if="QuestionList[index].JudgeType === 3" style="text-align: right; margin: 10px 0">
|
<div v-if="QuestionList[index].JudgeType === 3" style="text-align: right; margin: 10px 0">
|
||||||
<!-- 添加规则 -->
|
<!-- 添加规则 -->
|
||||||
<el-button v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']" size="mini" type="primary"
|
<el-button v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']" size="mini" type="primary"
|
||||||
:disabled="isSign" @click="addGroup(index, null)">{{ $t('trials:adRules:button:addRule')
|
:disabled="OtherInfo.IsSign" @click="addGroup(index, null)">{{ $t('trials:adRules:button:addRule')
|
||||||
}}</el-button>
|
}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-table v-if="QuestionList[index].JudgeType === 3" v-loading="loading"
|
<el-table v-if="QuestionList[index].JudgeType === 3" v-loading="loading"
|
||||||
@@ -133,10 +87,10 @@
|
|||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<!-- 编辑 -->
|
<!-- 编辑 -->
|
||||||
<el-button icon="el-icon-edit" circle :title="$t('common:button:edit')" size="mini"
|
<el-button icon="el-icon-edit" circle :title="$t('common:button:edit')" size="mini"
|
||||||
:disabled="isSign" @click="addGroup(index, scope.$index)" />
|
:disabled="OtherInfo.IsSign" @click="addGroup(index, scope.$index)" />
|
||||||
<!-- 删除 -->
|
<!-- 删除 -->
|
||||||
<el-button icon="el-icon-delete" circle :title="$t('common:button:delete')" size="mini"
|
<el-button icon="el-icon-delete" circle :title="$t('common:button:delete')" size="mini"
|
||||||
:disabled="isSign" @click="tagClose(index, scope.$index)" />
|
:disabled="OtherInfo.IsSign" @click="tagClose(index, scope.$index)" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -149,12 +103,12 @@
|
|||||||
">
|
">
|
||||||
<el-checkbox-group v-if="QuestionList[index].QuestionGenre === 3" v-model="QuestionList[index].grouping">
|
<el-checkbox-group v-if="QuestionList[index].QuestionGenre === 3" v-model="QuestionList[index].grouping">
|
||||||
<template v-for="item of $d[QuestionList[index].DictionaryCode]">
|
<template v-for="item of $d[QuestionList[index].DictionaryCode]">
|
||||||
<el-checkbox v-if="item.value !== -1" :key="item.id" :disabled="isSign" :label="item.value">{{
|
<el-checkbox v-if="item.value !== -1" :key="item.id" :disabled="OtherInfo.IsSign" :label="item.value">{{
|
||||||
item.label }}</el-checkbox>
|
item.label }}</el-checkbox>
|
||||||
</template>
|
</template>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
<el-checkbox-group v-else v-model="QuestionList[index].grouping">
|
<el-checkbox-group v-else v-model="QuestionList[index].grouping">
|
||||||
<el-checkbox v-for="item of item.TypeValue.split('|')" :key="item" :disabled="isSign"
|
<el-checkbox v-for="item of item.TypeValue.split('|')" :key="item" :disabled="OtherInfo.IsSign"
|
||||||
:label="item">{{
|
:label="item">{{
|
||||||
item }}</el-checkbox>
|
item }}</el-checkbox>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
@@ -181,7 +135,7 @@
|
|||||||
.toString()
|
.toString()
|
||||||
.replaceAll(',', '|')
|
.replaceAll(',', '|')
|
||||||
}}</el-tag>
|
}}</el-tag>
|
||||||
<el-button size="mini" type="primary" :disabled="isSign" @click="addGroup2(index)">
|
<el-button size="mini" type="primary" :disabled="OtherInfo.IsSign" @click="addGroup2(index)">
|
||||||
<!-- 添加分组 -->
|
<!-- 添加分组 -->
|
||||||
{{ $t('trials:adRules:title:addGroup') }}
|
{{ $t('trials:adRules:title:addGroup') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -227,7 +181,7 @@
|
|||||||
)
|
)
|
||||||
" prop="JudgeDifferenceType">
|
" prop="JudgeDifferenceType">
|
||||||
<el-select v-model="QuestionList[index].JudgeDifferenceType" placeholder="请选择"
|
<el-select v-model="QuestionList[index].JudgeDifferenceType" placeholder="请选择"
|
||||||
:disabled="isSign">
|
:disabled="OtherInfo.IsSign">
|
||||||
<el-option v-for="item of $d.JudgeDifferenceType" :key="item.id" :label="item.label"
|
<el-option v-for="item of $d.JudgeDifferenceType" :key="item.id" :label="item.label"
|
||||||
:value="item.value">
|
:value="item.value">
|
||||||
</el-option>
|
</el-option>
|
||||||
@@ -239,7 +193,7 @@
|
|||||||
" prop="JudgeDifferenceValue">
|
" prop="JudgeDifferenceValue">
|
||||||
<div style="display: flex">
|
<div style="display: flex">
|
||||||
<el-input v-model="QuestionList[index].JudgeDifferenceValue" clearable
|
<el-input v-model="QuestionList[index].JudgeDifferenceValue" clearable
|
||||||
:disabled="isSign"></el-input>
|
:disabled="OtherInfo.IsSign"></el-input>
|
||||||
<span style="margin-left: 10px" v-if="QuestionList[index].JudgeType !== 5 && QuestionList[index].Unit !== 0">
|
<span style="margin-left: 10px" v-if="QuestionList[index].JudgeType !== 5 && QuestionList[index].Unit !== 0">
|
||||||
{{ `${QuestionList[index].Unit === 4 ? QuestionList[index].CustomUnit : $fd('ValueUnit', QuestionList[index].Unit)}`}}
|
{{ `${QuestionList[index].Unit === 4 ? QuestionList[index].CustomUnit : $fd('ValueUnit', QuestionList[index].Unit)}`}}
|
||||||
</span>
|
</span>
|
||||||
@@ -249,6 +203,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
</el-collapse>
|
</el-collapse>
|
||||||
|
<!-- </el-tab-pane>-->
|
||||||
|
<!-- </el-tabs>-->
|
||||||
<!-- 选择答案 -->
|
<!-- 选择答案 -->
|
||||||
<el-dialog v-if="QuestionVisible" :title="$t('trials:adRules:title:selectAnswer')" :visible.sync="QuestionVisible"
|
<el-dialog v-if="QuestionVisible" :title="$t('trials:adRules:title:selectAnswer')" :visible.sync="QuestionVisible"
|
||||||
width="800px" :close-on-click-modal="false" custom-class="base-dialog-wrapper" append-to-body>
|
width="800px" :close-on-click-modal="false" custom-class="base-dialog-wrapper" append-to-body>
|
||||||
@@ -256,50 +212,40 @@
|
|||||||
<!-- 阅片人A -->
|
<!-- 阅片人A -->
|
||||||
<el-form-item label-width="110px" :label="$t('trials:adRules:title:answerGroupA')">
|
<el-form-item label-width="110px" :label="$t('trials:adRules:title:answerGroupA')">
|
||||||
<el-checkbox-group v-model="QuestionList[selectIndex].groupingA">
|
<el-checkbox-group v-model="QuestionList[selectIndex].groupingA">
|
||||||
<template v-for="item of QuestionList[selectIndex].TypeValue.split('|') || []">
|
<template v-for="item of QuestionList[selectIndex].TypeValue.split('|')">
|
||||||
<el-checkbox
|
<el-checkbox v-if="QuestionList[selectIndex].QuestionGenre !== 3" :key="item" :label="item" :disabled="QuestionList[selectIndex].groupingB.length
|
||||||
v-if="QuestionList[selectIndex].QuestionGenre !== 3"
|
? ~QuestionList[selectIndex].groupingB.indexOf(item)
|
||||||
:key="item"
|
: false
|
||||||
:label="item"
|
">{{ item }}</el-checkbox>
|
||||||
:disabled="QuestionList[selectIndex]?.groupingB?.includes(item) ?? false"
|
|
||||||
>
|
|
||||||
{{ item }}
|
|
||||||
</el-checkbox>
|
|
||||||
</template>
|
</template>
|
||||||
<template v-for="item of $d[QuestionList[selectIndex].DictionaryCode]">
|
<template v-for="item of $d[QuestionList[selectIndex].DictionaryCode]">
|
||||||
<el-checkbox
|
<el-checkbox v-if="
|
||||||
v-if="QuestionList[selectIndex].QuestionGenre === 3 && item.value !== -1"
|
QuestionList[selectIndex].QuestionGenre === 3 &&
|
||||||
:key="item.id"
|
item.value !== -1
|
||||||
:label="item.value"
|
" :key="item.id" :label="item.value" :disabled="QuestionList[selectIndex].groupingB.length
|
||||||
:disabled="QuestionList[selectIndex]?.groupingB?.includes(item.value) ?? false"
|
? ~QuestionList[selectIndex].groupingB.indexOf(item.value)
|
||||||
>
|
: false
|
||||||
{{ item.label }}
|
">{{ item.label }}</el-checkbox>
|
||||||
</el-checkbox>
|
|
||||||
</template>
|
</template>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 阅片人B -->
|
<!-- 阅片人B -->
|
||||||
<el-form-item label-width="110px" :label="$t('trials:adRules:title:answerGroupB')">
|
<el-form-item label-width="110px" :label="$t('trials:adRules:title:answerGroupB')">
|
||||||
<el-checkbox-group v-model="QuestionList[selectIndex].groupingB">
|
<el-checkbox-group v-model="QuestionList[selectIndex].groupingB">
|
||||||
<template v-for="item of QuestionList[selectIndex].TypeValue.split('|') || []">
|
<template v-for="item of QuestionList[selectIndex].TypeValue.split('|')">
|
||||||
<el-checkbox
|
<el-checkbox v-if="QuestionList[selectIndex].QuestionGenre !== 3" :key="item" :label="item" :disabled="QuestionList[selectIndex].groupingA.length
|
||||||
v-if="QuestionList[selectIndex].QuestionGenre !== 3"
|
? ~QuestionList[selectIndex].groupingA.indexOf(item)
|
||||||
:key="item"
|
: false
|
||||||
:label="item"
|
">{{ item }}</el-checkbox>
|
||||||
:disabled="QuestionList[selectIndex]?.groupingA?.includes(item) ?? false"
|
|
||||||
>
|
|
||||||
{{ item }}
|
|
||||||
</el-checkbox>
|
|
||||||
</template>
|
</template>
|
||||||
<template v-for="item of $d[QuestionList[selectIndex].DictionaryCode]">
|
<template v-for="item of $d[QuestionList[selectIndex].DictionaryCode]">
|
||||||
<el-checkbox
|
<el-checkbox v-if="
|
||||||
v-if="QuestionList[selectIndex].QuestionGenre === 3 && item.value !== -1"
|
QuestionList[selectIndex].QuestionGenre === 3 &&
|
||||||
:key="item.id"
|
item.value !== -1
|
||||||
:label="item.value"
|
" :key="item.id" :label="item.value" :disabled="QuestionList[selectIndex].groupingA.length
|
||||||
:disabled="QuestionList[selectIndex]?.groupingA?.includes(item.value) ?? false"
|
? ~QuestionList[selectIndex].groupingA.indexOf(item.value)
|
||||||
>
|
: false
|
||||||
{{ item.label }}
|
">{{ item.label }}</el-checkbox>
|
||||||
</el-checkbox>
|
|
||||||
</template>
|
</template>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -323,17 +269,13 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
/* eslint-disable */
|
|
||||||
import {
|
import {
|
||||||
|
getTrialConfirmCriterionList,
|
||||||
getTrialCriterionJudgeQuestionList,
|
getTrialCriterionJudgeQuestionList,
|
||||||
setTrialCriterionJudgeQuestionAnswerGroup,
|
setTrialCriterionJudgeQuestionAnswerGroup,
|
||||||
} from '@/api/trials/reading'
|
} from '@/api/trials/reading'
|
||||||
import { setTrialJudgyInfo, getTrialJudgyInfo, setTrialJudgeRuleInfo } from '@/api/trials/setting'
|
import { setTrialJudgyInfo, getTrialJudgyInfo } from '@/api/trials/setting'
|
||||||
import ArbitrationRulesByVisit from './ArbitrationRulesByVisit'
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
|
||||||
ArbitrationRulesByVisit,
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
trialReadingCriterionId: {
|
trialReadingCriterionId: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -352,7 +294,9 @@ export default {
|
|||||||
activeNames: null,
|
activeNames: null,
|
||||||
indexA: null,
|
indexA: null,
|
||||||
type: null,
|
type: null,
|
||||||
isSign: true,
|
OtherInfo: {
|
||||||
|
IsSign: true,
|
||||||
|
},
|
||||||
JudgyInfo: {},
|
JudgyInfo: {},
|
||||||
JudgeDifferenceValueQRules: {
|
JudgeDifferenceValueQRules: {
|
||||||
JudgeDifferenceType: [
|
JudgeDifferenceType: [
|
||||||
@@ -395,38 +339,47 @@ export default {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
judgeRuleEnum: -1,
|
|
||||||
savedJudgyInfo: {
|
|
||||||
JudgeModeEnum: null,
|
|
||||||
JudgeRuleEnum: null,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
async trialReadingCriterionId(v) {
|
TrialReadingCriterionId(v) {
|
||||||
if (v === null) return
|
if (v === null) return
|
||||||
await this.initData()
|
this.loading = true
|
||||||
|
getTrialCriterionJudgeQuestionList({
|
||||||
|
TrialId: this.$route.query.trialId,
|
||||||
|
// ReadingQuestionCriterionTrialId: v,
|
||||||
|
TrialReadingCriterionId: this.trialReadingCriterionId,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
this.loading = false
|
||||||
|
this.QuestionList = res.Result
|
||||||
|
this.OtherInfo = res.OtherInfo
|
||||||
|
this.activeNames = this.QuestionList.map(
|
||||||
|
(v) => v.ReadingQuestionTrialId
|
||||||
|
)
|
||||||
|
this.QuestionList.forEach((v) => {
|
||||||
|
this.$set(v, 'grouping', [])
|
||||||
|
this.$set(v, 'groupingA', [])
|
||||||
|
this.$set(v, 'groupingB', [])
|
||||||
|
this.$set(
|
||||||
|
v,
|
||||||
|
'AnswerGroupList',
|
||||||
|
Object.assign([], v.AnswerCombination)
|
||||||
|
)
|
||||||
|
this.$set(v, 'AnswerGroup2List', Object.assign([], v.AnswerGroup))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.btnLoading = false
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async mounted() {
|
mounted() {
|
||||||
await this.initData()
|
this.getList()
|
||||||
|
this.getTrialJudgyInfo()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resetJudgeTypeRelatedFields(question = {}) {
|
|
||||||
this.$set(question, 'AnswerGroup2List', [])
|
|
||||||
this.$set(question, 'AnswerGroupList', [])
|
|
||||||
this.$set(question, 'grouping', [])
|
|
||||||
this.$set(question, 'groupingA', [])
|
|
||||||
this.$set(question, 'groupingB', [])
|
|
||||||
this.$set(question, 'JudgeDifferenceValue', 0)
|
|
||||||
this.$set(question, 'JudgeDifferenceType', 0)
|
|
||||||
},
|
|
||||||
async initData() {
|
|
||||||
await this.getTrialJudgyInfo()
|
|
||||||
if (this.judgeRuleEnum !== 1) {
|
|
||||||
await this.getList(false)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 修改仲裁规则
|
// 修改仲裁规则
|
||||||
changeArbitrationRule(value) {
|
changeArbitrationRule(value) {
|
||||||
if (value !== 1) {
|
if (value !== 1) {
|
||||||
@@ -434,16 +387,12 @@ export default {
|
|||||||
item.JudgeDifferenceValue = 0
|
item.JudgeDifferenceValue = 0
|
||||||
item.JudgeDifferenceType = 0
|
item.JudgeDifferenceType = 0
|
||||||
})
|
})
|
||||||
if (this.$refs.visitRules) {
|
|
||||||
this.$refs.visitRules.changeArbitrationRule(value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
JudgeTypeChange(value, index) {
|
JudgeTypeChange(value, index) {
|
||||||
this.resetJudgeTypeRelatedFields(this.QuestionList[index])
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (value === 4 || value === 5) {
|
if (value === 4 || value === 5) {
|
||||||
if (this.$refs['JudgeDifferenceValue' + value + index] && this.$refs['JudgeDifferenceValue' + value + index][0]) {
|
if (this.$refs['JudgeDifferenceValue' + value + index][0]) {
|
||||||
this.$refs['JudgeDifferenceValue' + value + index][0].resetFields()
|
this.$refs['JudgeDifferenceValue' + value + index][0].resetFields()
|
||||||
// this.QuestionList[index].JudgeDifferenceValue = 0;
|
// this.QuestionList[index].JudgeDifferenceValue = 0;
|
||||||
}
|
}
|
||||||
@@ -451,26 +400,25 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
saveAllSync() {
|
saveAllSync() {
|
||||||
if (this.judgeRuleEnum === 1 && this.$refs.visitRules) {
|
return new Promise((resolve, reject) => {
|
||||||
return Promise.resolve(true)
|
|
||||||
// return this.$refs.visitRules.saveAllSync()
|
|
||||||
}
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
var arr = []
|
var arr = []
|
||||||
this.QuestionList.forEach((v, i) => {
|
this.QuestionList.forEach((v, i) => {
|
||||||
arr.push(this.applySync(v.ReadingQuestionTrialId, i))
|
arr.push(this.applySync(v.ReadingQuestionTrialId, i))
|
||||||
})
|
})
|
||||||
Promise.all(arr)
|
Promise.all(arr)
|
||||||
.then(() => {
|
.then((res) => {
|
||||||
|
console.log(res)
|
||||||
resolve(true)
|
resolve(true)
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch((res) => {
|
||||||
|
console.log('进入catch')
|
||||||
resolve(false)
|
resolve(false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
applySync(ReadingQuestionTrialId, index) {
|
applySync(ReadingQuestionTrialId, index) {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
|
console.log(this.QuestionList[index].JudgeType)
|
||||||
if (this.QuestionList[index].JudgeType === 0) {
|
if (this.QuestionList[index].JudgeType === 0) {
|
||||||
reject(false)
|
reject(false)
|
||||||
return
|
return
|
||||||
@@ -494,7 +442,7 @@ export default {
|
|||||||
this.QuestionList[index].JudgeType === 5
|
this.QuestionList[index].JudgeType === 5
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const validate = await this.$refs[
|
let validate = await this.$refs[
|
||||||
'JudgeDifferenceValue' +
|
'JudgeDifferenceValue' +
|
||||||
this.QuestionList[index].JudgeType +
|
this.QuestionList[index].JudgeType +
|
||||||
index
|
index
|
||||||
@@ -545,55 +493,19 @@ export default {
|
|||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async getTrialJudgyInfo() {
|
getTrialJudgyInfo() {
|
||||||
try {
|
|
||||||
this.loading = true
|
this.loading = true
|
||||||
const res = await getTrialJudgyInfo({
|
getTrialJudgyInfo({
|
||||||
TrialId: this.$route.query.trialId,
|
TrialId: this.$route.query.trialId,
|
||||||
TrialReadingCriterionId: this.trialReadingCriterionId,
|
TrialReadingCriterionId: this.trialReadingCriterionId,
|
||||||
})
|
})
|
||||||
|
.then((res) => {
|
||||||
this.JudgyInfo = res.Result
|
this.JudgyInfo = res.Result
|
||||||
this.judgeRuleEnum = this.JudgyInfo.JudgeRuleEnum
|
|
||||||
this.isSign = res.Result.IsSigned
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
} finally {
|
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}
|
})
|
||||||
},
|
.catch((v) => {
|
||||||
async saveJugeRule(showMessage = true) {
|
|
||||||
try {
|
|
||||||
this.loading = true
|
|
||||||
const prevJudgeRuleEnum = this.judgeRuleEnum
|
|
||||||
const params = {
|
|
||||||
trialReadingCriterionId: this.trialReadingCriterionId,
|
|
||||||
judgeModeEnum: this.JudgyInfo.JudgeModeEnum,
|
|
||||||
judgeRuleEnum: this.JudgyInfo.JudgeRuleEnum,
|
|
||||||
}
|
|
||||||
const res = await setTrialJudgeRuleInfo(params)
|
|
||||||
if (res.IsSuccess) {
|
|
||||||
if (showMessage) {
|
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
|
||||||
}
|
|
||||||
this.judgeRuleEnum = this.JudgyInfo.JudgeRuleEnum
|
|
||||||
if (prevJudgeRuleEnum !== this.judgeRuleEnum) {
|
|
||||||
if (this.judgeRuleEnum === 1) {
|
|
||||||
await this.$nextTick()
|
|
||||||
if (this.$refs.visitRules) {
|
|
||||||
await this.$refs.visitRules.initData()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
await this.getList(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
return false
|
|
||||||
} finally {
|
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}
|
})
|
||||||
},
|
},
|
||||||
tagClose2(index, indexA) {
|
tagClose2(index, indexA) {
|
||||||
// '删除该规则组?'
|
// '删除该规则组?'
|
||||||
@@ -681,7 +593,7 @@ export default {
|
|||||||
AnswerCombination: [],
|
AnswerCombination: [],
|
||||||
JudgeType: 0,
|
JudgeType: 0,
|
||||||
JudgeDifferenceValue: 0,
|
JudgeDifferenceValue: 0,
|
||||||
JudgeDifferenceType: 0
|
JudgeDifferenceType: 0,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.$set(this.QuestionList[index], 'AnswerGroup2List', [])
|
this.$set(this.QuestionList[index], 'AnswerGroup2List', [])
|
||||||
@@ -723,7 +635,7 @@ export default {
|
|||||||
this.QuestionList[index].JudgeType === 5
|
this.QuestionList[index].JudgeType === 5
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const validate = await this.$refs[
|
let validate = await this.$refs[
|
||||||
'JudgeDifferenceValue' + this.QuestionList[index].JudgeType + index
|
'JudgeDifferenceValue' + this.QuestionList[index].JudgeType + index
|
||||||
][0].validate()
|
][0].validate()
|
||||||
if (!validate) return
|
if (!validate) return
|
||||||
@@ -743,7 +655,7 @@ export default {
|
|||||||
),
|
),
|
||||||
JudgeDifferenceType: Number(
|
JudgeDifferenceType: Number(
|
||||||
this.QuestionList[index].JudgeDifferenceType
|
this.QuestionList[index].JudgeDifferenceType
|
||||||
)
|
),
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.$message.success(this.$t('trials:adRules:message:msg9')) // '应用成功'
|
this.$message.success(this.$t('trials:adRules:message:msg9')) // '应用成功'
|
||||||
@@ -759,23 +671,18 @@ export default {
|
|||||||
this.ReadingQuestionCriterionTrialId =
|
this.ReadingQuestionCriterionTrialId =
|
||||||
this.CriterionList[this.index].ReadingQuestionCriterionTrialId
|
this.CriterionList[this.index].ReadingQuestionCriterionTrialId
|
||||||
},
|
},
|
||||||
async getList(needGetTrialJudgyInfo = true) {
|
getList() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
if (needGetTrialJudgyInfo) {
|
getTrialCriterionJudgeQuestionList({
|
||||||
await this.getTrialJudgyInfo()
|
|
||||||
}
|
|
||||||
if (this.judgeRuleEnum === 1 && this.$refs.visitRules) {
|
|
||||||
return this.$refs.visitRules.getList()
|
|
||||||
}
|
|
||||||
return getTrialCriterionJudgeQuestionList({
|
|
||||||
TrialId: this.$route.query.trialId,
|
TrialId: this.$route.query.trialId,
|
||||||
TrialReadingCriterionId: this.trialReadingCriterionId,
|
TrialReadingCriterionId: this.trialReadingCriterionId,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
this.QuestionList = res.Result
|
this.QuestionList = res.Result
|
||||||
|
this.OtherInfo = res.OtherInfo
|
||||||
this.activeNames = this.QuestionList.map(
|
this.activeNames = this.QuestionList.map(
|
||||||
(item) => item.ReadingQuestionTrialId
|
(v) => v.ReadingQuestionTrialId
|
||||||
)
|
)
|
||||||
this.QuestionList.forEach((v) => {
|
this.QuestionList.forEach((v) => {
|
||||||
this.$set(v, 'grouping', [])
|
this.$set(v, 'grouping', [])
|
||||||
|
|||||||
-955
@@ -1,955 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div v-loading="loading">
|
|
||||||
<el-tabs v-model="activeVisitTab" class="visit-tabs" type="border-card">
|
|
||||||
<el-tab-pane v-for="visit in visitPlanOptions" :key="visit.Id"
|
|
||||||
:label="visit.VisitName" :name="visit.Id">
|
|
||||||
<div v-show="!isSign" class="visit-tabs-actions">
|
|
||||||
<!-- 批量保存 -->
|
|
||||||
<el-button
|
|
||||||
v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
|
||||||
:disabled="btnLoading || questionListMap[visit.Id] && questionListMap[visit.Id].length === 0"
|
|
||||||
:loading="btnLoading"
|
|
||||||
size="small"
|
|
||||||
type="primary"
|
|
||||||
@click="handleBatchSave(visit.Id, visit.VisitNum)"
|
|
||||||
>
|
|
||||||
{{ $t('common:button:batchSave') }}
|
|
||||||
</el-button>
|
|
||||||
<!-- 复制 -->
|
|
||||||
<el-button
|
|
||||||
v-show="visitPlanOptions.length > 1"
|
|
||||||
v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
|
||||||
:disabled="btnLoading || questionListMap[visit.Id] && questionListMap[visit.Id].length === 0"
|
|
||||||
:loading="btnLoading"
|
|
||||||
size="small"
|
|
||||||
type="primary"
|
|
||||||
@click="handleCopy(visit.VisitNum)"
|
|
||||||
>
|
|
||||||
{{ $t('common:button:copy') }}
|
|
||||||
</el-button>
|
|
||||||
<!-- 应用到随访 -->
|
|
||||||
<el-button
|
|
||||||
v-show="visitPlanOptions.length > 1 && visit.VisitNum === 0"
|
|
||||||
v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
|
||||||
:disabled="btnLoading || questionListMap[visit.Id] && questionListMap[visit.Id].length === 0"
|
|
||||||
:loading="btnLoading"
|
|
||||||
size="small"
|
|
||||||
type="primary"
|
|
||||||
@click="applyToFollowup"
|
|
||||||
>
|
|
||||||
{{ $t('trials:adRules:button:applyToFollowup') }}
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
<el-collapse v-if="questionListMap[visit.Id]" v-model="visitActiveNamesMap[visit.Id]" style="border-top:none;">
|
|
||||||
<el-collapse-item v-for="(item, index) of questionListMap[visit.Id]"
|
|
||||||
:key="item.ReadingQuestionTrialId"
|
|
||||||
style="position: relative;padding:0 10px;" :name="item.ReadingQuestionTrialId">
|
|
||||||
<div slot="title">
|
|
||||||
{{ item.PageName }}Q{{ index + 1 }}:{{ item.QuestionName }}
|
|
||||||
</div>
|
|
||||||
<div style="position: relative">
|
|
||||||
<el-button v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
|
||||||
style="position: absolute; right: 0; top: 0; z-index: 10" size="mini" type="primary"
|
|
||||||
:disabled="isSign"
|
|
||||||
@click="visitApply(item.ReadingQuestionTrialId, index, visit.Id, visit.VisitNum)">{{ $t('common:button:save')
|
|
||||||
}}</el-button>
|
|
||||||
<el-button v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
|
||||||
style="position: absolute; right: 60px; top: 0; z-index: 10" size="mini" type="primary"
|
|
||||||
:disabled="isSign"
|
|
||||||
@click="visitReset(item.ReadingQuestionTrialId, index, visit.Id, visit.VisitNum)">{{ $t('common:button:reset')
|
|
||||||
}}</el-button>
|
|
||||||
<el-form-item :label-width="'280px'" :label="$t('trials:adRules:title:judgeTypeEnum')" style="width: 95%">
|
|
||||||
<el-radio-group
|
|
||||||
v-model="questionListMap[visit.Id][index].JudgeType"
|
|
||||||
@input="(val) => visitJudgeTypeChange(val, index, visit.Id)"
|
|
||||||
>
|
|
||||||
<template v-for="judgeTypeItem of $d.JudgeTypeEnum">
|
|
||||||
<el-radio
|
|
||||||
style="margin-bottom: 5px"
|
|
||||||
:key="judgeTypeItem.id"
|
|
||||||
:disabled="isSign || !hasPermi(['trials:trials-panel:setting:reading-unit:edit'])"
|
|
||||||
:label="judgeTypeItem.value"
|
|
||||||
v-if="
|
|
||||||
(['number', 'calculation'].includes(questionListMap[visit.Id][index].Type)
|
|
||||||
? [1, 4, 5, 6]
|
|
||||||
: [1, 2, 3, 6]
|
|
||||||
).includes(judgeTypeItem.value)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{ judgeTypeItem.label }}
|
|
||||||
</el-radio>
|
|
||||||
</template>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
<div v-if="questionListMap[visit.Id][index].JudgeType === 3" style="text-align: right; margin: 10px 0">
|
|
||||||
<el-button v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']" size="mini" type="primary"
|
|
||||||
:disabled="isSign"
|
|
||||||
@click="visitAddGroup(index, null, visit.Id)">{{ $t('trials:adRules:button:addRule')
|
|
||||||
}}</el-button>
|
|
||||||
</div>
|
|
||||||
<el-table v-if="questionListMap[visit.Id][index].JudgeType === 3" v-loading="loading"
|
|
||||||
:data="questionListMap[visit.Id][index].AnswerGroupList" border stripe>
|
|
||||||
<el-table-column prop="AnswerGroupA" :label="$t('trials:adRules:title:order')" width="160">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{ scope.$index + 1 }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="AnswerGroupA" :label="$t('trials:adRules:title:answerGroupA')" min-width="100">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{
|
|
||||||
questionListMap[visit.Id][index].QuestionGenre === 3
|
|
||||||
? scope.row.AnswerGroupA.map((v) =>
|
|
||||||
$fd(questionListMap[visit.Id][index].DictionaryCode, parseInt(v))
|
|
||||||
).toString()
|
|
||||||
: scope.row.AnswerGroupA.toString()
|
|
||||||
}}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="AnswerGroupB" :label="$t('trials:adRules:title:answerGroupB')" min-width="100">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
{{
|
|
||||||
questionListMap[visit.Id][index].QuestionGenre === 3
|
|
||||||
? scope.row.AnswerGroupB.map((v) =>
|
|
||||||
$fd(questionListMap[visit.Id][index].DictionaryCode, parseInt(v))
|
|
||||||
).toString()
|
|
||||||
: scope.row.AnswerGroupB.toString()
|
|
||||||
}}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="AnswerGroupB" :label="$t('common:action:action')" min-width="80">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button icon="el-icon-edit" circle :title="$t('common:button:edit')" size="mini"
|
|
||||||
:disabled="isSign"
|
|
||||||
@click="visitAddGroup(index, scope.$index, visit.Id)" />
|
|
||||||
<el-button icon="el-icon-delete" circle :title="$t('common:button:delete')" size="mini"
|
|
||||||
:disabled="isSign"
|
|
||||||
@click="visitTagClose(index, scope.$index, visit.Id)" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
<div v-if="questionListMap[visit.Id][index].JudgeType === 2">
|
|
||||||
<div style="
|
|
||||||
background: #f6f6f6;
|
|
||||||
border-radius: 20px;
|
|
||||||
padding: 15px 20px;
|
|
||||||
margin-top: 10px;
|
|
||||||
">
|
|
||||||
<el-checkbox-group v-if="questionListMap[visit.Id][index].QuestionGenre === 3"
|
|
||||||
v-model="questionListMap[visit.Id][index].grouping"
|
|
||||||
>
|
|
||||||
<template v-for="dictItem of $d[questionListMap[visit.Id][index].DictionaryCode]">
|
|
||||||
<el-checkbox v-if="dictItem.value !== -1" :key="dictItem.id" :disabled="isSign"
|
|
||||||
:label="dictItem.value">{{ dictItem.label }}</el-checkbox>
|
|
||||||
</template>
|
|
||||||
</el-checkbox-group>
|
|
||||||
<el-checkbox-group v-else v-model="questionListMap[visit.Id][index].grouping">
|
|
||||||
<el-checkbox v-for="answerItem of item.TypeValue.split('|')" :key="answerItem"
|
|
||||||
:disabled="isSign" :label="answerItem">{{ answerItem }}</el-checkbox>
|
|
||||||
</el-checkbox-group>
|
|
||||||
<div style="margin-top: 20px">
|
|
||||||
{{ $t('trials:adRules:title:selectAnswerGroup') }}
|
|
||||||
<el-tag v-if="
|
|
||||||
questionListMap[visit.Id][index].grouping.length > 0 &&
|
|
||||||
questionListMap[visit.Id][index].QuestionGenre !== 3
|
|
||||||
">{{
|
|
||||||
questionListMap[visit.Id][index].grouping.toString().replaceAll(',', '|')
|
|
||||||
}}</el-tag>
|
|
||||||
<el-tag v-if="
|
|
||||||
questionListMap[visit.Id][index].grouping.length > 0 &&
|
|
||||||
questionListMap[visit.Id][index].QuestionGenre === 3
|
|
||||||
">{{
|
|
||||||
questionListMap[visit.Id][index].grouping
|
|
||||||
.map(
|
|
||||||
(v) =>
|
|
||||||
$d[questionListMap[visit.Id][index].DictionaryCode].find(
|
|
||||||
(v1) => v1.value === v
|
|
||||||
).label
|
|
||||||
)
|
|
||||||
.toString()
|
|
||||||
.replaceAll(',', '|')
|
|
||||||
}}</el-tag>
|
|
||||||
<el-button size="mini" type="primary" :disabled="isSign"
|
|
||||||
@click="visitAddGroup2(index, visit.Id)">
|
|
||||||
{{ $t('trials:adRules:title:addGroup') }}</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="questionListMap[visit.Id][index].QuestionGenre !== 3" style="margin-top: 20px">
|
|
||||||
{{ $t('trials:adRules:title:group') }}
|
|
||||||
<el-tag v-for="(itemA, indexA) of questionListMap[visit.Id][index].AnswerGroup2List"
|
|
||||||
:key="visit.Id+indexA" closable
|
|
||||||
style="margin-right: 10px" @close="() => visitTagClose2(index, indexA, visit.Id)">{{ itemA }}</el-tag>
|
|
||||||
</div>
|
|
||||||
<div v-if="questionListMap[visit.Id][index].QuestionGenre === 3" style="margin-top: 20px">
|
|
||||||
{{ $t('trials:adRules:title:group') }}
|
|
||||||
<el-tag v-for="(itemA, indexA) of questionListMap[visit.Id][index].AnswerGroup2List"
|
|
||||||
:key="visit.Id+indexA" closable
|
|
||||||
style="margin-right: 10px" @close="() => visitTagClose2(index, indexA, visit.Id)">
|
|
||||||
{{
|
|
||||||
itemA
|
|
||||||
.split('|')
|
|
||||||
.map((v) =>
|
|
||||||
$fd(questionListMap[visit.Id][index].DictionaryCode, parseInt(v))
|
|
||||||
)
|
|
||||||
.join('|')
|
|
||||||
}}
|
|
||||||
</el-tag>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="
|
|
||||||
questionListMap[visit.Id][index].JudgeType === 4 ||
|
|
||||||
questionListMap[visit.Id][index].JudgeType === 5
|
|
||||||
">
|
|
||||||
<el-form :inline="true" :model="questionListMap[visit.Id][index]" class="demo-form-inline"
|
|
||||||
:ref="`JudgeDifferenceValue${questionListMap[visit.Id][index].JudgeType}_${visit.Id}_${index}`"
|
|
||||||
:rules="JudgeDifferenceValueQRules">
|
|
||||||
<el-form-item :label="$t(
|
|
||||||
`trials:trials-panel:setting:reading-unit:JudgeDifferenceType`
|
|
||||||
)
|
|
||||||
" prop="JudgeDifferenceType">
|
|
||||||
<el-select
|
|
||||||
v-model="questionListMap[visit.Id][index].JudgeDifferenceType"
|
|
||||||
:disabled="isSign">
|
|
||||||
<el-option v-for="judgeDiffItem of $d.JudgeDifferenceType" :key="judgeDiffItem.id"
|
|
||||||
:label="judgeDiffItem.label" :value="judgeDiffItem.value">
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item :label="$t(
|
|
||||||
`trials:trials-panel:setting:reading-unit:JudgeDifferenceValue${questionListMap[visit.Id][index].JudgeType}`
|
|
||||||
)
|
|
||||||
" prop="JudgeDifferenceValue">
|
|
||||||
<div style="display: flex">
|
|
||||||
<el-input v-model="questionListMap[visit.Id][index].JudgeDifferenceValue" clearable
|
|
||||||
:disabled="isSign"></el-input>
|
|
||||||
<span style="margin-left: 10px"
|
|
||||||
v-if="questionListMap[visit.Id][index].JudgeType !== 5 && questionListMap[visit.Id][index].Unit !== 0">
|
|
||||||
{{ `${questionListMap[visit.Id][index].Unit === 4 ? questionListMap[visit.Id][index].CustomUnit : $fd('ValueUnit', questionListMap[visit.Id][index].Unit)}` }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
</el-collapse-item>
|
|
||||||
</el-collapse>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
<el-dialog v-if="questionVisible" :title="$t('trials:adRules:title:selectAnswer')" :visible.sync="questionVisible"
|
|
||||||
width="800px" :close-on-click-modal="false" custom-class="base-dialog-wrapper" append-to-body>
|
|
||||||
<div class="base-dialog-body">
|
|
||||||
<el-form-item label-width="110px" :label="$t('trials:adRules:title:answerGroupA')">
|
|
||||||
<el-checkbox-group v-model="questionList[selectIndex].groupingA">
|
|
||||||
<template v-for="item of questionList[selectIndex].TypeValue.split('|') || []">
|
|
||||||
<el-checkbox
|
|
||||||
v-if="questionList[selectIndex].QuestionGenre !== 3"
|
|
||||||
:key="item"
|
|
||||||
:label="item"
|
|
||||||
:disabled="questionList[selectIndex]?.groupingB?.includes(item) ?? false"
|
|
||||||
>
|
|
||||||
{{ item }}
|
|
||||||
</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<template v-for="item of $d[questionList[selectIndex].DictionaryCode]">
|
|
||||||
<el-checkbox
|
|
||||||
v-if="questionList[selectIndex].QuestionGenre === 3 && item.value !== -1"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.value"
|
|
||||||
:disabled="questionList[selectIndex]?.groupingB?.includes(item.value) ?? false"
|
|
||||||
>{{ item.label }}</el-checkbox>
|
|
||||||
</template>
|
|
||||||
</el-checkbox-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label-width="110px" :label="$t('trials:adRules:title:answerGroupB')">
|
|
||||||
<el-checkbox-group v-model="questionList[selectIndex].groupingB">
|
|
||||||
<template v-for="item of questionList[selectIndex].TypeValue.split('|') || []">
|
|
||||||
<el-checkbox
|
|
||||||
v-if="questionList[selectIndex].QuestionGenre !== 3"
|
|
||||||
:key="item"
|
|
||||||
:label="item"
|
|
||||||
:disabled="questionList[selectIndex]?.groupingA?.includes(item) ?? false"
|
|
||||||
>
|
|
||||||
{{ item }}
|
|
||||||
</el-checkbox>
|
|
||||||
</template>
|
|
||||||
<template v-for="item of $d[questionList[selectIndex].DictionaryCode]">
|
|
||||||
<el-checkbox
|
|
||||||
v-if="questionList[selectIndex].QuestionGenre === 3 && item.value !== -1"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.value"
|
|
||||||
:disabled="questionList[selectIndex]?.groupingA?.includes(item.value) ?? false"
|
|
||||||
>
|
|
||||||
{{ item.label }}
|
|
||||||
</el-checkbox>
|
|
||||||
</template>
|
|
||||||
</el-checkbox-group>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
<div class="base-dialog-footer" style="text-align: right; margin-top: 10px">
|
|
||||||
<el-button v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']" :disabled="btnLoading" size="small"
|
|
||||||
type="primary" @click="
|
|
||||||
questionVisible = false
|
|
||||||
$set(questionList[selectIndex], 'groupingA', [])
|
|
||||||
$set(questionList[selectIndex], 'groupingB', [])
|
|
||||||
">
|
|
||||||
{{ $t('common:button:cancel') }}
|
|
||||||
</el-button>
|
|
||||||
<el-button v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']" :disabled="btnLoading" size="small"
|
|
||||||
type="primary" @click="save">
|
|
||||||
{{ $t('common:button:save') }}
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
<el-dialog
|
|
||||||
v-if="copyVisible"
|
|
||||||
:title="$t('common:button:copy')"
|
|
||||||
:visible.sync="copyVisible"
|
|
||||||
width="500px"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
custom-class="base-dialog-wrapper"
|
|
||||||
append-to-body
|
|
||||||
>
|
|
||||||
<div class="base-dialog-body">
|
|
||||||
<el-form label-width="100px">
|
|
||||||
<el-form-item :label="$t('trials:trials-panel:setting:reading-unit:targetVisitNum')">
|
|
||||||
<el-select v-model="copySourceVisitNum" style="width: 100%" filterable>
|
|
||||||
<el-option
|
|
||||||
v-for="visit in copySourceVisitOptions"
|
|
||||||
:key="visit.Id"
|
|
||||||
:label="visit.VisitName"
|
|
||||||
:value="visit.VisitNum"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
<div class="base-dialog-footer" style="text-align: right; margin-top: 10px">
|
|
||||||
<el-button
|
|
||||||
v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
|
||||||
:disabled="btnLoading"
|
|
||||||
size="small"
|
|
||||||
@click="closeCopyDialog"
|
|
||||||
>
|
|
||||||
{{ $t('common:button:cancel') }}
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
|
||||||
:disabled="btnLoading"
|
|
||||||
:loading="btnLoading"
|
|
||||||
size="small"
|
|
||||||
type="primary"
|
|
||||||
@click="confirmCopy"
|
|
||||||
>
|
|
||||||
{{ $t('common:button:confirm') }}
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
/* eslint-disable */
|
|
||||||
import {
|
|
||||||
getTrialQuestionVisitJudgeRule,
|
|
||||||
setTrialQuestionVisitJudgeRule,
|
|
||||||
copyTrialQuestionVisitJudgeRule,
|
|
||||||
applyBaseLineTrialQuestionVisitJudgeRule
|
|
||||||
} from '@/api/trials/reading'
|
|
||||||
import { getTrialVisitStageSelect } from '@/api/trials'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
trialReadingCriterionId: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
isSign: {
|
|
||||||
type: Boolean,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
btnLoading: false,
|
|
||||||
loading: false,
|
|
||||||
activeVisitTab: '',
|
|
||||||
visitActiveNamesMap: {},
|
|
||||||
questionListMap: {},
|
|
||||||
visitPlanOptions: [],
|
|
||||||
questionVisible: false,
|
|
||||||
copyVisible: false,
|
|
||||||
copyTargetVisitNum: null,
|
|
||||||
copySourceVisitNum: null,
|
|
||||||
selectIndex: 0,
|
|
||||||
indexA: null,
|
|
||||||
selectVisitKey: '',
|
|
||||||
type: null,
|
|
||||||
OtherInfo: {
|
|
||||||
IsSign: true,
|
|
||||||
},
|
|
||||||
JudgeDifferenceValueQRules: {
|
|
||||||
JudgeDifferenceType: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: this.$t(
|
|
||||||
'trials:trials-list:setitng:JudgeDifferenceTypeRequired'
|
|
||||||
),
|
|
||||||
trigger: 'blur',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
JudgeDifferenceValue: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: this.$t(
|
|
||||||
'trials:trials-list:setitng:JudgeDifferenceValueRequired'
|
|
||||||
),
|
|
||||||
trigger: 'blur',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pattern: /^[0-9]+(.[0-9]{2})?$/,
|
|
||||||
message: this.$t('trials:trials-list:setitng:JudgeDifferenceValue'),
|
|
||||||
trigger: 'blur',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
validator: (rule, value, callback) => {
|
|
||||||
if (value <= 0) {
|
|
||||||
callback(
|
|
||||||
new Error(
|
|
||||||
this.$t(
|
|
||||||
'trials:trials-list:setitng:JudgeDifferenceValueMin'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
trigger: 'blur',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
questionList() {
|
|
||||||
return this.questionListMap[this.selectVisitKey]
|
|
||||||
},
|
|
||||||
copySourceVisitOptions() {
|
|
||||||
return this.visitPlanOptions.filter((visit) => visit.VisitNum !== this.copyTargetVisitNum)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
async activeVisitTab(v) {
|
|
||||||
if (!v) return
|
|
||||||
if (this.questionListMap[v]) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
await this.getList(v)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
async mounted() {
|
|
||||||
await this.initData()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async initData() {
|
|
||||||
this.questionListMap = {}
|
|
||||||
this.visitActiveNamesMap = {}
|
|
||||||
this.activeVisitTab = ''
|
|
||||||
await this.getVisitPlanOptions()
|
|
||||||
},
|
|
||||||
resetVisitJudgeTypeRelatedFields(question = {}) {
|
|
||||||
this.$set(question, 'AnswerGroup2List', [])
|
|
||||||
this.$set(question, 'AnswerGroupList', [])
|
|
||||||
this.$set(question, 'grouping', [])
|
|
||||||
this.$set(question, 'groupingA', [])
|
|
||||||
this.$set(question, 'groupingB', [])
|
|
||||||
this.$set(question, 'JudgeDifferenceValue', null)
|
|
||||||
this.$set(question, 'JudgeDifferenceType', 0)
|
|
||||||
},
|
|
||||||
normalizeQuestionList(questionList = []) {
|
|
||||||
return questionList.map((item) => ({
|
|
||||||
...item,
|
|
||||||
grouping: [],
|
|
||||||
groupingA: [],
|
|
||||||
groupingB: [],
|
|
||||||
AnswerGroupList: Array.isArray(item.AnswerCombination)
|
|
||||||
? item.AnswerCombination.map((group) => ({
|
|
||||||
...group,
|
|
||||||
AnswerGroupA: Array.isArray(group.AnswerGroupA)
|
|
||||||
? [...group.AnswerGroupA]
|
|
||||||
: group.AnswerGroupA,
|
|
||||||
AnswerGroupB: Array.isArray(group.AnswerGroupB)
|
|
||||||
? [...group.AnswerGroupB]
|
|
||||||
: group.AnswerGroupB
|
|
||||||
}))
|
|
||||||
: [],
|
|
||||||
AnswerGroup2List: Array.isArray(item.AnswerGroup)
|
|
||||||
? [...item.AnswerGroup]
|
|
||||||
: []
|
|
||||||
}))
|
|
||||||
},
|
|
||||||
closeCopyDialog() {
|
|
||||||
this.copyVisible = false
|
|
||||||
this.copyTargetVisitNum = null
|
|
||||||
this.copySourceVisitNum = null
|
|
||||||
},
|
|
||||||
async getVisitPlanOptions() {
|
|
||||||
try {
|
|
||||||
const trialId = this.$route.query.trialId
|
|
||||||
const res = await getTrialVisitStageSelect(trialId)
|
|
||||||
if (res.IsSuccess) {
|
|
||||||
this.visitPlanOptions = res.Result || []
|
|
||||||
if (!this.activeVisitTab && this.visitPlanOptions.length > 0) {
|
|
||||||
this.activeVisitTab = this.visitPlanOptions[0].Id
|
|
||||||
}
|
|
||||||
const outOfPlan = {
|
|
||||||
"Id": "00000000-0000-0000-0000-000000000000",
|
|
||||||
"VisitNum": -1,
|
|
||||||
"VisitName": "Out of Plan",
|
|
||||||
"IsBaseLine": false
|
|
||||||
}
|
|
||||||
const isExists = this.visitPlanOptions.some(x => x.Id === outOfPlan.Id);
|
|
||||||
if (!isExists) {
|
|
||||||
this.visitPlanOptions.push(outOfPlan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getVisitById(visitKey) {
|
|
||||||
return this.visitPlanOptions.find((visit) => visit.Id === visitKey)
|
|
||||||
},
|
|
||||||
async getList(visitKey = this.activeVisitTab) {
|
|
||||||
const visit = this.getVisitById(visitKey)
|
|
||||||
if (!visit) return
|
|
||||||
try {
|
|
||||||
this.loading = true
|
|
||||||
let params = {
|
|
||||||
trialId: this.$route.query.trialId,
|
|
||||||
trialReadingCriterionId: this.trialReadingCriterionId,
|
|
||||||
visitNum: visit.VisitNum
|
|
||||||
}
|
|
||||||
const res = await getTrialQuestionVisitJudgeRule(params)
|
|
||||||
const questionList = this.normalizeQuestionList(res.Result)
|
|
||||||
this.$set(this.questionListMap, visitKey, questionList)
|
|
||||||
this.$set(
|
|
||||||
this.visitActiveNamesMap,
|
|
||||||
visitKey,
|
|
||||||
questionList.map((item) => item.ReadingQuestionTrialId)
|
|
||||||
)
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
} finally {
|
|
||||||
this.loading = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
changeArbitrationRule(value) {
|
|
||||||
if (value !== 1) {
|
|
||||||
Object.values(this.questionListMap).forEach((questionList) => {
|
|
||||||
questionList.forEach((item) => {
|
|
||||||
item.JudgeDifferenceValue = 0
|
|
||||||
item.JudgeDifferenceType = 0
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
visitJudgeTypeChange(value, index, visitKey) {
|
|
||||||
this.resetVisitJudgeTypeRelatedFields(this.questionListMap[visitKey][index])
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (value === 4 || value === 5) {
|
|
||||||
const refName = `JudgeDifferenceValue${value}_${visitKey}_${index}`
|
|
||||||
if (this.$refs[refName] && this.$refs[refName][0]) {
|
|
||||||
this.$refs[refName][0].resetFields()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// async saveAllSync(showMessage = false) {
|
|
||||||
// try {
|
|
||||||
// this.btnLoading = true
|
|
||||||
// this.loading = true
|
|
||||||
// for (let i = 0; i < this.visitPlanOptions.length; i++) {
|
|
||||||
// const visit = this.visitPlanOptions[i]
|
|
||||||
// if (!this.questionListMap[visit.Id]) {
|
|
||||||
// await this.getList(visit.Id)
|
|
||||||
// }
|
|
||||||
// const questionList = this.questionListMap[visit.Id] || []
|
|
||||||
// if (questionList.length === 0) {
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// for (let index = 0; index < questionList.length; index++) {
|
|
||||||
// if (questionList[index].JudgeType === 0) {
|
|
||||||
// this.activeVisitTab = visit.Id
|
|
||||||
// this.$alert(this.$t('trials:adRules:message:msg8'))
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
// if (
|
|
||||||
// questionList[index].JudgeType === 2 &&
|
|
||||||
// questionList[index].AnswerGroup2List.length === 0
|
|
||||||
// ) {
|
|
||||||
// this.activeVisitTab = visit.Id
|
|
||||||
// this.$alert(this.$t('trials:adRules:message:msg8'))
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
// if (
|
|
||||||
// questionList[index].JudgeType === 3 &&
|
|
||||||
// questionList[index].AnswerGroupList.length === 0
|
|
||||||
// ) {
|
|
||||||
// this.activeVisitTab = visit.Id
|
|
||||||
// this.$alert(this.$t('trials:adRules:message:msg8'))
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
// if (
|
|
||||||
// questionList[index].JudgeType === 4 ||
|
|
||||||
// questionList[index].JudgeType === 5
|
|
||||||
// ) {
|
|
||||||
// this.activeVisitTab = visit.Id
|
|
||||||
// await this.$nextTick()
|
|
||||||
// const refName = `JudgeDifferenceValue${questionList[index].JudgeType}_${visit.Id}_${index}`
|
|
||||||
// try {
|
|
||||||
// const validate = await this.$refs[refName][0].validate()
|
|
||||||
// if (!validate) return false
|
|
||||||
// } catch (err) {
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// let params = {
|
|
||||||
// TrialReadingCriterionId: this.trialReadingCriterionId,
|
|
||||||
// VisitNum: visit.VisitNum,
|
|
||||||
// QuestionList: questionList.map((item) => {
|
|
||||||
// return {
|
|
||||||
// ReadingQuestionTrialId: item.ReadingQuestionTrialId,
|
|
||||||
// AnswerGroup: item.AnswerGroup2List,
|
|
||||||
// AnswerCombination: item.AnswerGroupList,
|
|
||||||
// JudgeType: item.JudgeType,
|
|
||||||
// JudgeDifferenceValue: item.JudgeDifferenceValue,
|
|
||||||
// JudgeDifferenceType: item.JudgeDifferenceType
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// let res = await setTrialQuestionVisitJudgeRule(params)
|
|
||||||
// if (!res.IsSuccess) {
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (showMessage) {
|
|
||||||
// this.$message.success(this.$t('common:message:savedSuccessfully'))
|
|
||||||
// }
|
|
||||||
// return true
|
|
||||||
// } catch (e) {
|
|
||||||
// console.log(e)
|
|
||||||
// return false
|
|
||||||
// } finally {
|
|
||||||
// this.btnLoading = false
|
|
||||||
// this.loading = false
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
async handleBatchSave(visitKey, visitNum) {
|
|
||||||
if (!visitKey) return
|
|
||||||
const questionList = this.questionListMap[visitKey] || []
|
|
||||||
if (questionList.length === 0) return
|
|
||||||
try {
|
|
||||||
this.btnLoading = true
|
|
||||||
this.loading = true
|
|
||||||
for (let index = 0; index < questionList.length; index++) {
|
|
||||||
if (questionList[index].JudgeType === 0) {
|
|
||||||
this.$alert(this.$t('trials:adRules:message:msg8'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
questionList[index].JudgeType === 2 &&
|
|
||||||
questionList[index].AnswerGroup2List.length === 0
|
|
||||||
) {
|
|
||||||
this.$alert(this.$t('trials:adRules:message:msg8'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
questionList[index].JudgeType === 3 &&
|
|
||||||
questionList[index].AnswerGroupList.length === 0
|
|
||||||
) {
|
|
||||||
this.$alert(this.$t('trials:adRules:message:msg8'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
questionList[index].JudgeType === 4 ||
|
|
||||||
questionList[index].JudgeType === 5
|
|
||||||
) {
|
|
||||||
await this.$nextTick()
|
|
||||||
const refName = `JudgeDifferenceValue${questionList[index].JudgeType}_${visitKey}_${index}`
|
|
||||||
try {
|
|
||||||
const validate = await this.$refs[refName][0].validate()
|
|
||||||
if (!validate) return
|
|
||||||
} catch (err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let params = {
|
|
||||||
TrialReadingCriterionId: this.trialReadingCriterionId,
|
|
||||||
VisitNum: visitNum,
|
|
||||||
QuestionList: questionList.map((item) => {
|
|
||||||
return {
|
|
||||||
ReadingQuestionTrialId: item.ReadingQuestionTrialId,
|
|
||||||
AnswerGroup: item.AnswerGroup2List,
|
|
||||||
AnswerCombination: item.AnswerGroupList,
|
|
||||||
JudgeType: item.JudgeType,
|
|
||||||
JudgeDifferenceValue: item.JudgeDifferenceValue,
|
|
||||||
JudgeDifferenceType: item.JudgeDifferenceType
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
let res = await setTrialQuestionVisitJudgeRule(params)
|
|
||||||
if (res.IsSuccess) {
|
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
} finally {
|
|
||||||
this.btnLoading = false
|
|
||||||
this.loading = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
save() {
|
|
||||||
const questionList = this.questionList
|
|
||||||
let index = this.selectIndex
|
|
||||||
let indexA = this.indexA
|
|
||||||
if (questionList[index].groupingA.length === 0) {
|
|
||||||
this.$alert(this.$t('trials:adRules:message:msg2'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (questionList[index].groupingB.length === 0) {
|
|
||||||
this.$alert(this.$t('trials:adRules:message:msg3'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (this.type === 'add') {
|
|
||||||
questionList[index].AnswerGroupList.push({
|
|
||||||
AnswerGroupA: questionList[index].groupingA,
|
|
||||||
AnswerGroupB: questionList[index].groupingB
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.$set(
|
|
||||||
questionList[index].AnswerGroupList[indexA],
|
|
||||||
'AnswerGroupA',
|
|
||||||
questionList[index].groupingA
|
|
||||||
)
|
|
||||||
this.$set(
|
|
||||||
questionList[index].AnswerGroupList[indexA],
|
|
||||||
'AnswerGroupB',
|
|
||||||
questionList[index].groupingB
|
|
||||||
)
|
|
||||||
}
|
|
||||||
this.$set(questionList[index], 'groupingA', [])
|
|
||||||
this.$set(questionList[index], 'groupingB', [])
|
|
||||||
this.$message.success(this.$t('trials:adRules:message:msg4'))
|
|
||||||
this.questionVisible = false
|
|
||||||
},
|
|
||||||
handleCopy(visitNum) {
|
|
||||||
this.copyTargetVisitNum = visitNum
|
|
||||||
this.copyVisible = true
|
|
||||||
},
|
|
||||||
async confirmCopy() {
|
|
||||||
if (!this.copySourceVisitNum) {
|
|
||||||
this.$alert(this.$t('trials:setting:reading-unit:msg1'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
this.btnLoading = true
|
|
||||||
this.loading = true
|
|
||||||
const params = {
|
|
||||||
trialReadingCriterionId: this.trialReadingCriterionId,
|
|
||||||
sourceVisitNum: this.copySourceVisitNum,
|
|
||||||
targetVisitNum: this.copyTargetVisitNum
|
|
||||||
}
|
|
||||||
const res = await copyTrialQuestionVisitJudgeRule(params)
|
|
||||||
if (res.IsSuccess) {
|
|
||||||
await this.getList(this.activeVisitTab)
|
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
|
||||||
this.closeCopyDialog()
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
} finally {
|
|
||||||
this.btnLoading = false
|
|
||||||
this.loading = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async applyToFollowup() {
|
|
||||||
try {
|
|
||||||
await this.$confirm(
|
|
||||||
this.$t('trials:adRules:message:msg10'),
|
|
||||||
{
|
|
||||||
type: 'warning',
|
|
||||||
distinguishCancelAndClose: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
this.btnLoading = true
|
|
||||||
this.loading = true
|
|
||||||
const res = await applyBaseLineTrialQuestionVisitJudgeRule({
|
|
||||||
trialReadingCriterionId: this.trialReadingCriterionId
|
|
||||||
})
|
|
||||||
if (res.IsSuccess) {
|
|
||||||
this.questionListMap = {}
|
|
||||||
this.visitActiveNamesMap = {}
|
|
||||||
if (this.activeVisitTab) {
|
|
||||||
await this.getList(this.activeVisitTab)
|
|
||||||
}
|
|
||||||
this.$message.success(this.$t('trials:adRules:message:msg9'))
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if (e === 'cancel') return
|
|
||||||
console.log(e)
|
|
||||||
} finally {
|
|
||||||
this.btnLoading = false
|
|
||||||
this.loading = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
visitTagClose2(index, indexA, visitKey) {
|
|
||||||
this.$confirm(this.$t('trials:adRules:message:msg1')).then(() => {
|
|
||||||
this.questionListMap[visitKey][index].AnswerGroup2List.splice(indexA, 1)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
visitTagClose(index, indexA, visitKey) {
|
|
||||||
this.$confirm(this.$t('trials:adRules:message:msg1')).then(() => {
|
|
||||||
this.questionListMap[visitKey][index].AnswerGroupList.splice(indexA, 1)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
visitAddGroup2(index, visitKey) {
|
|
||||||
const questionList = this.questionListMap[visitKey]
|
|
||||||
if (questionList[index].grouping.length === 0) {
|
|
||||||
this.$alert(this.$t('trials:adRules:message:msg5'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let grouping = questionList[index].grouping
|
|
||||||
.toString()
|
|
||||||
.replaceAll(',', '|')
|
|
||||||
questionList[index].AnswerGroup2List.push(`|${grouping}|`)
|
|
||||||
this.$set(questionList[index], 'grouping', [])
|
|
||||||
},
|
|
||||||
visitAddGroup(index, indexA, visitKey) {
|
|
||||||
const questionList = this.questionListMap[visitKey]
|
|
||||||
this.selectIndex = index
|
|
||||||
this.selectVisitKey = visitKey
|
|
||||||
this.type = 'add'
|
|
||||||
if (indexA !== null) {
|
|
||||||
this.indexA = indexA
|
|
||||||
this.type = 'edit'
|
|
||||||
this.$set(
|
|
||||||
questionList[index],
|
|
||||||
'groupingA',
|
|
||||||
questionList[index].AnswerGroupList[indexA].AnswerGroupA
|
|
||||||
)
|
|
||||||
this.$set(
|
|
||||||
questionList[index],
|
|
||||||
'groupingB',
|
|
||||||
questionList[index].AnswerGroupList[indexA].AnswerGroupB
|
|
||||||
)
|
|
||||||
}
|
|
||||||
this.questionVisible = true
|
|
||||||
},
|
|
||||||
async visitReset(ReadingQuestionTrialId, index, visitKey, visitNum) {
|
|
||||||
const questionList = this.questionListMap[visitKey]
|
|
||||||
this.btnLoading = true
|
|
||||||
this.loading = true
|
|
||||||
try {
|
|
||||||
await this.$confirm(this.$t('trials:adRules:message:msg6'))
|
|
||||||
const params = {
|
|
||||||
TrialReadingCriterionId: this.trialReadingCriterionId,
|
|
||||||
VisitNum: visitNum,
|
|
||||||
QuestionList: [
|
|
||||||
{
|
|
||||||
ReadingQuestionTrialId: ReadingQuestionTrialId,
|
|
||||||
AnswerGroup: [],
|
|
||||||
AnswerCombination: [],
|
|
||||||
JudgeType: 0,
|
|
||||||
JudgeDifferenceValue: 0,
|
|
||||||
JudgeDifferenceType: 0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
await setTrialQuestionVisitJudgeRule(params)
|
|
||||||
this.$set(questionList[index], 'AnswerGroup2List', [])
|
|
||||||
this.$set(questionList[index], 'AnswerGroupList', [])
|
|
||||||
this.$set(questionList[index], 'JudgeType', 0)
|
|
||||||
this.$set(questionList[index], 'JudgeDifferenceValue', 0)
|
|
||||||
this.$set(questionList[index], 'JudgeDifferenceType', 0)
|
|
||||||
|
|
||||||
this.$message.success(this.$t('trials:adRules:message:msg7'))
|
|
||||||
} catch(e) {
|
|
||||||
console.log(e)
|
|
||||||
} finally {
|
|
||||||
this.btnLoading = false
|
|
||||||
this.loading = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async visitApply(ReadingQuestionTrialId, index, visitKey, visitNum) {
|
|
||||||
try {
|
|
||||||
const questionList = this.questionListMap[visitKey]
|
|
||||||
if (questionList[index].JudgeType === 0) {
|
|
||||||
this.$alert(this.$t('trials:adRules:message:msg8'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
questionList[index].JudgeType === 2 &&
|
|
||||||
questionList[index].AnswerGroup2List.length === 0
|
|
||||||
) {
|
|
||||||
this.$alert(this.$t('trials:adRules:message:msg8'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
questionList[index].JudgeType === 3 &&
|
|
||||||
questionList[index].AnswerGroupList.length === 0
|
|
||||||
) {
|
|
||||||
this.$alert(this.$t('trials:adRules:message:msg8'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
questionList[index].JudgeType === 4 ||
|
|
||||||
questionList[index].JudgeType === 5
|
|
||||||
) {
|
|
||||||
const refName = `JudgeDifferenceValue${questionList[index].JudgeType}_${visitKey}_${index}`
|
|
||||||
const validate = await this.$refs[refName][0].validate()
|
|
||||||
if (!validate) return
|
|
||||||
}
|
|
||||||
this.btnLoading = true
|
|
||||||
this.loading = true
|
|
||||||
let params = {
|
|
||||||
TrialReadingCriterionId: this.trialReadingCriterionId,
|
|
||||||
VisitNum: visitNum,
|
|
||||||
QuestionList: [
|
|
||||||
{
|
|
||||||
ReadingQuestionTrialId: ReadingQuestionTrialId,
|
|
||||||
AnswerGroup: questionList[index].AnswerGroup2List,
|
|
||||||
AnswerCombination: questionList[index].AnswerGroupList,
|
|
||||||
JudgeType: questionList[index].JudgeType,
|
|
||||||
JudgeDifferenceValue: questionList[index].JudgeDifferenceValue,
|
|
||||||
JudgeDifferenceType: questionList[index].JudgeDifferenceType
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
let res = await setTrialQuestionVisitJudgeRule(params)
|
|
||||||
if (res.IsSuccess) {
|
|
||||||
this.$message.success(this.$t('trials:adRules:message:msg9'))
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
console.log(e)
|
|
||||||
} finally {
|
|
||||||
this.btnLoading = false
|
|
||||||
this.loading = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style scoped>
|
|
||||||
.visit-tabs-actions {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
padding: 0 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.visit-tabs ::v-deep .el-tabs__content {
|
|
||||||
min-height: 520px;
|
|
||||||
padding-top: 20px !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -240,6 +240,7 @@ export default {
|
|||||||
if (ReadingTool === 3) {
|
if (ReadingTool === 3) {
|
||||||
this.readingSegmentTools = getCustomizeStandardsSegmentDicomTools(readingSegmentTools)
|
this.readingSegmentTools = getCustomizeStandardsSegmentDicomTools(readingSegmentTools)
|
||||||
}
|
}
|
||||||
|
console.log(this.readingSegmentTools, 'this.readingSegmentTools')
|
||||||
},
|
},
|
||||||
setIsClinicalReading(isClinicalReading) {
|
setIsClinicalReading(isClinicalReading) {
|
||||||
this.isClinicalReading = isClinicalReading;
|
this.isClinicalReading = isClinicalReading;
|
||||||
@@ -299,15 +300,11 @@ export default {
|
|||||||
this.$refs["arbitrationRules" + this.TrialReadingCriterionId]
|
this.$refs["arbitrationRules" + this.TrialReadingCriterionId]
|
||||||
.length
|
.length
|
||||||
) {
|
) {
|
||||||
const arbitrationRulesRef = this.$refs[
|
var arbitrationRules = await this.$refs[
|
||||||
"arbitrationRules" + this.TrialReadingCriterionId
|
"arbitrationRules" + this.TrialReadingCriterionId
|
||||||
][0];
|
][0].saveAllSync();
|
||||||
var judgeRuleSaved = await arbitrationRulesRef.saveJugeRule(false);
|
|
||||||
var arbitrationRules = judgeRuleSaved
|
|
||||||
? await arbitrationRulesRef.saveAllSync()
|
|
||||||
: false;
|
|
||||||
isCheckList.push({
|
isCheckList.push({
|
||||||
isCheck: judgeRuleSaved && arbitrationRules,
|
isCheck: arbitrationRules,
|
||||||
msg: this.$t("trials:readingUnit:adRules"), // '仲裁规则'
|
msg: this.$t("trials:readingUnit:adRules"), // '仲裁规则'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -451,6 +448,9 @@ export default {
|
|||||||
this.$refs[
|
this.$refs[
|
||||||
"arbitrationRules" + this.TrialReadingCriterionId
|
"arbitrationRules" + this.TrialReadingCriterionId
|
||||||
][0].getList();
|
][0].getList();
|
||||||
|
this.$refs[
|
||||||
|
"arbitrationRules" + this.TrialReadingCriterionId
|
||||||
|
][0].getTrialJudgyInfo();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
<template>
|
||||||
|
<div class="json-editor" v-loading="loading">
|
||||||
|
<div class="header">
|
||||||
|
<!-- <span class="title">JSON 编辑</span> -->
|
||||||
|
<el-button type="primary" size="mini" icon="el-icon-check" @click="save">
|
||||||
|
{{ $t('common:button:save') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="json">
|
||||||
|
<json-node
|
||||||
|
:node-key="'root'"
|
||||||
|
:node-value="jsonData"
|
||||||
|
:is-root="true"
|
||||||
|
@update="handleUpdate"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getInspectionById, setJsonDetail } from '@/api/trials'
|
||||||
|
import JsonNode from './JsonNode.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'JsonEditor',
|
||||||
|
components: { JsonNode },
|
||||||
|
props: {
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
jsonData: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getJsonData()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleUpdate({ path, value }) {
|
||||||
|
const target = this.getTarget(path.slice(0, -1))
|
||||||
|
this.$set(target, path[path.length - 1], value)
|
||||||
|
},
|
||||||
|
getTarget(path) {
|
||||||
|
let t = this.jsonData
|
||||||
|
path.forEach(k => { t = t[k] })
|
||||||
|
return t
|
||||||
|
},
|
||||||
|
parseValue(val) {
|
||||||
|
if (typeof val === 'string') {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(val)
|
||||||
|
if (parsed && typeof parsed === 'object') {
|
||||||
|
return JSON.parse(JSON.stringify(parsed))
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(e.message)
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
return val ? JSON.parse(JSON.stringify(val)) : {}
|
||||||
|
},
|
||||||
|
async getJsonData() {
|
||||||
|
try {
|
||||||
|
this.loading = true
|
||||||
|
const res = await getInspectionById({ id: this.id })
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
this.jsonData = this.parseValue(res.Result.JsonDetail)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
} finally {
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isValidJsonObject(obj) {
|
||||||
|
if (obj === null || typeof obj !== 'object') return false
|
||||||
|
try {
|
||||||
|
JSON.stringify(obj)
|
||||||
|
return true
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(e.message)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
safeClone(obj) {
|
||||||
|
if (this.isValidJsonObject(obj)) {
|
||||||
|
return JSON.parse(JSON.stringify(obj))
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
async save() {
|
||||||
|
try {
|
||||||
|
this.loading = true
|
||||||
|
const result = this.safeClone(this.jsonData)
|
||||||
|
const res = await setJsonDetail({ id: this.id, jsonDetail: JSON.stringify(result) })
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
this.$emit('getList')
|
||||||
|
this.$emit('close')
|
||||||
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
} finally {
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.json-editor {
|
||||||
|
font-family: Consolas, Monaco, monospace;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 2;
|
||||||
|
padding: 12px;
|
||||||
|
background: #fafafa;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
.json {
|
||||||
|
max-height: 50vh;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
<template>
|
||||||
|
<div class="node" :style="{ paddingLeft: depth * 20 + 'px' }">
|
||||||
|
<span v-if="!isRoot" class="key">
|
||||||
|
{{ isArray ? `[${nodeKey}]` : `"${nodeKey}"` }}:
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<!-- 对象 -->
|
||||||
|
<template v-if="isObject">
|
||||||
|
<span class="bracket">{</span>
|
||||||
|
<div class="children">
|
||||||
|
<json-node
|
||||||
|
v-for="(v, k) in nodeValue"
|
||||||
|
:key="k"
|
||||||
|
:node-key="k"
|
||||||
|
:node-value="v"
|
||||||
|
:depth="depth + 1"
|
||||||
|
:parent-path="currentPath"
|
||||||
|
@update="$emit('update', $event)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span class="bracket">}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 数组 -->
|
||||||
|
<template v-else-if="isArray">
|
||||||
|
<span class="bracket">[</span>
|
||||||
|
<div class="children">
|
||||||
|
<json-node
|
||||||
|
v-for="(item, i) in nodeValue"
|
||||||
|
:key="i"
|
||||||
|
:node-key="i"
|
||||||
|
:node-value="item"
|
||||||
|
:depth="depth + 1"
|
||||||
|
:parent-path="currentPath"
|
||||||
|
@update="$emit('update', $event)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span class="bracket">]</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 文本 -->
|
||||||
|
<el-input
|
||||||
|
v-else-if="valueType === 'string'"
|
||||||
|
v-model="editVal"
|
||||||
|
size="mini"
|
||||||
|
style="width: 300px"
|
||||||
|
@blur="emitUpdate"
|
||||||
|
@keyup.enter.native="emitUpdate"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 数字 -->
|
||||||
|
<el-input-number
|
||||||
|
v-else-if="valueType === 'number'"
|
||||||
|
v-model="editVal"
|
||||||
|
size="mini"
|
||||||
|
style="width: 140px"
|
||||||
|
@blur="emitUpdate"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 布尔值 -->
|
||||||
|
<el-switch
|
||||||
|
v-else-if="valueType === 'boolean'"
|
||||||
|
v-model="editVal"
|
||||||
|
size="small"
|
||||||
|
@change="emitUpdate"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- null -->
|
||||||
|
<el-tag v-else size="mini" type="info">null</el-tag>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'JsonNode',
|
||||||
|
props: {
|
||||||
|
nodeKey: [String, Number],
|
||||||
|
nodeValue: [Object, Array, String, Number, Boolean],
|
||||||
|
depth: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
isRoot: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
parentPath: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return { editVal: this.nodeValue }
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isObject() {
|
||||||
|
return this.nodeValue && typeof this.nodeValue === 'object' && !Array.isArray(this.nodeValue)
|
||||||
|
},
|
||||||
|
isArray() {
|
||||||
|
return Array.isArray(this.nodeValue)
|
||||||
|
},
|
||||||
|
valueType() {
|
||||||
|
if (this.nodeValue === null) return 'null'
|
||||||
|
return typeof this.nodeValue
|
||||||
|
},
|
||||||
|
currentPath() {
|
||||||
|
return this.isRoot ? [] : [...this.parentPath, this.nodeKey]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
nodeValue(v) { this.editVal = v }
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
emitUpdate() {
|
||||||
|
this.$emit('update', { path: this.currentPath, value: this.editVal })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.node {
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
.key {
|
||||||
|
color: #c7254e;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
.bracket {
|
||||||
|
color: #e6a23c;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.children {
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -194,6 +194,9 @@
|
|||||||
<el-button type="text" @click="lookDetails(scope.row)">
|
<el-button type="text" @click="lookDetails(scope.row)">
|
||||||
{{ $t('trials:auditRecord:action:detail') }}
|
{{ $t('trials:auditRecord:action:detail') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button type="text" @click="edit(scope.row)">
|
||||||
|
{{ $t('common:button:edit') }}
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -622,6 +625,20 @@
|
|||||||
<!-- :src="openImageUrl"-->
|
<!-- :src="openImageUrl"-->
|
||||||
<!-- style="width: 50px;height: 50px; cursor:pointer">-->
|
<!-- style="width: 50px;height: 50px; cursor:pointer">-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
|
<!-- <json-editor v-model="data" /> -->
|
||||||
|
<el-dialog
|
||||||
|
v-if="editDialogVisible"
|
||||||
|
:visible.sync="editDialogVisible"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:title="$t('common:button:edit') + `${$i18n.locale === 'zh' ? '(' + editRow.DescriptionCN + ')' : '( ' + editRow.Description + ' )'}`"
|
||||||
|
width="720px"
|
||||||
|
custom-class="base-dialog-wrapper">
|
||||||
|
<json-editor
|
||||||
|
:id="editRow.Id"
|
||||||
|
@close="editDialogVisible = false"
|
||||||
|
@getList="getList"
|
||||||
|
/>
|
||||||
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
</BaseContainer>
|
</BaseContainer>
|
||||||
</template>
|
</template>
|
||||||
@@ -630,11 +647,12 @@
|
|||||||
import {
|
import {
|
||||||
getTrialSiteSelect,
|
getTrialSiteSelect,
|
||||||
getTrialVisitStageSelect,
|
getTrialVisitStageSelect,
|
||||||
getTrialCriterionList
|
getTrialCriterionList,
|
||||||
} from '@/api/trials'
|
} from '@/api/trials'
|
||||||
import { getInspectionList, getInspectionJsonDataList } from '@/api/trials/inspection'
|
import { getInspectionList, getInspectionJsonDataList } from '@/api/trials/inspection'
|
||||||
import { getFrontAuditConfigList, getAuditConfigChildList, getModuleTypeDescriptionList, setInspectionEnumValue, getModuleTypeList } from '@/api/dictionary/checkConfig'
|
import { getFrontAuditConfigList, getAuditConfigChildList, getModuleTypeDescriptionList, setInspectionEnumValue, getModuleTypeList } from '@/api/dictionary/checkConfig'
|
||||||
import Pagination from '@/components/Pagination'
|
import Pagination from '@/components/Pagination'
|
||||||
|
import JsonEditor from './components/JsonEditor'
|
||||||
import BaseContainer from '@/components/BaseContainer'
|
import BaseContainer from '@/components/BaseContainer'
|
||||||
import BaseModel from '@/components/BaseModel'
|
import BaseModel from '@/components/BaseModel'
|
||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
@@ -670,7 +688,7 @@ const searchDataDefault = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default {
|
export default {
|
||||||
components: { BaseContainer, Pagination, BaseModel },
|
components: { BaseContainer, Pagination, JsonEditor, BaseModel },
|
||||||
dicts: ['OptType', 'ModuleType', 'ChildrenType'],
|
dicts: ['OptType', 'ModuleType', 'ChildrenType'],
|
||||||
data() {
|
data() {
|
||||||
|
|
||||||
@@ -708,7 +726,10 @@ export default {
|
|||||||
imagesList: [],
|
imagesList: [],
|
||||||
moduleTypeList: [],
|
moduleTypeList: [],
|
||||||
list2_total: 0,
|
list2_total: 0,
|
||||||
list2_searchData: {}
|
list2_searchData: {},
|
||||||
|
editDialogVisible: false,
|
||||||
|
jsonData: null,
|
||||||
|
editRow: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -1346,7 +1367,12 @@ export default {
|
|||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
|
edit(row) {
|
||||||
|
this.editRow = Object.assign({}, row)
|
||||||
|
this.editDialogVisible = true
|
||||||
|
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -105,6 +105,7 @@
|
|||||||
<el-button icon="el-icon-delete" :title="$t('trials:uploadedDicoms:action:delete')" circle
|
<el-button icon="el-icon-delete" :title="$t('trials:uploadedDicoms:action:delete')" circle
|
||||||
:disabled="!isAfresh && data.SubmitState === 2 && data.SubmitTime && moment(data.SubmitTime).isAfter(moment(scope.row.UploadedTime))"
|
:disabled="!isAfresh && data.SubmitState === 2 && data.SubmitTime && moment(data.SubmitTime).isAfter(moment(scope.row.UploadedTime))"
|
||||||
@click="handleDeleteStudy(scope.row)" />
|
@click="handleDeleteStudy(scope.row)" />
|
||||||
|
<el-button icon="el-icon-upload2" title="上传" circle @click="upload(scope.row)" />
|
||||||
<!-- <el-button-->
|
<!-- <el-button-->
|
||||||
<!-- icon="el-icon-toilet-paper"-->
|
<!-- icon="el-icon-toilet-paper"-->
|
||||||
<!-- circle-->
|
<!-- circle-->
|
||||||
@@ -423,7 +424,8 @@
|
|||||||
<DicomPreview :uid="uid" :studyList="uploadQueues" />
|
<DicomPreview :uid="uid" :studyList="uploadQueues" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!--pet-ct临床数据上传-->
|
<!--pet-ct临床数据上传-->
|
||||||
<el-dialog v-if="petVisible" :show-close="true" :close-on-click-modal="false" :visible.sync="petVisible" append-to-body>
|
<el-dialog v-if="petVisible" :show-close="true" :close-on-click-modal="false" :visible.sync="petVisible"
|
||||||
|
append-to-body>
|
||||||
<uploadPetClinicalData :subject-visit-id="data.Id" :data="data" :studyData="studyData" :allow-add-or-edit="true"
|
<uploadPetClinicalData :subject-visit-id="data.Id" :data="data" :studyData="studyData" :allow-add-or-edit="true"
|
||||||
@getStudyInfo="getStudyInfo" />
|
@getStudyInfo="getStudyInfo" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -650,6 +652,7 @@ export default {
|
|||||||
BodyPart: {},
|
BodyPart: {},
|
||||||
|
|
||||||
isClose: false,
|
isClose: false,
|
||||||
|
StudyInstanceUID: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -682,6 +685,10 @@ export default {
|
|||||||
this.OSSclient.close()
|
this.OSSclient.close()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
upload(row) {
|
||||||
|
this.StudyInstanceUID = row.StudyInstanceUid
|
||||||
|
this.$refs.pathClear.click()
|
||||||
|
},
|
||||||
handleDragover(e) {
|
handleDragover(e) {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@@ -1144,7 +1151,7 @@ export default {
|
|||||||
var instanceItem = instanceList.find(function (item) {
|
var instanceItem = instanceList.find(function (item) {
|
||||||
return item.instanceUid === instanceUid
|
return item.instanceUid === instanceUid
|
||||||
})
|
})
|
||||||
if (!instanceItem) {
|
if (!false) {
|
||||||
var date = data.string('x00080023')
|
var date = data.string('x00080023')
|
||||||
var time = data.string('x00080033')
|
var time = data.string('x00080033')
|
||||||
var instanceTime = ''
|
var instanceTime = ''
|
||||||
@@ -1274,11 +1281,12 @@ export default {
|
|||||||
verifyStudy() {
|
verifyStudy() {
|
||||||
this.btnLoading = true
|
this.btnLoading = true
|
||||||
var studyList = []
|
var studyList = []
|
||||||
|
let scope = this
|
||||||
this.selectArr.forEach((item) => {
|
this.selectArr.forEach((item) => {
|
||||||
item.dicomInfo.uploadFileSize = 0
|
item.dicomInfo.uploadFileSize = 0
|
||||||
if (!item.uploadState.selected) {
|
if (!item.uploadState.selected) {
|
||||||
studyList.push({
|
studyList.push({
|
||||||
studyInstanceUid: item.dicomInfo.studyUid,
|
studyInstanceUid: scope.StudyInstanceUID ? scope.StudyInstanceUID : item.dicomInfo.studyUid,
|
||||||
studyDate: item.dicomInfo.studyTime,
|
studyDate: item.dicomInfo.studyTime,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1293,6 +1301,8 @@ export default {
|
|||||||
batchVerifyStudyAllowUpload(param)
|
batchVerifyStudyAllowUpload(param)
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
var messageArr = []
|
var messageArr = []
|
||||||
|
res.Result = []
|
||||||
|
console.log(res)
|
||||||
res.Result.forEach((item) => {
|
res.Result.forEach((item) => {
|
||||||
const i = this.uploadQueues.findIndex(
|
const i = this.uploadQueues.findIndex(
|
||||||
(value) => value.dicomInfo.studyUid === item.StudyInstanceUid
|
(value) => value.dicomInfo.studyUid === item.StudyInstanceUid
|
||||||
@@ -1475,8 +1485,21 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 上传影像并归档
|
// 上传影像并归档
|
||||||
archiveStudy(index, config) {
|
archiveStudy(index, config = {}) {
|
||||||
var scope = this
|
var scope = this
|
||||||
|
try {
|
||||||
|
if (!config.AnonymizeFixedList) config.AnonymizeFixedList = []
|
||||||
|
config.AnonymizeFixedList.push(
|
||||||
|
{
|
||||||
|
Element: '000D',
|
||||||
|
Group: '0020',
|
||||||
|
ReplaceValue: scope.StudyInstanceUID,
|
||||||
|
Id: 'StudyInstanceUID'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
try {
|
try {
|
||||||
preArchiveDicomStudy({
|
preArchiveDicomStudy({
|
||||||
@@ -1506,7 +1529,7 @@ export default {
|
|||||||
let t = setInterval(() => {
|
let t = setInterval(() => {
|
||||||
dicomUploadInProgress({
|
dicomUploadInProgress({
|
||||||
trialId: scope.trialId,
|
trialId: scope.trialId,
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
}).then((res) => { })
|
}).then((res) => { })
|
||||||
}, 5000)
|
}, 5000)
|
||||||
scope.myInterval.push(t)
|
scope.myInterval.push(t)
|
||||||
@@ -1531,7 +1554,7 @@ export default {
|
|||||||
dicomInfo.RadiopharmaceuticalStartTime,
|
dicomInfo.RadiopharmaceuticalStartTime,
|
||||||
|
|
||||||
studyId: dicomInfo.studyId,
|
studyId: dicomInfo.studyId,
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
studyTime: dicomInfo.studyTime,
|
studyTime: dicomInfo.studyTime,
|
||||||
description: dicomInfo.description,
|
description: dicomInfo.description,
|
||||||
seriesCount: dicomInfo.seriesNum,
|
seriesCount: dicomInfo.seriesNum,
|
||||||
@@ -1572,58 +1595,60 @@ export default {
|
|||||||
try {
|
try {
|
||||||
let o = v.instanceList[ii]
|
let o = v.instanceList[ii]
|
||||||
let name = `${v.instanceList[ii].file.webkitRelativePath}_${v.instanceList[ii].instanceUid}`
|
let name = `${v.instanceList[ii].file.webkitRelativePath}_${v.instanceList[ii].instanceUid}`
|
||||||
if (o.isReUpload) {
|
// if (o.isReUpload) {
|
||||||
dicomInfo.failedFileCount++
|
// dicomInfo.failedFileCount++
|
||||||
dicomInfo.uploadFileSize += o.file.size
|
// dicomInfo.uploadFileSize += o.file.size
|
||||||
Record.Existed.push(name)
|
// Record.Existed.push(name)
|
||||||
Record.FileCount++
|
// Record.FileCount++
|
||||||
} else if (o.myPath) {
|
// }
|
||||||
instanceList.push({
|
// else if (o.myPath) {
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
// instanceList.push({
|
||||||
seriesInstanceUid: v.seriesUid,
|
// studyInstanceUid: dicomInfo.studyUid,
|
||||||
SOPClassUID: o.SOPClassUID,
|
// seriesInstanceUid: v.seriesUid,
|
||||||
TransferSytaxUID: o.TransferSytaxUID,
|
// SOPClassUID: o.SOPClassUID,
|
||||||
MediaStorageSOPInstanceUID:
|
// TransferSytaxUID: o.TransferSytaxUID,
|
||||||
o.MediaStorageSOPInstanceUID,
|
// MediaStorageSOPInstanceUID:
|
||||||
MediaStorageSOPClassUID:
|
// o.MediaStorageSOPInstanceUID,
|
||||||
o.MediaStorageSOPClassUID,
|
// MediaStorageSOPClassUID:
|
||||||
sopInstanceUid: o.instanceUid,
|
// o.MediaStorageSOPClassUID,
|
||||||
instanceNumber: o.instanceNumber,
|
// sopInstanceUid: o.instanceUid,
|
||||||
instanceTime: o.instanceTime,
|
// instanceNumber: o.instanceNumber,
|
||||||
imageRows: o.imageRows,
|
// instanceTime: o.instanceTime,
|
||||||
imageColumns: o.imageColumns,
|
// imageRows: o.imageRows,
|
||||||
sliceLocation: o.sliceLocation,
|
// imageColumns: o.imageColumns,
|
||||||
sliceThickness: o.sliceThickness,
|
// sliceLocation: o.sliceLocation,
|
||||||
numberOfFrames: o.numberOfFrames,
|
// sliceThickness: o.sliceThickness,
|
||||||
pixelSpacing: o.pixelSpacing,
|
// numberOfFrames: o.numberOfFrames,
|
||||||
imagerPixelSpacing: o.imagerPixelSpacing,
|
// pixelSpacing: o.pixelSpacing,
|
||||||
frameOfReferenceUID: o.frameOfReferenceUID,
|
// imagerPixelSpacing: o.imagerPixelSpacing,
|
||||||
windowCenter: o.windowCenter,
|
// frameOfReferenceUID: o.frameOfReferenceUID,
|
||||||
windowWidth: o.windowWidth,
|
// windowCenter: o.windowCenter,
|
||||||
path: o.myPath,
|
// windowWidth: o.windowWidth,
|
||||||
FileSize: o.FileSize,
|
// path: o.myPath,
|
||||||
|
// FileSize: o.FileSize,
|
||||||
|
|
||||||
PhotometricInterpretation:
|
// PhotometricInterpretation:
|
||||||
o.PhotometricInterpretation,
|
// o.PhotometricInterpretation,
|
||||||
BitsAllocated: o.BitsAllocated,
|
// BitsAllocated: o.BitsAllocated,
|
||||||
PixelRepresentation: o.PixelRepresentation,
|
// PixelRepresentation: o.PixelRepresentation,
|
||||||
RescaleIntercept: o.RescaleIntercept,
|
// RescaleIntercept: o.RescaleIntercept,
|
||||||
RescaleSlope: o.RescaleSlope,
|
// RescaleSlope: o.RescaleSlope,
|
||||||
ImagePositionPatient: o.ImagePositionPatient,
|
// ImagePositionPatient: o.ImagePositionPatient,
|
||||||
ImageOrientationPatient:
|
// ImageOrientationPatient:
|
||||||
o.ImageOrientationPatient,
|
// o.ImageOrientationPatient,
|
||||||
SequenceOfUltrasoundRegions:
|
// SequenceOfUltrasoundRegions:
|
||||||
o.SequenceOfUltrasoundRegions,
|
// o.SequenceOfUltrasoundRegions,
|
||||||
FrameTime: o.FrameTime,
|
// FrameTime: o.FrameTime,
|
||||||
CorrectedImage: o.CorrectedImage,
|
// CorrectedImage: o.CorrectedImage,
|
||||||
Units: o.Units,
|
// Units: o.Units,
|
||||||
DecayCorrection: o.DecayCorrection,
|
// DecayCorrection: o.DecayCorrection,
|
||||||
EncapsulatedDocument: o.EncapsulatedDocument,
|
// EncapsulatedDocument: o.EncapsulatedDocument,
|
||||||
})
|
// })
|
||||||
Record.Uploaded.push(name)
|
// Record.Uploaded.push(name)
|
||||||
dicomInfo.failedFileCount++
|
// dicomInfo.failedFileCount++
|
||||||
Record.FileCount++
|
// Record.FileCount++
|
||||||
} else {
|
// }
|
||||||
|
// else {
|
||||||
let path = `/${params.trialId}/Image/${params.subjectId
|
let path = `/${params.trialId}/Image/${params.subjectId
|
||||||
}/${params.subjectVisitId}/${dicomInfo.studyUid
|
}/${params.subjectVisitId}/${dicomInfo.studyUid
|
||||||
}/${scope.getGuid(
|
}/${scope.getGuid(
|
||||||
@@ -1712,7 +1737,7 @@ export default {
|
|||||||
}
|
}
|
||||||
if (res && res.url) {
|
if (res && res.url) {
|
||||||
instanceList.push({
|
instanceList.push({
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
seriesInstanceUid: v.seriesUid,
|
seriesInstanceUid: v.seriesUid,
|
||||||
SOPClassUID: o.SOPClassUID,
|
SOPClassUID: o.SOPClassUID,
|
||||||
TransferSytaxUID: o.TransferSytaxUID,
|
TransferSytaxUID: o.TransferSytaxUID,
|
||||||
@@ -1761,7 +1786,7 @@ export default {
|
|||||||
Record.Failed.push(name)
|
Record.Failed.push(name)
|
||||||
Record.FileCount++
|
Record.FileCount++
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
resolve1()
|
resolve1()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
@@ -1779,7 +1804,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
params.study.seriesList.push({
|
params.study.seriesList.push({
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
seriesInstanceUid: v.seriesUid,
|
seriesInstanceUid: v.seriesUid,
|
||||||
seriesNumber: v.seriesNumber,
|
seriesNumber: v.seriesNumber,
|
||||||
seriesTime: v.seriesTime,
|
seriesTime: v.seriesTime,
|
||||||
|
|||||||
@@ -300,19 +300,7 @@
|
|||||||
<!-- 审核完成时间 -->
|
<!-- 审核完成时间 -->
|
||||||
<el-table-column prop="AuditTime" :label="$t('trials:crcUpload:table:auditTime')" show-overflow-tooltip
|
<el-table-column prop="AuditTime" :label="$t('trials:crcUpload:table:auditTime')" show-overflow-tooltip
|
||||||
width="170" />
|
width="170" />
|
||||||
<el-table-column v-if="
|
<el-table-column :label="$t('common:action:action')" width="250" fixed="right">
|
||||||
hasPermi(
|
|
||||||
[
|
|
||||||
'trials:trials-panel:visit:crc-upload:upload',
|
|
||||||
'trials:trials-panel:visit:crc-upload:submit',
|
|
||||||
'trials:trials-panel:visit:crc-upload:edit',
|
|
||||||
'trials:trials-panel:visit:crc-upload:delete',
|
|
||||||
'trials:trials-panel:visit:crc-upload:back',
|
|
||||||
'trials:trials-panel:visit:crc-upload:authBack'
|
|
||||||
],
|
|
||||||
'||'
|
|
||||||
)
|
|
||||||
" :label="$t('common:action:action')" width="250" fixed="right">
|
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<!-- 上传 -->
|
<!-- 上传 -->
|
||||||
<el-button v-hasPermi="['trials:trials-panel:visit:crc-upload:upload']" icon="el-icon-upload2" :disabled="!isOCTorIVUS && (scope.row.SubmitState * 1 === 2 ||
|
<el-button v-hasPermi="['trials:trials-panel:visit:crc-upload:upload']" icon="el-icon-upload2" :disabled="!isOCTorIVUS && (scope.row.SubmitState * 1 === 2 ||
|
||||||
@@ -320,10 +308,8 @@
|
|||||||
scope.row.IsLostVisit || (scope.row.IsSubjectQuit && scope.row.SubmitState * 1 !== 2))
|
scope.row.IsLostVisit || (scope.row.IsSubjectQuit && scope.row.SubmitState * 1 !== 2))
|
||||||
" circle :title="$t('trials:crcUpload:action:upload')" @click="CRChandleUpload(scope.row)" />
|
" circle :title="$t('trials:crcUpload:action:upload')" @click="CRChandleUpload(scope.row)" />
|
||||||
<!-- 上传2 -->
|
<!-- 上传2 -->
|
||||||
<el-button icon="el-icon-upload2" v-hasPermi="['trials:trials-panel:visit:crc-upload:upload2']" :disabled="!isOCTorIVUS && (scope.row.SubmitState * 1 === 2 ||
|
<el-button icon="el-icon-upload2"
|
||||||
scope.row.VisitExecuted === 2 ||
|
circle :title="$t('trials:crcUpload:action:upload')" @click="CRChandleUpload2(scope.row)" />
|
||||||
scope.row.IsLostVisit || (scope.row.IsSubjectQuit && scope.row.SubmitState * 1 !== 2))
|
|
||||||
" circle :title="$t('trials:crcUpload:action:upload')" @click="CRChandleUpload2(scope.row)" />
|
|
||||||
<!-- 提交 -->
|
<!-- 提交 -->
|
||||||
<el-button v-hasPermi="['trials:trials-panel:visit:crc-upload:submit']" icon="el-icon-check" :disabled="scope.row.AuditState * 1 > 0 ||
|
<el-button v-hasPermi="['trials:trials-panel:visit:crc-upload:submit']" icon="el-icon-check" :disabled="scope.row.AuditState * 1 > 0 ||
|
||||||
scope.row.SubmitState * 1 !== 1 ||
|
scope.row.SubmitState * 1 !== 1 ||
|
||||||
|
|||||||
@@ -644,7 +644,7 @@
|
|||||||
<el-input v-model="studyForm.Modalities" disabled />
|
<el-input v-model="studyForm.Modalities" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 检查类型 -->
|
<!-- 检查类型 -->
|
||||||
<el-form-item v-else :label="$t('trials:audit:table:modality')" prop="Modality" :rules="[
|
<el-form-item v-else :label="$t('trials:audit:table:modality')" prop="Modalities" :rules="[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: $t('common:ruleMessage:specify'),
|
message: $t('common:ruleMessage:specify'),
|
||||||
|
|||||||
+2
-9
@@ -52,7 +52,7 @@ module.exports = defineConfig({
|
|||||||
},
|
},
|
||||||
|
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'http://106.14.89.110:30000',
|
target: 'http://192.168.3.99:6100',
|
||||||
// target: 'http://101.132.253.119:7010', // uat
|
// target: 'http://101.132.253.119:7010', // uat
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
secure: false,
|
secure: false,
|
||||||
@@ -135,18 +135,11 @@ module.exports = defineConfig({
|
|||||||
test: /\.wasm$/,
|
test: /\.wasm$/,
|
||||||
type: 'asset/resource'
|
type: 'asset/resource'
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
exprContextCritical: false,
|
|
||||||
},
|
},
|
||||||
optimization: {
|
optimization: {
|
||||||
splitChunks: {
|
splitChunks: {
|
||||||
chunks: 'all',
|
chunks: 'all',
|
||||||
minSize: 30000, //字节 引入的文件大于30kb才进行分割
|
|
||||||
maxSize: 5000000, //50kb,尝试将大于50kb的文件拆分成n个50kb的文件
|
|
||||||
minChunks: 1, //模块至少使用次数
|
|
||||||
maxAsyncRequests: 30, //同时加载的模块数量最多是5个,只分割出同时引入的前5个文件
|
|
||||||
maxInitialRequests: 30, //首页加载的时候引入的文件最多3个
|
|
||||||
automaticNameDelimiter: '_', //缓存组和生成文件名称之间的连接符
|
|
||||||
cacheGroups: {
|
cacheGroups: {
|
||||||
libs: { // 第三方库
|
libs: { // 第三方库
|
||||||
name: 'chunk-libs',
|
name: 'chunk-libs',
|
||||||
|
|||||||
Reference in New Issue
Block a user