WXL
2 天以前 c80bc467a41daa6cbae4e5515a300a8ca98cfeaa
unpackage/dist/dev/mp-weixin/components/attachment/index.js
@@ -17,13 +17,23 @@
    files: { type: Array, default: () => [] },
    gradesFiles: { type: Array, default: () => [] },
    readonly: { type: Boolean, default: false },
    position: { type: Object, default: () => ({ right: "30rpx", bottom: "200rpx" }) },
    position: {
      type: Object,
      default: () => ({ right: "30rpx", bottom: "200rpx" })
    },
    bgColor: { type: String, default: "#67AFAB" },
    maxCount: { type: Number, default: 9 },
    showGradeSlip: { type: Boolean, default: false },
    isGradeRequired: { type: Boolean, default: false }
  },
  emits: ["update:files", "update:gradesFiles", "upload", "preview", "upload-grade", "upload-base"],
  emits: [
    "update:files",
    "update:gradesFiles",
    "upload",
    "preview",
    "upload-grade",
    "upload-base"
  ],
  setup(__props, { expose: __expose, emit: __emit }) {
    const userStore = stores_user.useUserStore();
    const props = __props;
@@ -33,35 +43,58 @@
    const gradeFiles = common_vendor.ref([]);
    const showButton = common_vendor.ref(true);
    const mainColor = common_vendor.ref("#67AFAB");
    const baseUrlHt = userStore.baseUrlHt;
    const currentTab = common_vendor.ref("base");
    const blobUrls = common_vendor.ref([]);
    const getBaseUrlHt = () => {
      return userStore.baseUrlHt;
    };
    const baseUrlHt = getBaseUrlHt();
    const currentFileList = common_vendor.computed(() => {
      if (!props.showGradeSlip)
        return baseFiles.value;
      return currentTab.value === "base" ? baseFiles.value : gradeFiles.value;
    });
    const totalFileCount = common_vendor.computed(() => baseFiles.value.length + gradeFiles.value.length);
    common_vendor.watch(() => props.files, (newFiles) => {
      baseFiles.value = [...newFiles];
    }, { immediate: true });
    common_vendor.watch(() => props.gradesFiles, (newFiles) => {
      gradeFiles.value = [...newFiles];
    }, { immediate: true });
    const totalFileCount = common_vendor.computed(
      () => baseFiles.value.length + gradeFiles.value.length
    );
    common_vendor.watch(
      () => props.files,
      (newFiles) => {
        baseFiles.value = [...newFiles];
      },
      { immediate: true }
    );
    common_vendor.watch(
      () => props.gradesFiles,
      (newFiles) => {
        gradeFiles.value = [...newFiles];
      },
      { immediate: true }
    );
    const getFullUrl = (path) => {
      if (!path)
        return "";
      if (path.startsWith("blob:") || path.startsWith("file://")) {
        return path;
      }
      if (path.startsWith("http://") || path.startsWith("https://")) {
        try {
          const url = new URL(path);
          return `${baseUrlHt}${url.pathname}${url.search}${url.hash}`;
        } catch {
          return path;
        const protocolEnd = path.indexOf("://") + 3;
        const pathStart = path.indexOf("/", protocolEnd);
        if (pathStart !== -1) {
          return `${baseUrlHt}${path.substring(pathStart)}`;
        }
        return baseUrlHt;
      }
      return `${baseUrlHt}${path.startsWith("/") ? "" : "/"}${path}`;
    };
    const supportedImageTypes = ["image/jpeg", "image/png", "image/gif", "image/webp", "image/bmp", "image/svg+xml"];
    const supportedImageTypes = [
      "image/jpeg",
      "image/png",
      "image/gif",
      "image/webp",
      "image/bmp",
      "image/svg+xml"
    ];
    const onPopupChange = (e) => {
      showButton.value = !e.show;
    };
@@ -112,7 +145,10 @@
      const isGradeTab = props.showGradeSlip && currentTab.value === "grade";
      const targetFiles = isGradeTab ? gradeFiles.value : baseFiles.value;
      if (targetFiles.length + newFiles.length > props.maxCount) {
        common_vendor.index.showToast({ title: `最多只能上传${props.maxCount}个文件`, icon: "none" });
        common_vendor.index.showToast({
          title: `最多只能上传${props.maxCount}个文件`,
          icon: "none"
        });
        newFiles.forEach((f) => {
          if (f.url && f.url.startsWith("blob:"))
            URL.revokeObjectURL(f.url);
@@ -133,7 +169,10 @@
        success: (res) => {
          const remain = props.maxCount - currentFileList.value.length;
          if (remain <= 0) {
            common_vendor.index.showToast({ title: `最多上传${props.maxCount}个文件`, icon: "none" });
            common_vendor.index.showToast({
              title: `最多上传${props.maxCount}个文件`,
              icon: "none"
            });
            return;
          }
          if (res.tapIndex === 0) {
@@ -147,7 +186,6 @@
                  path: file.path,
                  url: file.path,
                  uploadPath: file.path,
                  // 小程序临时文件路径
                  type: file.type || "image/jpeg",
                  size: file.size,
                  raw: file,
@@ -203,7 +241,9 @@
      }
      if (file.type && supportedImageTypes.includes(file.type)) {
        const allFiles = [...baseFiles.value, ...gradeFiles.value];
        const imageUrls = allFiles.filter((f) => f.type && supportedImageTypes.includes(f.type)).map((f) => f.url.startsWith("blob:") || f.url.startsWith("file://") || f.url.startsWith("/") ? f.url : getFullUrl(f.url));
        const imageUrls = allFiles.filter((f) => f.type && supportedImageTypes.includes(f.type)).map(
          (f) => f.url.startsWith("blob:") || f.url.startsWith("file://") || f.url.startsWith("/") ? f.url : getFullUrl(f.url)
        );
        common_vendor.index.previewImage({ urls: imageUrls, current: previewUrl });
      } else if (file.type && file.type.includes("pdf")) {
        common_vendor.index.downloadFile({
@@ -220,31 +260,34 @@
    const uploadFile = (file, type) => {
      return new Promise((resolve, reject) => {
        const token = common_vendor.index.getStorageSync("token");
        let filePath = file.uploadPath || file.url || file.path;
        const filePath = file.uploadPath || file.url || file.path;
        if (!filePath || typeof filePath !== "string") {
          reject(new Error("无效的文件路径"));
          return;
        }
        let uploadUrl = "/api/common/upload";
        uploadUrl = "https://opo.qduh.cn/common/upload";
        const uploadUrl = `${userStore.baseUrlHt}/common/upload`;
        common_vendor.index.uploadFile({
          url: uploadUrl,
          filePath,
          name: "file",
          header: { "Authorization": `Bearer ${token}` },
          header: {
            Authorization: `Bearer ${token}`
          },
          success: (res) => {
            if (res.statusCode === 200) {
              try {
                const data = JSON.parse(res.data);
                if (data.code === 200)
                if (data.code === 200) {
                  resolve({ ...data, fileName: data.fileName });
                else
                } else {
                  reject(new Error(data.msg || "上传失败"));
                }
              } catch {
                reject(new Error("解析响应失败"));
                reject(new Error("响应解析失败"));
              }
            } else
            } else {
              reject(new Error(`上传失败,状态码: ${res.statusCode}`));
            }
          },
          fail: reject
        });
@@ -256,15 +299,21 @@
        currentTab.value = "grade";
        return;
      }
      const totalPending = [...baseFiles.value, ...gradeFiles.value].filter((f) => !f.url || f.status === "pending").length;
      const totalPending = [...baseFiles.value, ...gradeFiles.value].filter(
        (f) => !f.url || f.status === "pending"
      ).length;
      if (totalPending === 0) {
        common_vendor.index.showToast({ title: "没有待上传的文件", icon: "none" });
        return;
      }
      common_vendor.index.showLoading({ title: "上传中", mask: true });
      try {
        const pendingBase = baseFiles.value.filter((f) => !f.url || f.status === "pending");
        const pendingGrade = gradeFiles.value.filter((f) => !f.url || f.status === "pending");
        const pendingBase = baseFiles.value.filter(
          (f) => !f.url || f.status === "pending"
        );
        const pendingGrade = gradeFiles.value.filter(
          (f) => !f.url || f.status === "pending"
        );
        for (const file of pendingBase) {
          try {
            file.status = "uploading";
@@ -305,7 +354,7 @@
        common_vendor.index.showToast({ title: "上传完成", icon: "success" });
        closePopup();
      } catch (error) {
        common_vendor.index.__f__("error", "at components/attachment/index.vue:398", "上传出错:", error);
        common_vendor.index.__f__("error", "at components/attachment/index.vue:609", "上传出错:", error);
        common_vendor.index.showToast({ title: "上传出错", icon: "none" });
      } finally {
        common_vendor.index.hideLoading();