irc_web/.svn/pristine/b0/b08a2e08f94a19f632eaceef62f...

843 lines
26 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>
<box-content class="reviewers-list">
<!-- 顶部搜索条件 -->
<div class="search">
<div class="base-search-form">
<el-form size="small" :inline="true">
<el-form-item label="Name:">
<el-input
v-model="searchData.Name"
style="width:100px;"
clearable
/>
</el-form-item>
<el-form-item label="Modality:">
<el-select
v-model="searchData.ReadingTypeIdList"
clearable
multiple
collapse-tags
style="width:150px;"
>
<!-- <el-option
v-for="(key,value) of dictionaryList.ReadingType"
:key="key"
:label="key"
:value="value"
/> -->
<el-option
v-for="item of dict.type.ReadingType"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="Subspeciality:">
<el-select
v-model="searchData.SubspecialityIdList"
multiple
collapse-tags
clearable
style="width:180px;"
>
<el-option
v-for="item of dict.type.Subspeciality"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<!-- <el-button type="text" @click="handleMore">More</el-button> -->
<el-button type="primary" icon="el-icon-search" @click="handleSearch">Search</el-button>
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">Reset</el-button>
<el-button
icon="el-icon-download"
type="primary"
:disabled="!(selectArr.length>0)"
@click="handleDownLoadOffical"
>Download CV</el-button>
<el-button
type="primary"
icon="el-icon-link"
@click="showResearchLink"
>
采集链接
</el-button>
</el-form-item>
</el-form>
</div>
<span style="margin-left:auto;">
<el-switch
v-model="isEN"
active-text="EN"
inactive-text="中文"
style="margin-right:10px;"
@change="handleIsEnChange"
/>
<el-button size="small" icon="el-icon-plus" type="primary" @click="handleNew">New</el-button>
</span>
</div>
<!-- 更多搜索条件 -->
<el-drawer
:visible.sync="isShow"
:with-header="false"
size="410px"
>
<div style="padding:10px;">
<el-form label-width="160px" size="mini">
<el-form-item label="Name">
<el-input
v-model="searchData.Name"
placeholder="Name"
style="width:100%;"
clearable
/>
</el-form-item>
<el-form-item label="Modality">
<el-select
v-model="searchData.ReadingTypeIdList"
placeholder="Modality"
clearable
multiple
style="width:100%;"
>
<!-- <el-option
v-for="(key,value) of dictionaryList.ReadingType"
:key="key"
:label="key"
:value="value"
/> -->
<el-option
v-for="item of dict.type.ReadingType"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="Subspeciality">
<el-select
v-model="searchData.SubspecialityIdList"
placeholder="Subspeciality"
multiple
clearable
style="width:100%;"
>
<!-- <el-option
v-for="(key,value) of dictionaryList.Subspeciality"
:key="key"
:label="key"
:value="value"
/> -->
<el-option
v-for="item of dict.type.Subspeciality"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="Department">
<el-select
v-model="searchData.DepartmentId"
placeholder="Department"
style="width:100%;"
clearable
>
<!-- <el-option
v-for="(key,value) of dictionaryList.Department"
:key="key"
:label="key"
:value="value"
/> -->
<el-option
v-for="item of dict.type.Department"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="Rank">
<el-select
v-model="searchData.RankId"
placeholder="Rank"
style="width:100%;"
clearable
>
<!-- <el-option
v-for="(key,value) of dictionaryList.Rank"
:key="key"
:label="key"
:value="value"
/> -->
<el-option
v-for="item of dict.type.Rank"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="Position">
<el-select
v-model="searchData.PositionId"
placeholder="Position"
style="width:100%;"
clearable
>
<!-- <el-option
v-for="(key,value) of dictionaryList.Position"
:key="key"
:label="key"
:value="value"
/> -->
<el-option
v-for="item of dict.type.Position"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="Institution">
<el-select
v-model="searchData.HospitalId"
placeholder="Institution"
style="width:100%;"
clearable
>
<el-option
v-for="(item,index) in hospitalList"
:key="index"
:label="item.HospitalName"
:value="item.Id"
/>
</el-select>
</el-form-item>
<el-form-item label="Review Criteria">
<el-select
v-model="searchData.EvaluationCriteriaIdList"
placeholder="Please select"
style="width:100%;"
clearable
multiple
>
<!-- <el-option v-for="(key,value) of dictionaryList.ReadingStandard" :key="key" :label="key" :value="value" /> -->
<el-option
v-for="item of dict.type.ReadingStandard"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="Enrollment">
<el-select
v-model="searchData.EnrollStatus"
placeholder="Enrollment"
style="width:100%;"
clearable
>
<el-option key="2" label="Yes" :value="2" />
<el-option key="1" label="No" :value="1" />
</el-select>
</el-form-item>
<el-form-item label="Information Confirmed">
<el-select
v-model="searchData.InformationConfirmed"
placeholder="Information Confirmed"
style="width:100%;"
clearable
>
<el-option key="1" label="Yes" :value="1" />
<el-option key="2" label="No" :value="2" />
</el-select>
</el-form-item>
<el-form-item label="Contractor Status">
<el-select
v-model="searchData.ContractorStatus"
placeholder="Contractor Status"
style="width:100%;"
clearable
>
<el-option key="1" label="Yes" :value="1" />
<el-option key="2" label="No" :value="2" />
</el-select>
</el-form-item>
<el-form-item label="Accepting New Trials">
<el-select
v-model="searchData.AcceptingNewTrial"
placeholder="Accepting New Trials"
style="width:100%;"
clearable
>
<el-option key="2" label="Yes" :value="true" />
<el-option key="1" label="No" :value="false" />
</el-select>
</el-form-item>
<el-form-item label="Actively Reading">
<el-select
v-model="searchData.ActivelyReading"
placeholder="Actively Reading"
style="width:100%;"
clearable
>
<el-option key="2" label="Yes" :value="true" />
<el-option key="1" label="No" :value="false" />
</el-select>
</el-form-item>
<el-form-item label="Payment Type: ">
<el-select
v-model="searchData.Nation"
clearable
style="width:100%;"
>
<el-option v-for="item of $d.AttendedReviewerType" :value="item.value" :label="item.label" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSelectSearch">Search</el-button>
<el-button type="primary" @click="handleReset">Reset</el-button>
<el-button type="primary" @click="isShow=false">Back</el-button>
</el-form-item>
</el-form>
</div>
</el-drawer>
<!-- 医生列表 -->
<el-table
v-adaptive="{bottomOffset:55}"
v-loading="listLoading"
stripe
height="100"
:data="list"
@sort-change="sortByColumn"
@selection-change="handleSelectChange"
>
<el-table-column type="selection" align="left" width="45" :selectable="hasResume" />
<el-table-column type="index" width="40" align="left" />
<el-table-column
align="left"
prop="LastName"
label="Name"
show-overflow-tooltip
width="130"
sortable="custom"
>
<template slot-scope="scope">
{{ scope.row.LastName + ' / ' + scope.row.FirstName }}
</template>
</el-table-column>
<el-table-column
prop="ChineseName"
label="Name CN"
show-overflow-tooltip
width="90"
align="left"
/>
<el-table-column prop="ReviewerCode" label="ID" width="80" show-overflow-tooltip sortable="custom" />
<el-table-column prop="AccountUserName" label="User Name" width="140" show-overflow-tooltip sortable="custom" />
<el-table-column
label="Reading"
width="100"
show-overflow-tooltip
sortable="custom"
align="left"
prop="Reading"
>
<template slot-scope="scope">
<span v-if="scope.row.Reading" style="color:#428bca">
<router-link
tag="a"
:to="{
path: `/trialStats?name=${scope.row.FirstName+' '+scope.row.LastName}&doctorId=${scope.row.Id}&status=10&TokenKey=${tokenKey}`
}"
target="_blank"
>{{ scope.row.Reading }}</router-link>
</span>
<span v-else>{{ scope.row.Reading }}</span>
</template>
</el-table-column>
<el-table-column
label="Finished"
width="100"
show-overflow-tooltip
sortable="custom"
align="left"
prop="Finished"
>
<template slot-scope="scope">
<span v-if=" scope.row.Finished" style="color:#428bca">
<router-link
tag="a"
:to="{
path: `/trialStats?name=${scope.row.FirstName+' '+scope.row.LastName}&doctorId=${scope.row.Id}&status=14&TokenKey=${tokenKey}`
}"
target="_blank"
>{{ scope.row.Finished }}</router-link>
</span>
<span v-else>{{ scope.row.Finished }}</span>
</template>
</el-table-column>
<el-table-column
align="left"
prop="SpecialityId"
label="Specialty"
sortable="custom"
show-overflow-tooltip
width="130"
>
<template slot-scope="scope">
<span>
{{ scope.row.SpecialityId === otherId ? scope.row.SpecialityOther : isEnglish?scope.row.Speciality:scope.row.SpecialityCN }}
</span>
</template>
</el-table-column>
<el-table-column
align="left"
prop="Subspeciality"
label="Subspecialty"
show-overflow-tooltip
min-width="150"
>
<template slot-scope="scope">
<span v-if="isEnglish">
{{ scope.row.SubspecialityList.length>0?scope.row.SubspecialityList.join(', '):'' }}
</span>
<span v-else>
{{ scope.row.SubspecialityCNList.length>0?scope.row.SubspecialityCNList.join(', '):'' }}
</span>
</template>
</el-table-column>
<el-table-column
prop="HospitalName"
label="Institution"
min-width="110"
align="left"
sortable="custom"
show-overflow-tooltip
>
<template slot-scope="scope">
<span>
{{ isEnglish?scope.row.HospitalName:scope.row.HospitalNameCN }}
</span>
</template>
</el-table-column>
<el-table-column
prop="City"
label="Location"
width="110"
align="left"
sortable="custom"
show-overflow-tooltip
>
<template slot-scope="scope">
<span>
{{ isEnglish?scope.row.City:scope.row.CityCN }}
</span>
</template>
</el-table-column>
<el-table-column
prop="IsVirtual"
label="Virtual"
min-width="80"
align="left"
sortable="custom"
show-overflow-tooltip
>
<template slot-scope="scope">
<span>
{{ scope.row.IsVirtual ? 'Yes' : 'No' }}
</span>
</template>
</el-table-column>
<el-table-column
prop="ReviewStatus"
label="Confirmed"
min-width="80"
align="left"
sortable="custom"
show-overflow-tooltip
>
<template slot-scope="scope">
<span>
{{ scope.row.ReviewStatus === 1 ? 'Yes' : 'No' }}
</span>
</template>
</el-table-column>
<el-table-column label="Action" min-width="100" align="left" fixed="right">
<template slot-scope="scope">
<el-button
size="mini"
circle
icon="el-icon-info"
title="Detail"
@click="handleDetail(scope.row)"
/>
<el-button
circle
icon="el-icon-edit-outline"
title="Edit"
@click="handleEdit(scope.row)"
/>
<el-button
icon="el-icon-view"
circle
title="盲态简历"
@click="lookResumeInfo(scope.row)"
/>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination
class="page"
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
<base-model :config="share_model">
<template slot="dialog-body">
<div>
<i style="color:#428bca;" class="el-icon-success" />
<span>成功创建分享链接</span>
</div>
<div style="margin:10px 0;">
<span style="">个人简历填写链接:</span><el-input type="textarea" :autosize="{ minRows: 2, maxRows: 4}" v-model="shareLink" readonly style="width: 100%;margin-top: 10px" />
</div>
<div>
<el-button type="primary" round @click="copyCode">复制链接</el-button>
</div>
</template>
</base-model>
<!-- 下载简历模态框 -->
<base-model :config="model_cfg">
<template slot="dialog-body">
<label>Language: </label>
<el-radio-group v-model="language">
<el-radio :label="2">English</el-radio>
<el-radio :label="1">中文</el-radio>
</el-radio-group>
</template>
<template slot="dialog-footer">
<el-button :disabled="btnLoading" size="small" type="primary" @click="model_cfg.visible = false">Cancel</el-button>
<el-button size="small" type="primary" :loading="btnLoading" @click="handleDownloadResumes">Ok</el-button>
</template>
</base-model>
</box-content>
</template>
<script>
import { getDoctorSearchList, downloadOfficialCV, getOfficialResume } from '@/api/reviewers'
import store from '@/store'
import { mapGetters, mapMutations } from 'vuex'
import Pagination from '@/components/Pagination'
import BoxContent from '@/components/BoxContent'
import BaseModel from '@/components/BaseModel'
import { getToken } from '@/utils/auth'
import JSZip from 'jszip'
import axios from 'axios'
import { saveAs } from 'file-saver'
const searchDataDefault = () => {
return {
Name: '',
ReadingTypeIdList: [],
SubspecialityIdList: [],
DepartmentId: '',
SpecialityId: '',
PositionId: '',
RankId: '',
HospitalId: '',
ContractorStatus: '',
InformationConfirmed: '',
EnrollStatus: '',
AcceptingNewTrial: '',
ActivelyReading: '',
EvaluationCriteriaIdList: [],
Nation: '',
PageIndex: 1,
PageSize: 20,
Asc: false,
SortField: ''
}
}
const otherId = 'ef84e9cb-f1a6-49d7-b6da-34be2c12abd5'
export default {
name: 'Reviewers',
components: { BoxContent, BaseModel, Pagination },
data() {
return {
otherId,
searchData: searchDataDefault(),
list: null,
total: 0,
listLoading: false,
selectArr: [],
isShow: false,
dialogVisible: false,
language: 2,
isEN: true,
btnLoading: false,
token: store.getters.token,
model_cfg: {
visible: false,
title: '',
width: '500px',
showClose: true
},
tokenKey: getToken(),
share_model: { visible: false, title: '', width: '500px' },
shareLink: null
}
},
dicts: ['ReadingType', 'Subspeciality', 'Department', 'Rank', 'Position', 'ReadingStandard'],
computed: {
...mapGetters(['hospitalList', 'reviewersQuery', 'isEnglish'])
},
created() {
this.isEN = this.isEnglish
this.reviewersQuery ? this.listQuery = this.reviewersQuery : ''
this.initPage()
},
methods: {
copyCode() {
this.$copyText(`链接: ${this.shareLink}`).then(
res => {
this.$message.success('复制成功')
}
).catch(() => { this.$alert('复制失败') })
},
// 复制链接
copyLink() {
// 中心调研表链接
this.$copyText(`${this.$t('trials:researchRecord:message:researchFormLink')}: ${this.shareLink}`).then(
res => {
// 复制成功
this.$message.success(this.$t('trials:researchRecord:message:copySuccessfully'))
}
).catch(() => {
// 复制失败
this.$alert(this.$t('trials:researchRecord:message:copyFailed'))
})
},
showResearchLink() {
const trialId = this.trialId
this.shareLink = `${location.protocol}//${location.host}/ReviewersResearch`
this.share_model.visible = true
},
lookResumeInfo(row) {
console.log(row)
window.open(`/blindResumeInfo?doctorId=${row.Id}&token=${this.token}`)
},
initPage() {
store.dispatch('global/getHospital')
this.getList()
},
// 获取医生列表数据
getList() {
this.setQueryParam(this.searchData)
this.listLoading = true
// ??
// this.searchData.InformationConfirmed = 1
// this.searchData.ContractorStatus = 1
getDoctorSearchList(this.searchData)
.then(res => {
this.listLoading = false
this.list = res.Result.CurrentPageData
this.list.forEach(item => {
if (item.SubspecialityOther) {
item.SubspecialityList.push(item.SubspecialityOther)
}
if (item.SubspecialityOtherCN) {
item.SubspecialityCNList.push(item.SubspecialityOtherCN)
}
})
this.total = res.Result.TotalCount
})
.catch(() => {
this.listLoading = false
})
},
// 新增医生信息
handleNew() {
this.$router.push({ path: `/reviewers/reviewers-add?Id=&isEnglish=${this.isEnglish}&tabActive=BasicInfo` })
},
// More按钮回调
handleMore() {
this.isShow = !this.isShow
},
// 重置列表
handleReset() {
this.searchData = searchDataDefault()
this.getList()
},
// 查询
handleSearch() {
this.searchData.PageIndex = 1
this.getList()
},
handleDetail(row) {
this.$router.push({ path: `/reviewers/reviewers-detail?doctorId=${row.Id}&isEnglish=${this.isEnglish}` })
},
handleEdit(row) {
this.$router.push({ path: `/reviewers/reviewers-edit?Id=${row.Id}&isEnglish=${this.isEnglish}&tabActive=BasicInfo` })
},
getFileData(fileUrl) {
return new Promise((resolve, reject) => {
axios(fileUrl, {
method: 'GET',
responseType: 'blob' // 返回的数据会被强制转为blob类型 转换成arraybuffer 也行
}).then((res) => {
console.log('res', res)
resolve(res)
}).catch(error => {
reject(error)
})
})
},
async handleBatchDown(dataSource) {
return new Promise(resolve => {
console.log('开始压缩')
const zip = new JSZip() // 创建实例对象
const promises = []
dataSource.FileList.forEach((item) => {
console.log(this.OSSclientConfig.basePath + item.Path)
const promise = this.getFileData(this.OSSclientConfig.basePath + item.Path).then((res) => {
const fileName = item.FileName + ''
// 创建文件用file(),创建文件夹用 floder()
zip.file(fileName, res.data, {binary: true})
})
promises.push(promise)
})
console.log(promises)
// 生成 zip 文件
Promise.all(promises).then(() => {
// 生成zip 文件
zip.generateAsync({
type: 'blob',
compression: 'DEFLATE', // STORE: 默认不压缩, DEFLATE需要压缩
compressionOptions: {
level: 9 // 压缩等级 1~9 1 压缩速度最快, 9 最优压缩方式
}
}).then((res) => {
saveAs(res, dataSource.ReviewerCode + '_CV.zip') // 使用FileSaver.saveAs保存文件文件名可自定义
resolve()
})
}).catch(reason => {
resolve()
})
})
},
// 下载指定语言类型的简历
handleDownloadResumes() {
this.btnLoading = true
this.model_cfg.showClose = false
getOfficialResume({
doctorIdList: this.selectArr,
language: this.language
}).then(async res => {
try {
this.btnLoading = false
this.model_cfg.visible = false
this.model_cfg.showClose = true
console.log(res.Result)
for (let i = 0; res.Result.length > i; i++) {
let item = res.Result[i]
console.log(item)
await this.handleBatchDown(item)
}
} catch (e) {
console.log(e)
}
// window.open(res.Result.FullFilePath)
}).catch(() => {
this.btnLoading = false
this.model_cfg.showClose = true
})
// downloadOfficialCV(this.selectArr, parseInt(this.language)).then(res => {
// this.btnLoading = false
// this.model_cfg.visible = false
// this.model_cfg.showClose = true
// window.open(res.Result.FullFilePath)
// }).catch(() => {
// this.btnLoading = false
// this.model_cfg.showClose = true
// })
},
// 查询
handleSelectSearch() {
this.searchData.PageIndex = 1
this.isShow = false
this.getList()
},
// language change事件回调
handleIsEnChange(val) {
this.setIsEnglish(val)
},
handleDownLoadOffical() {
this.language = 2
this.model_cfg.title = this.$t('trials:seletctedReviews:title:language')
this.model_cfg.visible = true
},
// 获取数据表排序类型及排序字段
sortByColumn(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()
},
// 获取勾选行数据
handleSelectChange(val) {
const arr = []
for (let index = 0; index < val.length; index++) {
arr.push(val[index].Id)
}
this.selectArr = arr
},
...mapMutations({
setQueryParam: 'reviewer/SET_QUERYPARAM',
setIsEnglish: 'reviewer/SET_ISENGLISH'
}),
hasResume(row) {
if (row.HasResume) {
return true
} else {
return false
}
}
}
}
</script>
<style lang="scss" scoped>
// .reviewers-list{
// .base-search-form{
// .el-form-item{
// margin-bottom: 0px;
// }
// }
// .page{
// text-align: right;
// margin-top: 5px;
// }
// }
</style>