irc_web/.svn/pristine/78/78cea322e38643fdbc602a19e7f...

531 lines
18 KiB
Plaintext
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>
<!-- 搜索框 -->
<template slot="search-container">
<el-form :inline="true">
<!-- Site -->
<el-form-item :label="$t('trials:studyList:table:siteId')">
<el-select
v-model="searchData.SiteId"
clearable
filterable
style="width:150px"
>
<el-option
v-for="item of siteOptions"
:key="item.SiteId"
:label="item.TrialSiteCode"
:value="item.SiteId"
/>
</el-select>
</el-form-item>
<!-- Subject -->
<el-form-item :label="$t('trials:studyList:table:subject')">
<el-input v-model="searchData.SubjectInfo" style="width:140px" />
</el-form-item>
<!-- Visit -->
<el-form-item :label="$t('trials:studyList:table:visit')">
<el-select
v-model="searchData.VisitPlanArray"
clearable
filterable
multiple
collapse-tags
>
<el-option
v-for="(item, index) of visitPlanOptions"
:key="index"
:label="item.VisitName"
:value="item.VisitNum"
>
<span style="float: left">{{ item.VisitName }}</span>
</el-option>
<el-option
key="Other"
label="OutPlan"
value="1.11"
/>
</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-form-item>
</el-form>
</template>
<!-- 检查列表 -->
<template slot="main-container">
<el-table
v-loading="loading"
v-adaptive="{bottomOffset:60}"
:data="list"
stripe
height="100"
@sort-change="handleSortByColumn"
>
<el-table-column type="index" width="40" />
<!-- Study ID -->
<el-table-column
prop="StudyCode"
:label="$t('trials:studyList:table:studyId')"
show-overflow-tooltip
sortable="custom"
min-width="100"
/>
<!-- Image Type -->
<el-table-column
prop="IsDicom"
:label="$t('trials:studyList:table:imageType')"
sortable="custom"
min-width="100"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.IsDicom" type="primary">DICOM</el-tag>
<el-tag v-else type="danger">Non-DICOM</el-tag>
</template>
</el-table-column>
<el-table-column
prop="StudyTime"
sortable="custom"
min-width="200"
show-overflow-tooltip
>
<template slot="header">
<el-tooltip placement="top">
<!-- Modality,Body Part Examined,Count,Study Date -->
<!-- Study Info -->
<div slot="content">
{{ `${$t('trials:studyList:table:modality')}, ${$t('trials:studyList:table:bodyPart')}, ${$t('trials:studyList:table:studyDate')}, ${$t('trials:studyList:table:count')}` }}
</div>
<span>{{ $t('trials:studyList:table:studyInfo') }}</span>
</el-tooltip>
</template>
<template slot-scope="scope">
<div style="display: flex;align-items: center">
<div v-if="scope.row.Modalities">{{ scope.row.Modalities }}({{ scope.row.Count }}), </div>
<div v-else style="color:#f44336;">N/A, </div>
<div v-if="scope.row.Bodypart" style="margin:0 3px;">{{ getBodyPart(scope.row.Bodypart) }}, </div>
<div v-else style="color:#f44336;margin:0 3px;">N/A, </div>
<div v-if="scope.row.StudyTime">{{ moment(scope.row.StudyTime).format('YYYY-MM-DD') }} </div>
<div v-else style="color:#f44336;">N/A </div>
<div>
<!-- <el-popover v-if="scope.row.Count && scope.row.IsDicom" trigger="click" placement="bottom">
<el-table v-loading="seriesLoading" :data="seriesList" height="200" size="small" class="seriesListOfStudy">
<el-table-column
prop="SeriesNumber"
:label="$t('trials:studyList:table:seriesNum')"
width="120"
/>
<el-table-column prop="Modality" :label="$t('trials:studyList:table:modality')" width="120" />
<el-table-column
prop="Description"
:label="$t('trials:studyList:table:description')"
width="150"
show-overflow-tooltip
/>
<el-table-column
prop="SliceThickness"
:label="$t('trials:studyList:table:sliceThickness')"
width="120"
/>
<el-table-column
prop="InstanceCount"
:label="$t('trials:studyList:table:instanceCount')"
width="120"
/>
<el-table-column :label="$t('common:action:action')" width="80">
<template slot-scope="series">
<router-link
style="color: #00d1b2; padding: 2px 5px"
tag="a"
:to="{
path: `/showdicom?studyId=${scope.row.Id}&studyCode=${scope.row.StudyCode}&modality=${scope.row.Modalities}&description=${scope.row.Description}&series=${JSON.stringify(series.row)}&type=Series&TokenKey=${tokenKey}`,
}"
target="_blank"
>
{{ $t('trials:studyList:button:view') }}
</router-link>
</template>
</el-table-column>
</el-table>
<div slot="reference" class="name-wrapper">
<span style="color:#00d1b2;cursor:pointer;" @click="handleGetseriesList(scope.row)">
{{ `${scope.row.Count}` }}
</span>
</div>
</el-popover>
<el-button
v-else-if="scope.row.Count && !scope.row.IsDicom"
type="text"
@click.native.prevent="handlePreviewNonDicom(scope.row)"
>
{{ scope.row.Count }}
</el-button> -->
<!-- <span>({{ scope.row.Count }})</span> -->
<!-- <span v-else style="color:#f44336;">N/A</span> -->
</div>
</div>
</template>
</el-table-column>
<el-table-column
min-width="100"
show-overflow-tooltip
>
<template slot="header">
<el-tooltip placement="top">
<div slot="content">
{{ `${$t('trials:studyList:table:visitName')}, ${$t('trials:studyList:table:visitNum')}` }}<br>
</div>
<span>{{ $t('trials:studyList:table:visit') }}</span>
</el-tooltip>
</template>
<template slot-scope="scope">
<span v-if="scope.row.VisitName">{{ scope.row.VisitName }}, </span>
<span v-else style="color:#f44336;">N/A, </span>
<span>{{ scope.row.VisitNum }}</span>
</template>
</el-table-column>
<el-table-column
prop="SubjectCode"
:label="$t('trials:studyList:table:subject')"
sortable="custom"
show-overflow-tooltip
/>
<el-table-column
min-width="100"
show-overflow-tooltip
>
<template slot="header">
<el-tooltip placement="top">
<div slot="content">
{{ `${$t('trials:studyList:table:siteId')}, ${$t('trials:studyList:table:siteName')}` }}
</div>
<span>{{ $t('trials:studyList:table:site') }}</span>
</el-tooltip>
</template>
<template slot-scope="scope">
<span v-if="scope.row.TrialSiteCode">{{ scope.row.TrialSiteCode }}, </span>
<span v-else style="color:#f44336;">N/A, </span>
<span v-if="scope.row.TrialSiteAliasName">{{ scope.row.TrialSiteAliasName }}</span>
<span v-else style="color:#f44336;">N/A</span>
</template>
</el-table-column>
<el-table-column
prop="Uploader"
:label="$t('trials:studyList:table:uploader')"
show-overflow-tooltip
sortable="custom"
min-width="100"
/>
<el-table-column
prop="UploadTime"
:label="$t('trials:studyList:table:uploadTime')"
show-overflow-tooltip
sortable="custom"
min-width="120"
/>
<el-table-column :label="$t('common:action:action')" min-width="100" fixed="right">
<template slot-scope="scope">
<!-- 查看 -->
<el-button
:disabled="!scope.row.Count"
circle
:title="$t('trials:studyList:button:view')"
icon="el-icon-view"
@click="handleViewStudy(scope.row)"
/>
<!-- 分享检查 -->
<el-button
v-hasPermi="['trials:trials-panel:study:share']"
:disabled="!(scope.row.Count > 0 && scope.row.IsDicom)"
circle
:title="$t('trials:studyList:action:share')"
icon="el-icon-share"
@click="handleShareImage(scope.row)"
/>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize" @pagination="getList" />
</template>
<base-model :config="share_model">
<template slot="dialog-body">
<div>
<i style="color:#00d1b2;" class="el-icon-success" />
<span>成功创建分享链接</span>
</div>
<div style="margin:10px 0;">
链接:<el-input v-model="shareLink" readonly style="width:420px;" />
</div>
<div style="margin-bottom:20px;">
提取码: <el-input v-model="extractionCode" style="width:100px;" readonly />
</div>
<div>
<el-button type="primary" round @click="copyCode">复制链接及提取码</el-button>
</div>
</template>
</base-model>
<!-- 预览非Dicom影像 -->
<el-dialog
v-if="previewNonDicomVisible"
:visible.sync="previewNonDicomVisible"
:title="$t('trials:studyList:dialogTitle:view')"
:fullscreen="true"
append-to-body
custom-class="base-dialog-wrapper"
>
<div class="base-modal-body" style="border:2px solid #ccc;padding: 10px">
<NonDicomPreview v-if="previewNonDicomVisible" :none-dicom-id="rowData.Id" />
</div>
</el-dialog>
</BaseContainer>
</template>
<script>
import {
getDicomAndNoneDicomStudyList,
getTrialSiteSelect,
getSeriesList,
getTrialVisitStageSelect,
getNoneDicomStudyFileList
} from '@/api/trials'
import { createImageShare } from '@/api/share'
import BaseContainer from '@/components/BaseContainer'
import Pagination from '@/components/Pagination'
import BaseModel from '@/components/BaseModel'
import NonDicomPreview from './components/nonDicomPreview'
import moment from 'moment'
import { getToken } from '@/utils/auth'
const searchDataDefault = () => {
return {
SubjectInfo: '',
VisitPlanArray: [],
Status: '',
SiteId: '',
PageIndex: 1,
PageSize: 20
}
}
export default {
name: 'StudyList',
components: { BaseContainer, Pagination, BaseModel, NonDicomPreview },
data() {
return {
searchData: searchDataDefault(),
list: [],
loading: false,
total: 0,
siteOptions: [],
visitPlanOptions: [],
seriesList: [],
nonDicomfilesList: [],
rowData: {},
userTypeEnumInt: zzSessionStorage.getItem('userTypeEnumInt') * 1,
share_model: { visible: false, title: '影像分享', showClose: true, width: '500px' },
shareLink: '',
extractionCode: '',
moment,
filesLoading: '',
seriesLoading: '',
previewNonDicomVisible: false,
trialId: this.$route.query.trialId,
tokenKey: getToken(),
openWindow: null
}
},
mounted() {
this.getSite()
this.getVisitPlanOptions()
this.getList()
},
methods: {
// 获取检查列表数据
getList() {
this.loading = true
this.searchData.TrialId = this.trialId
getDicomAndNoneDicomStudyList(this.searchData)
.then((res) => {
this.loading = false
this.list = res.Result.CurrentPageData
this.total = res.Result.TotalCount
})
.catch(() => {
this.loading = false
})
},
// 获取某个Dicom检查下的序列信息
handleGetseriesList(row) {
this.seriesLoading = true
this.seriesList = []
getSeriesList(row.Id).then((res) => {
this.seriesLoading = false
this.seriesList = res.Result
}).catch(() => {
this.seriesLoading = false
})
},
// 获取某个非Dicom检查下的文件
handleGetFilesList(id) {
this.filesLoading = true
getNoneDicomStudyFileList(id).then(res => {
this.nonDicomfilesList = res.Result
this.filesLoading = false
}).catch(() => { this.filesLoading = false })
},
// 预览当前检查下的影像
handleViewStudy(row) {
if (this.openWindow) {
this.openWindow.close()
}
if (row.IsDicom) {
const routeData = this.$router.resolve({
path: `/showdicom?studyId=${row.Id}&TokenKey=${this.tokenKey}&type=Study`
})
this.openWindow = window.open(routeData.href, '_blank')
} else {
// this.rowData = { ...row }
// this.previewNonDicomVisible = true
const routeData = this.$router.resolve({
path: `/showNoneDicoms?subjectVisitId=${row.SubjectVisitId}&studyId=${row.Id}&TokenKey=${this.tokenKey}`
})
this.openWindow = window.open(routeData.href, '_blank')
}
},
handlePreviewNonDicom(row) {
if (this.openWindow) {
this.openWindow.close()
}
const routeData = this.$router.resolve({
path: `/showNoneDicoms?subjectVisitId=${row.SubjectVisitId}&studyId=${row.Id}&TokenKey=${this.tokenKey}`
})
this.openWindow = window.open(routeData.href, '_blank')
},
// 预览
handlePreview(row) {
if (this.openWindow) {
this.openWindow.close()
}
this.openWindow = window.open(row.FullFilePath, '_blank')
},
// 格式化状态码
studyStatusFormatter(StudyStatus) {
if (StudyStatus === 5) return 'Uploaded'
else if (StudyStatus === 1) return 'Uploading'
else if (StudyStatus === 7) return 'QA Requested'
else if (StudyStatus === 10) return 'In QA'
else if (StudyStatus === 25) return 'QA-Passed'
else if (StudyStatus === 26) return 'QA-Failed'
else if (StudyStatus === 28) return 'Anonymizing'
else if (StudyStatus === 30) return 'Anonymized'
else if (StudyStatus === 32) return 'Anonymizing Failed'
else if (StudyStatus === 34) return 'Forwarding'
else if (StudyStatus === 36) return 'Forwarded'
else if (StudyStatus === 38) return 'Forwarding Failed'
else return ''
},
// 获取site下拉框数据
getSite() {
getTrialSiteSelect(this.trialId).then((res) => {
this.siteOptions = res.Result
})
},
// 获取visit下拉框数据
getVisitPlanOptions() {
getTrialVisitStageSelect(this.trialId)
.then((res) => {
this.visitPlanOptions = res.Result
})
},
// 分享影像链接
handleShareImage(row) {
this.shareLink = ''
this.extractionCode = ''
const params = {
TrialId: row.TrialId,
SiteId: row.SiteId,
SubjectId: row.SubjectId,
StudyId: row.Id
}
this.loading = true
createImageShare(params).then((res) => {
this.loading = false
if (res.IsSuccess) {
// this.shareLink = `${window.location.origin}${window.location.pathname}#/imagesShare?id=${res.Result.ResourceId}`
this.shareLink = `${window.location.origin}/imagesShare?id=${res.Result.ResourceId}`
this.extractionCode = res.Result.Password
this.share_model.visible = true
}
}).catch(() => { this.loading = false })
},
getBodyPart(bodyPart) {
if (!bodyPart) return ''
var separator = ','
if (bodyPart.indexOf('|') > -1) {
separator = '|'
} else if (bodyPart.indexOf(',') > -1) {
separator = ','
} else if (bodyPart.indexOf('') > -1) {
separator = ''
}
var arr = bodyPart.split(separator)
var newArr = arr.map(i => {
return this.$fd('Bodypart', i.trim())
})
return newArr.join(' | ')
},
// 复制
copyCode() {
this.$copyText(`链接: ${this.shareLink} 提取码: ${this.extractionCode}`).then(
res => {
this.$message.success('复制成功')
}
).catch(() => { this.$alert('复制失败') })
},
onCopyError() {
this.$alert('复制失败')
},
// 查询
handleSearch() {
this.searchData.PageIndex = 1
this.getList()
},
// 重置
handleReset() {
this.searchData = searchDataDefault()
this.getList()
},
// 排序
handleSortByColumn(column) {
if (column.order === 'ascending') {
this.searchData.Asc = true
} else {
this.searchData.Asc = false
}
this.searchData.SortField = column.prop
this.searchData.PageIndex = 1
this.getList()
}
}
}
</script>