irc_web/src/views/trials/trials-panel/subject/reading-period/index.vue

600 lines
27 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<BaseContainer class="reading-period">
<el-tabs v-model="TrialReadingCriterionId" type="border-card">
<el-tab-pane v-for="criterion of trialCriterionList" :key="criterion.TrialReadingCriterionId" :label="criterion.TrialReadingCriterionName" :name="criterion.TrialReadingCriterionId">
<div v-if="TrialReadingCriterionId === criterion.TrialReadingCriterionId">
<div slot="search-container">
<el-form :inline="true">
<el-form-item :label="$t('trials:readingPeriod:table:siteCode')">
<!-- 中心编号 -->
<el-select v-model="searchData.TrialSiteCode" clearable filterable style="width:120px;">
<el-option
v-for="(site,index) of siteOptions"
:key="index"
:label="site.TrialSiteCode"
:value="site.TrialSiteCode"
/>
</el-select>
</el-form-item>
<!-- 受试者编号 -->
<el-form-item :label="$t('trials:readingPeriod:table:subjectCode')">
<el-input
v-model="searchData.SubjectCode"
style="width:100px;"
clearable
/>
</el-form-item>
<!-- 阅片类型 -->
<el-form-item :label="$t('trials:readingPeriod:table:readingType')">
<el-select v-model="searchData.ModuleType" clearable style="width:120px">
<el-option
v-for="item of $d.ModuleTypeEnum"
:key="item.value"
:value="item.value"
:label="item.label"
/>
</el-select>
</el-form-item>
<!-- 进度 -->
<el-form-item :label="$t('trials:readingPeriod:table:readingSchedule')">
<el-select v-model="searchData.ReadingStatus" clearable style="width:120px">
<el-option
v-for="item of $d.ReadModuleEnum"
:key="item.value"
:value="item.value"
:label="item.label"
/>
</el-select>
</el-form-item>
<!-- 阅片名称 -->
<el-form-item :label="$t('trials:readingPeriod:table:readingName')">
<el-input
v-model="searchData.Name"
style="width:100px;"
clearable
/>
</el-form-item>
<el-form-item :label="$t('trials:readingPeriod:table:completeClinicalData')">
<el-select v-model="searchData.CompleteClinicalData" clearable style="width:120px">
<el-option
v-for="item of $d.CompleteClinicalDataEnum"
:key="item.value"
:value="item.value"
:label="item.label"
/>
</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-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
{{ $t('common:button:reset') }}
</el-button>
<!--导出受试者进展表-->
<el-button type="primary" icon="el-icon-download" @click="handleExportSubject">
{{ $t('trials:readingPeriod:buttton:exportSubjectTbl') }}
</el-button>
<!--导出阅片期信息表-->
<el-button type="primary" icon="el-icon-download" @click="handleExportPeriod">
{{ $t('trials:readingPeriod:buttton:exportPeriodTbl') }}
</el-button>
<!-- 阅片期管理 -->
<el-button
v-if="ReadingInfoSignTime && (otherInfo.IsClinicalReading || otherInfo.IsReadingPeriod)"
v-hasPermi="['trials:trials-panel:subject:readingPeriod:edit']"
type="primary"
icon="el-icon-edit-outline"
@click="handleReadingPeriod"
>
{{ $t('trials:readingPeriod:button:rpManage') }}
</el-button>
</el-form-item>
</el-form>
</div>
<div slot="main-container">
<el-table
ref="myTable"
v-adaptive="{bottomOffset:135}"
v-loading="loading"
:data="list"
stripe
height="100"
:header-row-class-name="headerRowStyle"
:cell-style="cellStyle"
@sort-change="handleSortChange"
>
<el-table-column type="index" width="40" fixed="left" />
<!-- 中心编号 -->
<el-table-column
prop="TrialSiteCode"
:label="$t('trials:readingPeriod:table:siteCode')"
min-width="110"
fixed="left"
sortable="custom"
show-overflow-tooltip
/>
<!-- 受试者编号 -->
<el-table-column
prop="SubjectCode"
:label="$t('trials:readingPeriod:table:subjectCode')"
min-width="120"
fixed="left"
sortable="custom"
show-overflow-tooltip
/>
<!-- 阅片计划 -->
<el-table-column
:label="$t('trials:readingPeriod:table:readingPlan')"
align="center"
min-width="100"
>
<el-table-column
v-for="i in maxLength"
:key="`${i}`"
:prop="`Plan${i-1}`"
label=""
width="240"
>
<template slot-scope="scope">
<div v-if="i<=scope.row.Data.length">
<!-- <div style="">-->
<div style="border-bottom: 1px solid #d9d9d9;margin-bottom: 8px;padding-bottom: 8px;display: flex;justify-content: space-between;">
<div style="font-size: 16px;font-weight: 900">
{{ scope.row.Data[i-1].Name }}
</div>
<div>
<span v-if="scope.row.Data[i-1].IsEnrollmentConfirm">
| {{ $t('trials:readingPeriod:table:enroll') }}
</span>
<span v-if="scope.row.Data[i-1].PDState">
| {{ $t('trials:readingPeriod:table:pd') }}
</span>
<span v-if="scope.row.Data[i-1].IsUrgent">
| {{ $t('trials:readingPeriod:table:urgent') }}
</span>
<span v-if="scope.row.Data[i-1].IsFinalVisit">
| {{ $t('trials:readingPeriod:table:finalVisit') }}
</span>
</div>
</div>
<div style="display: flex;justify-content: space-between;border-bottom: 1px solid #d9d9d9;margin-bottom: 8px;padding-bottom: 8px">
<div>{{ $fd('ModuleTypeEnum',scope.row.Data[i-1].ModuleType) }}</div>
<div style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;width: 110px;text-align: right;" :title="$fd('ReadModuleEnum',scope.row.Data[i-1].ReadingStatus)">
{{ $fd('ReadModuleEnum',scope.row.Data[i-1].ReadingStatus) }}
</div>
</div>
<div v-if="scope.row.Data[i-1].ModuleType === 1" style="display: flex;justify-content: space-between;border-bottom: 1px solid #d9d9d9;margin-bottom: 8px;padding-bottom: 8px">
<!-- 上一访视 -->
<div>{{ $t('trials:readingPeriod:table:lastVisit') }}</div>
<div>{{ scope.row.Data[i-1].OutPlanPreviousVisitName }} </div>
</div>
<div v-if="scope.row.Data[i-1].ModuleType === 2 || scope.row.Data[i-1].ModuleType ===3 || scope.row.Data[i-1].ModuleType ===5" style="display: flex;justify-content: space-between;border-bottom: 1px solid #d9d9d9;margin-bottom: 8px;padding-bottom: 8px">
<!-- 截止访视: -->
<div>{{ $t('trials:readingPeriod:table:deadlineVisit') }}</div>
<div>{{ scope.row.Data[i-1].CutOffVisitName }}</div>
</div>
<div v-if="scope.row.Data[i-1].ModuleType ===4 " style="display: flex;justify-content: space-between;border-bottom: 1px solid #d9d9d9;margin-bottom: 8px;padding-bottom: 8px">
<!-- 对应阅片期: -->
<div>{{ $t('trials:readingPeriod:table:correspondVisit2') }}</div>
<div>{{ scope.row.Data[i-1].ReadModuleName }}</div>
</div>
<div v-if="otherInfo.ExistClinicalData" style="display: flex;justify-content: space-between;border-bottom: 1px solid #d9d9d9;margin-bottom: 8px;padding-bottom: 8px">
<div style="display: flex;justify-content: space-between;width: 100%">
<!-- 临床资料 -->
<div>
<el-tooltip v-if="scope.row.Data[i-1].CompleteClinicalData===0" class="item" effect="dark" :content="$t('trials:readingPeriod:table:clinicalDataNotComplete')" placement="bottom">
<i class="el-icon-warning" style="color:red" />
</el-tooltip>
{{ $t('trials:readingPeriod:table:clinicalInfo2') }}
</div>
<el-link type="danger" v-if="(scope.row.Data[i-1].IsVisit && otherInfo.IsExistsSubjectClinicalData && scope.row.Data[i-1].IsBaseLine) ||(scope.row.Data[i-1].IsVisit && otherInfo.IsExistsVisitClinicalData) || (scope.row.Data[i-1].IsVisit && otherInfo.IsExistsStudyClinicalData) || (!scope.row.Data[i-1].IsVisit && otherInfo.IsExistsReadingClinicalData && scope.row.Data[i-1].ModuleType === 3) || (!scope.row.Data[i-1].IsVisit && otherInfo.IsExistsOncologyReadClinicalData && scope.row.Data[i-1].ModuleType === 5)" @click="handleView(scope.row,scope.row.Data[i-1])">
{{ $t('trials:readingPeriod:button:view') }}
</el-link>
<span v-else>{{ $t('trials:readingPeriod:table:noCD') }}</span>
</div>
</div>
<div>
<el-link style="color:#428bca;margin-right: 5px" @click="handleDetail(scope.row,scope.row.Data[i-1])">
{{ $t('trials:readingPeriod:button:detail') }}
</el-link>
<el-link style="color:#428bca;margin-right: 5px" v-if="scope.row.Data[i - 1].IsCanChangeCutOffVisit" @click="handleEdit(scope.row,scope.row.Data[i-1])">
{{ $t('common:button:edit') }}
</el-link>
<el-link
style="color:#428bca;margin-right: 5px"
v-if="(scope.row.Data[i-1].ModuleType === 3 || scope.row.Data[i-1].ModuleType === 5) && scope.row.Data[i-1].ReadingStatus < 4"
v-hasPermi="['trials:trials-panel:subject:readingPeriod:edit']"
@click="handleDelete(scope.row.Data[i-1])"
>
{{ $t('trials:readingPeriod:button:delete') }}
</el-link>
</div>
</div>
</template>
</el-table-column>
</el-table-column>
<el-table-column
:fixed="(otherInfo.IsReadingPeriod || otherInfo.IsClinicalReading) && ReadingInfoSignTime && hasPermi(['trials:trials-panel:subject:readingPeriod:edit']) ? 'right':false"
:label="(otherInfo.IsReadingPeriod || otherInfo.IsClinicalReading) && ReadingInfoSignTime && hasPermi(['trials:trials-panel:subject:readingPeriod:edit']) ? $t('common:action:action') : ''"
:width="(otherInfo.IsReadingPeriod || otherInfo.IsClinicalReading) && ReadingInfoSignTime && hasPermi(['trials:trials-panel:subject:readingPeriod:edit']) ? '150px' : '80px' "
>
<template slot-scope="scope">
<el-button
v-if="otherInfo.IsReadingPeriod"
circle
:title="$t('trials:readingPeriod:buttton:addSubjectImageRP')"
icon="el-icon-plus"
@click="handleAdd(scope.row,0)"
/>
<el-button
v-if="isClinicalReading"
circle
:title="$t('trials:readingPeriod:buttton:addSubjectOncologyRP')"
icon="el-icon-plus"
@click="handleAdd(scope.row,1)"
/>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize" @pagination="getList" />
<!-- 详情 -->
<el-dialog
v-if="dialogVisible"
:title="$t('trials:rpDetail:dialogTitle:detail')"
:visible.sync="dialogVisible"
width="600px"
:close-on-click-modal="false"
>
<el-descriptions :column="2" border>
<!-- 阅片期名称 -->
<el-descriptions-item :label="$t('trials:readingPeriod:table:readingName')">
{{ currentData.Name }}
</el-descriptions-item>
<!-- 阅片期类型 -->
<el-descriptions-item :label="$t('trials:readingPeriod:table:readingType')">
{{ $fd('ModuleTypeEnum',currentData.ModuleType) }}
</el-descriptions-item>
<!-- 是否加急 -->
<!-- <el-descriptions-item label="是否加急"> <el-tag size="small">{{ $fd('YesOrNo',currentData.IsUrgent) }}</el-tag></el-descriptions-item> -->
<!-- 进度 -->
<el-descriptions-item :label="$t('trials:readingPeriod:table:readingSchedule')">
{{ $fd('ReadModuleEnum',currentData.ReadingStatus) }}
</el-descriptions-item>
<el-descriptions-item
v-if="currentData.CutOffVisitName"
:label="$t('trials:readingPeriod:table:deadlineVisit')"
>
{{ currentData.CutOffVisitName }}
</el-descriptions-item>
<el-descriptions-item
v-if="currentData.OutPlanPreviousVisitName"
:label="$t('trials:readingPeriod:table:lastVisit')"
>
{{ currentData.OutPlanPreviousVisitName }}
</el-descriptions-item>
<el-descriptions-item
v-if="currentData.ReadModuleName"
:label="$t('trials:readingPeriod:table:correspondVisit')"
>
{{ currentData.ReadModuleName }}
</el-descriptions-item>
<!-- 临床资料 -->
<el-descriptions-item v-if="otherInfo.ExistClinicalData" :label="$t('trials:readingPeriod:table:clinicalInfo')">
<template v-if="(currentData.IsVisit && otherInfo.IsExistsSubjectClinicalData && currentData.IsBaseLine) ||(currentData.IsVisit && otherInfo.IsExistsVisitClinicalData) || (!currentData.IsVisit && otherInfo.IsExistsReadingClinicalData)">
<el-link @click="view">{{ $t('trials:readingPeriod:button:view') }}</el-link>
</template>
<template v-else>
<span>{{ $t('trials:readingPeriod:table:noCD') }}</span>
</template>
</el-descriptions-item>
<!-- 当前干系人 -->
<el-descriptions-item :label="$t('trials:readingPeriod:table:stakeholder')" :span="2">
{{ currentData.Stakeholders }}
</el-descriptions-item>
</el-descriptions>
</el-dialog>
<!-- 设置阅片期 -->
<el-dialog
v-if="readPeriodVisible"
:title="$t('trials:rpManage:dialogTitle:setRP')"
:visible.sync="readPeriodVisible"
width="1400px"
:close-on-click-modal="false"
>
<ReadingPeriod
:trial-id="trialId"
:trial-reading-criterion-id="TrialReadingCriterionId"
:is-clinical-reading="isClinicalReading"
:is-global-reading="otherInfo.IsReadingPeriod"
@getList="getList"
/>
</el-dialog>
<!-- 临床资料 -->
<el-dialog
v-if="clinicalDataVisible"
:title="`${$t('trials:readingPeriod:dialogTitle:clinicalData')}${currentData.SubjectCode}|${currentData.Name}|${currentData.CriterionName}`"
:visible.sync="clinicalDataVisible"
:close-on-click-modal="false"
append-to-body
width="70%"
>
<ClinicalData :trial-reading-criterion-id="TrialReadingCriterionId" :trial-id="trialId" :data="currentData" @getList="getList"/>
</el-dialog>
<!-- 添加受试者阅片期 -->
<el-dialog
v-if="subjectPeriod.visible"
:title="subjectPeriod.title"
:visible.sync="subjectPeriod.visible"
width="500px"
custom-class="base-dialog-wrapper"
:close-on-click-modal="false"
>
<SubjectPR :trial-reading-criterion-id="TrialReadingCriterionId" :trial-id="trialId" :data="param" @close="subjectPeriod.visible = false" @getList="getList" />
</el-dialog>
<!-- 编辑受试者阅片期 -->
<el-dialog
v-if="subjectPeriodEdit.visible"
:title="subjectPeriodEdit.title"
:visible.sync="subjectPeriodEdit.visible"
width="500px"
custom-class="base-dialog-wrapper"
:close-on-click-modal="false"
>
<SubjectPR :type="'edit'" :trial-reading-criterion-id="TrialReadingCriterionId" :trial-id="trialId" :data="param" @close="subjectPeriodEdit.visible = false" @getList="getList" />
</el-dialog>
</div>
</div>
</el-tab-pane>
</el-tabs>
</BaseContainer>
</template>
<script>
import { getReadModuleList, deleteReadModule, getReadModule, getTrialSiteSelect, getTrialCriterionList } from '@/api/trials'
import { getReadingPeriodList_Export, getSubjectProgress_Export } from '@/api/export'
import BaseContainer from '@/components/BaseContainer'
import Pagination from '@/components/Pagination'
import ReadingPeriod from './components/RPList'
import ClinicalData from './components/ClinicalData'
import SubjectPR from './components/AddSubjectRP'
const searchDataDefault = () => {
return {
TrialSiteCode: '',
SubjectCode: '',
ModuleType: null,
ReadingStatus: null,
Name: '',
CompleteClinicalData: '',
PageIndex: 1,
PageSize: 20
}
}
const MinPlanCount = 10
export default {
name: 'TrialsNotice',
components: { BaseContainer, Pagination, ReadingPeriod, ClinicalData, SubjectPR },
data() {
return {
searchData: searchDataDefault(),
list: [],
total: 0,
maxLength: 0,
loading: false,
dialogVisible: false,
readPeriodVisible: false,
clinicalDataVisible: false,
subjectPeriod: { visible: false, title: this.$t('trials:readingPeriod:dialogTitle:addSubjectPR') },
subjectPeriodEdit: { visible: false, title: this.$t('trials:readingPeriod:dialogTitle:EditSubjectPR') },
trialId: this.$route.query.trialId,
currentData: {},
param: {},
siteOptions: [],
isClinicalReading: false,
otherInfo: {},
trialCriterionList: [],
TrialReadingCriterionId: '0',
ReadingInfoSignTime: null
}
},
watch: {
TrialReadingCriterionId(v) {
if (v) {
this.getList()
this.ReadingInfoSignTime = this.trialCriterionList.find(v => {
return v.TrialReadingCriterionId === this.TrialReadingCriterionId
}).ReadingInfoSignTime
}
}
},
mounted() {
this.getSite()
this.getTrialCriterionList()
},
methods: {
getList() {
this.searchData.TrialId = this.$route.query.trialId
this.searchData.TrialReadingCriterionId = this.TrialReadingCriterionId
this.loading = true
getReadModuleList(this.searchData).then(res => {
this.loading = false
this.list = res.Result.CurrentPageData
this.total = res.Result.TotalCount
this.maxLength = res.OtherInfo.MaxLength > MinPlanCount ? res.OtherInfo.MaxLength : MinPlanCount
this.isClinicalReading = res.OtherInfo.IsClinicalReading
this.otherInfo = res.OtherInfo
this.$nextTick(() => {
// myTable是表格的ref属性值
if (this.$refs.myTable && this.$refs.myTable.doLayout) {
this.$refs.myTable.doLayout()
}
})
}).catch(() => { this.loading = false })
},
handleAdd(row, type) {
this.param = {}
this.param.SubjectId = row.SubjectId
this.param.TrialSiteId = row.TrialSiteId
this.param.SubjectCode = row.SubjectCode
this.param.TrialSiteCode = row.TrialSiteCode
this.param.TrialId = this.trialId
this.param.IsClinicalReading = this.isClinicalReading
this.param.ReadingSetType = type
this.subjectPeriod.visible = true
this.subjectPeriod.title = type === 0 ? this.$t('trials:readingPeriod:dialogTitle:addSubjectPR') : this.$t('trials:readingPeriod:dialogTitle:addSubjectTumorPR')
},
handleEdit(row, type) {
this.param = {...type}
this.param.VisitStageId = this.param.CutOffVisitId
this.subjectPeriodEdit.visible = true
},
handleDelete(row) {
this.$confirm(this.$t('trials:readingPeriod:message:sureToDelete'), {
type: 'warning',
distinguishCancelAndClose: true
})
.then(() => {
this.loading = true
deleteReadModule(row.Id)
.then(res => {
this.loading = false
if (res.IsSuccess) {
this.getList()
this.$message.success(this.$t('common:message:deletedSuccessfully'))
}
}).catch(() => { this.loading = false })
})
},
handleReadingPeriod() {
this.readPeriodVisible = true
},
view() {
this.clinicalDataVisible = true
},
handleView(row, ReadingPlan) {
this.currentData = Object.assign({}, ReadingPlan)
this.clinicalDataVisible = true
},
handleDetail(row, ReadingPlan) {
this.loading = true
var param = {
trialId: this.trialId,
id: ReadingPlan.Id,
TrialReadingCriterionId: this.TrialReadingCriterionId,
// subjectId: row.SubjectId
subjectId: ReadingPlan.SubjectId
}
getReadModule(param).then(res => {
this.currentData = Object.assign({}, ReadingPlan)
// this.currentData.SubjectId = row.SubjectId
// this.currentData.SiteId = row.SiteId
// this.currentData.TrialId = this.trialId
this.currentData.Stakeholders = res.Result.StakeholderNames.join(', ')
this.dialogVisible = true
this.loading = false
}).catch(() => { this.loading = false })
},
// 获取site下拉框数据
getSite() {
getTrialSiteSelect(this.trialId).then(res => {
this.siteOptions = res.Result
})
},
handleExportSubject() {
getSubjectProgress_Export(this.searchData).then(res => {
}).catch(() => {})
},
handleExportPeriod() {
getReadingPeriodList_Export(this.searchData).then(res => {
}).catch(() => {})
},
getTrialCriterionList() {
getTrialCriterionList(this.trialId, false).then(res => {
this.trialCriterionList = res.Result
this.TrialReadingCriterionId = this.trialCriterionList[0].TrialReadingCriterionId
}).catch(() => {})
},
handleSearch() {
this.searchData.PageIndex = 1
this.getList()
},
handleReset() {
this.searchData = searchDataDefault()
this.getList()
},
// 排序
handleSortChange(column) {
if (column.order === 'ascending') {
this.searchData.Asc = true
} else {
this.searchData.Asc = false
}
this.searchData.SortField = column.prop
this.searchData.PageIndex = 1
this.getList()
},
headerRowStyle({ row, rowIndex }) {
if (rowIndex === 1) {
return 'hidden-row'
} else {
return
}
},
cellStyle({ row, column, rowIndex, columnIndex }) {
if (columnIndex > 2 && (row.Data.length >= columnIndex - 2) && column.property) {
const index = column.property.substring(4) * 1
// 0 计划内访视; 1 计划外访视; 2 阅片期; 3 全局阅片; 4 裁判; 5肿瘤学
const type = row.Data[index].ModuleType
const status = row.Data[index].ReadingStatus
if ((type === 0 || type === 1) && status === 0) {
return { 'vertical-align': 'top' }
} else if ((type === 0 || type === 1) && status === 1) {
// 计划访视 影像质控 (蓝色)
return { 'background-color': 'rgb(189,215,238)', 'vertical-align': 'top' }
} else if ((type === 0 || type === 1) && status === 2) {
// 计划访视 一致性核查 (黄色)
return { 'background-color': 'rgb(255,217,102)', 'vertical-align': 'top' }
} else if ((type === 0 || type === 1) && status === 3) {
// 计划访视 任务分配 (绿色)
return { 'background-color': 'rgb(169,208,142)', 'vertical-align': 'top' }
} else if ((type === 0 || type === 1) && status === 4) {
// 计划访视 影像阅片 (绿色)
return { 'background-color': 'rgb(169,208,142)', 'vertical-align': 'top' }
} else if ((type === 0 || type === 1) && status === 5) {
// 计划访视 阅片完成 (橙色)
return { 'background-color': 'rgb(244,176,132)', 'vertical-align': 'top' }
}
}
}
}
}
</script>
<style lang="scss" scoped>
.reading-period{
/deep/.search {
padding: 0px !important;
}
}
/deep/ .hidden-row{
display: none;
}
/deep/ .el-dialog__body {
padding: 0px 20px;
}
/deep/ .el-dialog__header {
padding: 10px 20px;
}
/deep/ .el-tag--danger.el-tag--dark {
// background-color: #f56c6c!important;
border-color: none!important;
// color: #fff!important;
}
</style>