WXL
7 天以前 f806aff5702fc6be9c9348d51964366cbf434bf7
维护
已修改4个文件
已添加2个文件
338 ■■■■ 文件已修改
src/api/businessApi/ethicalReview.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/FilePreviewDialog/index.vue 114 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/decide/DecideInfo.vue 91 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/ethicalReview/ethicalReviewInfo.vue 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
管理端 (2).zip 补丁 | 查看 | 原始文档 | blame | 历史
管理端 (3).zip 补丁 | 查看 | 原始文档 | blame | 历史
src/api/businessApi/ethicalReview.js
@@ -57,9 +57,9 @@
// ä¸“家消息推送
export function sendNotification(data) {
  return request({
    url: "/system/dingtalk/sendNotification",
    method: "post",
    data: data
    url: "/GiLink/sendExpert",
    method: "get",
    params: data
  });
}
// çŸ­ä¿¡
src/components/FilePreviewDialog/index.vue
@@ -11,7 +11,10 @@
  >
    <!-- åŠ è½½çŠ¶æ€ -->
    <div v-if="loading" class="preview-loading">
      <i class="el-icon-loading" style="font-size: 40px; margin-bottom: 16px;"></i>
      <i
        class="el-icon-loading"
        style="font-size: 40px; margin-bottom: 16px;"
      ></i>
      <span>文件加载中...</span>
    </div>
@@ -19,11 +22,19 @@
    <div v-else-if="fileType === 'image'" class="preview-container">
      <div class="image-toolbar">
        <el-button-group>
          <el-button size="mini" @click="zoomImageIn" :disabled="imageScale >= 300">
          <el-button
            size="mini"
            @click="zoomImageIn"
            :disabled="imageScale >= 300"
          >
            <i class="el-icon-zoom-in"></i> æ”¾å¤§
          </el-button>
          <el-button size="mini" disabled>{{ imageScale }}%</el-button>
          <el-button size="mini" @click="zoomImageOut" :disabled="imageScale <= 50">
          <el-button
            size="mini"
            @click="zoomImageOut"
            :disabled="imageScale <= 50"
          >
            <i class="el-icon-zoom-out"></i> ç¼©å°
          </el-button>
          <el-button size="mini" @click="resetImageZoom">
@@ -83,11 +94,7 @@
          </el-button>
        </el-button-group>
        <el-button
          size="mini"
          type="success"
          @click="handleDownload"
        >
        <el-button size="mini" type="success" @click="handleDownload">
          <i class="el-icon-download"></i> ä¸‹è½½
        </el-button>
      </div>
@@ -111,7 +118,10 @@
    </div>
    <!-- Office文档预览 -->
    <div v-else-if="fileType === 'office'" class="preview-container office-preview">
    <div
      v-else-if="fileType === 'office'"
      class="preview-container office-preview"
    >
      <div class="office-toolbar">
        <el-alert
          title="Office文档预览提示"
@@ -127,7 +137,11 @@
      <div class="office-content">
        <iframe
          :src="`https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(fileUrl)}`"
          :src="
            `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(
              fileUrl
            )}`
          "
          width="100%"
          height="600px"
          frameborder="0"
