| | |
| | | <template> |
| | | <div class="ethics-review-detail"> |
| | | <case-basic-info :case-id="caseId" :show-attachment="true" /> |
| | | <case-basic-info :case-id="caseId" :show-attachment="true":column="3" /> |
| | | |
| | | <el-card class="detail-card"> |
| | | <el-card class="detail-card paper-card"> |
| | | <!-- 伦理审查基本信息 --> |
| | | <div slot="header" class="clearfix"> |
| | | <span class="detail-title">伦理审查基本信息</span> |
| | | <div style="float: right;"> |
| | | <el-button type="primary" @click="handleSave" :loading="saveLoading"> |
| | | 保存 |
| | | </el-button> |
| | | |
| | | <el-button |
| | | type="success" |
| | | @click="handleCompleteReview" |
| | | :disabled="form.status == '3' || form.status == '2'" |
| | | :loading="completeLoading" |
| | | > |
| | | 审查完成 |
| | | </el-button> |
| | | |
| | | <el-button |
| | | type="warning" |
| | | @click="handleSuspendReview" |
| | | :disabled="form.status == '2' || form.status == '3'" |
| | | :loading="suspendLoading" |
| | | > |
| | | 审查中止 |
| | | </el-button> |
| | | |
| | | <el-button |
| | | type="danger" |
| | | @click="handleEndReview" |
| | | :disabled="form.status == '2'" |
| | | :loading="endLoading" |
| | | > |
| | | 结束审查 |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | <el-form :model="form" ref="form" :rules="rules" label-width="120px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="发起主题" prop="initiateTheme"> |
| | | <el-input |
| | | v-model="form.initiateTheme" |
| | | placeholder="请输入发起主题" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="发起人" prop="initiatePerson"> |
| | | <el-input v-model="form.initiatePerson" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-form :model="form" ref="form" :rules="rules" label-width="120px" class="paper-form"> |
| | | <div class="form-row"> |
| | | <el-form-item label="发起主题" prop="initiateTheme" class="col-1-3"> |
| | | <el-input |
| | | v-model="form.initiateTheme" |
| | | placeholder="请输入发起主题" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="发起人" prop="initiatePerson" class="col-1-3"> |
| | | <el-input v-model="form.initiatePerson" /> |
| | | </el-form-item> |
| | | <!-- <el-col :span="8"> |
| | | <el-form-item label="审查状态" prop="status"> |
| | | <el-select v-model="form.status" style="width: 100%"> |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> --> |
| | | </el-row> |
| | | </div> |
| | | |
| | | <!-- 专家相关信息 --> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="伦理审查结论" prop="expertConclusion"> |
| | | <el-select v-model="form.expertConclusion" style="width: 100%"> |
| | | <el-option label="同意" value="1" /> |
| | | <el-option label="审查中" value="2" /> |
| | | <el-option label="不同意" value="0" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="伦理审查结论时间" prop="expertTime"> |
| | | <el-date-picker |
| | | v-model="form.expertTime" |
| | | type="datetime" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-row"> |
| | | <el-form-item label="伦理审查结论" prop="expertConclusion" class="col-1-3"> |
| | | <el-select v-model="form.expertConclusion" style="width: 100%"> |
| | | <el-option label="同意" value="1" /> |
| | | <el-option label="审查中" value="2" /> |
| | | <el-option label="不同意" value="0" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="伦理审查结论时间" prop="expertTime" class="col-1-3"> |
| | | <el-date-picker |
| | | v-model="form.expertTime" |
| | | type="datetime" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </div> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="审查意见" prop="expertOpinion"> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="2" |
| | | v-model="form.expertOpinion" |
| | | placeholder="请输入意见" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-row"> |
| | | <el-form-item label="审查意见" prop="expertOpinion" class="col-full"> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="2" |
| | | v-model="form.expertOpinion" |
| | | placeholder="请输入意见" |
| | | /> |
| | | </el-form-item> |
| | | </div> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="备注" prop="remark"> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="3" |
| | | v-model="form.remark" |
| | | placeholder="请输入备注信息" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-row"> |
| | | <el-form-item label="备注" prop="remark" class="col-full"> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="3" |
| | | v-model="form.remark" |
| | | placeholder="请输入备注信息" |
| | | /> |
| | | </el-form-item> |
| | | </div> |
| | | </el-form> |
| | | </el-card> |
| | | |
| | |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | <div style="text-align: center; margin: 30px 0;"> |
| | | <el-button type="primary" @click="handleSave" :loading="saveLoading"> |
| | | 保存 |
| | | </el-button> |
| | | |
| | | <el-button |
| | | v-if="form.status != '3'" |
| | | type="success" |
| | | @click="handleCompleteReview" |
| | | :loading="completeLoading" |
| | | > |
| | | 审查完成 |
| | | </el-button> |
| | | |
| | | <el-button |
| | | type="warning" |
| | | @click="handleSuspendReview" |
| | | :disabled="form.status == '2' || form.status == '3'" |
| | | :loading="suspendLoading" |
| | | > |
| | | 审查中止 |
| | | </el-button> |
| | | |
| | | <el-button |
| | | type="danger" |
| | | @click="handleEndReview" |
| | | :disabled="form.status == '2'" |
| | | :loading="endLoading" |
| | | > |
| | | 结束审查 |
| | | </el-button> |
| | | </div> |
| | | <!-- 添加专家对话框 --> |
| | | <el-dialog |
| | | title="添加专家" |
| | |
| | | </div> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="发送方式" prop="sendType" required> |
| | | <!-- <el-form-item label="发送方式" prop="sendType" required> |
| | | <el-select |
| | | v-model="sendForm.sendType" |
| | | placeholder="请选择发送方式" |
| | |
| | | <el-option label="短信发送" value="2"></el-option> |
| | | <el-option label="其他方式" value="3"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-form-item> --> |
| | | |
| | | <el-form-item label="发送标题" prop="title" required> |
| | | <!-- <el-form-item label="发送标题" prop="title" required> |
| | | <el-input v-model="sendForm.title" placeholder="请输入发送标题" /> |
| | | </el-form-item> |
| | | </el-form-item> --> |
| | | |
| | | <el-form-item label="发送内容" prop="content" required> |
| | | <!-- <el-form-item label="发送内容" prop="content" required> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="4" |
| | | v-model="sendForm.content" |
| | | placeholder="请输入发送给专家的审查内容说明" |
| | | /> |
| | | </el-form-item> |
| | | </el-form-item> --> |
| | | |
| | | <el-form-item label="跳转链接" prop="url"> |
| | | <!-- <el-form-item label="跳转链接" prop="url"> |
| | | <el-input |
| | | v-model="sendForm.url" |
| | | placeholder="请输入跳转链接(可选)" |
| | | /> |
| | | </el-form-item> |
| | | </el-form-item> --> |
| | | </el-form> |
| | | <div slot="footer"> |
| | | <el-button @click="sendDialogVisible = false">取消</el-button> |
| | |
| | | startTime: "", |
| | | endTime: "", |
| | | sendType: "0", |
| | | title: "伦理审查任务通知", |
| | | content: "", |
| | | url: "" |
| | | }, |
| | |
| | | }, |
| | | |
| | | // 获取详情 |
| | | async getDetail(infoid, id) { |
| | | async getDetail(infoid, id) { |
| | | try { |
| | | this.expertLoading = true; |
| | | let response = {}; |
| | |
| | | response = await ethicalreviewInfo(id); |
| | | } else if (infoid) { |
| | | response = await reviewinitiateBaseInfoList({ infoid: infoid }); |
| | | if (response.data[0].id) { |
| | | this.id = response.data[0].id; |
| | | response = await ethicalreviewInfo(this.id); |
| | | } |
| | | } |
| | | |
| | | if ( |
| | | !response.data.status || |
| | | response.data.status == 0 || |
| | | response.data.status == 1 |
| | | ) { |
| | | response.data.status = "2"; |
| | | } |
| | | if (response.code == 200) { |
| | | let detailData = {}; |
| | | |
| | | if (response.data && id) { |
| | | if (response.data && this.id) { |
| | | this.form = response.data; |
| | | // 解析 filePatch 字段 |
| | | this.parseFilePatch(this.form.filePatch); |
| | |
| | | if (!this.form.ethicalreviewopinionsList) { |
| | | this.$set(this.form, "ethicalreviewopinionsList", []); |
| | | } |
| | | } else if (response.data && infoid) { |
| | | } else if (response.data && this.infoid) { |
| | | this.form = response.data[0]; |
| | | this.parseFilePatch(this.form.filePatch); |
| | | this.initAttachmentFileList(); |
| | |
| | | if (valid) { |
| | | this.saveLoading = true; |
| | | // 保存清空id便于后端整体删除新增 |
| | | this.form.ethicalreviewopinionsList.forEach(item => { |
| | | item.id = null; |
| | | }); |
| | | // this.form.ethicalreviewopinionsList.forEach(item => { |
| | | // item.id = null; |
| | | // }); |
| | | try { |
| | | const submitData = { |
| | | ...this.form, |
| | |
| | | // 保存成功后更新原始数据 |
| | | this.saveOriginalData(); |
| | | this.isEdit = false; |
| | | if (!this.form.id && response.data && response.data.id) { |
| | | this.form.id = response.data.id; |
| | | this.$router.replace({ |
| | | query: { ...this.$route.query, id: this.form.id } |
| | | }); |
| | | if (!this.form.id && response.data ) { |
| | | this.form.id = response.data; |
| | | this.id = this.form.id; |
| | | // this.$router.replace({ |
| | | // query: { ...this.$route.query, id: this.form.id } |
| | | // }); |
| | | } |
| | | this.refreshPageData(); |
| | | } else { |
| | | this.$message.error("保存失败:" + (response.msg || "未知错误")); |
| | | } |
| | |
| | | |
| | | // 发送给普通专家 |
| | | handleSendToNormalExperts() { |
| | | if (!this.validateAllIds(this.ethicalreviewopinionsList)) { |
| | | return; |
| | | } |
| | | this.currentSendExperts = this.availableNormalExperts; |
| | | this.sendForm.expertType = "normal"; |
| | | this.sendForm.endTime = ""; // 重置截止时间 |
| | |
| | | |
| | | // 发送给主委专家 |
| | | handleSendToChiefExpert() { |
| | | if (!this.validateAllIds(this.ethicalreviewopinionsList)) { |
| | | return; |
| | | } |
| | | this.currentSendExperts = this.availableChiefExperts; |
| | | this.sendForm.expertType = "chief"; |
| | | this.sendForm.endTime = ""; // 主委专家无需截止时间 |
| | |
| | | |
| | | // 发送给单个专家 |
| | | handleSendToExpert(expert) { |
| | | if (!this.validateAllIds(this.ethicalreviewopinionsList)) { |
| | | return; |
| | | } |
| | | this.currentSendExperts = [expert]; |
| | | this.sendForm.expertType = expert.expertType == "1" ? "chief" : "normal"; |
| | | this.sendForm.endTime = expert.expertType == "1" ? "" : ""; // 主委专家无需截止时间 |
| | | this.sendDialogVisible = true; |
| | | }, |
| | | |
| | | validateAllIds(arr, idField = "id") { |
| | | if (!Array.isArray(arr) || arr.length === 0) { |
| | | this.$message.warning("请先选择专家列表"); |
| | | return false; |
| | | } |
| | | |
| | | const emptyIdItems = arr.filter(item => { |
| | | const id = item[idField]; |
| | | return ( |
| | | id === undefined || |
| | | id === null || |
| | | id === "" || |
| | | id.toString().trim() === "" |
| | | ); |
| | | }); |
| | | |
| | | if (emptyIdItems.length > 0) { |
| | | this.$message.warning( |
| | | "当前选中专家列表有未保存数据,请保存刷新后再发送" |
| | | ); |
| | | return false; |
| | | } |
| | | |
| | | return true; |
| | | }, |
| | | // 发送对话框关闭 |
| | | handleSendDialogClose() { |
| | | this.sendForm = { |
| | |
| | | startTime: "", |
| | | endTime: "", |
| | | sendType: "0", |
| | | title: "伦理审查任务通知", |
| | | content: "", |
| | | url: "" |
| | | }; |
| | |
| | | return; |
| | | } |
| | | |
| | | if (!this.sendForm.sendType) { |
| | | this.$message.warning("请选择发送方式"); |
| | | return; |
| | | } |
| | | // if (!this.sendForm.sendType) { |
| | | // this.$message.warning("请选择发送方式"); |
| | | // return; |
| | | // } |
| | | |
| | | if (!this.sendForm.title) { |
| | | this.$message.warning("请输入发送标题"); |
| | | return; |
| | | } |
| | | // if (!this.sendForm.title) { |
| | | // this.$message.warning("请输入发送标题"); |
| | | // return; |
| | | // } |
| | | |
| | | if (!this.sendForm.content) { |
| | | this.$message.warning("请输入发送内容"); |
| | | return; |
| | | } |
| | | // if (!this.sendForm.content) { |
| | | // this.$message.warning("请输入发送内容"); |
| | | // return; |
| | | // } |
| | | |
| | | if (this.currentSendExperts.length == 0) { |
| | | this.$message.warning("没有找到可发送的专家"); |
| | |
| | | startTime: "", |
| | | endTime: "", |
| | | sendType: "0", |
| | | title: "伦理审查任务通知", |
| | | content: "", |
| | | url: "" |
| | | }; |
| | |
| | | }, |
| | | // 发送单个专家的方法 |
| | | async sendSingleExpert(expert, index) { |
| | | console.log(expert, "expert", index); |
| | | |
| | | try { |
| | | // 构建发送数据 |
| | | const sendData = { |
| | | number: expert.deptname || "", // 用户手机号 |
| | | title: this.sendForm.title, |
| | | url: this.sendForm.url || "", |
| | | createTime: new Date() |
| | | .toISOString() |
| | | .replace("T", " ") |
| | | .substring(0, 19) |
| | | // // 构建发送数据 |
| | | // const sendData = { |
| | | // number: expert.deptname || "", // 用户手机号 |
| | | // title: this.sendForm.title, |
| | | // url: this.sendForm.url || "", |
| | | // createTime: new Date() |
| | | // .toISOString() |
| | | // .replace("T", " ") |
| | | // .substring(0, 19) |
| | | // }; |
| | | const sendDatas = { |
| | | expertNo: expert.donorno || "",//7.14 |
| | | id: expert.id || "", |
| | | infoId: this.infoid || "" |
| | | }; |
| | | |
| | | console.log(`正在发送第 ${index + 1} 个专家: ${expert.expertname}`); |
| | | |
| | | // 调用发送通知接口 |
| | | // const response = await sendNotification(sendData); |
| | | const response = await sendcall({ |
| | | tel: expert.donorno ? expert.donorno : 13634195431, // 这里应该是 expert.deptname 或 expert.phone |
| | | messageContent: |
| | | "青岛大学附属医院上报潜在捐献案例,请登录OPO系统查看详细信息,及时进行对接。登录链接:https://brdeddd.qduhosos.cn/dklejdj/deljf/index" |
| | | }); |
| | | // const response = await sendcall({ |
| | | // tel: expert.donorno ? expert.donorno : 13634195431, // 这里应该是 expert.deptname 或 expert.phone |
| | | // messageContent: |
| | | // "青岛大学附属医院上报潜在捐献案例,请登录OPO系统查看详细信息,及时进行对接。登录链接:https://brdeddd.qduhosos.cn/dklejdj/deljf/index" |
| | | // }); |
| | | const response = await sendNotification(sendDatas); |
| | | |
| | | if (response.code == 200) { |
| | | return { |
| | |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | |
| | | /* ===== 纸质表格网格样式 ===== */ |
| | | .paper-card >>> .el-card__body { |
| | | padding: 16px; |
| | | } |
| | | |
| | | .paper-form { |
| | | border-left: 1px solid #d0d3db; |
| | | background: #fff; |
| | | /* 超宽屏限制表单最大宽度,右侧留白,避免字段分布过开 */ |
| | | max-width: 1400px; |
| | | } |
| | | |
| | | .paper-form >>> .form-row { |
| | | display: flex; |
| | | width: 100%; |
| | | border-top: 1px solid #d0d3db; |
| | | /* 上移1px与上一行的border-bottom重叠,两行之间只显示一条1px细线 */ |
| | | margin-top: -1px; |
| | | } |
| | | .paper-form >>> .form-row:first-child { |
| | | margin-top: 0; |
| | | } |
| | | |
| | | /* 行尾空白填充:不满整行的右侧自动补一个空白格子,网格保持闭合(右侧适当留白) */ |
| | | .paper-form >>> .form-row::after { |
| | | content: ""; |
| | | flex: 1 1 0; |
| | | min-height: 42px; |
| | | background: linear-gradient(to left, #d0d3db 1px, transparent 1px), |
| | | linear-gradient(to top, #d0d3db 1px, transparent 1px); |
| | | background-color: #fff; |
| | | } |
| | | |
| | | .paper-form >>> .el-form-item { |
| | | flex: 0 0 33.3333%; |
| | | display: flex; |
| | | margin: 0; |
| | | background: #fff; |
| | | border-right: 1px solid #d0d3db; |
| | | border-bottom: 1px solid #d0d3db; |
| | | } |
| | | .paper-form >>> .el-form-item::after, |
| | | .paper-form >>> .el-form-item::before { |
| | | display: none; |
| | | } |
| | | |
| | | .paper-form >>> .col-1-3 { flex: 0 0 33.3333%; } |
| | | .paper-form >>> .col-half { flex: 0 0 50%; } |
| | | .paper-form >>> .col-2-3 { flex: 0 0 66.6666%; } |
| | | .paper-form >>> .col-full { flex: 0 0 100%; } |
| | | |
| | | .paper-form >>> .el-form-item__label { |
| | | flex: 0 0 150px; |
| | | width: 150px !important; |
| | | float: none; |
| | | padding: 0 8px !important; |
| | | background: #ecf5ff; |
| | | border-right: 1px solid #d0d3db; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | text-align: center; |
| | | font-size: 13px; |
| | | font-weight: 600; |
| | | color: #2c3038; |
| | | line-height: 1.3; |
| | | white-space: nowrap; |
| | | } |
| | | .paper-form >>> .el-form-item.is-required:not(.is-no-asterisk) > .el-form-item__label:before { |
| | | color: #f56c6c; |
| | | margin-right: 2px; |
| | | } |
| | | |
| | | .paper-form >>> .el-form-item__content { |
| | | flex: 1; |
| | | margin-left: 0 !important; |
| | | display: flex; |
| | | align-items: center; |
| | | flex-wrap: wrap; |
| | | padding: 6px 10px; |
| | | background: #fff; |
| | | min-height: 42px; |
| | | line-height: 1.4; |
| | | } |
| | | |
| | | /* 控件宽度适中,不铺满整格(内容短时输入框不再拉得很长) */ |
| | | .paper-form >>> .el-form-item__content .el-input, |
| | | .paper-form >>> .el-form-item__content .el-select, |
| | | .paper-form >>> .el-form-item__content .el-cascader { |
| | | width: 220px; |
| | | max-width: 100%; |
| | | } |
| | | .paper-form >>> .el-form-item__content .el-date-editor { |
| | | width: 240px; |
| | | max-width: 100%; |
| | | } |
| | | .paper-form >>> .el-form-item__content .el-range-editor { |
| | | width: 360px; |
| | | max-width: 100%; |
| | | } |
| | | </style> |