项目列表、培训列表、影像质控列表导出
continuous-integration/drone/push Build is passing Details

uat_us
DESKTOP-6C3NK6N\WXS 2024-08-12 18:02:15 +08:00
parent b0ce6e0cb8
commit cd581041b9
4 changed files with 1270 additions and 710 deletions

View File

@ -160,3 +160,30 @@ export function getSubjectProgress_Export(param) {
data: param data: param
}) })
} }
// 导出项目列表
export function getTrialList_Export(data) {
return requestDownload({
url: `/ExcelExport/getTrialList_Export`,
responseType: 'blob',
method: 'post',
data
})
}
// 导出培训记录
export function pMTrainingRecordList_Export(data) {
return requestDownload({
url: `/ExcelExport/pMTrainingRecordList_Export`,
responseType: 'blob',
method: 'post',
data
})
}
// 导出影像指控
export function qCVisitList_Export(data) {
return requestDownload({
url: `/ExcelExport/qCVisitList_Export`,
responseType: 'blob',
method: 'post',
data
})
}

View File

@ -5,17 +5,13 @@
<el-form :inline="true"> <el-form :inline="true">
<!-- 项目编号 --> <!-- 项目编号 -->
<el-form-item :label="$t('trials:trials-list:table:trialId')"> <el-form-item :label="$t('trials:trials-list:table:trialId')">
<el-input <el-input v-model="searchData.Code" style="width: 100px" clearable />
v-model="searchData.Code"
style="width:100px;"
clearable
/>
</el-form-item> </el-form-item>
<!-- 研究方案号 --> <!-- 研究方案号 -->
<el-form-item :label="$t('trials:trials-list:table:researchNumber')"> <el-form-item :label="$t('trials:trials-list:table:researchNumber')">
<el-input <el-input
v-model="searchData.ResearchProgramNo" v-model="searchData.ResearchProgramNo"
style="width:100px;" style="width: 100px"
clearable clearable
/> />
</el-form-item> </el-form-item>
@ -23,7 +19,7 @@
<el-form-item :label="$t('trials:trials-list:table:experimentName')"> <el-form-item :label="$t('trials:trials-list:table:experimentName')">
<el-input <el-input
v-model="searchData.ExperimentName" v-model="searchData.ExperimentName"
style="width:100px;" style="width: 100px"
clearable clearable
/> />
</el-form-item> </el-form-item>
@ -32,11 +28,11 @@
<el-form-item :label="$t('trials:trials-list:table:sponsor')"> <el-form-item :label="$t('trials:trials-list:table:sponsor')">
<el-select <el-select
v-model="searchData.SponsorId" v-model="searchData.SponsorId"
style="width:150px;" style="width: 150px"
clearable clearable
> >
<el-option <el-option
v-for="(item) in sponsorList" v-for="item in sponsorList"
:key="item.Id" :key="item.Id"
:label="item.SponsorName" :label="item.SponsorName"
:value="item.Id" :value="item.Id"
@ -44,14 +40,17 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 阅片标准 --> <!-- 阅片标准 -->
<el-form-item :label="$t('trials:trials-list:table:IR_ReadingCriterionList')" v-if="hasPermi(['role:ir'])"> <el-form-item
:label="$t('trials:trials-list:table:IR_ReadingCriterionList')"
v-if="hasPermi(['role:ir'])"
>
<el-select <el-select
v-model="searchData.CriterionType" v-model="searchData.CriterionType"
style="width:150px;" style="width: 150px"
clearable clearable
> >
<el-option <el-option
v-for="(item) in $d.CriterionType" v-for="item in $d.CriterionType"
:key="item.id" :key="item.id"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
@ -59,10 +58,13 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 联系人 --> <!-- 联系人 -->
<el-form-item :label="$t('trials:trials-list:table:IR_PMEmailList')" v-if="hasPermi(['role:ir'])"> <el-form-item
<el-input :label="$t('trials:trials-list:table:IR_PMEmailList')"
v-if="hasPermi(['role:ir'])"
>
<el-input
v-model="searchData.PM_EMail" v-model="searchData.PM_EMail"
style="width:100px;" style="width: 100px"
clearable clearable
/> />
</el-form-item> </el-form-item>
@ -70,26 +72,29 @@
<!-- <el-button type="text" @click="isShow = !isShow">More</el-button> --> <!-- <el-button type="text" @click="isShow = !isShow">More</el-button> -->
<!-- Search --> <!-- Search -->
<el-button type="primary" icon="el-icon-search" @click="handleSearch"> <el-button type="primary" icon="el-icon-search" @click="handleSearch">
{{ $t('common:button:search') }} {{ $t("common:button:search") }}
</el-button> </el-button>
<!-- Reset --> <!-- Reset -->
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset"> <el-button
{{ $t('common:button:reset') }} type="primary"
icon="el-icon-refresh-left"
@click="handleReset"
>
{{ $t("common:button:reset") }}
</el-button> </el-button>
<!-- Export --> <!-- Export -->
<el-button <el-button
v-hasPermi="['trials:trials-list:export']" v-hasPermi="['trials:trials-list:export']"
type="primary" type="primary"
icon="el-icon-download" icon="el-icon-download"
:disabled="!(selectArr.length>0)" :loading="exportLoading"
@click="handleExportTrial" @click="handleExportTrial"
> >
{{ $t('common:button:export') }} {{ $t("common:button:export") }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span style="margin-left:auto;"> <span style="margin-left: auto">
<!-- New --> <!-- New -->
<el-button <el-button
v-hasPermi="['trials:trials-list:new']" v-hasPermi="['trials:trials-list:new']"
@ -97,24 +102,20 @@
type="primary" type="primary"
@click="handleNew" @click="handleNew"
> >
{{ $t('common:button:new') }} {{ $t("common:button:new") }}
</el-button> </el-button>
</span> </span>
</template> </template>
<!-- 更多搜索条件 --> <!-- 更多搜索条件 -->
<el-drawer <el-drawer :visible.sync="isShow" :with-header="false" size="390px">
:visible.sync="isShow" <div style="padding: 10px">
:with-header="false"
size="390px"
>
<div style="padding:10px;">
<el-form label-width="140px"> <el-form label-width="140px">
<el-form-item label="Trial ID"> <el-form-item label="Trial ID">
<el-input <el-input
v-model="searchData.Code" v-model="searchData.Code"
placeholder="Trial ID" placeholder="Trial ID"
style="width:100%;" style="width: 100%"
clearable clearable
/> />
</el-form-item> </el-form-item>
@ -122,7 +123,7 @@
<el-input <el-input
v-model="searchData.Indication" v-model="searchData.Indication"
placeholder="Indication" placeholder="Indication"
style="width:100%;" style="width: 100%"
clearable clearable
/> />
</el-form-item> </el-form-item>
@ -130,7 +131,7 @@
<el-select <el-select
v-model="searchData.CriterionIds" v-model="searchData.CriterionIds"
placeholder="Assessment Criteria" placeholder="Assessment Criteria"
style="width:100%;" style="width: 100%"
clearable clearable
multiple multiple
> >
@ -152,11 +153,11 @@
<el-select <el-select
v-model="searchData.SponsorId" v-model="searchData.SponsorId"
placeholder="Sponsor" placeholder="Sponsor"
style="width:100%;" style="width: 100%"
clearable clearable
> >
<el-option <el-option
v-for="(item) in sponsorList" v-for="item in sponsorList"
:key="item.Id" :key="item.Id"
:label="item.SponsorName" :label="item.SponsorName"
:value="item.Id" :value="item.Id"
@ -164,9 +165,14 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="CRO"> <el-form-item label="CRO">
<el-select v-model="searchData.CROId" placeholder="CRO" style="width:100%;" clearable> <el-select
v-model="searchData.CROId"
placeholder="CRO"
style="width: 100%"
clearable
>
<el-option <el-option
v-for="(item) of croList" v-for="item of croList"
:key="item.Id" :key="item.Id"
:label="item.CROName" :label="item.CROName"
:value="item.Id" :value="item.Id"
@ -177,7 +183,7 @@
<el-select <el-select
v-model="searchData.Phase" v-model="searchData.Phase"
placeholder="Phase" placeholder="Phase"
style="width:100%;" style="width: 100%"
clearable clearable
> >
<el-option <el-option
@ -193,7 +199,7 @@
<el-select <el-select
v-model="searchData.ReviewTypeIds" v-model="searchData.ReviewTypeIds"
placeholder="ReviewType" placeholder="ReviewType"
style="width:100%;" style="width: 100%"
clearable clearable
multiple multiple
> >
@ -216,7 +222,7 @@
v-model="searchData.ModalityIds" v-model="searchData.ModalityIds"
multiple multiple
placeholder="Modality" placeholder="Modality"
style="width:100%;" style="width: 100%"
clearable clearable
> >
<!-- <el-option <!-- <el-option
@ -234,7 +240,12 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="Expedited: "> <el-form-item label="Expedited: ">
<el-select v-model="searchData.Expedited" value-key="value" clearable style="width:100%;"> <el-select
v-model="searchData.Expedited"
value-key="value"
clearable
style="width: 100%"
>
<el-option <el-option
v-for="item in expeditedOption" v-for="item in expeditedOption"
:key="item.value" :key="item.value"
@ -251,7 +262,7 @@
type="date" type="date"
:picker-options="beginPickerOption" :picker-options="beginPickerOption"
:clearable="false" :clearable="false"
style="width:100%;" style="width: 100%"
/> />
</el-form-item> </el-form-item>
<el-form-item label="EndDate: "> <el-form-item label="EndDate: ">
@ -262,7 +273,7 @@
type="date" type="date"
:picker-options="endpickerOption" :picker-options="endpickerOption"
:clearable="false" :clearable="false"
style="width:100%;" style="width: 100%"
/> />
</el-form-item> </el-form-item>
@ -270,16 +281,23 @@
<el-select <el-select
v-model="searchData.AttendedReviewerType" v-model="searchData.AttendedReviewerType"
placeholder="Attended Reviewer Type" placeholder="Attended Reviewer Type"
style="width:100%;" style="width: 100%"
clearable clearable
> >
<el-option v-for="item of $d.AttendedReviewerType" :key="item.value" :label="item.label" :value="item.value" /> <el-option
v-for="item of $d.AttendedReviewerType"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="handleSelectSearch">Search</el-button> <el-button type="primary" @click="handleSelectSearch"
>Search</el-button
>
<el-button type="primary" @click="handleReset">Reset</el-button> <el-button type="primary" @click="handleReset">Reset</el-button>
<el-button type="primary" @click="isShow=false">Back</el-button> <el-button type="primary" @click="isShow = false">Back</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -288,7 +306,7 @@
<!-- 项目列表 --> <!-- 项目列表 -->
<template slot="main-container"> <template slot="main-container">
<el-table <el-table
v-adaptive="{bottomOffset:60}" v-adaptive="{ bottomOffset: 60 }"
v-loading="listLoading" v-loading="listLoading"
:data="list" :data="list"
stripe stripe
@ -336,10 +354,26 @@
min-width="120" min-width="120"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.TrialStatusStr === 'Initializing'" type="info">{{ $fd('TrialStatusEnum', scope.row.TrialStatusStr) }}</el-tag> <el-tag
<el-tag v-if="scope.row.TrialStatusStr === 'Ongoing'" type="primary">{{ $fd('TrialStatusEnum', scope.row.TrialStatusStr) }}</el-tag> v-if="scope.row.TrialStatusStr === 'Initializing'"
<el-tag v-if="scope.row.TrialStatusStr === 'Completed'" type="warning">{{ $fd('TrialStatusEnum', scope.row.TrialStatusStr) }}</el-tag> type="info"
<el-tag v-if="scope.row.TrialStatusStr === 'Stopped'" type="danger">{{ $fd('TrialStatusEnum', scope.row.TrialStatusStr) }}</el-tag> >{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag
>
<el-tag
v-if="scope.row.TrialStatusStr === 'Ongoing'"
type="primary"
>{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag
>
<el-tag
v-if="scope.row.TrialStatusStr === 'Completed'"
type="warning"
>{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag
>
<el-tag
v-if="scope.row.TrialStatusStr === 'Stopped'"
type="danger"
>{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag
>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@ -406,7 +440,7 @@
min-width="160" min-width="160"
> >
<template slot-scope="scope"> <template slot-scope="scope">
{{scope.row.IR_ReadingCriterionList.join(', ')}} {{ scope.row.IR_ReadingCriterionList.join(", ") }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@ -441,7 +475,7 @@
min-width="170" min-width="170"
> >
<template slot-scope="scope"> <template slot-scope="scope">
{{scope.row.IR_PMEmailList.join(', ')}} {{ scope.row.IR_PMEmailList.join(", ") }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@ -519,7 +553,9 @@
<el-table-column <el-table-column
v-if="hasPermi(['role:spm', 'role:cpm'])" v-if="hasPermi(['role:spm', 'role:cpm'])"
prop="SPM_ReviewerSelectApprovalCount" prop="SPM_ReviewerSelectApprovalCount"
:label="$t('trials:trials-list:table:SPM_ReviewerSelectApprovalCount')" :label="
$t('trials:trials-list:table:SPM_ReviewerSelectApprovalCount')
"
show-overflow-tooltip show-overflow-tooltip
sortable="custom" sortable="custom"
min-width="160" min-width="160"
@ -543,7 +579,11 @@
v-hasPermi="['trials:trials-list:panel']" v-hasPermi="['trials:trials-list:panel']"
circle circle
icon="el-icon-info" icon="el-icon-info"
:disabled="(scope.row.TrialStatusStr === 'Initializing' && !hasPermi(['role:pm'])) || scope.row.IsDeleted" :disabled="
(scope.row.TrialStatusStr === 'Initializing' &&
!hasPermi(['role:pm'])) ||
scope.row.IsDeleted
"
:title="$t('trials:trials-list:action:panel')" :title="$t('trials:trials-list:action:panel')"
@click.stop="handleDetail(scope.row)" @click.stop="handleDetail(scope.row)"
/> />
@ -570,19 +610,22 @@
v-hasPermi="['trials:trials-list:abolish']" v-hasPermi="['trials:trials-list:abolish']"
circle circle
icon="el-icon-delete" icon="el-icon-delete"
:disabled="scope.row.IsDeleted || scope.row.TrialStatusStr !== 'Initializing'" :disabled="
scope.row.IsDeleted ||
scope.row.TrialStatusStr !== 'Initializing'
"
:title="$t('trials:trials-list:action:abolition')" :title="$t('trials:trials-list:action:abolition')"
@click.stop="handleAbandon(scope.row)" @click.stop="handleAbandon(scope.row)"
/> />
<!-- 代办详情--> <!-- 代办详情-->
<!-- <el-button--> <!-- <el-button-->
<!-- v-hasPermi="['trials:trials-list:abolish']"--> <!-- v-hasPermi="['trials:trials-list:abolish']"-->
<!-- circle--> <!-- circle-->
<!-- icon="el-icon-receiving"--> <!-- icon="el-icon-receiving"-->
<!-- :disabled="scope.row.TrialStatusStr === 'Initializing'"--> <!-- :disabled="scope.row.TrialStatusStr === 'Initializing'"-->
<!-- :title="$t('trials:trials-list:action:commission')"--> <!-- :title="$t('trials:trials-list:action:commission')"-->
<!-- @click.stop="handleCommission(scope.row)"--> <!-- @click.stop="handleCommission(scope.row)"-->
<!-- />--> <!-- />-->
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -606,7 +649,11 @@
append-to-body append-to-body
custom-class="base-dialog-wrapper" custom-class="base-dialog-wrapper"
> >
<TrialForm :trial-id="currentId" @getList="getList" @closeDialog="closeDialog" /> <TrialForm
:trial-id="currentId"
@getList="getList"
@closeDialog="closeDialog"
/>
</el-dialog> </el-dialog>
<!-- 修改项目状态 --> <!-- 修改项目状态 -->
@ -619,7 +666,11 @@
custom-class="base-dialog-wrapper" custom-class="base-dialog-wrapper"
append-to-body append-to-body
> >
<TrialStatusForm :data="currentRow" @closeDialog="closeStatusDialog" @getList="getList" /> <TrialStatusForm
:data="currentRow"
@closeDialog="closeStatusDialog"
@getList="getList"
/>
</el-dialog> </el-dialog>
<el-dialog <el-dialog
@ -630,51 +681,66 @@
append-to-body append-to-body
custom-class="base-dialog-wrapper" custom-class="base-dialog-wrapper"
> >
<DoneList :trial-id="currentId" @getList="getList" @closeDialog="doneDialogVisible = false" /> <DoneList
:trial-id="currentId"
@getList="getList"
@closeDialog="doneDialogVisible = false"
/>
</el-dialog> </el-dialog>
</BaseContainer> </BaseContainer>
</template> </template>
<script> <script>
import { abandonTrial, ifTrialCanOngoing, getTrialToBeDoneList } from '@/api/trials' import {
import store from '@/store' abandonTrial,
import { mapGetters } from 'vuex' ifTrialCanOngoing,
import Excel from 'exceljs' getTrialToBeDoneList,
import BaseContainer from '@/components/BaseContainer' } from "@/api/trials";
import Pagination from '@/components/Pagination' import { getTrialList_Export } from "@/api/export";
import TrialForm from './components/TrialForm' import store from "@/store";
import TrialStatusForm from './components/TrialStatusForm' import { mapGetters } from "vuex";
import DoneList from './components/DoneList' import BaseContainer from "@/components/BaseContainer";
import Pagination from "@/components/Pagination";
import TrialForm from "./components/TrialForm";
import TrialStatusForm from "./components/TrialStatusForm";
import DoneList from "./components/DoneList";
const searchDataDefault = () => { const searchDataDefault = () => {
return { return {
Code: '', Code: "",
CriterionIds: [], CriterionIds: [],
SponsorId: '', SponsorId: "",
ReviewTypeIds: [], ReviewTypeIds: [],
CROId: '', CROId: "",
Expedited: '', Expedited: "",
Indication: '', Indication: "",
Phase: '', Phase: "",
ModalityIds: [], ModalityIds: [],
BeginDate: '', BeginDate: "",
EndDate: '', EndDate: "",
AttendedReviewerType: '', AttendedReviewerType: "",
ResearchProgramNo: '', ResearchProgramNo: "",
ExperimentName: '', ExperimentName: "",
PageIndex: 1, PageIndex: 1,
PageSize: 20, PageSize: 20,
Asc: false, Asc: false,
SortField: '', SortField: "",
CriterionType:null, CriterionType: null,
PM_EMail:null, PM_EMail: null,
} };
} };
export default { export default {
name: 'Trials', name: "Trials",
components: { Pagination, BaseContainer, TrialForm, TrialStatusForm, DoneList }, components: {
dicts: ['ReadingStandard', 'ReviewType', 'ReadingType'], Pagination,
BaseContainer,
TrialForm,
TrialStatusForm,
DoneList,
},
dicts: ["ReadingStandard", "ReviewType", "ReadingType"],
data() { data() {
return { return {
userTypeEnumInt: zzSessionStorage.getItem('userTypeEnumInt') * 1, exportLoading: false,
userTypeEnumInt: zzSessionStorage.getItem("userTypeEnumInt") * 1,
doneDialogVisible: false, doneDialogVisible: false,
doneTitle: null, doneTitle: null,
selectArr: [], selectArr: [],
@ -684,192 +750,224 @@ export default {
total: 0, total: 0,
isShow: false, isShow: false,
dialogVisible: false, dialogVisible: false,
title: '', title: "",
currentId: '', currentId: "",
statusVisible: false, statusVisible: false,
currentRow: {}, currentRow: {},
currentUser: zzSessionStorage.getItem('userName'), currentUser: zzSessionStorage.getItem("userName"),
phaseOptions: [ phaseOptions: [
{ value: 'I' }, { value: "I" },
{ value: 'II' }, { value: "II" },
{ value: 'III' }, { value: "III" },
{ value: 'IV' } { value: "IV" },
], ],
expeditedOption: this.$d.TrialExpeditedState, expeditedOption: this.$d.TrialExpeditedState,
beginPickerOption: { beginPickerOption: {
disabledDate: time => { disabledDate: (time) => {
if (this.searchData.EndDate) { if (this.searchData.EndDate) {
return time.getTime() > new Date(this.searchData.EndDate).getTime() return time.getTime() > new Date(this.searchData.EndDate).getTime();
} else { } else {
return time.getTime() > Date.now() return time.getTime() > Date.now();
} }
} },
}, },
endpickerOption: { endpickerOption: {
disabledDate: time => { disabledDate: (time) => {
if (this.searchData.BeginDate) { if (this.searchData.BeginDate) {
return time.getTime() > Date.now() || time.getTime() <= new Date(this.searchData.BeginDate).getTime() return (
time.getTime() > Date.now() ||
time.getTime() <= new Date(this.searchData.BeginDate).getTime()
);
} else { } else {
return time.getTime() > Date.now() return time.getTime() > Date.now();
} }
} },
} },
} };
}, },
computed: { computed: {
...mapGetters(['sponsorList', 'croList']) ...mapGetters(["sponsorList", "croList"]),
}, },
created() { created() {
this.initPage() this.initPage();
}, },
methods: { methods: {
initPage() { initPage() {
this.getList() this.getList();
store.dispatch('global/getSponsorList') store.dispatch("global/getSponsorList");
store.dispatch('global/getCROList') store.dispatch("global/getCROList");
}, },
// //
getList() { getList() {
this.listLoading = true this.listLoading = true;
getTrialToBeDoneList(this.searchData) getTrialToBeDoneList(this.searchData)
.then(res => { .then((res) => {
this.list = res.Result.CurrentPageData this.list = res.Result.CurrentPageData;
this.total = res.Result.TotalCount this.total = res.Result.TotalCount;
this.listLoading = false this.listLoading = false;
}) })
.catch(() => { .catch(() => {
this.listLoading = false this.listLoading = false;
}) });
}, },
// //
handleSearch() { handleSearch() {
this.searchData.PageIndex = 1 this.searchData.PageIndex = 1;
this.getList() this.getList();
}, },
// //
handleSelectSearch() { handleSelectSearch() {
this.searchData.PageIndex = 1 this.searchData.PageIndex = 1;
this.getList() this.getList();
this.isShow = false this.isShow = false;
}, },
// //
handleReset() { handleReset() {
this.searchData = searchDataDefault() this.searchData = searchDataDefault();
this.getList() this.getList();
}, },
// //
handleNew() { handleNew() {
// this.$router.push({ name: 'CreateTrial' }) // this.$router.push({ name: 'CreateTrial' })
this.title = this.$t('trials:trials-list:dialogTitle:new') this.title = this.$t("trials:trials-list:dialogTitle:new");
this.currentId = '' this.currentId = "";
this.dialogVisible = true this.dialogVisible = true;
}, },
// //
handleEdit(row) { handleEdit(row) {
this.title = this.$t('trials:trials-list:dialogTitle:edit') this.title = this.$t("trials:trials-list:dialogTitle:edit");
this.currentId = row.Id this.currentId = row.Id;
this.dialogVisible = true this.dialogVisible = true;
}, },
handleCommission(row) { handleCommission(row) {
this.doneTitle = this.$t('trials:trials-list:dialogTitle:doneTitle') this.doneTitle = this.$t("trials:trials-list:dialogTitle:doneTitle");
this.currentId = row.Id this.currentId = row.Id;
this.doneDialogVisible = true this.doneDialogVisible = true;
}, },
closeDialog() { closeDialog() {
this.dialogVisible = false this.dialogVisible = false;
}, },
// //
handleStatus(row) { handleStatus(row) {
if (row.TrialStatusStr === 'Initializing') { if (row.TrialStatusStr === "Initializing") {
this.listLoading = true this.listLoading = true;
ifTrialCanOngoing(row.Id).then(res => { ifTrialCanOngoing(row.Id)
this.listLoading = false .then((res) => {
if (res.Result) { this.listLoading = false;
this.currentRow = { ...row } if (res.Result) {
this.statusVisible = true this.currentRow = { ...row };
} else { this.statusVisible = true;
this.$confirm(res.ErrorMessage, { } else {
type: 'warning', this.$confirm(res.ErrorMessage, {
showCancelButton: false, type: "warning",
callback: action => {} showCancelButton: false,
}) callback: (action) => {},
} });
}).catch(() => { this.listLoading = false }) }
})
.catch(() => {
this.listLoading = false;
});
} else { } else {
this.currentRow = { ...row } this.currentRow = { ...row };
this.statusVisible = true this.statusVisible = true;
} }
}, },
closeStatusDialog() { closeStatusDialog() {
this.statusVisible = false this.statusVisible = false;
}, },
// //
handleAbandon(row) { handleAbandon(row) {
this.$confirm(this.$t('trials:trials-list:message:abolition'), { this.$confirm(this.$t("trials:trials-list:message:abolition"), {
type: 'warning', type: "warning",
distinguishCancelAndClose: true distinguishCancelAndClose: true,
}).then(() => { })
this.currentRow = { ...row } .then(() => {
this.abandonTrial() this.currentRow = { ...row };
}).catch(() => {}) this.abandonTrial();
})
.catch(() => {});
}, },
// //
abandonTrial() { abandonTrial() {
this.listLoading = true this.listLoading = true;
abandonTrial(this.currentRow.Id, true) abandonTrial(this.currentRow.Id, true)
.then(res => { .then((res) => {
this.listLoading = false this.listLoading = false;
if (res.IsSuccess) { if (res.IsSuccess) {
this.getList() this.getList();
this.$message.success(this.$t('trials:trials-list:message:abolitionSuccessfully')) this.$message.success(
this.$t("trials:trials-list:message:abolitionSuccessfully")
);
} }
}).catch(() => { this.listLoading = false }) })
.catch(() => {
this.listLoading = false;
});
}, },
rowClick(row, col) { rowClick(row, col) {
if (row.TrialStatusStr === 'Initializing' && !this.hasPermi(['role:pm']) || row.IsDeleted) return if (
this.$router.push({ path: `/trials/trials-panel?trialId=${row.Id}&trialCode=${row.TrialCode}&researchProgramNo=${row.ResearchProgramNo}` }) (row.TrialStatusStr === "Initializing" &&
!this.hasPermi(["role:pm"])) ||
row.IsDeleted
)
return;
this.$router.push({
path: `/trials/trials-panel?trialId=${row.Id}&trialCode=${row.TrialCode}&researchProgramNo=${row.ResearchProgramNo}`,
});
}, },
// panel // panel
handleDetail(row) { handleDetail(row) {
this.$router.push({ path: `/trials/trials-panel?trialId=${row.Id}&trialCode=${row.TrialCode}&researchProgramNo=${row.ResearchProgramNo}` }) this.$router.push({
path: `/trials/trials-panel?trialId=${row.Id}&trialCode=${row.TrialCode}&researchProgramNo=${row.ResearchProgramNo}`,
});
}, },
// //
handleSelectChange(val) { handleSelectChange(val) {
const arr = [] const arr = [];
for (let index = 0; index < val.length; index++) { for (let index = 0; index < val.length; index++) {
arr.push(val[index]) arr.push(val[index]);
} }
this.selectArr = arr this.selectArr = arr;
}, },
// //
handleSortChange(column) { handleSortChange(column) {
if (column.order === 'ascending') { if (column.order === "ascending") {
this.searchData.Asc = true this.searchData.Asc = true;
} else { } else {
this.searchData.Asc = false this.searchData.Asc = false;
} if (column.prop === 'Criterion') {
this.searchData.SortField = 'CriterionId'
} else {
this.searchData.SortField = column.prop
} }
this.searchData.PageIndex = 1 if (column.prop === "Criterion") {
this.getList() this.searchData.SortField = "CriterionId";
} else {
this.searchData.SortField = column.prop;
}
this.searchData.PageIndex = 1;
this.getList();
}, },
// Excel // Excel
handleExportTrial() { handleExportTrial() {
this.exportLoading = true;
return getTrialList_Export(this.searchData)
.then((res) => {
this.exportLoading = false;
})
.catch(() => {
this.exportLoading = false;
});
this.selectArr.forEach((element, index) => { this.selectArr.forEach((element, index) => {
// element.ExpeditedStr = element.Expedited === 0 ? 'No' : element.Expedited === 1 ? '24H' : '48H' // element.ExpeditedStr = element.Expedited === 0 ? 'No' : element.Expedited === 1 ? '24H' : '48H'
// element.ModalityListStr = element.ModalityList.join(', ') // element.ModalityListStr = element.ModalityList.join(', ')
// element.CreateTimeStr = element.CreateTime // element.CreateTimeStr = element.CreateTime
// element.Criterion = element.CriterionList.join(', ') // element.Criterion = element.CriterionList.join(', ')
element.Deleted = element.IsDeleted ? 'Yes' : 'No' element.Deleted = element.IsDeleted ? "Yes" : "No";
element.Index = (index + 1) element.Index = index + 1;
}) });
var workbook = new Excel.Workbook() var workbook = new Excel.Workbook();
var sheet = workbook.addWorksheet('Trials') var sheet = workbook.addWorksheet("Trials");
sheet.properties.defaultRowHeight = 22 sheet.properties.defaultRowHeight = 22;
// sheet.columns = [ // sheet.columns = [
// { key: 'Index', width: 5 }, // { key: 'Index', width: 5 },
// { key: 'Code', width: 15 }, // { key: 'Code', width: 15 },
@ -885,102 +983,96 @@ export default {
// { key: 'CreateTimeStr', width: 18 } // { key: 'CreateTimeStr', width: 18 }
// ] // ]
sheet.columns = [ sheet.columns = [
{ key: 'Index', width: 5 }, { key: "Index", width: 5 },
{ key: 'TrialCode', width: 25 }, { key: "TrialCode", width: 25 },
{ key: 'ExperimentName', width: 25 }, { key: "ExperimentName", width: 25 },
{ key: 'ResearchProgramNo', width: 25 }, { key: "ResearchProgramNo", width: 25 },
{ key: 'Sponsor', width: 25 }, { key: "Sponsor", width: 25 },
{ key: 'Deleted', width: 10 }, { key: "Deleted", width: 10 },
{ key: 'CreateTime', width: 25 } { key: "CreateTime", width: 25 },
] ];
// //
sheet.mergeCells('A1', 'G2') sheet.mergeCells("A1", "G2");
sheet.getCell('A1').value = 'Trials' sheet.getCell("A1").value = "Trials";
sheet.getCell('A1').alignment = { sheet.getCell("A1").alignment = {
vertical: 'middle', vertical: "middle",
horizontal: 'center' horizontal: "center",
} };
sheet.getCell('A1').font = { sheet.getCell("A1").font = {
name: 'SimSun', name: "SimSun",
family: 4, family: 4,
size: 13, size: 13,
bold: true bold: true,
} };
sheet.mergeCells('A3', 'G3') sheet.mergeCells("A3", "G3");
var now = new Date() var now = new Date();
sheet.getCell('A3').value = now.toLocaleDateString() sheet.getCell("A3").value = now.toLocaleDateString();
sheet.getCell('A3').alignment = { sheet.getCell("A3").alignment = {
vertical: 'middle', vertical: "middle",
horizontal: 'right' horizontal: "right",
} };
sheet.getRow(4).values = [ sheet.getRow(4).values = [
'NO.', "NO.",
'Trial ID', "Trial ID",
'试验名称', "试验名称",
'研究方案号', "研究方案号",
'申办方', "申办方",
'是否废除', "是否废除",
'Date Created' "Date Created",
] ];
sheet.getRow(4).font = { sheet.getRow(4).font = {
name: 'SimSun', name: "SimSun",
family: 4, family: 4,
size: 11, size: 11,
bold: true bold: true,
} };
sheet.getRow(4).alignment = { vertical: 'middle', horizontal: 'left' } sheet.getRow(4).alignment = { vertical: "middle", horizontal: "left" };
sheet.addRows(this.selectArr) sheet.addRows(this.selectArr);
sheet.eachRow((row, number) => { sheet.eachRow((row, number) => {
if (number > 3) { if (number > 3) {
row.eachCell((cell, rowNumber) => { row.eachCell((cell, rowNumber) => {
cell.alignment = { vertical: 'center', horizontal: 'left' } cell.alignment = { vertical: "center", horizontal: "left" };
cell.border = { cell.border = {
top: { style: 'thin' }, top: { style: "thin" },
left: { style: 'thin' }, left: { style: "thin" },
bottom: { style: 'thin' }, bottom: { style: "thin" },
right: { style: 'thin' } right: { style: "thin" },
} };
}) });
} }
}) });
workbook.xlsx workbook.xlsx
.writeBuffer({ .writeBuffer({
base64: true base64: true,
}) })
.then(function(xls64) { .then(function (xls64) {
var data = new Blob([xls64], { var data = new Blob([xls64], {
type: type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
})
if ('msSaveOrOpenBlob' in navigator) { if ("msSaveOrOpenBlob" in navigator) {
// ie使 // ie使
window.navigator.msSaveOrOpenBlob( window.navigator.msSaveOrOpenBlob(data, "Trials" + ".xlsx");
data,
'Trials' + '.xlsx'
)
} else { } else {
var a = document.createElement('a') var a = document.createElement("a");
var url = URL.createObjectURL(data) var url = URL.createObjectURL(data);
a.href = url a.href = url;
a.download = a.download = "Trials" + ".xlsx";
'Trials' + '.xlsx' document.body.appendChild(a);
document.body.appendChild(a) a.click();
a.click() setTimeout(function () {
setTimeout(function() { document.body.removeChild(a);
document.body.removeChild(a) window.URL.revokeObjectURL(url);
window.URL.revokeObjectURL(url) }, 0);
}, 0)
} }
}) });
} },
},
} };
}
</script> </script>

View File

@ -5,10 +5,7 @@
<el-form :inline="true"> <el-form :inline="true">
<!-- 文件类型 --> <!-- 文件类型 -->
<el-form-item :label="$t('trials:signRecords:table:fileType')"> <el-form-item :label="$t('trials:signRecords:table:fileType')">
<el-select <el-select v-model="searchData.FileTypeId" style="width: 150px">
v-model="searchData.FileTypeId"
style="width:150px;"
>
<el-option <el-option
v-for="item of typeOptions" v-for="item of typeOptions"
:key="item.FileTypeId" :key="item.FileTypeId"
@ -19,19 +16,31 @@
</el-form-item> </el-form-item>
<!-- 文件名称 --> <!-- 文件名称 -->
<el-form-item :label="$t('trials:signRecords:table:fileName')"> <el-form-item :label="$t('trials:signRecords:table:fileName')">
<el-input v-model="searchData.Name" style="width:120px;" /> <el-input v-model="searchData.Name" style="width: 120px" />
</el-form-item> </el-form-item>
<!-- 签署人 --> <!-- 签署人 -->
<el-form-item :label="$t('trials:signRecords:table:user')"> <el-form-item :label="$t('trials:signRecords:table:user')">
<el-select v-model="searchData.UserId" clearable filterable style="width:140px;"> <el-select
v-model="searchData.UserId"
clearable
filterable
style="width: 140px"
>
<el-option <el-option
v-for="(item) of userOptions" v-for="item of userOptions"
:key="item.UserId" :key="item.UserId"
:label="item.RealName" :label="item.RealName"
:value="item.UserId" :value="item.UserId"
> >
<span style="float: left">{{ item.RealName }}</span> <span style="float: left">{{ item.RealName }}</span>
<span style="float: right; color: #8492a6; font-size: 13px;margin-left:5px;"> <span
style="
float: right;
color: #8492a6;
font-size: 13px;
margin-left: 5px;
"
>
{{ item.UserName }} {{ item.UserName }}
</span> </span>
</el-option> </el-option>
@ -43,7 +52,7 @@
v-model="searchData.UserTypeId" v-model="searchData.UserTypeId"
clearable clearable
filterable filterable
style="width:120px;" style="width: 120px"
> >
<el-option <el-option
v-for="item of userTypeOptions" v-for="item of userTypeOptions"
@ -57,23 +66,54 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="$t('trials:signRecords:table:isSign')"> <el-form-item :label="$t('trials:signRecords:table:isSign')">
<el-select v-model="searchData.IsConfirmed" clearable style="width:120px;"> <el-select
<el-option v-for="i of $d.YesOrNo" :key="'IsConfirmed' + i.label" :value="i.value" :label="i.label" /> v-model="searchData.IsConfirmed"
clearable
style="width: 120px"
>
<el-option
v-for="i of $d.YesOrNo"
:key="'IsConfirmed' + i.label"
:value="i.value"
:label="i.label"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="$t('trials:signRecords:table:isDeleted')"> <el-form-item :label="$t('trials:signRecords:table:isDeleted')">
<el-select v-model="searchData.IsDeleted" clearable style="width:120px;"> <el-select
<el-option v-for="i of $d.YesOrNo" :key="'IsDeleted' + i.label" :value="i.value" :label="i.label" /> v-model="searchData.IsDeleted"
clearable
style="width: 120px"
>
<el-option
v-for="i of $d.YesOrNo"
:key="'IsDeleted' + i.label"
:value="i.value"
:label="i.label"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<!-- 查询 --> <!-- 查询 -->
<el-button icon="el-icon-search" type="primary" @click="handleSearch"> <el-button icon="el-icon-search" type="primary" @click="handleSearch">
{{ $t('common:button:search') }} {{ $t("common:button:search") }}
</el-button> </el-button>
<!-- 重置 --> <!-- 重置 -->
<el-button icon="el-icon-refresh-left" type="primary" @click="handleReset"> <el-button
{{ $t('common:button:reset') }} icon="el-icon-refresh-left"
type="primary"
@click="handleReset"
>
{{ $t("common:button:reset") }}
</el-button>
<!-- 导出 -->
<el-button
type="primary"
icon="el-icon-download"
:loading="exportLoading"
@click="handleExport"
>
{{ $t("common:button:export") }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -84,7 +124,7 @@
<el-table <el-table
ref="AttachmentsManagement" ref="AttachmentsManagement"
v-loading="loading" v-loading="loading"
v-adaptive="{bottomOffset:60}" v-adaptive="{ bottomOffset: 60 }"
:data="list" :data="list"
stripe stripe
height="100" height="100"
@ -115,8 +155,12 @@
sortable="custom" sortable="custom"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.IsSystemDoc" type="primary">{{ $fd('IsSystemDoc', scope.row.IsSystemDoc) }}</el-tag> <el-tag v-if="scope.row.IsSystemDoc" type="primary">{{
<el-tag v-else type="warning">{{ $fd('IsSystemDoc', scope.row.IsSystemDoc) }}</el-tag> $fd("IsSystemDoc", scope.row.IsSystemDoc)
}}</el-tag>
<el-tag v-else type="warning">{{
$fd("IsSystemDoc", scope.row.IsSystemDoc)
}}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<!-- 是否废除 --> <!-- 是否废除 -->
@ -127,8 +171,12 @@
sortable="custom" sortable="custom"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.IsDeleted" type="danger">{{ $fd('YesOrNo', scope.row.IsDeleted) }}</el-tag> <el-tag v-if="scope.row.IsDeleted" type="danger">{{
<el-tag v-else type="primary">{{ $fd('YesOrNo', scope.row.IsDeleted) }}</el-tag> $fd("YesOrNo", scope.row.IsDeleted)
}}</el-tag>
<el-tag v-else type="primary">{{
$fd("YesOrNo", scope.row.IsDeleted)
}}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<!-- 上传时间 --> <!-- 上传时间 -->
@ -147,8 +195,12 @@
sortable="custom" sortable="custom"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="!scope.row.IsConfirmed" type="primary">{{ $fd('YesOrNo', scope.row.IsConfirmed) }}</el-tag> <el-tag v-if="!scope.row.IsConfirmed" type="primary">{{
<el-tag v-else type="danger">{{ $fd('YesOrNo', scope.row.IsConfirmed) }}</el-tag> $fd("YesOrNo", scope.row.IsConfirmed)
}}</el-tag>
<el-tag v-else type="danger">{{
$fd("YesOrNo", scope.row.IsConfirmed)
}}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<!-- 签署人 --> <!-- 签署人 -->
@ -193,7 +245,13 @@
</el-table> </el-table>
<!-- 分页组件 --> <!-- 分页组件 -->
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize" @pagination="getList" /> <pagination
class="page"
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
</template> </template>
<!-- 预览文件 --> <!-- 预览文件 -->
@ -205,32 +263,45 @@
append-to-body append-to-body
custom-class="base-dialog-wrapper" custom-class="base-dialog-wrapper"
> >
<div class="base-modal-body" style="border:2px solid #ccc;padding: 10px"> <div
<PreviewFile v-if="previewVisible" :file-path="currentPath" :file-type="currentType" @getList="getList" /> class="base-modal-body"
style="border: 2px solid #ccc; padding: 10px"
>
<PreviewFile
v-if="previewVisible"
:file-path="currentPath"
:file-type="currentType"
@getList="getList"
/>
</div> </div>
</el-dialog> </el-dialog>
</BaseContainer> </BaseContainer>
</template> </template>
<script> <script>
import { getDocumentConfirmList, getTrialUserSelect, getTrialUserTypeList, getTrialDocAndSystemDocType } from '@/api/trials' import {
import BaseContainer from '@/components/BaseContainer' getDocumentConfirmList,
import Pagination from '@/components/Pagination' getTrialUserSelect,
import PreviewFile from '@/components/PreviewFile/index' getTrialUserTypeList,
import store from '@/store' getTrialDocAndSystemDocType,
} from "@/api/trials";
import { pMTrainingRecordList_Export } from "@/api/export";
import BaseContainer from "@/components/BaseContainer";
import Pagination from "@/components/Pagination";
import PreviewFile from "@/components/PreviewFile/index";
const searchDataDefault = () => { const searchDataDefault = () => {
return { return {
FileTypeId: '', FileTypeId: "",
Name: '', Name: "",
UserId: '', UserId: "",
UserTypeId: '', UserTypeId: "",
PageIndex: 1, PageIndex: 1,
PageSize: 20, PageSize: 20,
IsConfirmed: null, IsConfirmed: null,
IsDeleted: null IsDeleted: null,
} };
} };
export default { export default {
name: 'AttachmentsManagement', name: "AttachmentsManagement",
components: { BaseContainer, Pagination, PreviewFile }, components: { BaseContainer, Pagination, PreviewFile },
data() { data() {
return { return {
@ -239,84 +310,99 @@ export default {
list: [], list: [],
total: 0, total: 0,
currentRow: {}, currentRow: {},
currentPath: '', currentPath: "",
currentType: '', currentType: "",
previewVisible: false, previewVisible: false,
userOptions: [], userOptions: [],
userTypeOptions: [], userTypeOptions: [],
currentUser: zzSessionStorage.getItem('userName'), currentUser: zzSessionStorage.getItem("userName"),
typeOptions: [], typeOptions: [],
trialId: this.$route.query.trialId trialId: this.$route.query.trialId,
} exportLoading: false,
};
}, },
mounted() { mounted() {
this.getTypeOptions() this.getTypeOptions();
this.getUserSelect() this.getUserSelect();
this.getUserType() this.getUserType();
this.getList() this.getList();
}, },
methods: { methods: {
handleExport() {
this.exportLoading = true;
pMTrainingRecordList_Export(this.searchData)
.then(() => {
this.exportLoading = false;
})
.catch((err) => {
this.exportLoading = false;
});
},
// //
getList() { getList() {
this.loading = true this.loading = true;
this.searchData.TrialId = this.trialId this.searchData.TrialId = this.trialId;
getDocumentConfirmList(this.searchData).then(async res => { getDocumentConfirmList(this.searchData)
this.loading = false .then(async (res) => {
this.list = res.Result.CurrentPageData this.loading = false;
this.total = res.Result.TotalCount this.list = res.Result.CurrentPageData;
console.log(this.total) this.total = res.Result.TotalCount;
}).catch(() => { console.log(this.total);
this.loading = false })
}) .catch(() => {
this.loading = false;
});
}, },
// //
getTypeOptions() { getTypeOptions() {
getTrialDocAndSystemDocType(this.trialId).then(res => { getTrialDocAndSystemDocType(this.trialId).then((res) => {
this.typeOptions = res.Result this.typeOptions = res.Result;
}) });
}, },
// //
getUserSelect() { getUserSelect() {
getTrialUserSelect(this.trialId).then(res => { getTrialUserSelect(this.trialId).then((res) => {
this.userOptions = res.Result this.userOptions = res.Result;
}) });
}, },
// //
getUserType() { getUserType() {
getTrialUserTypeList().then(res => { getTrialUserTypeList().then((res) => {
this.userTypeOptions = res.Result this.userTypeOptions = res.Result;
}) });
}, },
// //
handlePreview(row) { handlePreview(row) {
this.currentRow = { ...row } this.currentRow = { ...row };
const { Name, FullFilePath } = row const { Name, FullFilePath } = row;
this.currentPath = FullFilePath this.currentPath = FullFilePath;
this.currentType = row.Name ? Name.substring(Name.lastIndexOf('.') + 1).toLocaleLowerCase() : '' this.currentType = row.Name
this.previewVisible = true ? Name.substring(Name.lastIndexOf(".") + 1).toLocaleLowerCase()
: "";
this.previewVisible = true;
}, },
// //
handleReset() { handleReset() {
this.searchData = searchDataDefault() this.searchData = searchDataDefault();
this.getList() this.getList();
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.AttachmentsManagement.clearSort() this.$refs.AttachmentsManagement.clearSort();
}) });
}, },
// //
handleSearch() { handleSearch() {
this.getList() this.getList();
}, },
// //
handleSortByColumn(column) { handleSortByColumn(column) {
if (column.order === 'ascending') { if (column.order === "ascending") {
this.searchData.Asc = true this.searchData.Asc = true;
} else { } else {
this.searchData.Asc = false this.searchData.Asc = false;
} }
this.searchData.SortField = column.prop this.searchData.SortField = column.prop;
this.getList() this.getList();
} },
} },
} };
</script> </script>

File diff suppressed because it is too large Load Diff