diff --git a/src/api/assets/asset/index.ts b/src/api/assets/asset/index.ts index cc9165f..f0ef671 100644 --- a/src/api/assets/asset/index.ts +++ b/src/api/assets/asset/index.ts @@ -76,7 +76,7 @@ export function uploadAssetImage(file: File) { const formData = new FormData(); formData.append('file', file); return newService({ - url: '/assets/asset/Uploadimage', + url: '/oss/file/uploadFile', method: 'post', data: formData, headers: { diff --git a/src/views/assets/asset/component/editAsset.vue b/src/views/assets/asset/component/editAsset.vue index d6e1ce9..edf7cc4 100644 --- a/src/views/assets/asset/component/editAsset.vue +++ b/src/views/assets/asset/component/editAsset.vue @@ -135,9 +135,9 @@ @@ -191,7 +191,8 @@ { }; // 图片相关 -const mainImageFile = ref(null); const mainImagePreview = ref(''); const imageFileList = ref([]); -const attrImageFiles = ref>({}); // 暂存属性图片文件 const dialogVisible = ref(false); const dialogImageUrl = ref(''); // 图片拼接 -const imgAddressPrefix = ref(''); +const fileAddressPrefix = ref(''); const formatImageUrl = (url?: string) => { if (!url) return ''; if (/^https?:\/\//i.test(url)) return url; if (/^blob:/i.test(url)) return url; // 支持本地预览地址 - return `${imgAddressPrefix.value || ''}${url}`; + return `${fileAddressPrefix.value || ''}${url}`; }; const createDefaultTimeSlots = (): TimeSlot[] => { @@ -674,15 +673,56 @@ const rules: FormRules = { }; // 主图上传处理 -const handleMainImageChange = (file: UploadFile) => { - if (file.raw) { - mainImageFile.value = file.raw; - mainImagePreview.value = URL.createObjectURL(file.raw); - ruleForm.mainImage = 'set'; // 标记已上传 - formRef.value?.validateField('mainImage'); +const handleMainImageUpload = async (options: UploadRequestOptions) => { + try { + const url = await uploadImage(options.file); + if (url) { + ruleForm.mainImage = url; + mainImagePreview.value = formatImageUrl(url); + formRef.value?.validateField('mainImage'); + } + } catch (error) { + ElMessage.error('主图上传失败'); } }; +// 图片列表上传处理 +const handleImageListUpload = async (options: UploadRequestOptions) => { + try { + const url = await uploadImage(options.file); + if (url) { + const fileItem = imageFileList.value.find((f) => f.uid === options.file.uid); + if (fileItem) { + fileItem.url = formatImageUrl(url); + fileItem.status = 'success'; + fileItem.response = url; // 存储原始 URL + } + } + } catch (error) { + ElMessage.error('上传失败'); + const index = imageFileList.value.findIndex((f) => f.uid === options.file.uid); + if (index !== -1) { + imageFileList.value.splice(index, 1); + } + } +}; + +// 属性图片上传处理 +const onAttrImageUpload = (attr: CategoryAttr) => { + return async (options: UploadRequestOptions) => { + try { + const url = await uploadImage(options.file); + if (url) { + const key = getAttrKey(attr); + ruleForm.metadata[key] = url; + formRef.value?.validateField(`metadata.${key}`); + } + } catch (error) { + ElMessage.error('图片上传失败'); + } + }; +}; + // 主图预览 const previewMainImage = () => { if (mainImagePreview.value) { @@ -693,7 +733,6 @@ const previewMainImage = () => { // 主图删除 const removeMainImage = () => { - mainImageFile.value = null; mainImagePreview.value = ''; ruleForm.mainImage = ''; formRef.value?.validateField('mainImage'); @@ -701,8 +740,6 @@ const removeMainImage = () => { // 图片列表预览 const handlePictureCardPreview = (file: UploadFile) => { - console.log(file,'111'); - dialogImageUrl.value = file.url || ''; dialogVisible.value = true; }; @@ -715,29 +752,10 @@ const handleRemove = (file: UploadFile) => { } }; -// 属性图片上传处理 -const handleAttrImageChange = (file: UploadFile, attr: CategoryAttr) => { - if (file.raw) { - const key = getAttrKey(attr); - const url = URL.createObjectURL(file.raw); - ruleForm.metadata[key] = url; - attrImageFiles.value[key] = file.raw; - formRef.value?.validateField(`metadata.${key}`); - } -}; - -// 生成属性图片上传回调 -const onAttrImageChange = (attr: CategoryAttr) => { - return (file: UploadFile) => handleAttrImageChange(file, attr); -}; - // 移除属性图片 const removeAttrImage = (attr: CategoryAttr) => { const key = getAttrKey(attr); ruleForm.metadata[key] = ''; - if (attrImageFiles.value[key]) { - delete attrImageFiles.value[key]; - } formRef.value?.validateField(`metadata.${key}`); }; @@ -806,12 +824,10 @@ const removeKeyValuePair = (list: KeyValuePair[], index: number) => { const resetForm = () => { const initial = getInitialForm(); Object.assign(ruleForm, initial); - mainImageFile.value = null; mainImagePreview.value = ''; imageFileList.value = []; - attrImageFiles.value = {}; categoryAttrs.value = []; - imgAddressPrefix.value = ''; + fileAddressPrefix.value = ''; }; // 获取分类数据 @@ -863,7 +879,8 @@ const openDialog = (row?: any, edit?: boolean) => { getAsset(row.id) .then((res: any) => { const data = res.data; - imgAddressPrefix.value = data.imgAddressPrefix || ''; + // 支持 fileAddressPrefix 和 imgAddressPrefix + fileAddressPrefix.value = data.fileAddressPrefix || data.imgAddressPrefix || ''; ruleForm.id = data.id || ''; ruleForm.name = data.name || ''; ruleForm.type = data.type || 'physical'; @@ -872,10 +889,11 @@ const openDialog = (row?: any, edit?: boolean) => { ruleForm.onlineTime = data.onlineTime || ''; ruleForm.offlineTime = data.offlineTime || ''; - // 主图预览 - if (data.imageUrl) { - mainImagePreview.value = formatImageUrl(data.imageUrl); - ruleForm.mainImage = data.imageUrl; + // 主图预览 (支持 imageUrl 和 fileURL) + const mainImg = data.imageUrl || data.fileURL; + if (mainImg) { + mainImagePreview.value = formatImageUrl(mainImg); + ruleForm.mainImage = mainImg; } // 图片列表 @@ -883,6 +901,7 @@ const openDialog = (row?: any, edit?: boolean) => { imageFileList.value = data.images.map((url: string, index: number) => ({ name: `image-${index}`, url: formatImageUrl(url), + response: url, // 存储原始相对路径,供提交时使用 })); } @@ -1023,7 +1042,29 @@ const onCancel = () => { // 上传图片并返回URL const uploadImage = async (file: File): Promise => { const res: any = await uploadAssetImage(file); - return res.data?.url || res.data || ''; + + // 1. 尝试获取并设置 fileAddressPrefix + // 优先检查顶层,再检查 data 内部 + if (res.fileAddressPrefix) { + fileAddressPrefix.value = res.fileAddressPrefix; + } else if (res.data && typeof res.data === 'object' && res.data.fileAddressPrefix) { + fileAddressPrefix.value = res.data.fileAddressPrefix; + } + + // 2. 尝试获取 fileURL / url + // 优先检查顶层 fileURL + if (res.fileURL) return res.fileURL; + + // 检查 data 对象中的 fileURL 或 url + if (res.data && typeof res.data === 'object') { + if (res.data.fileURL) return res.data.fileURL; + if (res.data.url) return res.data.url; + } + + // 3. 兼容旧逻辑 (data 直接是 url 字符串) + if (typeof res.data === 'string') return res.data; + + return ''; }; // 构建请求体 @@ -1048,21 +1089,19 @@ const buildRequestBody = async (): Promise => { body.offlineTime = ruleForm.offlineTime; } - // 主图上传 - if (mainImageFile.value) { - body.imageUrl = await uploadImage(mainImageFile.value); - } else if (ruleForm.mainImage && !ruleForm.mainImage.startsWith('blob:')) { - body.imageUrl = ruleForm.mainImage; + // 主图 (已在上传时直接赋值给 ruleForm.mainImage) + if (ruleForm.mainImage) { + body.fileURL = ruleForm.mainImage; } - // 图片列表上传 + // 图片列表 const imageUrls: string[] = []; for (const file of imageFileList.value) { - if (file.raw) { - const url = await uploadImage(file.raw); - if (url) imageUrls.push(url); + if (file.response) { + // 新上传的图片使用原始 URL + imageUrls.push(file.response as string); } else if (file.url && !file.url.startsWith('blob:')) { - // 已有图片保留原URL + // 已有图片保留原 URL imageUrls.push(file.url); } } @@ -1108,10 +1147,8 @@ const buildRequestBody = async (): Promise => { const key = getAttrKey(attr); let value = ruleForm.metadata[key]; - // 如果是图片类型且有文件需要上传 - if (attr.type === 'image' && attrImageFiles.value[key]) { - value = await uploadImage(attrImageFiles.value[key]); - } else if (typeof value === 'string' && value.startsWith('blob:')) { + // 如果是图片类型,且值是 blob 开头(未上传成功的情况),置为空 + if (attr.type === 'image' && typeof value === 'string' && value.startsWith('blob:')) { value = ''; }