From c80bc467a41daa6cbae4e5515a300a8ca98cfeaa Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期二, 21 七月 2026 15:44:01 +0800
Subject: [PATCH] 维护
---
components/attachment/index.vue | 545 ++++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 402 insertions(+), 143 deletions(-)
diff --git a/components/attachment/index.vue b/components/attachment/index.vue
index e3fd029..cebfc08 100644
--- a/components/attachment/index.vue
+++ b/components/attachment/index.vue
@@ -1,31 +1,54 @@
<template>
<view class="attachment-upload">
<!-- 闄勪欢鎮诞鎸夐挳 -->
- <view class="attachment-btn" :style="{
- right: position.right,
- bottom: position.bottom,
- backgroundColor: bgColor,
- display: showButton ? 'flex' : 'none',
- }" @click="togglePopup">
+ <view
+ class="attachment-btn"
+ :style="{
+ right: position.right,
+ bottom: position.bottom,
+ backgroundColor: bgColor,
+ display: showButton ? 'flex' : 'none',
+ }"
+ @click="togglePopup"
+ >
<text>闄勪欢</text>
<text class="badge" v-if="totalFileCount > 0">{{ totalFileCount }}</text>
</view>
<!-- 闄勪欢寮瑰眰 -->
- <uni-popup ref="popup" type="bottom" :safe-area="false" @change="onPopupChange">
+ <uni-popup
+ ref="popup"
+ type="bottom"
+ :safe-area="false"
+ @change="onPopupChange"
+ >
<view class="attachment-popup">
<view class="popup-header">
<text class="title">闄勪欢绠$悊</text>
- <uni-icons v-if="!readonly" type="plus" size="24" :color="mainColor" @click="chooseFile" />
+ <uni-icons
+ v-if="!readonly"
+ type="plus"
+ size="24"
+ :color="mainColor"
+ @click="chooseFile"
+ />
<uni-icons type="close" size="24" color="#999" @click="closePopup" />
</view>
<!-- 鏍囩椤� -->
<view v-if="showGradeSlip" class="attachment-tabs">
- <view class="tab-item" :class="{ active: currentTab === 'base' }" @click="currentTab = 'base'">
+ <view
+ class="tab-item"
+ :class="{ active: currentTab === 'base' }"
+ @click="currentTab = 'base'"
+ >
<text>鍩虹闄勪欢</text>
</view>
- <view class="tab-item" :class="{ active: currentTab === 'grade' }" @click="currentTab = 'grade'">
+ <view
+ class="tab-item"
+ :class="{ active: currentTab === 'grade' }"
+ @click="currentTab = 'grade'"
+ >
<text>鎴愮哗鍗曢檮浠�</text>
<text class="required-mark" v-if="isGradeRequired">*</text>
</view>
@@ -34,34 +57,76 @@
<!-- 闄勪欢鍒楄〃 -->
<scroll-view scroll-y class="file-list">
<template v-if="currentTab === 'base' || !showGradeSlip">
- <view class="file-item" v-for="(file, index) in baseFiles" :key="'base-' + index">
+ <view
+ class="file-item"
+ v-for="(file, index) in baseFiles"
+ :key="'base-' + index"
+ >
<view class="file-icon" @click="previewFile(file)">
- <uni-icons :type="getFileIcon(file.type)" size="24" :color="getFileColor(file.type)" />
+ <uni-icons
+ :type="getFileIcon(file.type)"
+ size="24"
+ :color="getFileColor(file.type)"
+ />
</view>
<view class="file-info" @click="previewFile(file)">
- <text class="file-name">{{ file.originalFilename || file.name }}</text>
+ <text class="file-name">{{
+ file.originalFilename || file.name
+ }}</text>
<text class="file-size">{{ formatFileSize(file.size) }}</text>
- <text class="file-status" v-if="file.status === 'uploading'">涓婁紶涓�...</text>
- <text class="file-status error" v-else-if="file.status === 'error'">涓婁紶澶辫触</text>
+ <text class="file-status" v-if="file.status === 'uploading'"
+ >涓婁紶涓�...</text
+ >
+ <text
+ class="file-status error"
+ v-else-if="file.status === 'error'"
+ >涓婁紶澶辫触</text
+ >
</view>
- <uni-icons v-if="!readonly" type="trash" size="20" color="#ff4d4f"
- @click="(e) => removeFile('base', index, e)" />
+ <uni-icons
+ v-if="!readonly"
+ type="trash"
+ size="20"
+ color="#ff4d4f"
+ @click="(e) => removeFile('base', index, e)"
+ />
</view>
</template>
<template v-if="currentTab === 'grade' && showGradeSlip">
- <view class="file-item" v-for="(file, index) in gradeFiles" :key="'grade-' + index">
+ <view
+ class="file-item"
+ v-for="(file, index) in gradeFiles"
+ :key="'grade-' + index"
+ >
<view class="file-icon" @click="previewFile(file)">
- <uni-icons :type="getFileIcon(file.type)" size="24" :color="getFileColor(file.type)" />
+ <uni-icons
+ :type="getFileIcon(file.type)"
+ size="24"
+ :color="getFileColor(file.type)"
+ />
</view>
<view class="file-info" @click="previewFile(file)">
- <text class="file-name">{{ file.originalFilename || file.name }}</text>
+ <text class="file-name">{{
+ file.originalFilename || file.name
+ }}</text>
<text class="file-size">{{ formatFileSize(file.size) }}</text>
- <text class="file-status" v-if="file.status === 'uploading'">涓婁紶涓�...</text>
- <text class="file-status error" v-else-if="file.status === 'error'">涓婁紶澶辫触</text>
+ <text class="file-status" v-if="file.status === 'uploading'"
+ >涓婁紶涓�...</text
+ >
+ <text
+ class="file-status error"
+ v-else-if="file.status === 'error'"
+ >涓婁紶澶辫触</text
+ >
</view>
- <uni-icons v-if="!readonly" type="trash" size="20" color="#ff4d4f"
- @click="(e) => removeFile('grade', index, e)" />
+ <uni-icons
+ v-if="!readonly"
+ type="trash"
+ size="20"
+ color="#ff4d4f"
+ @click="(e) => removeFile('grade', index, e)"
+ />
</view>
</template>
@@ -90,47 +155,141 @@
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 }
+ isGradeRequired: { type: Boolean, default: false },
});
-const emit = defineEmits(["update:files", "update:gradesFiles", "upload", "preview", "upload-grade", "upload-base"]);
+const emit = defineEmits([
+ "update:files",
+ "update:gradesFiles",
+ "upload",
+ "preview",
+ "upload-grade",
+ "upload-base",
+]);
const popup = ref(null);
const baseFiles = ref([]);
const gradeFiles = ref([]);
const showButton = ref(true);
const mainColor = ref("#67AFAB");
-const baseUrlHt = userStore.baseUrlHt;
-const currentTab = ref('base');
-const blobUrls = ref([]); // 瀛樺偍 H5 blob URL 浠ヤ究閲婃斁鍐呭瓨
+const currentTab = ref("base");
+const blobUrls = ref([]);
+
+const getBaseUrlHt = () => {
+ // #ifdef 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
+ return userStore.baseUrlHt;
+ // #endif
+};
+
+
+const baseUrlHt = getBaseUrlHt();
const currentFileList = computed(() => {
if (!props.showGradeSlip) return baseFiles.value;
- return currentTab.value === 'base' ? baseFiles.value : gradeFiles.value;
+ return currentTab.value === "base" ? baseFiles.value : gradeFiles.value;
});
-const totalFileCount = computed(() => baseFiles.value.length + gradeFiles.value.length);
+const totalFileCount = computed(
+ () => baseFiles.value.length + gradeFiles.value.length,
+);
-watch(() => props.files, (newFiles) => { baseFiles.value = [...newFiles]; }, { immediate: true });
-watch(() => props.gradesFiles, (newFiles) => { gradeFiles.value = [...newFiles]; }, { immediate: true });
+watch(
+ () => props.files,
+ (newFiles) => {
+ baseFiles.value = [...newFiles];
+ },
+ { immediate: true },
+);
+watch(
+ () => props.gradesFiles,
+ (newFiles) => {
+ gradeFiles.value = [...newFiles];
+ },
+ { immediate: true },
+);
+// 鑾峰彇瀹屾暣URL - 骞冲彴宸紓鍖栧鐞�
const getFullUrl = (path) => {
- if (!path) return '';
- if (path.startsWith('http://') || path.startsWith('https://')) {
+ if (!path) return "";
+
+ // 濡傛灉鏄� 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 瑙f瀽
try {
const url = new URL(path);
return `${baseUrlHt}${url.pathname}${url.search}${url.hash}`;
- } catch { return path; }
+ } catch (error) {
+ console.error("URL瑙f瀽澶辫触:", error);
+ // 闄嶇骇澶勭悊锛氭墜鍔ㄦ埅鍙栬矾寰�
+ const pathIndex = path.indexOf("/", 8); // 璺宠繃 http:// 鎴� https://
+ if (pathIndex !== -1) {
+ return `${baseUrlHt}${path.substring(pathIndex)}`;
+ }
+ return path;
+ }
+ // #endif
+
+ // #ifdef MP-WEIXIN
+ // 灏忕▼搴忕幆澧冿細涓嶄娇鐢� new URL锛屾墜鍔ㄥ鐞�
+ const protocolEnd = path.indexOf("://") + 3;
+ const pathStart = path.indexOf("/", protocolEnd);
+ if (pathStart !== -1) {
+ // 鎻愬彇璺緞閮ㄥ垎锛堝寘鎷矾寰勩�佹煡璇㈠弬鏁板拰hash锛�
+ return `${baseUrlHt}${path.substring(pathStart)}`;
+ }
+ return baseUrlHt;
+ // #endif
}
- return `${baseUrlHt}${path.startsWith('/') ? '' : '/'}${path}`;
+
+ // 鐩稿璺緞澶勭悊
+ 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; };
+const onPopupChange = (e) => {
+ showButton.value = !e.show;
+};
const getFileIcon = (type) => {
if (type && supportedImageTypes.includes(type)) return "image";
if (type && type.includes("pdf")) return "paperclip";
@@ -153,15 +312,24 @@
if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)}KB`;
return `${(size / (1024 * 1024)).toFixed(1)}MB`;
};
-const togglePopup = () => { popup.value?.open(); };
-const closePopup = () => { popup.value?.close(); };
+const togglePopup = () => {
+ popup.value?.open();
+};
+const closePopup = () => {
+ popup.value?.close();
+};
const addFilesToCurrentTab = (newFiles) => {
- const isGradeTab = props.showGradeSlip && currentTab.value === 'grade';
+ const isGradeTab = props.showGradeSlip && currentTab.value === "grade";
const targetFiles = isGradeTab ? gradeFiles.value : baseFiles.value;
if (targetFiles.length + newFiles.length > props.maxCount) {
- uni.showToast({ title: `鏈�澶氬彧鑳戒笂浼�${props.maxCount}涓枃浠禶, icon: "none" });
- newFiles.forEach(f => { if (f.url && f.url.startsWith('blob:')) URL.revokeObjectURL(f.url); });
+ uni.showToast({
+ title: `鏈�澶氬彧鑳戒笂浼�${props.maxCount}涓枃浠禶,
+ icon: "none",
+ });
+ newFiles.forEach((f) => {
+ if (f.url && f.url.startsWith("blob:")) URL.revokeObjectURL(f.url);
+ });
return;
}
if (isGradeTab) {
@@ -176,34 +344,41 @@
// 閫夋嫨鏂囦欢锛堝钩鍙板樊寮傦級
const chooseFile = () => {
// #ifdef H5
- const input = document.createElement('input');
- input.type = 'file';
- input.accept = 'image/*,application/pdf';
+ const input = document.createElement("input");
+ input.type = "file";
+ input.accept = "image/*,application/pdf";
input.multiple = true;
input.onchange = (e) => {
const files = Array.from(e.target.files);
if (files.length === 0) return;
- const newFiles = files.map(file => {
- const ext = file.name.split('.').pop().toLowerCase();
- const isImage = supportedImageTypes.includes(file.type) || ['jpg','jpeg','png','gif','webp','bmp','svg'].includes(ext);
- const isPDF = file.type.includes('pdf') || ext === 'pdf';
- if (!isImage && !isPDF) {
- uni.showToast({ title: `鏂囦欢 ${file.name} 鏍煎紡涓嶆敮鎸乣, icon: 'none' });
- return null;
- }
- const blobUrl = URL.createObjectURL(file);
- blobUrls.value.push(blobUrl);
- return {
- name: file.name,
- path: blobUrl,
- url: blobUrl,
- uploadPath: blobUrl, // 鍏抽敭锛氫笂浼犺矾寰勪娇鐢� blob URL 瀛楃涓�
- type: file.type,
- size: file.size,
- raw: file,
- status: 'pending'
- };
- }).filter(f => f);
+ const newFiles = files
+ .map((file) => {
+ const ext = file.name.split(".").pop().toLowerCase();
+ const isImage =
+ supportedImageTypes.includes(file.type) ||
+ ["jpg", "jpeg", "png", "gif", "webp", "bmp", "svg"].includes(ext);
+ const isPDF = file.type.includes("pdf") || ext === "pdf";
+ if (!isImage && !isPDF) {
+ uni.showToast({
+ title: `鏂囦欢 ${file.name} 鏍煎紡涓嶆敮鎸乣,
+ icon: "none",
+ });
+ return null;
+ }
+ const blobUrl = URL.createObjectURL(file);
+ blobUrls.value.push(blobUrl);
+ return {
+ name: file.name,
+ path: blobUrl,
+ url: blobUrl,
+ uploadPath: blobUrl,
+ type: file.type,
+ size: file.size,
+ raw: file,
+ status: "pending",
+ };
+ })
+ .filter((f) => f);
addFilesToCurrentTab(newFiles);
input.remove();
};
@@ -212,38 +387,41 @@
// #ifdef MP-WEIXIN
uni.showActionSheet({
- itemList: ['鎷嶇収/鐩稿唽', '浠庤亰澶╄褰曢�夋嫨鏂囦欢'],
+ itemList: ["鎷嶇収/鐩稿唽", "浠庤亰澶╄褰曢�夋嫨鏂囦欢"],
success: (res) => {
const remain = props.maxCount - currentFileList.value.length;
if (remain <= 0) {
- uni.showToast({ title: `鏈�澶氫笂浼�${props.maxCount}涓枃浠禶, icon: 'none' });
+ uni.showToast({
+ title: `鏈�澶氫笂浼�${props.maxCount}涓枃浠禶,
+ icon: "none",
+ });
return;
}
if (res.tapIndex === 0) {
uni.chooseImage({
count: remain,
- sizeType: ['original', 'compressed'],
- sourceType: ['album', 'camera'],
+ sizeType: ["original", "compressed"],
+ sourceType: ["album", "camera"],
success: (chooseRes) => {
- const files = chooseRes.tempFiles.map(file => ({
- name: file.name || 'image.jpg',
+ const files = chooseRes.tempFiles.map((file) => ({
+ name: file.name || "image.jpg",
path: file.path,
url: file.path,
- uploadPath: file.path, // 灏忕▼搴忎复鏃舵枃浠惰矾寰�
- type: file.type || 'image/jpeg',
+ uploadPath: file.path,
+ type: file.type || "image/jpeg",
size: file.size,
raw: file,
- status: 'pending'
+ status: "pending",
}));
addFilesToCurrentTab(files);
- }
+ },
});
} else if (res.tapIndex === 1) {
uni.chooseMessageFile({
count: remain,
- type: 'all',
+ type: "all",
success: (chooseRes) => {
- const files = chooseRes.tempFiles.map(file => ({
+ const files = chooseRes.tempFiles.map((file) => ({
name: file.name,
path: file.path,
url: file.path,
@@ -251,26 +429,27 @@
type: file.type,
size: file.size,
raw: file,
- status: 'pending'
+ status: "pending",
}));
addFilesToCurrentTab(files);
- }
+ },
});
}
- }
+ },
});
// #endif
};
const removeFile = (type, index, event) => {
if (event) event.stopPropagation();
- const file = type === 'grade' ? gradeFiles.value[index] : baseFiles.value[index];
- if (file.url && file.url.startsWith('blob:')) {
+ const file =
+ type === "grade" ? gradeFiles.value[index] : baseFiles.value[index];
+ if (file.url && file.url.startsWith("blob:")) {
URL.revokeObjectURL(file.url);
const idx = blobUrls.value.indexOf(file.url);
if (idx !== -1) blobUrls.value.splice(idx, 1);
}
- if (type === 'grade') {
+ if (type === "grade") {
gradeFiles.value.splice(index, 1);
emit("update:gradesFiles", gradeFiles.value);
} else {
@@ -282,57 +461,79 @@
// 棰勮鏂囦欢
const previewFile = (file) => {
let previewUrl = file.url;
- if (previewUrl && !previewUrl.startsWith('blob:') && !previewUrl.startsWith('file://') && !previewUrl.startsWith('/')) {
+ if (
+ previewUrl &&
+ !previewUrl.startsWith("blob:") &&
+ !previewUrl.startsWith("file://") &&
+ !previewUrl.startsWith("/")
+ ) {
previewUrl = getFullUrl(previewUrl);
}
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));
+ .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),
+ );
uni.previewImage({ urls: imageUrls, current: previewUrl });
} else if (file.type && file.type.includes("pdf")) {
uni.downloadFile({
url: previewUrl,
- success: (res) => { uni.openDocument({ filePath: res.tempFilePath, fileType: "pdf" }); },
- fail: () => uni.showToast({ title: "鎵撳紑PDF澶辫触", icon: "none" })
+ success: (res) => {
+ uni.openDocument({ filePath: res.tempFilePath, fileType: "pdf" });
+ },
+ fail: () => uni.showToast({ title: "鎵撳紑PDF澶辫触", icon: "none" }),
});
} else {
emit("preview", file);
}
};
-// 涓婁紶鏂囦欢锛堝叧閿慨澶嶏級
-// 涓婁紶鏂囦欢锛堝钩鍙拌嚜閫傚簲锛�
const uploadFile = (file, type) => {
return new Promise((resolve, reject) => {
const token = uni.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;
}
- // 鏍规嵁骞冲彴鏋勯�犱笂浼燯RL
- let uploadUrl = '/api/common/upload';
+ // #ifdef H5
+ const uploadUrl = '/api/common/upload';
+ // #endif
+
// #ifdef MP-WEIXIN
- // 灏忕▼搴忛渶瑕佸畬鏁碪RL锛宐aseUrlHt 鏉ヨ嚜 userStore锛堝 https://opo.qduh.cn锛�
- uploadUrl = 'https://opo.qduh.cn/common/upload';
+ const uploadUrl = `${userStore.baseUrlHt}/common/upload`;
// #endif
uni.uploadFile({
url: uploadUrl,
- filePath: filePath,
+ 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) resolve({ ...data, fileName: data.fileName });
- else reject(new Error(data.msg || '涓婁紶澶辫触'));
- } catch { reject(new Error('瑙f瀽鍝嶅簲澶辫触')); }
- } else reject(new Error(`涓婁紶澶辫触锛岀姸鎬佺爜: ${res.statusCode}`));
+ if (data.code === 200) {
+ resolve({ ...data, fileName: data.fileName });
+ } else {
+ reject(new Error(data.msg || '涓婁紶澶辫触'));
+ }
+ } catch {
+ reject(new Error('鍝嶅簲瑙f瀽澶辫触'));
+ }
+ } else {
+ reject(new Error(`涓婁紶澶辫触锛岀姸鎬佺爜: ${res.statusCode}`));
+ }
},
fail: reject
});
@@ -341,72 +542,83 @@
// 纭涓婁紶
const confirmUpload = async () => {
- if (props.showGradeSlip && props.isGradeRequired && gradeFiles.value.length === 0) {
+ if (
+ props.showGradeSlip &&
+ props.isGradeRequired &&
+ gradeFiles.value.length === 0
+ ) {
uni.showToast({ title: "璇蜂笂浼犳垚缁╁崟闄勪欢", icon: "none" });
- currentTab.value = 'grade';
+ 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) {
uni.showToast({ title: "娌℃湁寰呬笂浼犵殑鏂囦欢", icon: "none" });
return;
}
- uni.showLoading({ title: '涓婁紶涓�', mask: true });
+ uni.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';
- const res = await uploadFile(file, 'base');
+ file.status = "uploading";
+ const res = await uploadFile(file, "base");
Object.assign(file, {
url: res.url,
fileName: res.name,
newFileName: res.newFileName,
originalFilename: res.originalFilename,
- status: 'success',
- size: res.size
+ status: "success",
+ size: res.size,
});
emit("upload-base", file);
} catch (err) {
- file.status = 'error';
- uni.showToast({ title: `鏂囦欢 ${file.name} 涓婁紶澶辫触`, icon: 'none' });
+ file.status = "error";
+ uni.showToast({ title: `鏂囦欢 ${file.name} 涓婁紶澶辫触`, icon: "none" });
}
}
for (const file of pendingGrade) {
try {
- file.status = 'uploading';
- const res = await uploadFile(file, 'grade');
+ file.status = "uploading";
+ const res = await uploadFile(file, "grade");
Object.assign(file, {
url: res.fileName,
fileName: res.fileName,
newFileName: res.newFileName,
originalFilename: res.originalFilename,
- status: 'success'
+ status: "success",
});
emit("upload-grade", file);
} catch (err) {
- file.status = 'error';
- uni.showToast({ title: `鏂囦欢 ${file.name} 涓婁紶澶辫触`, icon: 'none' });
+ file.status = "error";
+ uni.showToast({ title: `鏂囦欢 ${file.name} 涓婁紶澶辫触`, icon: "none" });
}
}
emit("update:files", baseFiles.value);
emit("update:gradesFiles", gradeFiles.value);
- uni.showToast({ title: '涓婁紶瀹屾垚', icon: 'success' });
+ uni.showToast({ title: "涓婁紶瀹屾垚", icon: "success" });
closePopup();
} catch (error) {
- console.error('涓婁紶鍑洪敊:', error);
- uni.showToast({ title: '涓婁紶鍑洪敊', icon: 'none' });
+ console.error("涓婁紶鍑洪敊:", error);
+ uni.showToast({ title: "涓婁紶鍑洪敊", icon: "none" });
} finally {
uni.hideLoading();
}
};
-const getFilesByType = (type) => type === 'grade' ? gradeFiles.value : baseFiles.value;
+const getFilesByType = (type) =>
+ type === "grade" ? gradeFiles.value : baseFiles.value;
const getAllFiles = () => [...baseFiles.value, ...gradeFiles.value];
onBeforeUnmount(() => {
- blobUrls.value.forEach(url => URL.revokeObjectURL(url));
+ blobUrls.value.forEach((url) => URL.revokeObjectURL(url));
blobUrls.value = [];
});
@@ -426,9 +638,9 @@
font-size: 28rpx;
color: #666;
&.active {
- color: #67AFAB;
+ color: #67afab;
font-weight: bold;
- border-bottom: 4rpx solid #67AFAB;
+ border-bottom: 4rpx solid #67afab;
}
.required-mark {
color: red;
@@ -447,13 +659,16 @@
display: flex;
align-items: center;
justify-content: center;
- box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.15);
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
z-index: 999;
color: #fff;
font-size: 28rpx;
font-weight: bold;
transition: all 0.3s;
- &:active { opacity: 0.8; transform: scale(0.95); }
+ &:active {
+ opacity: 0.8;
+ transform: scale(0.95);
+ }
.badge {
position: absolute;
top: -10rpx;
@@ -481,8 +696,17 @@
margin-bottom: 30rpx;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #f5f5f5;
- .title { font-size: 32rpx; font-weight: bold; color: #333; }
- .uni-icons { padding: 10rpx; &:active { opacity: 0.7; } }
+ .title {
+ font-size: 32rpx;
+ font-weight: bold;
+ color: #333;
+ }
+ .uni-icons {
+ padding: 10rpx;
+ &:active {
+ opacity: 0.7;
+ }
+ }
}
.file-list {
max-height: 50vh;
@@ -492,16 +716,44 @@
align-items: center;
padding: 20rpx 0;
border-bottom: 1rpx solid #f5f5f5;
- &:active { background-color: #f9f9f9; }
- .file-icon { margin-right: 20rpx; }
+ &:active {
+ background-color: #f9f9f9;
+ }
+ .file-icon {
+ margin-right: 20rpx;
+ }
.file-info {
flex: 1;
overflow: hidden;
- .file-name { font-size: 28rpx; color: #333; display: block; margin-bottom: 8rpx; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
- .file-size { font-size: 24rpx; color: #999; display: block; }
- .file-status { font-size: 24rpx; color: #666; display: block; &.error { color: #ff4d4f; } }
+ .file-name {
+ font-size: 28rpx;
+ color: #333;
+ display: block;
+ margin-bottom: 8rpx;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+ .file-size {
+ font-size: 24rpx;
+ color: #999;
+ display: block;
+ }
+ .file-status {
+ font-size: 24rpx;
+ color: #666;
+ display: block;
+ &.error {
+ color: #ff4d4f;
+ }
+ }
}
- .uni-icons { padding: 10rpx; &:active { opacity: 0.7; } }
+ .uni-icons {
+ padding: 10rpx;
+ &:active {
+ opacity: 0.7;
+ }
+ }
}
.empty {
display: flex;
@@ -511,7 +763,9 @@
padding: 60rpx 0;
color: #999;
font-size: 28rpx;
- .uni-icons { margin-bottom: 20rpx; }
+ .uni-icons {
+ margin-bottom: 20rpx;
+ }
}
}
.popup-footer {
@@ -527,10 +781,15 @@
background-color: #f5f5f5;
color: #666;
border: none;
- &:active { opacity: 0.8; }
- &.primary { background-color: #67afab; color: #fff; }
+ &:active {
+ opacity: 0.8;
+ }
+ &.primary {
+ background-color: #67afab;
+ color: #fff;
+ }
}
}
}
}
-</style>
\ No newline at end of file
+</style>
--
Gitblit v1.9.3