@@ -177,6 +191,11 @@
      type: Object,
      default: () => ({})
    }
    // æ·»åŠ baseUrlHt作为props传入
    // baseUrlHt: {
    //   type: String,
    //   default: process.env.VUE_APP_BASE_API
    // }
  },
  data() {
    return {
@@ -185,6 +204,7 @@
      // åŠ è½½çŠ¶æ€
      loading: false,
      pdfLoading: false,
      baseUrlHt: "",
      // æ–‡ä»¶ä¿¡æ¯
      fileUrl: "",
      fileName: "",
@@ -214,19 +234,75 @@
      }
    },
    previewVisible(newVal) {
      this.$emit('update:visible', newVal);
      this.$emit("update:visible", newVal);
      if (!newVal) {
        this.handleClose();
      }
    }
  },
  created() {
    this.calculateBaseUrl();
  },
  methods: {
    /** URL处理函数 - å°†å®Œæ•´URL替换为baseUrlHt */
    processFileUrl(url) {
      if (!url) return "";
      // å¦‚果已经是完整的http或https链接
      if (url.startsWith("http://") || url.startsWith("https://")) {
        // æ‰¾åˆ°ç¬¬ä¸‰ä¸ªæ–œæ åŽçš„位置,提取路径部分
        const thirdSlashIndex = url.indexOf("/", 8); // ä»Žhttp://或https://之后开始找
        if (thirdSlashIndex !== -1) {
          return `${this.baseUrlHt}${url.substring(thirdSlashIndex)}`;
        }
        return this.baseUrlHt; // å¦‚果没有路径部分,只返回baseUrlHt
      }
      // ç›¸å¯¹è·¯å¾„处理
      if (url.startsWith("/")) {
        return `${this.baseUrlHt}${url}`;
      }
      return `${this.baseUrlHt}/${url}`;
    },
    /** è®¡ç®— baseUrlHt */
    calculateBaseUrl() {
      // èŽ·å–å½“å‰æµè§ˆå™¨åœ°å€
      const currentUrl = window.location.href;
      console.log("当前浏览器地址:", currentUrl);
      try {
        // ä½¿ç”¨ URL å¯¹è±¡è§£æž
        const urlObj = new URL(currentUrl);
        // èŽ·å–ä¸»æœºåï¼ˆIP æˆ–域名)
        const hostname = urlObj.hostname;
        // æ‹¼æŽ¥ç«¯å£ :9095
        this.baseUrlHt = `http://${hostname}:9095`;
        console.log("计算得到的 baseUrlHt:", this.baseUrlHt);
      } catch (error) {
        console.error("解析URL失败:", error);
        // å¤‡ç”¨æ–¹æ¡ˆï¼šä½¿ç”¨æ­£åˆ™æå–
        const match = currentUrl.match(/https?:\/\/([^:\/]+)/);
        if (match) {
          this.baseUrlHt = `http://${match[1]}:9095`;
        } else {
          // æœ€åŽçš„备用方案
          this.baseUrlHt =
            process.env.VUE_APP_BASE_API || "http://localhost:9095";
        }
      }
    },
    /** åˆå§‹åŒ–预览 */
    initPreview() {
      if (!this.file) return;
      this.fileName = this.file.fileName || this.file.name || "未知文件";
      this.fileUrl = this.file.fileUrl || this.file.path || this.file.url;
      const originalUrl = this.file.fileUrl || this.file.path || this.file.url;
      // å¤„理URL,替换域名部分
      this.fileUrl = this.processFileUrl(originalUrl);
      this.fileType = this.getFileType(this.fileName);
      this.loading = true;
@@ -250,7 +326,10 @@
    getFileType(fileName) {
      if (!fileName) return "other";
      const extension = fileName.split('.').pop().toLowerCase();
      const extension = fileName
        .split(".")
        .pop()
        .toLowerCase();
      const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"];
      const pdfTypes = ["pdf"];
      const officeTypes = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"];
@@ -263,7 +342,12 @@
    /** èŽ·å–æ–‡ä»¶æ‰©å±•å */
    getFileExtension(filename) {
      return filename.split('.').pop().toLowerCase() || "未知";
      return (
        filename
          .split(".")
          .pop()
          .toLowerCase() || "未知"
      );
    },
    /** PDF加载完成 */
@@ -337,7 +421,7 @@
      this.imageScale = 100;
    },
    /** ä¸‹è½½æ–‡ä»¶ */
    /** ä¸‹è½½æ–‡ä»¶ - ä¹Ÿéœ€è¦å¤„理URL */
    handleDownload() {
      if (!this.fileUrl) {
        this.$message.warning("文件路径不存在,无法下载");
src/views/business/decide/DecideInfo.vue
@@ -502,6 +502,13 @@
        </el-button>
      </div>
    </el-dialog>
    <!-- é™„件预览 -->
    <FilePreviewDialog
      :visible="previewVisible"
      :file="currentPreviewFile"
      @close="previewVisible = false"
      @download="handleDownload"
    />
  </div>
</template>
@@ -513,10 +520,11 @@
} from "@/api/businessApi";
import { getToken } from "@/utils/auth";
import CaseBasicInfo from "@/components/CaseBasicInfo";
import FilePreviewDialog from "@/components/FilePreviewDialog";
export default {
  name: "DeathJudgmentDetail",
  components: { CaseBasicInfo },
  components: { CaseBasicInfo, FilePreviewDialog },
  data() {
    return {
@@ -527,7 +535,9 @@
      // åˆ¤å®šç±»åž‹æ ‡ç­¾
      activeJudgmentType: "brain", // é»˜è®¤æ˜¾ç¤ºè„‘死亡
      // é¢„览相关
      previewVisible: false,
      currentPreviewFile: null,
      // è¡¨å•数据
      form: {
        id: undefined,
@@ -1000,30 +1010,63 @@
    },
    // é¢„览附件
    handlePreview(attachment) {
      if (attachment.fileName.endsWith(".pdf")) {
        window.open(attachment.fileUrl, "_blank");
      } else if (attachment.fileName.match(/\.(jpg|jpeg|png)$/i)) {
        this.$alert(
          `<img src="${attachment.fileUrl}" style="max-width: 100%;" alt="${attachment.fileName}">`,
          "图片预览",
          {
            dangerouslyUseHTMLString: true,
            customClass: "image-preview-dialog"
          }
        );
      } else {
        this.$message.info("该文件类型暂不支持在线预览,请下载后查看");
      }
    },
    handlePreview(file) {
      console.log(file, "file");
      this.currentPreviewFile = {
        fileName: file.fileName,
        fileUrl: file.path || file.fileUrl,
        fileType: this.getFileType(file.fileName)
      };
      this.previewVisible = true;
      // if (attachment.fileName.endsWith(".pdf")) {
      //   window.open(attachment.fileUrl, "_blank");
      // } else if (attachment.fileName.match(/\.(jpg|jpeg|png)$/i)) {
      //   this.$alert(
      //     `<img src="${attachment.fileUrl}" style="max-width: 100%;" alt="${attachment.fileName}">`,
      //     "图片预览",
      //     {
      //       dangerouslyUseHTMLString: true,
      //       customClass: "image-preview-dialog"
      //     }
      //   );
      // } else {
      //   this.$message.info("该文件类型暂不支持在线预览,请下载后查看");
      // }
    },
    getFileType(fileName) {
      if (!fileName) return "other";
      const extension = fileName
        .split(".")
        .pop()
        .toLowerCase();
      const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"];
      const pdfTypes = ["pdf"];
      const officeTypes = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"];
      if (imageTypes.includes(extension)) return "image";
      if (pdfTypes.includes(extension)) return "pdf";
      if (officeTypes.includes(extension)) return "office";
      return "other";
    },
    // ä¸‹è½½é™„ä»¶
    handleDownload(attachment) {
      const link = document.createElement("a");
      link.href = attachment.fileUrl;
      link.download = attachment.fileName;
      link.click();
      this.$message.success(`开始下载: ${attachment.fileName}`);
    handleDownload(file) {
      const fileUrl = file.path || file.fileUrl;
      const fileName = file.fileName;
      if (fileUrl) {
        const link = document.createElement("a");
        link.href = fileUrl;
        link.download = fileName;
        link.style.display = "none";
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        this.$message.success("开始下载文件");
      } else {
        this.$message.warning("文件路径不存在,无法下载");
      }
    },
    // ç¼–辑信息
src/views/business/ethicalReview/ethicalReviewInfo.vue
@@ -620,7 +620,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 +631,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 +962,6 @@
        startTime: "",
        endTime: "",
        sendType: "0",
        title: "伦理审查任务通知",
        content: "",
        url: ""
      },
@@ -1504,9 +1503,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,
@@ -1532,10 +1531,12 @@
              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 }
                });
                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 +2061,9 @@
    // å‘送给普通专家
    handleSendToNormalExperts() {
      if (!this.validateAllIds(this.ethicalreviewopinionsList)) {
        return;
      }
      this.currentSendExperts = this.availableNormalExperts;
      this.sendForm.expertType = "normal";
      this.sendForm.endTime = ""; // é‡ç½®æˆªæ­¢æ—¶é—´
@@ -2068,6 +2072,9 @@
    // å‘送给主委专家
    handleSendToChiefExpert() {
      if (!this.validateAllIds(this.ethicalreviewopinionsList)) {
        return;
      }
      this.currentSendExperts = this.availableChiefExperts;
      this.sendForm.expertType = "chief";
      this.sendForm.endTime = ""; // ä¸»å§”专家无需截止时间
@@ -2076,12 +2083,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 +2125,6 @@
        startTime: "",
        endTime: "",
        sendType: "0",
        title: "伦理审查任务通知",
        content: "",
        url: ""
      };
@@ -2110,20 +2144,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 +2279,6 @@
          startTime: "",
          endTime: "",
          sendType: "0",
          title: "伦理审查任务通知",
          content: "",
          url: ""
        };
@@ -2262,27 +2295,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.expertNo || "",
          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 {
¹ÜÀí¶Ë (2).zip
Binary files differ
¹ÜÀí¶Ë (3).zip
Binary files differ