部分问题修复
continuous-integration/drone/push Build encountered an error Details

uat
wangxiaoshuang 2025-07-16 16:58:38 +08:00
parent 33a8d8743e
commit f8b4dd70c8
8 changed files with 148 additions and 201 deletions

View File

@ -245,13 +245,13 @@ export default {
if (this.IsDicom) {
var token = getToken()
routeData = this.$router.resolve({
path: `/showdicom?studyId=${row.Id}&TokenKey=${token}&type=Study&visitTaskId=${this.visitTaskId}`,
path: `/showdicom?studyId=${row.Id}&TokenKey=${token}&type=Study&visitTaskId=${this.visitTaskId}&isReading=true`,
})
} else {
let trialId = this.$route.query.trialId
var token = getToken()
routeData = this.$router.resolve({
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${row.SourceSubjectVisitId}&studyId=${row.Id}&TokenKey=${token}`,
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${row.SourceSubjectVisitId}&studyId=${row.Id}&TokenKey=${token}&isReading=true`,
})
}
window.open(routeData.href, '_blank')

View File

@ -110,7 +110,8 @@ let timer = null, // 网速定时器
// 获取网速
export function getNetWorkSpeed() {
if (timer) return false;
if (lastPercentage < 100) return false;
// if (lastPercentage < 100) return false;
if (imageId && imageId !== Id) return false
imageId = null
timer = setInterval(() => {
let timeList = Object.keys(bytesReceivedPerSecond).sort((a, b) => a - b);
@ -135,8 +136,9 @@ export function setNetWorkSpeedSize(totalPercentage, total, Id) {
if (imageId && imageId !== Id) return false
imageId = Id
let percentage = totalPercentage - lastPercentage
percentage = percentage / 100
lastPercentage = totalPercentage
console.log(percentage, totalPercentage, total)
// console.log(percentage, totalPercentage, total)
let time = new Date().getTime();
let timeList = Object.keys(bytesReceivedPerSecond).sort((a, b) => a - b);
let bytesTime = timeList.find(item => time - item < 1000);
@ -156,6 +158,7 @@ export function workSpeedclose(isForce = false) {
if (!isForce && lastPercentage < 100) {
return false
}
console.log('workSpeedclose')
if (timer) {
clearInterval(timer);
timer = null;

View File

@ -192,7 +192,8 @@ export default {
imageList: [],
showSeriesList: [],
currentLoadIns: [],
isFromCRCUpload: false
isFromCRCUpload: false,
isReading: null
}
},
created: function () {
@ -206,6 +207,9 @@ export default {
store.dispatch('user/setToken', this.$router.currentRoute.query.TokenKey)
changeURLStatic('TokenKey', '')
}
if (this.$router.currentRoute.query.isReading) {
this.isReading = this.$router.currentRoute.query.isReading
}
this.studyId = this.$router.currentRoute.query.studyId
this.isFromCRCUpload = !!this.$router.currentRoute.query.isFromCRCUpload
if (this.type === 'Series') {
@ -244,7 +248,8 @@ export default {
this.seriesCount = data.Result.SeriesCount
this.description = data.Result.Description
}
const url = `/series/list/${this.studyId}`
let isReading = !!this.isReading ? `?IsReading=true` : ''
const url = `/series/list/${this.studyId}${isReading}`
this.getSeriesList(url)
}
},

View File

@ -149,7 +149,7 @@
</div>
</div>
</el-tab-pane>
<el-tab-pane v-if="!visitTaskId" :label="$t('trials:dicom-show:relatedVisit')" name="relation-study"
<el-tab-pane v-show="!visitTaskId" :label="$t('trials:dicom-show:relatedVisit')" name="relation-study"
class="pane-relation-wrapper">
<div class="viewerSidethumbinner">
<el-collapse v-model="relationActiveName" @change="handelRelationActiveChange">
@ -171,66 +171,69 @@
<div v-show="study.Description" class="text-desc" style="background-color: #1f1f1f;">
{{ study.Description }}
</div>
<div v-if="study.seriesList" class="viewerSidethumbs ps" style="position: relative;">
<div class="viewerSidethumbs ps" style="position: relative;">
<div class="viewerSidethumbinner">
<div v-for="(seriesItem, index) in study.seriesList" :key="index"
class="viewernavigatorwrapper" style="position: relative;border:1px solid #434343;"
series-type="relation"
@click="showRelationSeriesImage($event, seriesItem, studyIndex, index)">
<div v-for="(seriesItem, index) in study.seriesList" :key="seriesItem.seriesId">
<div class="viewernavigatorwrapper" style="position: relative;border:1px solid #434343;"
series-type="relation"
@click="showRelationSeriesImage($event, seriesItem, studyIndex, index)">
<img class="image-preview" :src="seriesItem.previewImageUrl" crossorigin="anonymous"
alt="" style="width: 85px;height:85px;" fit="fill">
<div class="viewernavitextwrapper">
<div style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
<div v-if="seriesItem.keySeries" style="color:red">
Key Images
</div>
<div v-else>#{{ seriesItem.seriesNumber }}</div>
<div v-if="seriesItem.isExistMutiFrames && seriesItem.instanceCount > 1">
<el-popover placement="right-start" trigger="click"
popper-class="instance_frame_wrapper">
<div class="frame_list">
<div v-for="(instance, idx) in seriesItem.instanceInfoList" :key="instance.Id"
class="frame_content"
:style="{ 'margin-bottom': idx < seriesItem.instanceInfoList.length - 1 ? '5px' : '0px' }"
@click="showMultiFrames(studyIndex, seriesItem, index, instance)">
<div>
<div>{{ instance.InstanceNumber }}</div>
<div>{{ `${instance.NumberOfFrames > 0 ? instance.NumberOfFrames : 1} frame`
}}</div>
</div>
</div>
</div>
<i slot="reference" class="el-icon-connection"
style="font-size: 15px;cursor: pointer;" />
</el-popover>
</div>
</div>
<div v-show="seriesItem.instanceCount" style="padding: 1px;">
{{ seriesItem.modality }}: {{ seriesItem.instanceCount }} image
</div>
<div v-show="seriesItem.sliceThickness" style="padding: 1px;">
T: {{ seriesItem.sliceThickness }}
</div>
<el-tooltip v-show="seriesItem.description" class="item" effect="dark"
:content="seriesItem.description" placement="bottom">
<div v-show="seriesItem.description"
style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
{{ seriesItem.description }}
</div>
</el-tooltip>
</div>
</div>
<!-- <el-image
class="image-preview"
style="height:72px;width:72px;"
:src="seriesItem.previewImageUrl"
fit="fill"
/> -->
<img class="image-preview" :src="seriesItem.previewImageUrl" crossorigin="anonymous" alt=""
style="width: 85px;height:85px;" fit="fill">
<div class="viewernavitextwrapper">
<div style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
<div v-if="seriesItem.keySeries" style="color:red">
Key Images
</div>
<div v-else>#{{ seriesItem.seriesNumber }}</div>
<div v-if="seriesItem.isExistMutiFrames && seriesItem.instanceCount > 1">
<el-popover placement="right-start" trigger="click"
popper-class="instance_frame_wrapper">
<div class="frame_list">
<div v-for="(instance, idx) in seriesItem.instanceInfoList" :key="instance.Id"
class="frame_content"
:style="{ 'margin-bottom': idx < seriesItem.instanceInfoList.length - 1 ? '5px' : '0px' }"
@click="showMultiFrames(studyIndex, seriesItem, index, instance)">
<div>
<div>{{ instance.InstanceNumber }}</div>
<div>{{ `${instance.NumberOfFrames > 0 ? instance.NumberOfFrames : 1} frame`
}}</div>
</div>
</div>
</div>
<i slot="reference" class="el-icon-connection"
style="font-size: 15px;cursor: pointer;" />
</el-popover>
</div>
</div>
<div v-show="seriesItem.instanceCount" style="padding: 1px;">
{{ seriesItem.modality }}: {{ seriesItem.instanceCount }} image
</div>
<div v-show="seriesItem.sliceThickness" style="padding: 1px;">
T: {{ seriesItem.sliceThickness }}
</div>
<el-tooltip v-show="seriesItem.description" class="item" effect="dark"
:content="seriesItem.description" placement="bottom">
<div v-show="seriesItem.description"
style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
{{ seriesItem.description }}
</div>
</el-tooltip>
<div
v-if="seriesItem.prefetchInstanceCount > 0 && seriesItem.prefetchInstanceCount < seriesItem.instanceCount * 100">
<el-progress
:percentage="parseInt((seriesItem.prefetchInstanceCount / seriesItem.instanceCount).toFixed(2))" />
</div>
<!-- <div style="position: absolute;bottom: -10px;left: 0;width: 100%;">
<el-progress v-if="seriesItem.prefetchInstanceCount>0 && seriesItem.prefetchInstanceCount<seriesItem.instanceCount" :percentage="Number(seriesItem.prefetchInstanceCount/seriesItem.instanceCount)*100" />
</div> -->
</div>
</div>
</div>
@ -303,7 +306,8 @@ export default {
currentLoadIns: [],
isFromCRCUpload: false,
visitTaskId: null,
page: ''
page: '',
activeSeriesId: null
}
},
mounted() {
@ -435,6 +439,8 @@ export default {
}
},
showSeriesImage(e, studyIndex, seriesIndex, series) {
this.activeSeriesId = series.seriesId
workSpeedclose(true)
const element = e.currentTarget
const elements = document.querySelectorAll('[series-type]')
Array.from(elements).forEach((e) => {
@ -725,9 +731,15 @@ export default {
item.InstanceInfoList.forEach(i => {
if (i.NumberOfFrames && i.NumberOfFrames > 1) {
for (let j = 0; j < i.NumberOfFrames; j++) {
if (!i.ImageId) {
i.ImageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${i.Path}?frame=${j}&instanceId=${i.Id}&idx=${index}|${seriesIndex}&isRelation=1`
}
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${i.Path}?frame=${j}&instanceId=${i.Id}&idx=${index}|${seriesIndex}&isRelation=1`)
}
} else {
if (!i.ImageId) {
i.ImageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${i.Path}?instanceId=${i.Id}&idx=${index}|${seriesIndex}&isRelation=1`
}
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${i.Path}?instanceId=${i.Id}&idx=${index}|${seriesIndex}&isRelation=1`)
}
})
@ -751,9 +763,12 @@ export default {
isShowPopper: false
})
})
scope.relationStudyList[index].seriesCount = seriesList.length
scope.relationStudyList[index].seriesList = seriesList
scope.relationStudyList[index].showSeries = true
// scope.relationStudyList[index].seriesCount = seriesList.length
// scope.relationStudyList[index].seriesList = seriesList
// scope.relationStudyList[index].showSeries = true
scope.$set(scope.relationStudyList[index], 'seriesCount', seriesList.length)
scope.$set(scope.relationStudyList[index], 'seriesList', seriesList)
scope.$set(scope.relationStudyList[index], 'showSeries', true)
scope.$forceUpdate()
}
} catch (e) {
@ -762,6 +777,8 @@ export default {
}
},
showRelationSeriesImage(e, series, studyIndex, index) {
this.activeSeriesId = series.seriesId
workSpeedclose(true)
this.currentRelationIndex = index
const element = e.currentTarget
const elements = document.querySelectorAll('[series-type]')
@ -840,8 +857,11 @@ export default {
}
const studyIndex = params.idx.split('|')[0]
const seriesIndex = params.idx.split('|')[1]
var series = !params.isRelation ? this.studyList[studyIndex].SeriesList[seriesIndex] : null
var series = !params.isRelation ? this.studyList[studyIndex].SeriesList[seriesIndex] : this.relationStudyList[studyIndex].seriesList[seriesIndex]
if (!series) return
if (!this.activeSeriesId) {
this.activeSeriesId = series.seriesId
}
var prefetchInstanceCount = series.prefetchInstanceCount
var instanceCount = series.instanceCount
if (series.imageloadedArr.indexOf(imageId) < 0) {
@ -863,8 +883,8 @@ export default {
series.imageloadedArr.push(imageId)
}
}
let file = this.studyList[studyIndex].SeriesList[seriesIndex].instanceInfoList.find(item => item.ImageId === imageId)
if (file) {
let file = series.instanceInfoList.find(item => item.ImageId === imageId)
if (file && this.activeSeriesId === series.seriesId) {
getNetWorkSpeed()
setNetWorkSpeedSize(percentComplete, file.FileSize, imageId)
}

View File

@ -1,139 +1,68 @@
<template>
<el-form
ref="questionForm"
v-loading="loading"
:model="form"
label-width="120px"
size="small"
:rules="rules"
>
<el-form ref="questionForm" v-loading="loading" :model="form" label-width="120px" size="small" :rules="rules">
<div class="base-dialog-body">
<!-- 审核问题 -->
<el-form-item
:label="$t('trials:qcCfg:table:questionName')"
prop="QuestionName"
>
<el-input
v-model="form.QuestionName"
/>
<el-form-item :label="$t('trials:qcCfg:table:questionName')" prop="QuestionName">
<el-input v-model="form.QuestionName" :disabled="data.IsQuestionQCAuditPassed" />
</el-form-item>
<!-- <el-form-item-->
<!-- :label="$t('common:title:languageType')"-->
<!-- prop="LanguageType"-->
<!-- >-->
<!-- <el-select-->
<!-- v-model="form.LanguageType"-->
<!-- >-->
<!-- <el-option-->
<!-- v-for="item of $d.LanguageType"-->
<!-- :key="item.value"-->
<!-- :value="item.value"-->
<!-- :label="item.label"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- <el-form-item-->
<!-- :label="$t('common:title:languageType')"-->
<!-- prop="LanguageType"-->
<!-- >-->
<!-- <el-select-->
<!-- v-model="form.LanguageType"-->
<!-- >-->
<!-- <el-option-->
<!-- v-for="item of $d.LanguageType"-->
<!-- :key="item.value"-->
<!-- :value="item.value"-->
<!-- :label="item.label"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- 类型 -->
<el-form-item
:label="$t('trials:qcCfg:table:type')"
>
<el-select
v-model="form.Type"
@change="((val)=>{typeChange(val, form)})"
>
<el-option
v-for="item of $d.QcType"
:key="item.value"
:value="item.value"
:label="item.label"
/>
<el-form-item :label="$t('trials:qcCfg:table:type')">
<el-select v-model="form.Type" @change="((val) => { typeChange(val, form) })"
:disabled="data.IsQuestionQCAuditPassed">
<el-option v-for="item of $d.QcType" :key="item.value" :value="item.value" :label="item.label" />
</el-select>
</el-form-item>
<!-- 选项 -->
<el-form-item
v-if="form.Type === 'select' || form.Type === 'radio'"
:label="$t('trials:qcCfg:table:typeValue')"
prop="TypeValue"
>
<el-input
v-model="form.TypeValue"
:placeholder="$t('trials:qcCfg:message:typeValue')"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
/>
<el-form-item v-if="form.Type === 'select' || form.Type === 'radio'" :label="$t('trials:qcCfg:table:typeValue')"
prop="TypeValue">
<el-input v-model="form.TypeValue" :placeholder="$t('trials:qcCfg:message:typeValue')" type="textarea"
:autosize="{ minRows: 2, maxRows: 4 }" :disabled="data.IsQuestionQCAuditPassed" />
</el-form-item>
<!-- 父问题 -->
<el-form-item
:label="$t('trials:qcCfg:table:parentQs')"
>
<el-select
v-model="form.ParentId"
clearable
@change="((val)=>{parentQuestionChange(val, form)})"
>
<el-option
v-for="item of parentOptions"
:key="item.Id"
:label="item.QuestionName"
:value="item.Id"
/>
<el-form-item :label="$t('trials:qcCfg:table:parentQs')">
<el-select v-model="form.ParentId" clearable @change="((val) => { parentQuestionChange(val, form) })"
:disabled="data.IsQuestionQCAuditPassed">
<el-option v-for="item of parentOptions" :key="item.Id" :label="item.QuestionName" :value="item.Id" />
</el-select>
</el-form-item>
<!-- 父问题触发值 -->
<el-form-item
v-if="form.ParentId"
:label="$t('trials:qcCfg:table:parentTriggerValue')"
prop="ParentTriggerValue"
>
<el-select
v-model="form.ParentTriggerValue"
>
<el-option
v-for="item of parentTriggerValOptions"
:key="item"
:label="item"
:value="item"
/>
<el-form-item v-if="form.ParentId" :label="$t('trials:qcCfg:table:parentTriggerValue')" prop="ParentTriggerValue">
<el-select v-model="form.ParentTriggerValue" :disabled="data.IsQuestionQCAuditPassed">
<el-option v-for="item of parentTriggerValOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
<!-- 序号 -->
<el-form-item
:label="$t('trials:qcCfg:table:order')"
prop="ShowOrder"
>
<el-input-number
v-model="form.ShowOrder"
controls-position="right"
:min="0"
/>
<el-form-item :label="$t('trials:qcCfg:table:order')" prop="ShowOrder">
<el-input-number v-model="form.ShowOrder" controls-position="right" :min="0"
:disabled="data.IsQuestionQCAuditPassed" />
</el-form-item>
<!-- 是否必填 -->
<el-form-item
:label="$t('trials:qcCfg:table:isRequired')"
>
<el-radio-group
v-model="form.IsRequired"
>
<el-radio
v-for="item of $d.YesOrNo"
:key="`IsRequired${item.value}`"
:label="item.value"
>
<el-form-item :label="$t('trials:qcCfg:table:isRequired')">
<el-radio-group v-model="form.IsRequired">
<el-radio v-for="item of $d.YesOrNo" :key="`IsRequired${item.value}`" :label="item.value">
{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<!-- 启用状态 -->
<el-form-item
:label="$t('trials:qcCfg:table:isEnable')"
>
<el-radio-group
v-model="form.IsEnable"
>
<el-radio
v-for="item of $d.YesOrNo"
:key="item.value"
:label="item.value"
>
<el-form-item :label="$t('trials:qcCfg:table:isEnable')">
<el-radio-group v-model="form.IsEnable">
<el-radio v-for="item of $d.YesOrNo" :key="item.value" :label="item.value">
{{ item.label }}
</el-radio>
</el-radio-group>
@ -143,19 +72,11 @@
<div class="base-dialog-footer" style="text-align:right;margin-top:10px;">
<el-form-item style="text-align:right;">
<!-- 取消 -->
<el-button
size="small"
type="primary"
@click="handleClose"
>
<el-button size="small" type="primary" @click="handleClose">
{{ $t('common:button:cancel') }}
</el-button>
<!-- Save -->
<el-button
size="small"
type="primary"
@click="handleSave"
>
<el-button size="small" type="primary" @click="handleSave">
{{ $t('common:button:save') }}
</el-button>
</el-form-item>
@ -202,7 +123,7 @@ export default {
},
rules: {
QuestionName: [{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ max: 300, message: `${this.$t('common:ruleMessage:maxLength')} 300` }],
{ max: 300, message: `${this.$t('common:ruleMessage:maxLength')} 300` }],
TypeValue: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ validator: validateTypeVal, trigger: 'blur' },
@ -308,6 +229,4 @@ export default {
}
</script>
<style lang="scss">
</style>
<style lang="scss"></style>

View File

@ -135,8 +135,7 @@
:label="$t('common:action:action')" min-width="150">
<template slot-scope="scope">
<el-button v-hasPermi="['trials:trials-panel:setting:qc-question:edit']" circle
:title="$t('common:button:edit')" icon="el-icon-edit-outline" @click="handleEdit(scope.row)"
:disabled="scope.row.IsQuestionQCAuditPassed" />
:title="$t('common:button:edit')" icon="el-icon-edit-outline" @click="handleEdit(scope.row)" />
<el-button v-hasPermi="['trials:trials-panel:setting:qc-question:delete']" circle
:title="$t('common:button:delete')" icon="el-icon-delete" @click="handleDelete(scope.row)"
:disabled="scope.row.IsQuestionQCAuditPassed" />

View File

@ -1042,10 +1042,10 @@ export default {
this.isAudit = true
this.currentQCType = this.qType
} else {
this.currentQCType = this.data.AuditState < 6 ? 1 : 2
this.currentQCType = this.data.QCProcessEnum === 2 && this.data.PreliminaryAuditUserId ? 2 : 1
}
window.addEventListener('message', this.receiveMsg)
console.log(this.SecondReviewState, 'SecondReviewState')
this.trialId = this.$route.query.trialId
this.getQCInfo()
this.getDicData()
@ -2133,7 +2133,7 @@ export default {
var token = getToken()
const routeData = this.$router.resolve({
path: `/showvisitdicoms?trialId=${this.data.TrialId}&visitInfo=${this.data.VisitName
}(${this.data.VisitNum})&subjectVisitId=${this.data.Id}&showDelete=${this.isAudit ? 0 : 1
}(${this.data.VisitNum})&subjectVisitId=${this.data.Id}&showDelete=${this.isAudit || this.SecondReviewState > 0 ? 0 : 1
}&TokenKey=${token}`,
})
this.open = window.open(routeData.href, '_blank')
@ -2199,7 +2199,7 @@ export default {
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${this.data.Id}&TokenKey=${token}&isReading=1`,
})
: this.$router.resolve({
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${this.data.Id}&TokenKey=${token}&isQcCheck=1`,
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${this.data.Id}&TokenKey=${token}&isQcCheck=${this.SecondReviewState > 0 ? 0 : 1}`,
})
this.open = window.open(routeData.href, '_blank')
},
@ -2211,7 +2211,7 @@ export default {
let trialId = this.$route.query.trialId
var token = getToken()
const routeData = this.$router.resolve({
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${this.data.Id}&studyId=${row.Id}&TokenKey=${token}&isQcCheck=1`,
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${this.data.Id}&studyId=${row.Id}&TokenKey=${token}&isQcCheck=${this.SecondReviewState > 0 ? 0 : 1}`,
})
this.open = window.open(routeData.href, '_blank')
},

View File

@ -50,9 +50,10 @@ module.exports = defineConfig({
pathRewrite: {
}
},
// uat http://101.132.253.119:7010
'/api': {
target: 'http://106.14.89.110:30000',
// target: 'http://101.132.253.119:7010', // uat
changeOrigin: true,
secure: false,
pathRewrite: {