WXL
昨天 c80bc467a41daa6cbae4e5515a300a8ca98cfeaa
pagesSub/ethicalReview/ethicalInfo.vue
@@ -156,7 +156,7 @@
            }}</text>
            <view class="signature-actions" v-if="!isReadonly">
              <button class="re-sign-btn" @tap="removeSignature">
                <u-icon name="photo" size="16" />
                <up-icon name="photo" size="16" />
                <text>重新签名</text>
              </button>
            </view>
@@ -317,7 +317,39 @@
const id = ref(null);
const fcid = ref(null);
const materials = ref([]);
const baseUrlHt = userStore.baseUrlHt;
// ==================== 新增:根据环境获取 baseUrlHt ====================
const getBaseUrlHt = () => {
  // #ifdef H5
  // H5 环境:根据浏览器地址动态拼接
  try {
    const href = window.location.href;
    // 规则 1:192.168.120.27:8091 → 120.27 + :9095
    if (href.startsWith('http://192.168.120.27:8091')) {
      return 'http://192.168.120.27:9095';
    }
    // 规则 2:192.168.76.25:8091 → 76.25 + :9095
    if (href.startsWith('http://192.168.76.25:8091')) {
      return 'http://192.168.76.25:9095';
    }
    // 规则 3:其余全部走生产
    return 'https://opo.qduh.cn';
  } catch {
    return 'https://opo.qduh.cn';
  }
  // #endif
  // #ifdef MP-WEIXIN
  // 小程序环境:使用 userStore 中的 baseUrlHt
  return userStore.baseUrlHt;
  // #endif
};
const baseUrlHt = getBaseUrlHt();
const form = ref({
  expertconclusion: "", // 专家结论
  expertopinion: "", // 专家意见
@@ -511,17 +543,9 @@
        }
      }
      // 设置签名
      // 设置签名 - 使用 getFullUrl 处理
      if (data.sigin) {
        // 检查签名URL是否是完整路径
        if (data.sigin.startsWith("http")) {
          signatureData.signatureUrl = data.sigin;
        } else {
          // 如果不是完整路径,可能需要拼接基础URL
          signatureData.signatureUrl = `/api${
            data.sigin.startsWith("/") ? "" : "/"
          }${data.sigin}`;
        }
        signatureData.signatureUrl = getFullUrl(data.sigin);
        signatureData.signatureTime = data.conclusiontime || "";
      }
