"use strict"; const common_vendor = require("../../common/vendor.js"); const stores_user = require("../../stores/user.js"); if (!Array) { const _easycom_uni_icons2 = common_vendor.resolveComponent("uni-icons"); const _easycom_uni_popup2 = common_vendor.resolveComponent("uni-popup"); const _easycom_uni_file_picker2 = common_vendor.resolveComponent("uni-file-picker"); (_easycom_uni_icons2 + _easycom_uni_popup2 + _easycom_uni_file_picker2)(); } const _easycom_uni_icons = () => "../../node-modules/@dcloudio/uni-ui/lib/uni-icons/uni-icons.js"; const _easycom_uni_popup = () => "../../node-modules/@dcloudio/uni-ui/lib/uni-popup/uni-popup.js"; const _easycom_uni_file_picker = () => "../../node-modules/@dcloudio/uni-ui/lib/uni-file-picker/uni-file-picker.js"; if (!Math) { (_easycom_uni_icons + _easycom_uni_popup + _easycom_uni_file_picker)(); } const _sfc_main = { __name: "index", props: { files: { type: Array, default: () => [] }, gradesFiles: { // 新增属性:成绩单附件列表 type: Array, default: () => [] }, readonly: { type: Boolean, default: false }, 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" // 新增事件:上传基础附件 ], setup(__props, { expose: __expose, emit: __emit }) { const userStore = stores_user.useUserStore(); const props = __props; const emit = __emit; const popup = common_vendor.ref(null); const filePicker = common_vendor.ref(null); const baseFiles = common_vendor.ref([]); 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 currentFileList = common_vendor.computed(() => { if (!props.showGradeSlip) { return baseFiles.value; } return currentTab.value === "base" ? baseFiles.value : gradeFiles.value; }); const totalFileCount = common_vendor.computed(() => { return 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("http://") || path.startsWith("https://")) { return path; } return `${baseUrlHt}${path.startsWith("/") ? "" : "/"}${path}`; }; const imageStyles = { width: 120, height: 120, border: false }; const supportedImageTypes = [ "image/jpeg", "image/png", "image/gif", "image/webp", "image/bmp", "image/svg+xml" ]; const onPopupChange = (e) => { showButton.value = !e.show; }; const getFileIcon = (type) => { if (type && supportedImageTypes.includes(type)) return "image"; if (type && type.includes("pdf")) return "paperclip"; if (type && type.includes("word")) return "file-word"; if (type && type.includes("excel")) return "file-excel"; if (type && type.includes("powerpoint")) return "file-ppt"; return "file"; }; const getFileColor = (type) => { if (type && supportedImageTypes.includes(type)) return mainColor.value; if (type && type.includes("pdf")) return "#ff4d4f"; if (type && type.includes("word")) return "#2b579a"; if (type && type.includes("excel")) return "#217346"; if (type && type.includes("powerpoint")) return "#b7472a"; return "#666"; }; const formatFileSize = (size) => { if (!size) return ""; if (size < 1024) return `${size}B`; if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)}KB`; return `${(size / (1024 * 1024)).toFixed(1)}MB`; }; const togglePopup = () => { if (popup.value) { popup.value.open(); } }; const closePopup = () => { if (popup.value) { popup.value.close(); } }; const chooseFile = () => { var _a; (_a = filePicker.value) == null ? void 0 : _a.choose(); }; const getFileTypeFromName = (filename) => { if (!filename) return "application/octet-stream"; const ext = filename.split(".").pop().toLowerCase(); const typeMap = { jpg: "image/jpeg", jpeg: "image/jpeg", png: "image/png", gif: "image/gif", webp: "image/webp", bmp: "image/bmp", SVG: "image/svg+xml", pdf: "application/pdf" }; return typeMap[ext] || "application/octet-stream"; }; const onFileSelect = (e) => { const isGradeTab = props.showGradeSlip && currentTab.value === "grade"; const targetFiles = isGradeTab ? gradeFiles.value : baseFiles.value; const newFiles = e.tempFiles.filter((file) => { const fileExt = file.name ? file.name.split(".").pop().toLowerCase() : ""; const isImage = supportedImageTypes.includes(file.type) || ["jpg", "jpeg", "png", "gif", "webp", "bmp", "svg"].includes(fileExt); const isPDF = file.type && file.type.includes("pdf") || fileExt === "pdf"; return isImage || isPDF; }).map((file) => ({ name: file.name, url: file.path || file.url, type: file.type || getFileTypeFromName(file.name), size: file.size, file, status: "pending", // 明确标记附件类型 attachmentType: isGradeTab ? "grade" : "base" })); if (targetFiles.length + newFiles.length > props.maxCount) { common_vendor.index.showToast({ title: `最多只能上传${props.maxCount}个文件`, icon: "none" }); return; } if (isGradeTab) { gradeFiles.value = [...gradeFiles.value, ...newFiles]; emit("update:gradesFiles", gradeFiles.value); } else { baseFiles.value = [...baseFiles.value, ...newFiles]; emit("update:files", baseFiles.value); } }; const getAllFiles = () => { return [...baseFiles.value, ...gradeFiles.value]; }; const removeFile = (type, index, event) => { if (event) { event.stopPropagation(); } if (type === "grade") { gradeFiles.value.splice(index, 1); emit("update:gradesFiles", gradeFiles.value); } else { baseFiles.value.splice(index, 1); emit("update:files", baseFiles.value); } }; const previewFile = (file) => { const fullUrl = getFullUrl(file.url); if (file.type && supportedImageTypes.includes(file.type)) { const allFiles = getAllFiles(); common_vendor.index.previewImage({ urls: allFiles.filter((f) => f.type && supportedImageTypes.includes(f.type)).map((f) => getFullUrl(f.url)), current: fullUrl }); } else if (file.type && file.type.includes("pdf")) { common_vendor.index.downloadFile({ url: fullUrl, success: (res) => { const filePath = res.tempFilePath; common_vendor.index.openDocument({ filePath, fileType: "pdf", success: () => common_vendor.index.__f__("log", "at components/attachment/index.vue:358", "打开PDF成功"), fail: (err) => { common_vendor.index.__f__("error", "at components/attachment/index.vue:360", "打开PDF失败", err); common_vendor.index.showToast({ title: "打开PDF失败", icon: "none" }); } }); }, fail: (err) => { common_vendor.index.__f__("error", "at components/attachment/index.vue:369", "下载PDF失败", err); common_vendor.index.showToast({ title: "下载PDF失败", icon: "none" }); } }); } else { emit("preview", file); } }; const uploadFile = (file, type) => { return new Promise((resolve, reject) => { const token = common_vendor.index.getStorageSync("token"); common_vendor.index.uploadFile({ url: "/api/common/upload", filePath: file.path || file.url, name: "file", header: { "Authorization": `Bearer ${token}` }, success: (res) => { if (res.statusCode === 200) { const data = JSON.parse(res.data); common_vendor.index.__f__("log", "at components/attachment/index.vue:397", data, "文件"); if (data.code === 200) { resolve({ ...data, fileName: data.fileName }); } else { reject(new Error(data.msg || "上传失败")); } } else { reject(new Error(`上传失败,状态码: ${res.statusCode}`)); } }, fail: (err) => { reject(err); } }); }); }; const confirmUpload = async () => { if (props.showGradeSlip && props.isGradeRequired && gradeFiles.value.length === 0) { common_vendor.index.showToast({ title: "请上传成绩单附件", icon: "none" }); currentTab.value = "grade"; return; } const allFiles = getAllFiles(); if (allFiles.length === 0) { common_vendor.index.showToast({ title: "请先添加附件", icon: "none" }); return; } common_vendor.index.showLoading({ title: "上传中", mask: true }); try { const pendingBaseFiles = baseFiles.value.filter((file) => !file.url || file.status === "pending"); const pendingGradeFiles = gradeFiles.value.filter((file) => !file.url || file.status === "pending"); for (const file of pendingBaseFiles) { try { file.status = "uploading"; const res = await uploadFile(file.file, "base"); Object.assign(file, { url: res.url, fileName: res.name, newFileName: res.newFileName, originalFilename: res.originalFilename, status: "success", size: res.size }); emit("upload-base", file); } catch (error) { common_vendor.index.__f__("error", "at components/attachment/index.vue:466", "上传失败:", error); file.status = "error"; common_vendor.index.showToast({ title: `文件 ${file.name} 上传失败`, icon: "none" }); } } for (const file of pendingGradeFiles) { try { file.status = "uploading"; const res = await uploadFile(file.file, "grade"); Object.assign(file, { url: res.fileName, fileName: res.fileName, newFileName: res.newFileName, originalFilename: res.originalFilename, status: "success" }); emit("upload-grade", file); } catch (error) { common_vendor.index.__f__("error", "at components/attachment/index.vue:489", "成绩单附件上传失败:", error); file.status = "error"; common_vendor.index.showToast({ title: `文件 ${file.name} 上传失败`, icon: "none" }); } } common_vendor.index.__f__("log", "at components/attachment/index.vue:497", baseFiles.value, "1"); common_vendor.index.__f__("log", "at components/attachment/index.vue:498", gradeFiles.value, "2"); emit("update:files", baseFiles.value); emit("update:gradesFiles", gradeFiles.value); common_vendor.index.showToast({ title: "上传完成", icon: "success" }); closePopup(); } catch (error) { common_vendor.index.__f__("error", "at components/attachment/index.vue:511", "上传出错:", error); common_vendor.index.showToast({ title: "上传出错", icon: "none" }); } finally { common_vendor.index.hideLoading(); } }; const getFilesByType = (type) => { return type === "grade" ? gradeFiles.value : baseFiles.value; }; __expose({ getFilesByType, getAllFiles }); return (_ctx, _cache) => { return common_vendor.e({ a: totalFileCount.value > 0 }, totalFileCount.value > 0 ? { b: common_vendor.t(totalFileCount.value) } : {}, { c: __props.position.right, d: __props.position.bottom, e: __props.bgColor, f: showButton.value ? "flex" : "none", g: common_vendor.o(togglePopup), h: !__props.readonly }, !__props.readonly ? { i: common_vendor.o(chooseFile), j: common_vendor.p({ type: "plus", size: "24", color: mainColor.value }) } : {}, { k: common_vendor.o(closePopup), l: common_vendor.p({ type: "close", size: "24", color: "#999" }), m: __props.showGradeSlip }, __props.showGradeSlip ? common_vendor.e({ n: currentTab.value === "base" ? 1 : "", o: common_vendor.o(($event) => currentTab.value = "base"), p: __props.isGradeRequired }, __props.isGradeRequired ? {} : {}, { q: currentTab.value === "grade" ? 1 : "", r: common_vendor.o(($event) => currentTab.value = "grade") }) : {}, { s: currentTab.value === "base" || !__props.showGradeSlip }, currentTab.value === "base" || !__props.showGradeSlip ? { t: common_vendor.f(baseFiles.value, (file, index, i0) => { return common_vendor.e({ a: "2d320176-3-" + i0 + ",2d320176-0", b: common_vendor.p({ type: getFileIcon(file.type), size: "24", color: getFileColor(file.type) }), c: common_vendor.o(($event) => previewFile(file), "base-" + index), d: common_vendor.t(file.originalFilename || file.name), e: common_vendor.t(formatFileSize(file.size)), f: file.status === "uploading" }, file.status === "uploading" ? {} : file.status === "error" ? {} : {}, { g: file.status === "error", h: common_vendor.o(($event) => previewFile(file), "base-" + index) }, !__props.readonly ? { i: common_vendor.o((e) => removeFile("base", index, e), "base-" + index), j: "2d320176-4-" + i0 + ",2d320176-0", k: common_vendor.p({ type: "trash", size: "20", color: "#ff4d4f" }) } : {}, { l: "base-" + index }); }), v: !__props.readonly } : {}, { w: currentTab.value === "grade" && __props.showGradeSlip }, currentTab.value === "grade" && __props.showGradeSlip ? { x: common_vendor.f(gradeFiles.value, (file, index, i0) => { return common_vendor.e({ a: "2d320176-5-" + i0 + ",2d320176-0", b: common_vendor.p({ type: getFileIcon(file.type), size: "24", color: getFileColor(file.type) }), c: common_vendor.o(($event) => previewFile(file), "grade-" + index), d: common_vendor.t(file.originalFilename || file.name), e: common_vendor.t(formatFileSize(file.size)), f: file.status === "uploading" }, file.status === "uploading" ? {} : file.status === "error" ? {} : {}, { g: file.status === "error", h: common_vendor.o(($event) => previewFile(file), "grade-" + index) }, !__props.readonly ? { i: common_vendor.o((e) => removeFile("grade", index, e), "grade-" + index), j: "2d320176-6-" + i0 + ",2d320176-0", k: common_vendor.p({ type: "trash", size: "20", color: "#ff4d4f" }) } : {}, { l: "grade-" + index }); }), y: !__props.readonly } : {}, { z: currentFileList.value.length === 0 }, currentFileList.value.length === 0 ? common_vendor.e({ A: common_vendor.p({ type: "info", size: "24", color: "#999" }), B: currentTab.value === "base" || !__props.showGradeSlip }, currentTab.value === "base" || !__props.showGradeSlip ? {} : currentTab.value === "grade" ? {} : {}, { C: currentTab.value === "grade" }) : {}, { D: !__props.readonly }, !__props.readonly ? { E: common_vendor.o(chooseFile), F: common_vendor.o(confirmUpload) } : {}, { G: common_vendor.sr(popup, "2d320176-0", { "k": "popup" }), H: common_vendor.o(onPopupChange), I: common_vendor.p({ type: "bottom", ["safe-area"]: false }), J: !__props.readonly }, !__props.readonly ? { K: common_vendor.sr(filePicker, "2d320176-8", { "k": "filePicker" }), L: common_vendor.o(onFileSelect), M: common_vendor.o(_ctx.onFileDelete), N: common_vendor.p({ ["auto-upload"]: false, ["file-mediatype"]: "all", limit: __props.maxCount - currentFileList.value.length, ["image-styles"]: imageStyles }) } : {}, { O: common_vendor.gei(_ctx, "") }); }; } }; wx.createComponent(_sfc_main); //# sourceMappingURL=../../../.sourcemap/mp-weixin/components/attachment/index.js.map