diff --git a/src/views/assets/asset/component/editAsset.vue b/src/views/assets/asset/component/editAsset.vue index 2497ebf..6aafb49 100644 --- a/src/views/assets/asset/component/editAsset.vue +++ b/src/views/assets/asset/component/editAsset.vue @@ -69,7 +69,11 @@ 分类属性 - + - - 上传图片 - +
+ + + + + + 删除图片 + +
@@ -146,16 +168,22 @@ - - - - +
+ + + + +
+ 预览 + 删除 +
+
@@ -395,6 +423,7 @@ const getAttrLabel = (attr: CategoryAttr): string => { const mainImageFile = ref(null); const mainImagePreview = ref(''); const imageFileList = ref([]); +const attrImageFiles = ref>({}); // 暂存属性图片文件 const dialogVisible = ref(false); const dialogImageUrl = ref(''); // 图片拼接 @@ -403,6 +432,7 @@ const imgAddressPrefix = 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}`; }; @@ -516,6 +546,22 @@ const handleMainImageChange = (file: UploadFile) => { } }; +// 主图预览 +const previewMainImage = () => { + if (mainImagePreview.value) { + dialogImageUrl.value = mainImagePreview.value; + dialogVisible.value = true; + } +}; + +// 主图删除 +const removeMainImage = () => { + mainImageFile.value = null; + mainImagePreview.value = ''; + ruleForm.mainImage = ''; + formRef.value?.validateField('mainImage'); +}; + // 图片列表预览 const handlePictureCardPreview = (file: UploadFile) => { console.log(file,'111'); @@ -532,6 +578,32 @@ 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}`); +}; + // 时间段操作 const addTimeSlot = () => { if (!ruleForm.serviceAssetConfig.schedule) { @@ -591,6 +663,7 @@ const resetForm = () => { mainImageFile.value = null; mainImagePreview.value = ''; imageFileList.value = []; + attrImageFiles.value = {}; categoryAttrs.value = []; imgAddressPrefix.value = ''; }; @@ -618,6 +691,13 @@ const onCategoryChange = (categoryId: string) => { const data = res.data; if (data?.attrs && Array.isArray(data.attrs)) { categoryAttrs.value = data.attrs; + // 初始化属性值,确保 boolean 类型默认为 false + data.attrs.forEach((attr: CategoryAttr) => { + const key = getAttrKey(attr); + if (attr.type === 'boolean') { + ruleForm.metadata[key] = false; + } + }); } }) .catch(() => { @@ -708,6 +788,13 @@ const openDialog = (row?: any, edit?: boolean) => { const catData = catRes.data; if (catData?.attrs && Array.isArray(catData.attrs)) { categoryAttrs.value = catData.attrs; + // 初始化属性值,确保 boolean 类型默认为 false + catData.attrs.forEach((attr: CategoryAttr) => { + const key = getAttrKey(attr); + if (attr.type === 'boolean' && ruleForm.metadata[key] === undefined) { + ruleForm.metadata[key] = false; + } + }); } }) .catch(() => { @@ -773,9 +860,22 @@ const buildFormData = (): FormData => { formData.append('serviceAssetConfig', JSON.stringify(ruleForm.serviceAssetConfig)); } + // 属性图片 + Object.keys(attrImageFiles.value).forEach((key) => { + formData.append(key, attrImageFiles.value[key]); + }); + // 元数据(分类属性值) if (Object.keys(ruleForm.metadata).length > 0) { - formData.append('metadata', JSON.stringify(ruleForm.metadata)); + // 过滤掉 blob url,避免传给后端 + const metadataToSend = { ...ruleForm.metadata }; + Object.keys(metadataToSend).forEach((key) => { + if (typeof metadataToSend[key] === 'string' && metadataToSend[key].startsWith('blob:')) { + // 如果有对应的文件在 attrImageFiles 中,则置空或不传,这里选择置空 + metadataToSend[key] = ''; + } + }); + formData.append('metadata', JSON.stringify(metadataToSend)); } return formData;