裁判规则及阅片更改

uat_us^2
caiyiling 2026-08-18 15:49:10 +08:00
parent e2b105cf39
commit 8c931a2cbb
5 changed files with 706 additions and 184 deletions

View File

@ -536,3 +536,11 @@ export function setTrialQuestionVisitJudgeRule(data) {
data
})
}
export function copyTrialQuestionVisitJudgeRule(data) {
return request({
url: `/ReadingQuestion/copyTrialQuestionVisitJudgeRule`,
method: 'post',
data
})
}

View File

@ -172,27 +172,28 @@
</template>
</el-table-column>
</el-table>
<el-table v-else :data="judgeAnswers" border style="width: 100%">
<el-table v-else :data="judgeAnswers" border style="width: 70%">
<!-- 问题名称 -->
<el-table-column
prop="QuestionName"
:label="$t('trials:readingTracking:config:questionName')"
show-overflow-tooltip
width="500"
min-width="600"
/>
<!-- R1 -->
<el-table-column
prop="R1Answer"
show-overflow-tooltip
width="150"
min-width="300"
>
<template slot="header">
{{ $t('trials:adReview:table:viewR1') }}
<span v-show="isReadingShowSubjectInfo" style="margin: 0 10px;">{{ taskBlindName }}</span>
<el-button
type="text"
class="judge-answer-header-btn"
@click.stop="handleViewDetail(r1VisitTaskId)"
>
R1
{{ $t('trials:adReview:table:view') }}
</el-button>
</template>
<template slot-scope="scope">
@ -211,15 +212,16 @@
<el-table-column
prop="R2Answer"
show-overflow-tooltip
width="150"
min-width="300"
>
<template slot="header">
{{ $t('trials:adReview:table:viewR2') }}
<span v-show="isReadingShowSubjectInfo" style="margin: 0 10px;">{{ taskBlindName }}</span>
<el-button
type="text"
class="judge-answer-header-btn"
@click.stop="handleViewDetail(r2VisitTaskId)"
>
R2
{{ $t('trials:adReview:table:view') }}
</el-button>
</template>
<template slot-scope="scope">
@ -382,105 +384,69 @@
ref="adForm2"
v-loading="loading"
:model="judgeForm"
style="width: 800px"
label-width="300px"
style="width: 70%"
>
<el-form-item
v-for="question in judgeQs"
:key="question.ReadingQuestionId"
:label="`${question.QuestionName}`"
:prop="question.ReadingQuestionId"
:rules="[{
required: true,
message: ['radio', 'select', 'checkbox'].includes(question.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']
}]"
<el-table
:data="judgeQs"
border
style="width: 100%; margin-bottom: 16px"
>
<div class="judge-form-row">
<div class="judge-form-control">
<el-input
v-if="question.Type === 'number'"
v-model="judgeForm[question.ReadingQuestionId]"
type="text"
:disabled="readingTaskState >= 2"
style="width: 200px;"
>
<template v-if="question.Unit !== 0" slot="append">
{{ question.Unit !== 4 ? $fd('ValueUnit', question.Unit) : question.CustomUnit }}
</template>
</el-input>
<el-radio-group
v-else-if="question.Type === 'radio'"
v-model="judgeForm[question.ReadingQuestionId]"
:disabled="readingTaskState >= 2"
>
<template v-if="question.DictionaryCode">
<el-radio v-for="val in $d[question.DictionaryCode]" :key="val.id" :label="String(val.value)">
{{ val.label }}
</el-radio>
</template>
<template v-else>
<el-radio v-for="val in question.TypeValue.split('|')" :key="val.trim()" :label="val.trim()">
{{ val.trim() }}
</el-radio>
</template>
</el-radio-group>
<el-select
v-else-if="question.Type === 'select'"
v-model="judgeForm[question.ReadingQuestionId]"
:disabled="readingTaskState >= 2"
>
<template
v-if="question.QuestionGenre === 2 && question.DictionaryCode"
<el-table-column
prop="QuestionName"
:label="$t('trials:readingTracking:config:questionName')"
show-overflow-tooltip
min-width="600"
/>
<el-table-column
prop="judgeResult"
:label="$t('trials:adReview:title:result')"
show-overflow-tooltip
min-width="300"
>
<template slot-scope="scope">
<div>
<span v-if="scope.row.DictionaryCode">
{{
$fd(
scope.row.DictionaryCode,
parseInt(judgeForm[scope.row.ReadingQuestionId])
)
}}
</span>
<span v-else>
{{ judgeForm[scope.row.ReadingQuestionId] }}
</span>
<span
v-if="scope.row.Unit && !isNaN(parseFloat(judgeForm[scope.row.ReadingQuestionId]))"
>
<el-option
v-for="item of $d[question.DictionaryCode]"
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template>
<template v-else>
<el-option
v-for="val in question.TypeValue.split('|')"
:key="val.trim()"
:label="val.trim()"
:value="val.trim()"
/>
</template>
</el-select>
<el-checkbox-group
v-else-if="question.Type === 'checkbox'"
v-model="judgeForm[question.ReadingQuestionId]"
{{ scope.row.Unit !== 4 ? $fd('ValueUnit', scope.row.Unit) : scope.row.CustomUnit }}
</span>
</div>
</template>
</el-table-column>
<el-table-column
prop="judgeSelect"
:label="$t('trials:adReview:title:select')"
show-overflow-tooltip
min-width="300"
v-show="readingTaskState < 2"
>
<template slot-scope="scope">
<el-radio-group
v-model="judgeSelectedArmMap[scope.row.ReadingQuestionId]"
:disabled="readingTaskState >= 2"
@change="(val) => handleJudgeArmChange(scope.row, val)"
>
<template v-if="question.DictionaryCode">
<el-checkbox v-for="item of $d[question.DictionaryCode]" :key="item.id" :label="String(item.value)">
{{ item.label }}
</el-checkbox>
</template>
<template v-else>
<el-checkbox v-for="val in question.TypeValue.split('|')" :key="val.trim()" :label="val.trim()">
{{ val.trim() }}
</el-checkbox>
</template>
</el-checkbox-group>
</div>
<div v-if="readingTaskState < 2" class="judge-form-actions">
<el-button
type="text"
@click="applyJudgeAnswer(question, 1)"
>
R1
</el-button>
<el-button
type="text"
@click="applyJudgeAnswer(question, 2)"
>
R2
</el-button>
</div>
</div>
</el-form-item>
<el-radio :label="1">
R1
</el-radio>
<el-radio :label="2">
R2
</el-radio>
</el-radio-group>
</template>
</el-table-column>
</el-table>
<el-form-item :label="$t('trials:adReview:title:adReason1')">
<el-input
@ -624,7 +590,8 @@ import {
// uploadJudgeTaskImage,
saveJudgeVisitTaskResult,
submitJudgeVisitTaskResult,
getReadingPastResultList
getReadingPastResultList,
getQuestionCalculateRelation
} from '@/api/trials'
import {
getSingleVisitJudgeAnswer,
@ -640,6 +607,7 @@ import SignForm from '@/views/trials/components/newSignForm'
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
// import store from '@/store'
import { changeURLStatic } from '@/utils/history.js'
import LengthTool from '../dicoms/tools/Length/LengthTool'
export default {
name: 'AdReview',
components: { SignForm },
@ -724,13 +692,17 @@ export default {
judgeForm: {
judgeResultRemark: ''
},
readingTaskState: taskInfo.ReadingTaskState || 2
judgeSelectedArmMap: {},
readingTaskState: taskInfo.ReadingTaskState || 2,
calculationList: [],
classArr: []
}
},
mounted() {
this.criterionType = parseInt(this.$route.query.criterionType)
if (this.taskInfo.JudgeModeEnum === 1) {
this.getVisitJudgeAnswer()
this.getQuestionCalculateRelation()
} else {
this.getAdInfo()
}
@ -851,7 +823,8 @@ export default {
}
})
}
this.judgeQs = QuestionList
this.judgeQs = QuestionList.filter(item => item.ShowQuestion === 0)
// this.judgeQs = QuestionList
this.$set(this.judgeForm, 'judgeResultRemark', res.Result.JudgeResultRemark || '')
QuestionList.map((item) => {
this.$set(
@ -859,6 +832,17 @@ export default {
item.ReadingQuestionId,
item.Answer
)
if (item.Type === 'class') {
this.classArr.push({ triggerId: item.ClassifyQuestionId, classId: item.ReadingQuestionId, classifyAlgorithms: item.ClassifyAlgorithms, classifyType: item.ClassifyType })
}
this.$set(this.judgeSelectedArmMap, item.ReadingQuestionId, null)
// if (item.Answer === this.getJudgeAnswerValue(item, 1)) {
// this.$set(this.judgeSelectedArmMap, item.ReadingQuestionId, 1)
// } else if (item.Answer === this.getJudgeAnswerValue(item, 2)) {
// this.$set(this.judgeSelectedArmMap, item.ReadingQuestionId, 2)
// } else {
// this.$set(this.judgeSelectedArmMap, item.ReadingQuestionId, '')
// }
})
}
} catch (e) {
@ -867,6 +851,293 @@ export default {
this.loading = false
}
},
async getQuestionCalculateRelation() {
try {
const res = await getQuestionCalculateRelation({ TrialReadingCriterionId: this.$route.query.TrialReadingCriterionId, IsGetJudge: true })
this.calculationList = res.Result
} catch (e) {
console.log(e)
}
},
handleJudgeArmChange(question, armEnum) {
this.$set(this.judgeSelectedArmMap, question.ReadingQuestionId, armEnum)
let val = this.getJudgeAnswerValue(question, armEnum)
this.$set(
this.judgeForm,
question.ReadingQuestionId,
val
)
//
this.classArr.map(i => {
if (i.triggerId === question.ReadingQuestionId) {
let answer = null
const list = JSON.parse(i.classifyAlgorithms)
if (i.classifyType === 0) {
const o = list.find(v => {
return (
parseFloat(val) >= parseFloat(v.gt) &&
parseFloat(val) < parseFloat(v.lt)
)
})
answer = o ? o.label : null
} else if (i.classifyType === 1) {
const o = list.find(v => {
return v.val.includes(val)
})
answer = o ? o.label : null
}
this.$set(this.judgeForm, i.classId, answer)
}
})
//
this.calculationList.forEach(v => {
let find = v.CalculateQuestionList.filter(o => {
return o.TableQuestionId === question.ReadingQuestionId
})
// findnumber
if (find) {
var num = this.logic(v)
if (num !== false) {
this.$set(this.judgeForm, v.QuestionId, num)
}
}
})
},
logic(rules, num = 0) {
let isNE = false, isNAN = false
try {
if (rules.CalculateQuestionList.length === 0) {
return false
}
let dataArr = []
rules.CalculateQuestionList.forEach((o, i) => {
if (i === 0) {
if (rules.CustomCalculateMark > 4 && rules.CustomCalculateMark < 10) {
switch (rules.CustomCalculateMark) {
case 5:
this.judgeForm[o.QuestionId].forEach((q, qi) => {
if (!isNaN(parseFloat(q[o.TableQuestionId]))) {
if (qi === 0) {
num = parseFloat(q[o.TableQuestionId])
} else {
num *= parseFloat(q[o.TableQuestionId])
}
} else {
isNAN = true
}
if (q[o.TableQuestionId] === 'NE') {
isNE = true
}
})
break;
case 6:
this.judgeForm[o.QuestionId].forEach((q, qi) => {
if (!isNaN(parseFloat(q[o.TableQuestionId]))) {
if (qi === 0) {
num = parseFloat(q[o.TableQuestionId])
} else {
num += parseFloat(q[o.TableQuestionId])
}
} else {
isNAN = true
}
if (q[o.TableQuestionId] === 'NE') {
isNE = true
}
})
break;
case 7:
this.judgeForm[o.QuestionId].forEach((q, qi) => {
if (!isNaN(parseFloat(q[o.TableQuestionId]))) {
if (qi === 0) {
num = parseFloat(q[o.TableQuestionId])
} else {
num += parseFloat(q[o.TableQuestionId])
}
} else {
isNAN = true
}
if (q[o.TableQuestionId] === 'NE') {
isNE = true
}
})
num = this.judgeForm[o.QuestionId].length === 0 ? 0 : num / this.judgeForm[o.QuestionId].length
break;
case 8:
var arr = []
this.judgeForm[o.QuestionId].forEach(q => {
if (!isNaN(parseFloat(q[o.TableQuestionId]))) {
arr.push(q[o.TableQuestionId])
} else {
isNAN = true
}
if (q[o.TableQuestionId] === 'NE') {
isNE = true
}
})
num = arr.length === 0 ? 0 : Math.max(...arr)
break;
case 9:
var arr = []
this.judgeForm[o.QuestionId].forEach(q => {
if (!isNaN(parseFloat(q[o.TableQuestionId]))) {
arr.push(q[o.TableQuestionId])
} else {
isNAN = true
}
if (q[o.TableQuestionId] === 'NE') {
isNE = true
}
})
num = arr.length === 0 ? 0 : Math.min(...arr)
break;
}
} else {
switch (rules.CustomCalculateMark) {
case 15:
if (!isNaN(parseFloat(this.judgeForm[o.TableQuestionId]))) {
num = Math.abs(this.judgeForm[o.TableQuestionId])
}
else {
isNAN = true
}
if (this.judgeForm[o.TableQuestionId] === 'NE') {
isNE = true
}
break;
default:
if (this.judgeForm[o.TableQuestionId] === 'NE') {
isNE = true
}
if (!isNaN(parseFloat(this.judgeForm[o.TableQuestionId]))) {
num = parseFloat(this.judgeForm[o.TableQuestionId])
} else {
isNAN = true
}
if (!isNaN(num)) {
dataArr.push(num)
}
break;
}
}
} else {
if (this.judgeForm[o.TableQuestionId] === 'NE') {
isNE = true
}
switch (rules.CustomCalculateMark) {
case 1:
if (!isNaN(parseFloat(this.judgeForm[o.TableQuestionId]))) {
num += parseFloat(this.judgeForm[o.TableQuestionId])
} else {
isNAN = true
}
break;
case 2:
if (!isNaN(parseFloat(this.judgeForm[o.TableQuestionId]))) {
num -= parseFloat(this.judgeForm[o.TableQuestionId])
} else {
isNAN = true
}
break;
case 3:
if (!isNaN(parseFloat(this.judgeForm[o.TableQuestionId]))) {
num *= parseFloat(this.judgeForm[o.TableQuestionId])
} else {
isNAN = true
}
break;
case 4:
if (!isNaN(parseFloat(this.judgeForm[o.TableQuestionId]))) {
if (parseFloat(this.judgeForm[o.TableQuestionId]) === 0) {
num = 0
} else {
num /= parseFloat(this.judgeForm[o.TableQuestionId])
}
} else {
isNAN = true
}
break;
case 10:
if (!isNaN(parseFloat(this.judgeForm[o.TableQuestionId]))) {
dataArr.push(parseFloat(this.judgeForm[o.TableQuestionId]))
} else {
isNAN = true
}
num = dataArr.length === 0 ? 0 : dataArr.reduce((acc, curr) => {
return acc + (typeof curr === "number" ? curr : 0);
}, 0) / dataArr.length;
break;
case 11:
if (!isNaN(parseFloat(this.judgeForm[o.TableQuestionId]))) {
dataArr.push(parseFloat(this.judgeForm[o.TableQuestionId]))
} else {
isNAN = true
}
num = Math.max(...dataArr);
break;
case 12:
if (!isNaN(parseFloat(this.judgeForm[o.TableQuestionId]))) {
dataArr.push(parseFloat(this.judgeForm[o.TableQuestionId]))
} else {
isNAN = true
}
num = Math.min(...dataArr);
break;
case 13:
if (!isNaN(parseFloat(this.judgeForm[o.TableQuestionId]))) {
dataArr.push(parseFloat(this.judgeForm[o.TableQuestionId]))
} else {
isNAN = true
}
num = dataArr.length === 0 ? 0 : dataArr.reduce((acc, curr) => acc && curr) ? 1 : 0
break;
case 14:
if (!isNaN(parseFloat(this.judgeForm[o.TableQuestionId]))) {
dataArr.push(parseFloat(this.judgeForm[o.TableQuestionId]))
} else {
isNAN = true
}
num = dataArr.length === 0 ? 0 : dataArr.reduce((acc, curr) => acc || curr, 0) ? 1 : 0;
break;
case 15:
if (!isNaN(parseFloat(this.judgeForm[o.TableQuestionId]))) {
num = Math.abs(this.judgeForm[o.TableQuestionId])
}
else {
isNAN = true
}
break;
}
}
})
} catch (e) {
console.log(e)
}
if (isNE) {
return 'NE'
}
if (isNAN) {
return null
}
if (rules.ValueType === 2) {
num = num * 100
}
if (rules.CustomCalculateMark === 13 || rules.CustomCalculateMark === 14) {
return num
} else {
return num.toFixed(this.digitPlaces)
}
},
getJudgeAnswerValue(question, armEnum) {
const row = this.judgeAnswers.find((item) => {
return item.ReadingQuestionId === question.ReadingQuestionId
@ -874,27 +1145,17 @@ export default {
if (!row) return null
return armEnum === 1 ? row.R1Answer : row.R2Answer
},
applyJudgeAnswer(question, armEnum) {
const answer = this.getJudgeAnswerValue(question, armEnum)
this.$set(
this.judgeForm,
question.ReadingQuestionId,
answer
)
if (this.$refs.adForm2) {
this.$refs.adForm2.clearValidate(question.ReadingQuestionId)
}
},
applyAllJudgeAnswers(armEnum) {
const props = []
this.judgeQs.forEach((question) => {
const answer = this.getJudgeAnswerValue(question, armEnum)
this.$set(this.judgeForm, question.ReadingQuestionId, answer)
props.push(question.ReadingQuestionId)
validateJudgeSelections() {
const missingQuestion = this.judgeQs.find((question) => {
const answer = this.judgeForm[question.ReadingQuestionId]
return answer === '' || answer === null || answer === undefined
})
if (this.$refs.adForm2 && props.length > 0) {
this.$refs.adForm2.clearValidate(props)
if (missingQuestion) {
let msg = this.$t('trials:ad-review:msg:validMsg').replace('xxx', missingQuestion.QuestionName)
this.$message.error(msg)
return false
}
return true
},
async getPriorAdList() {
this.priorLoading = true
@ -995,10 +1256,16 @@ export default {
if (this.taskInfo.JudgeModeEnum === 1) {
// 访
const qsList = this.judgeQs.map((question) => ({
readingQuestionId: question.ReadingQuestionId,
answer: this.judgeForm[question.ReadingQuestionId]
}))
const qsList = []
let reg = new RegExp(/^[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}$/)
Object.keys(this.judgeForm).forEach(key => {
if (reg.test(key)) {
qsList.push({
readingQuestionId: key,
answer: this.judgeForm[key]
})
}
})
const params = {
data: {
visitTaskId: this.visitTaskId,
@ -1091,12 +1358,18 @@ export default {
this.submitLockAction = 'save'
this.loading = true
try {
const valid = await this.$refs.adForm2.validate()
const valid = this.validateJudgeSelections()
if (!valid) return false
const qsList = this.judgeQs.map((question) => ({
readingQuestionId: question.ReadingQuestionId,
answer: this.judgeForm[question.ReadingQuestionId]
}))
const qsList = []
let reg = new RegExp(/^[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}$/)
Object.keys(this.judgeForm).forEach(key => {
if (reg.test(key)) {
qsList.push({
readingQuestionId: key,
answer: this.judgeForm[key]
})
}
})
const paths = this.fileList.reduce((acc, file) => {
if (file.url) acc.push(file.url)
return acc
@ -1121,7 +1394,7 @@ export default {
if (this.submitLockAction) return false
this.submitLockAction = 'submit'
try {
const valid = await this.$refs['adForm2'].validate()
const valid = this.validateJudgeSelections()
if (!valid) return false
const { ImageAssessmentReportConfirmation } = const_.processSignature
this.signCode = ImageAssessmentReportConfirmation
@ -1221,21 +1494,6 @@ export default {
var routeData = this.$router.resolve({ path })
this.openWindow = window.open(routeData.href, '_blank')
},
// uploadScreenshot(param) {
// this.loading = true
// this.uploadDisabled = false
// const formData = new FormData()
// formData.append('file', param.file)
// uploadJudgeTaskImage(this.$route.query.trialId, this.visitTaskId, formData).then(res => {
// this.loading = false
// if (res.IsSuccess) {
// this.fileList.push({ name: res.Result.FileName, url: `${res.Result.Path}` })
// }
// this.uploadDisabled = true
// }).catch(() => {
// this.loading = false
// })
// },
async uploadScreenshot(param) {
this.loading = true
this.uploadDisabled = false
@ -1337,17 +1595,6 @@ export default {
margin: 10px 0;
}
.judge-form-row {
display: grid;
grid-template-columns: 250px 72px;
column-gap: 12px;
align-items: flex-start;
}
.judge-form-control {
min-width: 0;
}
.judge-remark-tip {
margin-bottom: 8px;
color: #606266;
@ -1369,9 +1616,15 @@ export default {
white-space: nowrap;
}
.judge-answer-header-btn {
padding: 0;
font-weight: 600;
.judge-select-radio-group {
display: flex;
gap: 16px;
}
.judge-answer-text {
min-width: 0;
line-height: 20px;
word-break: break-word;
}
.disabled {

View File

@ -424,7 +424,7 @@ export default {
async initData() {
await this.getTrialJudgyInfo()
if (this.judgeRuleEnum !== 1) {
await this.getList()
await this.getList(false)
}
},
//
@ -452,7 +452,8 @@ export default {
},
saveAllSync() {
if (this.judgeRuleEnum === 1 && this.$refs.visitRules) {
return this.$refs.visitRules.saveAllSync()
return Promise.resolve(true)
// return this.$refs.visitRules.saveAllSync()
}
return new Promise((resolve) => {
var arr = []
@ -582,7 +583,7 @@ export default {
await this.$refs.visitRules.initData()
}
} else {
await this.getList()
await this.getList(false)
}
}
}
@ -758,11 +759,14 @@ export default {
this.ReadingQuestionCriterionTrialId =
this.CriterionList[this.index].ReadingQuestionCriterionTrialId
},
getList() {
async getList(needGetTrialJudgyInfo = true) {
this.loading = true
if (needGetTrialJudgyInfo) {
await this.getTrialJudgyInfo()
}
if (this.judgeRuleEnum === 1 && this.$refs.visitRules) {
return this.$refs.visitRules.getList()
}
this.loading = true
return getTrialCriterionJudgeQuestionList({
TrialId: this.$route.query.trialId,
TrialReadingCriterionId: this.trialReadingCriterionId,

View File

@ -3,6 +3,29 @@
<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>
</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"
@ -140,13 +163,13 @@
<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="itemA" closable
: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="itemA" closable
:key="visit.Id+indexA" closable
style="margin-right: 10px" @close="() => visitTagClose2(index, indexA, visit.Id)">
{{
itemA
@ -262,6 +285,50 @@
</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>
@ -269,6 +336,7 @@
import {
getTrialQuestionVisitJudgeRule,
setTrialQuestionVisitJudgeRule,
copyTrialQuestionVisitJudgeRule,
} from '@/api/trials/reading'
import { getTrialVisitStageSelect } from '@/api/trials'
@ -292,6 +360,9 @@ export default {
questionListMap: {},
visitPlanOptions: [],
questionVisible: false,
copyVisible: false,
copyTargetVisitNum: null,
copySourceVisitNum: null,
selectIndex: 0,
indexA: null,
selectVisitKey: '',
@ -346,6 +417,9 @@ export default {
questionList() {
return this.questionListMap[this.selectVisitKey]
},
copySourceVisitOptions() {
return this.visitPlanOptions.filter((visit) => visit.VisitNum !== this.copyTargetVisitNum)
}
},
watch: {
async activeVisitTab(v) {
@ -397,6 +471,11 @@ export default {
: []
}))
},
closeCopyDialog() {
this.copyVisible = false
this.copyTargetVisitNum = null
this.copySourceVisitNum = null
},
async getVisitPlanOptions() {
try {
const trialId = this.$route.query.trialId
@ -405,14 +484,16 @@ export default {
this.visitPlanOptions = res.Result || []
if (!this.activeVisitTab && this.visitPlanOptions.length > 0) {
this.activeVisitTab = this.visitPlanOptions[0].Id
this.visitPlanOptions.push(
{
"Id": "00000000-0000-0000-0000-000000000000",
"VisitNum": -1,
"VisitName": "Out of Plan",
"IsBaseLine": false
}
)
}
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) {
@ -467,8 +548,151 @@ export default {
}
})
},
saveAllSync() {
return Promise.resolve(true)
// 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
@ -504,6 +728,36 @@ export default {
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
}
},
visitTagClose2(index, indexA, visitKey) {
this.$confirm(this.$t('trials:adRules:message:msg1')).then(() => {
this.questionListMap[visitKey][index].AnswerGroup2List.splice(indexA, 1)
@ -637,12 +891,18 @@ export default {
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;

View File

@ -451,9 +451,6 @@ export default {
this.$refs[
"arbitrationRules" + this.TrialReadingCriterionId
][0].getList();
this.$refs[
"arbitrationRules" + this.TrialReadingCriterionId
][0].getTrialJudgyInfo();
}
},
},