487 lines
14 KiB
Vue
487 lines
14 KiB
Vue
<template>
|
||
<el-dialog
|
||
:visible.sync="visible"
|
||
:close-on-click-modal="false"
|
||
:fullscreen="true"
|
||
custom-class="upload-dialog"
|
||
:before-close="beforeCloseStudyDig"
|
||
>
|
||
<span slot="title"
|
||
>{{ $t("trials:inspection:button:addTrials") }}({{
|
||
$t("trials:uploadDicomList:table:patientInfo")
|
||
}}:{{ Patient.PatientIdStr }},{{ Patient.PatientName }})</span
|
||
>
|
||
<div class="top">
|
||
<p class="line">{{ $t("trials:inspection:message:checkAddTrials") }}</p>
|
||
<el-form
|
||
ref="submitMessageForm"
|
||
:inline="true"
|
||
:model="submitMessage"
|
||
class="demo-form-inline"
|
||
:rules="rules"
|
||
label-width="130px"
|
||
>
|
||
<div>
|
||
<!--项目-->
|
||
<el-form-item
|
||
:label="$t('trials:workbench:label:trialsStats')"
|
||
prop="TrialId"
|
||
label-width="50px"
|
||
>
|
||
<trialsSelect
|
||
:options="trialList"
|
||
:data.sync="submitMessage"
|
||
:status="status"
|
||
/>
|
||
</el-form-item>
|
||
<div style="display: inline-block">
|
||
<!--受试者编号-->
|
||
<el-form-item
|
||
:label="$t('trials:crcQuestion:table:subjectId')"
|
||
prop="SubjectId"
|
||
>
|
||
<el-select
|
||
v-model="submitMessage.SubjectId"
|
||
clearable
|
||
filterable
|
||
:disabled="status === 'visit' || !submitMessage.TrialId"
|
||
style="width: 300px"
|
||
>
|
||
<el-option
|
||
v-for="item in subjectIdList"
|
||
:key="item.SubejctId"
|
||
:label="
|
||
item.ShortName || item.Sex
|
||
? `${item.SubjectCode}(${item.ShortName},${
|
||
item.Sex ? $fd('sex', item.Sex) : ''
|
||
})`
|
||
: item.SubjectCode
|
||
"
|
||
:value="item.SubejctId"
|
||
>
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<!--添加受试者-->
|
||
<el-button
|
||
type="primary"
|
||
v-if="status === 'trial' && submitMessage.TrialId"
|
||
@click="addSubject_model.visible = true"
|
||
>
|
||
{{ $t("trials:selectSubject:button:add") }}
|
||
</el-button>
|
||
<div>
|
||
<el-form-item
|
||
:label="$t('trials:study:tabpane:bindPatient')"
|
||
:style="{ opacity: bindPatientTip ? 1 : 0 }"
|
||
>
|
||
<span v-if="bindPatientTip">{{
|
||
bindPatientTip.map((item) => item.PatientIdStr).join(", ")
|
||
}}</span>
|
||
</el-form-item>
|
||
</div>
|
||
</div>
|
||
<div class="btnBox">
|
||
<!--确认添加按钮-->
|
||
<el-button
|
||
type="primary"
|
||
v-if="status === 'trial'"
|
||
@click="addTrials"
|
||
:loading="btnLoading"
|
||
>
|
||
{{ $t("trials:addRP:button:confirmAddPR") }}
|
||
</el-button>
|
||
<!--移除按钮-->
|
||
<el-button
|
||
type="primary"
|
||
v-else
|
||
@click="remove"
|
||
:loading="btnLoading"
|
||
>
|
||
{{ $t("common:button:remove") }}
|
||
</el-button>
|
||
</div>
|
||
</div>
|
||
</el-form>
|
||
</div>
|
||
<confirmVisitList
|
||
ref="confirmVisit"
|
||
:Patient="PatientData"
|
||
:submitMessage="submitMessage"
|
||
:status="status"
|
||
@close="beforeCloseStudyDig"
|
||
/>
|
||
<base-model v-if="addSubject_model.visible" :config="addSubject_model">
|
||
<template slot="dialog-body">
|
||
<el-form
|
||
ref="addSubjectForm"
|
||
:inline="true"
|
||
:model="addSubjectForm"
|
||
class="demo-form-inline"
|
||
:rules="addSubjectrules"
|
||
>
|
||
<!--受试者编号-->
|
||
<el-form-item
|
||
:label="$t('trials:addSuject:form:subjectCode')"
|
||
prop="SubjectCode"
|
||
label-width="150px"
|
||
>
|
||
<el-input
|
||
v-model="addSubjectForm.SubjectCode"
|
||
:maxlength="14"
|
||
clearable
|
||
@input="
|
||
addSubjectForm.SubjectCode = addSubjectForm.SubjectCode.replace(
|
||
/[^0-9a-zA-Z]/g,
|
||
''
|
||
)
|
||
"
|
||
@focus="errMessage = null"
|
||
></el-input>
|
||
<span class="errTip" v-if="errMessage">{{ errMessage }}</span>
|
||
</el-form-item>
|
||
</el-form>
|
||
</template>
|
||
<template slot="dialog-footer">
|
||
<el-button type="primary" @click="addSubject">
|
||
{{ $t("common:button:confirm") }}
|
||
</el-button>
|
||
<el-button @click="addSubject_model.visible = false">
|
||
{{ $t("common:button:cancel") }}
|
||
</el-button>
|
||
</template>
|
||
</base-model>
|
||
</el-dialog>
|
||
</template>
|
||
<script>
|
||
import Pagination from "@/components/Pagination";
|
||
import trialsSelect from "./trials-select.vue";
|
||
import confirmVisitList from "./confirm-visit-list.vue";
|
||
import BaseModel from "@/components/BaseModel";
|
||
import {
|
||
getPatientJoinTrialInitSelectList,
|
||
getTrialSubejctSelectList,
|
||
addSubjectPatientBinding,
|
||
deleteSubjectPatientBinding,
|
||
verifyTrialSubject,
|
||
} from "@/api/inspection.js";
|
||
export default {
|
||
name: "addTrialsList",
|
||
components: { Pagination, trialsSelect, confirmVisitList, BaseModel },
|
||
props: {
|
||
visible: {
|
||
required: true,
|
||
default: false,
|
||
},
|
||
Patient: {
|
||
required: true,
|
||
default: () => {
|
||
return {};
|
||
},
|
||
},
|
||
},
|
||
data() {
|
||
return {
|
||
// 绑定项目相关提交数据
|
||
status: "trial", // 页面当前状态 trial 绑定项目 visit 确认访视
|
||
trialList: [],
|
||
btnLoading: false,
|
||
submitMessage: {
|
||
SubjectId: null,
|
||
TrialId: null,
|
||
TrialCode: null,
|
||
ResearchProgramNo: null,
|
||
},
|
||
PatientData: {},
|
||
subjectIdList: [], // 受试者列表
|
||
rules: {
|
||
TrialId: [
|
||
{
|
||
required: true,
|
||
message: this.$t("trials:inspection:message:checkAddTrials"),
|
||
trigger: "change",
|
||
},
|
||
],
|
||
SubjectId: [
|
||
{
|
||
required: true,
|
||
message: this.$t("trials:inscept:rules:selectOrInputSubject"),
|
||
trigger: "change",
|
||
},
|
||
],
|
||
},
|
||
// 新增受试者
|
||
addSubject_model: {
|
||
visible: false,
|
||
title: this.$t("trials:selectSubject:button:add"),
|
||
width: "500px",
|
||
appendToBody: true,
|
||
},
|
||
addSubjectForm: {
|
||
SubjectCode: null,
|
||
},
|
||
addSubjectrules: {
|
||
SubjectCode: [
|
||
{
|
||
required: true,
|
||
message: this.$t("trials:subject:format:notSubject"),
|
||
trigger: ["blur", "change"],
|
||
},
|
||
{
|
||
validator: (rule, value, callback) => {
|
||
let flag = this.subjectIdList.some(
|
||
(item) => item.SubjectCode === value
|
||
);
|
||
if (flag) {
|
||
callback(
|
||
new Error(this.$t("trials:addSubject:format:hasSubject"))
|
||
);
|
||
} else {
|
||
callback();
|
||
}
|
||
},
|
||
message: this.$t("trials:addSubject:format:hasSubject"),
|
||
trigger: ["blur", "change"],
|
||
},
|
||
],
|
||
},
|
||
errMessage: null,
|
||
};
|
||
},
|
||
computed: {
|
||
bindPatientTip() {
|
||
if (!this.submitMessage.SubjectId) return false;
|
||
let PatientList = [];
|
||
this.subjectIdList.some((item) => {
|
||
if (
|
||
item.SubejctId === this.submitMessage.SubjectId &&
|
||
item.PatientList &&
|
||
item.PatientList.length > 0
|
||
) {
|
||
PatientList.push(...item.PatientList);
|
||
}
|
||
});
|
||
if (PatientList.length <= 0) return false;
|
||
return PatientList;
|
||
},
|
||
},
|
||
created() {
|
||
this.getTrialList();
|
||
},
|
||
watch: {
|
||
"submitMessage.TrialId": {
|
||
handler() {
|
||
if (this.submitMessage.TrialId) {
|
||
this.getTrialSubejctSelectList(this.submitMessage.TrialId);
|
||
} else {
|
||
this.subjectIdList = [];
|
||
}
|
||
},
|
||
},
|
||
"addSubject_model.visible": {
|
||
handler() {
|
||
if (!this.addSubject_model.visible) {
|
||
this.addSubjectForm.SubjectCode = null;
|
||
}
|
||
},
|
||
},
|
||
},
|
||
methods: {
|
||
// 新增受试者(前端操作未同步后端)
|
||
async addSubject() {
|
||
try {
|
||
this.errMessage = null;
|
||
let validate = await this.$refs.addSubjectForm.validate();
|
||
if (!validate) return;
|
||
let data = {
|
||
TrialId: this.submitMessage.TrialId,
|
||
SubjectCode: this.addSubjectForm.SubjectCode,
|
||
};
|
||
let res = await verifyTrialSubject(data);
|
||
if (res.IsSuccess) {
|
||
let subject = {
|
||
SubjectCode: this.addSubjectForm.SubjectCode,
|
||
SubejctId: this.addSubjectForm.SubjectCode,
|
||
};
|
||
this.subjectIdList.unshift(subject);
|
||
this.submitMessage.SubjectId = this.addSubjectForm.SubjectCode;
|
||
this.addSubject_model.visible = false;
|
||
}
|
||
} catch (err) {
|
||
console.log(err);
|
||
if (err.Code === 5) {
|
||
this.getTrialSubejctSelectList(this.submitMessage.TrialId, null);
|
||
this.$emit("getList");
|
||
this.errMessage = err.ErrorMessage;
|
||
}
|
||
}
|
||
},
|
||
// 获取受试者列表
|
||
async getTrialSubejctSelectList(id, SubjectId = null) {
|
||
let data = {
|
||
TrialId: id,
|
||
};
|
||
try {
|
||
let res = await getTrialSubejctSelectList(data);
|
||
if (res.IsSuccess) {
|
||
this.subjectIdList = res.Result || [];
|
||
this.submitMessage.SubjectId = SubjectId;
|
||
if (SubjectId) {
|
||
this.$nextTick(() => {
|
||
Object.keys(this.Patient).forEach((key) => {
|
||
this.PatientData[key] = this.Patient[key];
|
||
});
|
||
let patient = this.bindPatientTip
|
||
? this.bindPatientTip.map((item) => item.PatientId)
|
||
: [];
|
||
this.PatientData.PatientId = [this.Patient.PatientId, ...patient];
|
||
this.$refs.confirmVisit.getList(true);
|
||
this.$refs.confirmVisit.getSubjectVisitSelectList();
|
||
});
|
||
}
|
||
}
|
||
} catch (err) {
|
||
console.log(err);
|
||
}
|
||
},
|
||
// 关闭弹框
|
||
beforeCloseStudyDig() {
|
||
this.$emit("update:visible", false);
|
||
},
|
||
// 加入项目
|
||
async addTrials() {
|
||
if (this.btnLoading) return;
|
||
try {
|
||
let validate = await this.$refs.submitMessageForm.validate();
|
||
if (!validate) return;
|
||
let data = {
|
||
TrialId: this.submitMessage.TrialId,
|
||
PatientIdList: [this.Patient.PatientId],
|
||
};
|
||
if (this.submitMessage.SubjectId.length === 36) {
|
||
data.SubjectId = this.submitMessage.SubjectId;
|
||
} else {
|
||
data.SubjectCode = this.submitMessage.SubjectId;
|
||
}
|
||
this.btnLoading = true;
|
||
let res = await addSubjectPatientBinding(data);
|
||
this.btnLoading = false;
|
||
if (res.IsSuccess) {
|
||
this.submitMessage.SubjectId = res.Result;
|
||
this.getTrialSubejctSelectList(
|
||
this.submitMessage.TrialId,
|
||
res.Result
|
||
);
|
||
this.$message.success(this.$t("common:message:addedSuccessfully"));
|
||
this.status = "visit";
|
||
this.$emit("getList");
|
||
}
|
||
} catch (err) {
|
||
this.btnLoading = false;
|
||
console.log(err);
|
||
}
|
||
},
|
||
// 移除项目
|
||
async remove() {
|
||
try {
|
||
let confirm = await this.$confirm(
|
||
this.$t("trials:sitesList:message:removeSite"),
|
||
{
|
||
type: "warning",
|
||
distinguishCancelAndClose: true,
|
||
confirmButtonText: this.$t("common:button:confirm"),
|
||
cancelButtonText: this.$t("recompose:button:cancel"),
|
||
}
|
||
);
|
||
if (confirm !== "confirm") return;
|
||
let params = {
|
||
PatientId: this.Patient.PatientId,
|
||
SubjectId: this.submitMessage.SubjectId,
|
||
TrialId: this.submitMessage.TrialId,
|
||
};
|
||
this.btnLoading = true;
|
||
let res = await deleteSubjectPatientBinding(params);
|
||
this.btnLoading = false;
|
||
if (res.IsSuccess) {
|
||
this.getTrialSubejctSelectList(this.submitMessage.TrialId);
|
||
this.$refs.confirmVisit.reset(true);
|
||
this.status = "trial";
|
||
this.$message.success(this.$t("common:message:removedSuccessfully"));
|
||
this.$emit("getList");
|
||
this.$refs.confirmVisit.changeVisitStatus(true);
|
||
}
|
||
} catch (err) {
|
||
this.btnLoading = false;
|
||
console.log(err);
|
||
}
|
||
},
|
||
// 获取项目列表
|
||
async getTrialList() {
|
||
let data = {};
|
||
data.PatientId = this.Patient.PatientId;
|
||
try {
|
||
let res = await getPatientJoinTrialInitSelectList(data);
|
||
if (res.IsSuccess) {
|
||
this.trialList = res.Result;
|
||
}
|
||
} catch (err) {
|
||
console.log(err);
|
||
}
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
.errTip {
|
||
color: #f56c6c;
|
||
font-size: 12px;
|
||
line-height: 1;
|
||
padding-top: 4px;
|
||
position: absolute;
|
||
top: 100%;
|
||
left: 0;
|
||
}
|
||
.top {
|
||
padding-top: 20px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
flex-wrap: wrap;
|
||
}
|
||
.btnBox {
|
||
float: right;
|
||
}
|
||
.search {
|
||
display: flex;
|
||
align-items: center;
|
||
flex-wrap: wrap;
|
||
.form {
|
||
width: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
}
|
||
.line {
|
||
width: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
&::after {
|
||
display: block;
|
||
content: "";
|
||
flex: 1;
|
||
height: 1px;
|
||
border-top: 1px solid #ddd;
|
||
}
|
||
}
|
||
.selectAndBtn {
|
||
width: 100%;
|
||
display: flex;
|
||
align-items: flex-start;
|
||
justify-content: space-between;
|
||
}
|
||
.demo-form-inline {
|
||
width: 100%;
|
||
}
|
||
</style> |