update:修改副图新增和副图修改逻辑

This commit is contained in:
lihaoyuan 2025-12-23 09:08:11 +08:00
parent 2acb439c9d
commit 294aa013e4

View File

@ -6,81 +6,79 @@
:close-on-click-modal="false"
@close="handleClose"
>
<div class="edit-tip">
正在编辑商品: <strong>{{ formData.name }}</strong>
(条码: {{ formData.barcode || '无条码' }})
</div>
<div class="edit-tip">
正在编辑商品: <strong>{{ formData.name }}</strong>
(条码: {{ formData.barcode || '无条码' }})
</div>
<el-form ref="editForm" :model="formData" label-width="100px" label-position="right">
<!-- 主图编辑 -->
<!-- <el-form-item label="当前主图">
<el-image
v-if="formData.thumb"
:src="formData.thumb"
style="width: 100px; height: 100px; object-fit: cover; border: 1px solid #eee;"
:preview-src-list="[formData.thumb, ...getSubImages(formData.product_image_list)]"
/>
<span v-else class="text-gray-500">暂无主图</span>
</el-form-item> -->
<el-form-item
label="上传新主图"
label="商品主图"
prop="newThumb"
:rules="[
{ required: true, message: '请上传新的商品主图', trigger: 'change' }
{ required: true, message: '请上传商品主图', trigger: 'change' }
]"
>
<upload
height="100px"
:image="formData.newThumb"
width="100px"
@upImage="handleMainImageUpload"
height="100px"
:image="formData.newThumb"
width="100px"
@upImage="handleMainImageUpload"
/>
<div class="el-form-item__error" style="padding-top: 10px;">
<span>支持 JPG, PNG 格式建议尺寸 800x800px</span>
</div>
</el-form-item>
<!-- 副图编辑 -->
<!-- <el-form-item label="商品副图">
<el-form-item label="商品副图">
<div class="sub-images-container">
<div v-for="(item, index) in formData.product_image_list" :key="item.id || index" class="sub-image-item">
<upload
v-if="item.uploadNew"
height="80px"
:image="item.newImageUrl || item.imageUrl"
width="80px"
@upImage="(url) => handleSubImageUpload(url, index)"
/>
<el-image
v-else
:src="item.imageUrl"
style="width: 80px; height: 80px; object-fit: cover; border: 1px solid #eee;"
:preview-src-list="[formData.thumb, ...getSubImages(formData.product_image_list)]"
:preview-index="index + 1"
/>
<div class="sub-img-actions">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="toggleEditSubImage(index)"
/>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="deleteSubImage(index)"
/>
</div>
</div>
<!-- 副图列表 -->
<div v-for="(item, index) in formData.product_image_list" :key="item.id || `sub_${index}`" class="sub-image-item">
<el-image
:src="item.imageUrl"
style="width: 80px; height: 80px; object-fit: cover; border: 1px solid #eee;"
:preview-src-list="[formData.thumb, ...getSubImages(formData.product_image_list)]"
:preview-index="index + 1"
/>
<div class="sub-img-actions">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleEditSubImage(index)"
title="更换图片"
/>
</div>
<!-- 现有副图的隐藏上传组件 -->
<upload
ref="subImageUploadRefs"
class="sub-image-uploader"
height="80px"
width="80px"
:image="item.imageUrl"
@upImage="(url) => handleSubImageUpload(url, index)"
/>
</div>
<div class="add-sub-image" @click="addSubImage">
<!-- 新增副图按钮-->
<div class="add-sub-image" @click="handleAddSubImage">
<i class="el-icon-plus" />
<span>添加副图</span>
</div>
<!-- 新增副图专用的隐藏上传组件 -->
<upload
ref="newSubImageUpload"
class="sub-image-uploader"
height="80px"
width="80px"
:image="''"
@upImage="handleNewSubImageUpload"
v-show="false"
/>
</div>
</el-form-item> -->
</el-form-item>
</el-form>
<template #footer>
@ -106,13 +104,14 @@ export default {
formData: {
id: '',
name: '',
barcode: '', //
barcode: '',
thumb: '',
newThumb: '',
product_image_list: [],
original_product_image_list: [], //
original_thumb: '' //
original_product_image_list: [],
original_thumb: ''
},
currentEditingSubImageIndex: -1 //
}
},
methods: {
@ -120,41 +119,41 @@ export default {
getSubImages(imageList) {
return (imageList || []).map(item => item.imageUrl).filter(url => url);
},
// open
open(row) {
if (!row || !row.id) {
this.$message.error('无效的商品数据');
return;
}
//
const originalProductImages = JSON.parse(JSON.stringify(row.product_image_list || []));
const originalThumb = row.thumb || '';
// barcode
this.formData = {
id: row.id,
name: row.name || '未知名称',
barcode: row.barcode || '', //
thumb: originalThumb,
newThumb: originalThumb,
original_thumb: originalThumb,
product_image_list: originalProductImages.map(item => ({
...item,
uploadNew: false,
newImageUrl: ''
})),
original_product_image_list: originalProductImages
};
this.visible = true;
this.$nextTick(() => {
this.$refs.editForm?.clearValidate();
});
},
//
open(row) {
if (!row || !row.id) {
this.$message.error('无效的商品数据');
return;
}
const originalProductImages = JSON.parse(JSON.stringify(row.product_image_list || []));
const originalThumb = row.thumb || '';
this.formData = {
id: row.id,
name: row.name || '未知名称',
barcode: row.barcode || '',
thumb: originalThumb,
newThumb: originalThumb,
original_thumb: originalThumb,
product_image_list: originalProductImages.map(item => {
const { id, productId, imageUrl, seq, status, createdAt, updatedAt } = item;
return { id, productId, imageUrl, seq, status, createdAt, updatedAt };
}),
original_product_image_list: originalProductImages
};
this.visible = true;
this.$nextTick(() => {
this.$refs.editForm?.clearValidate();
});
},
//
handleClose() {
this.visible = false;
this.currentEditingSubImageIndex = -1;
this.formData = {
id: '',
name: '',
@ -172,80 +171,97 @@ export default {
this.formData.newThumb = imageUrl;
},
//
handleSubImageUpload(imageUrl, index) {
if (this.formData.product_image_list[index]) {
const item = this.formData.product_image_list[index];
item.newImageUrl = imageUrl;
item.imageUrl = imageUrl; // URL
item.uploadNew = false; // 退
item.tmpUrl = ''; // URL
}
},
//
toggleEditSubImage(idx) {
const item = this.formData.product_image_list[idx];
if (item.uploadNew) {
// URL
if (item.tmpUrl) {
item.imageUrl = item.tmpUrl;
item.tmpUrl = ''; // URL
}
item.newImageUrl = '';
} else {
// URL
item.tmpUrl = item.imageUrl;
}
item.uploadNew = !item.uploadNew;
},
//
deleteSubImage(index) {
this.formData.product_image_list.splice(index, 1);
},
addSubImage() {
const max = this.formData.product_image_list.reduce((p, c) => Math.max(p, c.seq || 0), 0);
this.formData.product_image_list.push({
id: null,
productId: this.formData.id,
imageUrl: '',
newImageUrl: '',
uploadNew: true, //
tmpUrl: '', // URL
isMain: false,
seq: max + 1,
status: 1
// -
handleEditSubImage(index) {
this.currentEditingSubImageIndex = index;
this.$nextTick(() => {
const uploadRefs = this.$refs.subImageUploadRefs;
const uploadComp = Array.isArray(uploadRefs) ? uploadRefs[index] : uploadRefs;
this.triggerUploadComp(uploadComp);
});
},
// "" -
handleAddSubImage() {
this.$nextTick(() => {
const uploadComp = this.$refs.newSubImageUpload;
this.triggerUploadComp(uploadComp);
});
},
// upload
triggerUploadComp(uploadComp) {
if (!uploadComp) return;
// open
if (typeof uploadComp.open === 'function') {
uploadComp.open();
}
// input
else if (uploadComp.$el) {
const fileInput = uploadComp.$el.querySelector('input[type="file"]');
if (fileInput) {
fileInput.click();
} else {
this.$message.warning('上传组件初始化中,请稍候');
}
}
},
// - URLID
handleSubImageUpload(imageUrl, index) {
if (this.formData.product_image_list[index]) {
this.formData.product_image_list[index].imageUrl = imageUrl;
this.$message.success('副图更新成功');
this.currentEditingSubImageIndex = -1;
}
},
// -
handleNewSubImageUpload(imageUrl) {
if (!imageUrl) {
this.$message.warning('请选择有效的图片');
return;
}
//
const maxSeq = this.formData.product_image_list.reduce((p, c) => Math.max(p, c.seq || 0), 0);
// IDnull
this.formData.product_image_list.push({
id: null,
productId: this.formData.id,
imageUrl: imageUrl, // URL
seq: maxSeq + 1,
status: 1,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
});
this.$message.success('新增副图成功');
},
//
async handleSubmit() {
try {
await this.$refs.editForm.validate();
// - 使
const submitData = [
{
id: this.formData.id,
name: this.formData.name,
// 使
barcode: this.formData.barcode,
thumb: this.formData.newThumb || this.formData.original_thumb,
// 使使
product_image_list: this.hasSubImagesChanged()
? this.formData.product_image_list.filter(item => item.imageUrl).map((item, index) => ({
id: item.id,
productId: this.formData.id,
imageUrl: item.imageUrl,
isMain: false,
seq: index + 1,
status: 1
}))
: this.formData.original_product_image_list
product_image_list: this.formData.product_image_list
.filter(item => item.imageUrl)
.map((item, index) => ({
...item,
seq: index + 1 //
}))
}
];
console.log('提交更新商品图片请求:', submitData);
console.log('提交数据:', submitData);
const response = await saveBatchBarcode(submitData);
if (response.status === 200) {
@ -256,30 +272,25 @@ export default {
this.$message.error('修改失败: ' + (response.msg || '未知错误'));
}
} catch (error) {
console.error('提交修改失败:', error);
console.error('提交失败:', error);
if (error.name !== 'ValidateError') {
this.$message.error('修改失败,请稍后重试');
}
}
},
//
//
hasSubImagesChanged() {
//
if (this.formData.product_image_list.length !== this.formData.original_product_image_list.length) {
return true;
}
//
for (let i = 0; i < this.formData.product_image_list.length; i++) {
const newItem = this.formData.product_image_list[i];
const originalItem = this.formData.original_product_image_list[i];
if (!originalItem || newItem.imageUrl !== originalItem.imageUrl) {
return true;
}
}
return false;
}
}
@ -311,20 +322,17 @@ export default {
.sub-img-actions {
display: flex;
gap: 5px;
.el-button {
color: #666;
padding: 0;
&:hover {
color: #409eff;
}
}
.el-button:nth-child(2):hover {
color: #f56c6c;
&:hover { color: #409eff; }
}
}
//
.sub-image-uploader {
display: none !important;
}
}
.add-sub-image {