WXL
3 天以前 7f67f2e6fbb7d47249fef0905a40a66f13ae2f2b
src/views/business/ethicalReview/ethicalReviewInfo.vue
@@ -1,60 +1,24 @@
<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%">
@@ -67,57 +31,49 @@
              </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>
@@ -458,7 +414,38 @@
        </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="添加专家"
@@ -620,7 +607,7 @@
          </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="请选择发送方式"
@@ -631,27 +618,27 @@
            <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>
@@ -962,7 +949,6 @@
        startTime: "",
        endTime: "",
        sendType: "0",
        title: "伦理审查任务通知",
        content: "",
        url: ""
      },
@@ -1165,7 +1151,7 @@
    },
    // 获取详情
    async getDetail(infoid, id) {
   async getDetail(infoid, id) {
      try {
        this.expertLoading = true;
        let response = {};
@@ -1173,12 +1159,23 @@
          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);
@@ -1187,7 +1184,7 @@
            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();
@@ -1504,9 +1501,9 @@
        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,
@@ -1530,12 +1527,14 @@
              // 保存成功后更新原始数据
              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 || "未知错误"));
            }
@@ -2060,6 +2059,9 @@
    // 发送给普通专家
    handleSendToNormalExperts() {
      if (!this.validateAllIds(this.ethicalreviewopinionsList)) {
        return;
      }
      this.currentSendExperts = this.availableNormalExperts;
      this.sendForm.expertType = "normal";
      this.sendForm.endTime = ""; // 重置截止时间
@@ -2068,6 +2070,9 @@
    // 发送给主委专家
    handleSendToChiefExpert() {
      if (!this.validateAllIds(this.ethicalreviewopinionsList)) {
        return;
      }
      this.currentSendExperts = this.availableChiefExperts;
      this.sendForm.expertType = "chief";
      this.sendForm.endTime = ""; // 主委专家无需截止时间
@@ -2076,12 +2081,40 @@
    // 发送给单个专家
    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 = {
@@ -2090,7 +2123,6 @@
        startTime: "",
        endTime: "",
        sendType: "0",
        title: "伦理审查任务通知",
        content: "",
        url: ""
      };
@@ -2110,20 +2142,20 @@
        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("没有找到可发送的专家");
@@ -2245,7 +2277,6 @@
          startTime: "",
          endTime: "",
          sendType: "0",
          title: "伦理审查任务通知",
          content: "",
          url: ""
        };
@@ -2262,27 +2293,35 @@
    },
    // 发送单个专家的方法
    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 {
@@ -2702,4 +2741,105 @@
    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>