From ee4b6c4de7e07b0bd570d9dc58aecbff2f24851c Mon Sep 17 00:00:00 2001 From: Mrx <18278715334@163.com> Date: Wed, 18 Mar 2026 11:00:35 +0800 Subject: [PATCH] f --- .../components/EnterpriseInfo.vue | 240 +++++------------- 1 file changed, 65 insertions(+), 175 deletions(-) diff --git a/src/pages/certification/components/EnterpriseInfo.vue b/src/pages/certification/components/EnterpriseInfo.vue index c6de9c4..2b235b4 100644 --- a/src/pages/certification/components/EnterpriseInfo.vue +++ b/src/pages/certification/components/EnterpriseInfo.vue @@ -125,33 +125,25 @@
请在非 IE 浏览器下上传大小不超过 1M 的图片,最多 10 张,需体现门楣 LOGO、办公设备与工作人员。
-
- -
- -
上传办公场地环境照片
-
-
-
+
+ +
上传办公场地环境照片
+
+ @@ -319,33 +311,25 @@
请在非 IE 浏览器下上传大小不超过 1M 的图片,最多 10 张后台应用截图。
-
- -
- -
上传业务场景相关截图或证明材料
-
-
-
+
+ +
上传业务场景相关截图或证明材料
+
+ @@ -378,7 +362,7 @@ import { CheckIcon, DocumentIcon } from '@heroicons/vue/24/outline' -import { ElMessage, ElMessageBox, genFileId } from 'element-plus' +import { ElMessage, ElMessageBox } from 'element-plus' import { useAliyunCaptcha } from '@/composables/useAliyunCaptcha' const props = defineProps({ @@ -449,8 +433,6 @@ const ocrResult = ref(false) const uploadRef = ref() const officePlaceUploadRef = ref() const scenarioUploadRef = ref() -const officePlaceDragover = ref(false) -const scenarioDragover = ref(false) // 上传文件列表(前端展示用) const officePlaceFileList = ref([]) @@ -681,9 +663,6 @@ const handleFileChange = async (file) => { } } -// 判断是否为前端 blob 预览地址(需上传到服务器后替换为真实 URL) -const isBlobUrl = (url) => typeof url === 'string' && url.startsWith('blob:') - // 上传单张图片到七牛云,返回可访问 URL const uploadFileToServer = async (file) => { const res = await certificationApi.uploadFile(file) @@ -693,17 +672,17 @@ const uploadFileToServer = async (file) => { return res.data.url } -// 选择后立即上传:对 el-upload 的 file 对象上传并更新 url/status,不更新表单(由调用方更新) +// 选择后立即上传:服务器 URL 存到 response.url,保留 file.url 为 blob 以便预览(避免服务器证书等问题导致预览失败) const uploadFileOnceSelected = async (file) => { if (!file?.raw) return null - if (file.url && !isBlobUrl(file.url)) return file.url // 已是服务器 URL,不重复上传 + if (file.response?.url) return file.response.url // 已上传过,不重复上传 file.status = 'uploading' try { const url = await uploadFileToServer(file.raw) - file.url = url file.status = 'success' if (file.response === undefined) file.response = {} file.response.url = url + // 不覆盖 file.url,保留 blob 预览地址,避免服务器证书无效时预览失败 return url } catch (err) { file.status = 'fail' @@ -712,64 +691,27 @@ const uploadFileOnceSelected = async (file) => { } } -// 提交前将 blob 图片全部上传到七牛云,并更新表单中的 URL -const uploadAllBlobFilesAndFillForm = async () => { - const tasks = [] +// 提交前仅从 fileList 同步 URL 到表单,并检查是否全部已上传(选择即上传,提交时不再批量上传) +const syncFormUrlsAndCheckReady = () => { + form.value.businessLicenseImageURL = extractUrls(businessLicenseFileList.value)[0] || '' + form.value.officePlaceImageURLs = extractUrls(officePlaceFileList.value) + form.value.scenarioAttachmentURLs = extractUrls(scenarioFileList.value) + updateAuthorizedRepIDImageURLs() - // 营业执照:若当前是 blob 则上传 - if (isBlobUrl(form.value.businessLicenseImageURL) && businessLicenseFileList.value.length > 0 && businessLicenseFileList.value[0].raw) { - tasks.push( - uploadFileToServer(businessLicenseFileList.value[0].raw).then((url) => { - form.value.businessLicenseImageURL = url - }) - ) - } - - // 办公场地多图:按顺序上传 - if (officePlaceFileList.value.length > 0) { - const files = officePlaceFileList.value.filter((f) => f.raw).map((f) => f.raw) - if (files.length > 0) { - tasks.push( - Promise.all(files.map((f) => uploadFileToServer(f))).then((urls) => { - form.value.officePlaceImageURLs = urls - }) - ) - } - } - - // 应用场景附件多图:按顺序上传 - if (scenarioFileList.value.length > 0) { - const files = scenarioFileList.value.filter((f) => f.raw).map((f) => f.raw) - if (files.length > 0) { - tasks.push( - Promise.all(files.map((f) => uploadFileToServer(f))).then((urls) => { - form.value.scenarioAttachmentURLs = urls - }) - ) - } - } - - // 授权代表身份证正反面:人像面 + 国徽面 - const frontRaw = authorizedRepIDFrontFileList.value[0]?.raw - const backRaw = authorizedRepIDBackFileList.value[0]?.raw - if (frontRaw || backRaw) { - tasks.push( - (async () => { - const urls = [] - if (frontRaw) urls.push(await uploadFileToServer(frontRaw)) - if (backRaw) urls.push(await uploadFileToServer(backRaw)) - form.value.authorizedRepIDImageURLs = urls - })() - ) - } - - await Promise.all(tasks) + const hasUploading = (list) => list.some((f) => f.status === 'uploading') + const hasUnfinished = (list) => list.some((f) => f.raw && !f.response?.url) + if (hasUploading(businessLicenseFileList.value) || hasUnfinished(businessLicenseFileList.value)) return false + if (hasUploading(officePlaceFileList.value) || hasUnfinished(officePlaceFileList.value)) return false + if (hasUploading(scenarioFileList.value) || hasUnfinished(scenarioFileList.value)) return false + if (hasUploading(authorizedRepIDFrontFileList.value) || hasUnfinished(authorizedRepIDFrontFileList.value)) return false + if (hasUploading(authorizedRepIDBackFileList.value) || hasUnfinished(authorizedRepIDBackFileList.value)) return false + return true } -// 从 el-upload 的 fileList 中提取 URL 数组(后端接好上传接口后可用 response.url) +// 从 el-upload 的 fileList 中提取 URL 数组,优先用服务器 URL(response.url),提交用 const extractUrls = (fileList) => { return fileList - .map(f => f.url || f.response?.url || f.name) + .map(f => f.response?.url || f.url || f.name) .filter(Boolean) } @@ -781,8 +723,8 @@ const handleBusinessLicenseChange = async (file, fileList) => { if (file && file.raw) { await handleFileChange(file) - // OCR 若未返回服务器 URL,则选择后立即上传 - if (isBlobUrl(form.value.businessLicenseImageURL)) { + // OCR 若未返回服务器 URL,则选择后立即上传(未上传过才上传) + if (!file.response?.url) { const url = await uploadFileOnceSelected(file) if (url) form.value.businessLicenseImageURL = url } @@ -804,7 +746,7 @@ const clearBusinessLicense = () => { // 授权代表身份证人像面图片变更:选择即上传 const handleAuthorizedRepIDFrontChange = async (file, fileList) => { authorizedRepIDFrontFileList.value = fileList - if (file?.raw && isBlobUrl(file.url)) { + if (file?.raw && !file.response?.url) { await uploadFileOnceSelected(file) } updateAuthorizedRepIDImageURLs() @@ -818,7 +760,7 @@ const handleAuthorizedRepIDFrontRemove = (file, fileList) => { // 授权代表身份证国徽面图片变更:选择即上传 const handleAuthorizedRepIDBackChange = async (file, fileList) => { authorizedRepIDBackFileList.value = fileList - if (file?.raw && isBlobUrl(file.url)) { + if (file?.raw && !file.response?.url) { await uploadFileOnceSelected(file) } updateAuthorizedRepIDImageURLs() @@ -851,48 +793,10 @@ const updateAuthorizedRepIDImageURLs = () => { form.value.authorizedRepIDImageURLs = urls } -// 办公场地:拖放文件时通过 handleStart 加入列表 -const onOfficePlaceDrop = (e) => { - officePlaceDragover.value = false - const upload = officePlaceUploadRef.value - if (!upload) return - const files = Array.from(e.dataTransfer?.files || []).filter( - (f) => f.type && /^image\/(jpeg|jpg|png|webp)$/i.test(f.type) - ) - const limit = 10 - const remain = Math.max(0, limit - officePlaceFileList.value.length) - const toAdd = files.slice(0, remain) - for (const file of toAdd) { - if (!beforeUpload(file)) continue - if (typeof file.uid === 'undefined') file.uid = genFileId() - upload.handleStart(file) - } - if (files.length > remain && remain > 0) ElMessage.warning(`最多上传 ${limit} 张,已忽略多余文件`) -} - -// 应用场景:拖放文件时通过 handleStart 加入列表 -const onScenarioDrop = (e) => { - scenarioDragover.value = false - const upload = scenarioUploadRef.value - if (!upload) return - const files = Array.from(e.dataTransfer?.files || []).filter( - (f) => f.type && /^image\/(jpeg|jpg|png|webp)$/i.test(f.type) - ) - const limit = 10 - const remain = Math.max(0, limit - scenarioFileList.value.length) - const toAdd = files.slice(0, remain) - for (const file of toAdd) { - if (!beforeUpload(file)) continue - if (typeof file.uid === 'undefined') file.uid = genFileId() - upload.handleStart(file) - } - if (files.length > remain && remain > 0) ElMessage.warning(`最多上传 ${limit} 张,已忽略多余文件`) -} - // 办公场地图片变更:选择即上传 const handleOfficePlaceChange = async (file, fileList) => { officePlaceFileList.value = fileList - if (file?.raw && isBlobUrl(file.url)) { + if (file?.raw && !file.response?.url) { await uploadFileOnceSelected(file) } form.value.officePlaceImageURLs = extractUrls(fileList) @@ -906,7 +810,7 @@ const handleOfficePlaceRemove = (file, fileList) => { // 应用场景附件图片变更:选择即上传 const handleScenarioChange = async (file, fileList) => { scenarioFileList.value = fileList - if (file?.raw && isBlobUrl(file.url)) { + if (file?.raw && !file.response?.url) { await uploadFileOnceSelected(file) } form.value.scenarioAttachmentURLs = extractUrls(fileList) @@ -937,11 +841,9 @@ const submitForm = async () => { } ) - // 先将所有 blob 图片上传到七牛云,再提交企业信息 - try { - await uploadAllBlobFilesAndFillForm() - } catch (err) { - ElMessage.error(err?.message || '图片上传失败,请重试') + // 选择即上传:提交时不再上传,仅同步 URL 并校验是否均已上传完成 + if (!syncFormUrlsAndCheckReady()) { + ElMessage.warning('请等待所有图片上传完成后再提交') submitting.value = false return } @@ -1157,18 +1059,6 @@ onUnmounted(() => { padding: 8px 12px; } -/* 拖放区域:包裹 picture-card 上传,支持拖拽图片到整块区域 */ -.upload-drop-zone { - width: 100%; - border-radius: 8px; - transition: background 0.2s, border-color 0.2s; -} -.upload-drop-zone.is-dragover { - background: var(--el-color-primary-light-9, #ecf5ff); - outline: 2px dashed var(--el-color-primary); - outline-offset: -2px; -} - /* 上传区域基础样式 */ .upload-area { width: 100%;