@@ -562,38 +586,50 @@
    // 状态已经是超时
    return;
  }
  // 如果有截止时间,检查是否超过当前时间
  // if (data.endtime) {
  //   const endTime = new Date(data.endtime);
  //   const now = new Date();
  //   if (now > endTime) {
  //     // 标记为超时状态
  //     caseInfo.value.receiveStatus = "3";
  //     updateButtonStatus("3");
  //   }
  // }
};
// URL替换函数
const replaceUrlDomain = (url) => {
  if (!url) return '';
// ==================== 新增:获取完整URL(平台安全版) ====================
const getFullUrl = (path) => {
  if (!path) return '';
  
  if (url.startsWith('http://') || url.startsWith('https://')) {
    // 找到第三个斜杠后的位置,提取路径部分
    const thirdSlashIndex = url.indexOf('/', 8);
    if (thirdSlashIndex !== -1) {
      return `${baseUrlHt}${url.substring(thirdSlashIndex)}`;
  // blob / file 本地路径直接返回
  if (path.startsWith('blob:') || path.startsWith('file://')) {
    return path;
  }
  // 已经是完整 http/https
  if (path.startsWith('http://') || path.startsWith('https://')) {
    // #ifdef H5
    // H5 环境:使用 new URL 解析
    try {
      const url = new URL(path);
      return `${baseUrlHt}${url.pathname}${url.search}${url.hash}`;
    } catch {
      // 降级:手动截路径
      const idx = path.indexOf('/', 8);
      return idx !== -1
        ? `${baseUrlHt}${path.substring(idx)}`
        : baseUrlHt;
    }
    return baseUrlHt; // 如果没有路径部分,只返回baseUrlHt
    // #endif
    // #ifdef MP-WEIXIN
    // 小程序环境:不使用 new URL,手动处理
    const protoEnd = path.indexOf('://') + 3;
    const pathStart = path.indexOf('/', protoEnd);
    return pathStart !== -1
      ? `${baseUrlHt}${path.substring(pathStart)}`
      : baseUrlHt;
    // #endif
  }
  
  // 相对路径处理
  if (url.startsWith('/')) {
    return `${baseUrlHt}${url}`;
  }
  return `${baseUrlHt}/${url}`;
  // 相对路径
  return `${baseUrlHt}${path.startsWith('/') ? '' : '/'}${path}`;
};
// ==================== 修改:replaceUrlDomain 使用 getFullUrl ====================
const replaceUrlDomain = (url) => {
  return getFullUrl(url);
};
// 解析附件文件
@@ -625,7 +661,8 @@
    // 转换为需要的格式
    materials.value = fileList.map((file, index) => {
      const fileName = file.fileName || `附件${index + 1}`;
      const fileUrl = replaceUrlDomain(file.fileUrl || file.path || file.url || "");
      // 使用 getFullUrl 处理URL
      const fileUrl = getFullUrl(file.fileUrl || file.path || file.url || "");
      
      const ext = fileName.split(".").pop().toLowerCase();
      let icon = "file-text";
@@ -669,7 +706,8 @@
    const fileList = filePatch.split(";").filter((item) => item.trim());
    materials.value = fileList.map((file, index) => {
      const fileName = file.split("/").pop() || `附件${index + 1}`;
      const fileUrl = replaceUrlDomain(file);
      // 使用 getFullUrl 处理URL
      const fileUrl = getFullUrl(file);
      
      const ext = fileName.split(".").pop().toLowerCase();
      let icon = "file-text";
@@ -870,8 +908,8 @@
    const uploadResult = await uploadSignature(tempSignatureData.value);
    if (uploadResult) {
      // 更新签名数据
      signatureData.signatureUrl = uploadResult.url;
      // 使用 getFullUrl 处理签名URL
      signatureData.signatureUrl = getFullUrl(uploadResult.url);
      signatureData.signatureTime = new Date().toLocaleString("zh-CN");
      signatureData.fileName =
        uploadResult.originalFilename || `signature_${Date.now()}.png`;
@@ -1000,25 +1038,29 @@
  });
};
// 预览签名
// 预览签名
// ==================== 修改:预览签名 ====================
const previewSignature = () => {
  if (signatureData.signatureUrl) {
    // 检查URL是否需要拼接基础路径
    let previewUrl = signatureData.signatureUrl;
    if (!previewUrl.startsWith("http")) {
      // 可能需要拼接服务器基础URL
      previewUrl = `${userStore?.baseUrlHt || ""}${previewUrl}`;
    }
    // 使用 getFullUrl 处理URL
    let previewUrl = getFullUrl(signatureData.signatureUrl);
    uni.previewImage({
      urls: [previewUrl],
      success: () => {
        console.log("签名预览成功");
      },
      fail: (err) => {
        console.error("签名预览失败:", err);
        uni.showToast({
          title: "签名加载失败",
          icon: "none",
        });
      },
    });
  }
};
// 预览材料
// 预览材料
// ==================== 修改:预览材料 ====================
const previewMaterial = (material) => {
  if (material.url) {
    uni.showLoading({ title: "加载中..." });
@@ -1026,11 +1068,14 @@
    const fileExt =
      material.type || material.url.split(".").pop().toLowerCase();
    // 使用 getFullUrl 处理URL
    const fileUrl = getFullUrl(material.url);
    // 判断文件类型
    if (["jpg", "jpeg", "png", "gif", "bmp", "webp"].includes(fileExt)) {
      // 图片直接预览
      uni.previewImage({
        urls: [material.url],
        urls: [fileUrl],
        current: 0,
        success: () => {
          console.log("图片预览成功");
@@ -1053,7 +1098,7 @@
    ) {
      // 文档文件下载后打开
      uni.downloadFile({
        url: material.url,
        url: fileUrl,
        success: (res) => {
          if (res.statusCode == 200) {
            const filePath = res.tempFilePath;