364 lines
10 KiB
Vue
364 lines
10 KiB
Vue
<template>
|
||
<el-dialog
|
||
title="编辑商品图片"
|
||
:visible.sync="visible"
|
||
width="800px"
|
||
:close-on-click-modal="false"
|
||
@close="handleClose"
|
||
>
|
||
<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="商品主图"
|
||
prop="newThumb"
|
||
:rules="[
|
||
{ required: true, message: '请上传商品主图', trigger: 'change' }
|
||
]"
|
||
>
|
||
<upload
|
||
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="商品副图">
|
||
<div class="sub-images-container">
|
||
<!-- 副图列表 -->
|
||
<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="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>
|
||
|
||
<template #footer>
|
||
<el-button @click="handleClose">{{ __('取消') }}</el-button>
|
||
<el-button type="primary" @click="handleSubmit">{{ __('提交修改') }}</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
</template>
|
||
|
||
<script>
|
||
import upload from '@/components/upload'
|
||
import { URL } from '@/config'
|
||
import { saveBatchBarcode } from '@/api/goodsTool';
|
||
|
||
export default {
|
||
name: 'ImgEdit',
|
||
components: {
|
||
upload
|
||
},
|
||
data() {
|
||
return {
|
||
visible: false,
|
||
formData: {
|
||
id: '',
|
||
name: '',
|
||
barcode: '',
|
||
thumb: '',
|
||
newThumb: '',
|
||
product_image_list: [],
|
||
original_product_image_list: [],
|
||
original_thumb: ''
|
||
},
|
||
currentEditingSubImageIndex: -1 // 记录当前编辑的现有副图索引
|
||
}
|
||
},
|
||
methods: {
|
||
// 获取副图URL列表用于预览
|
||
getSubImages(imageList) {
|
||
return (imageList || []).map(item => item.imageUrl).filter(url => url);
|
||
},
|
||
|
||
// 打开编辑弹窗
|
||
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: '',
|
||
thumb: '',
|
||
newThumb: '',
|
||
product_image_list: [],
|
||
original_product_image_list: [],
|
||
original_thumb: ''
|
||
};
|
||
this.$refs.editForm?.clearValidate();
|
||
},
|
||
|
||
// 主图上传
|
||
handleMainImageUpload(imageUrl) {
|
||
this.formData.newThumb = imageUrl;
|
||
},
|
||
|
||
// 编辑现有副图 - 触发对应上传组件
|
||
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('上传组件初始化中,请稍候');
|
||
}
|
||
}
|
||
},
|
||
|
||
// 现有副图上传完成 - 只替换URL,保留ID等信息
|
||
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);
|
||
|
||
// 创建新的副图条目(ID为null,由后端生成)
|
||
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.formData.product_image_list
|
||
.filter(item => item.imageUrl)
|
||
.map((item, index) => ({
|
||
...item,
|
||
seq: index + 1 // 重新排序
|
||
}))
|
||
}
|
||
];
|
||
|
||
console.log('提交数据:', submitData);
|
||
const response = await saveBatchBarcode(submitData);
|
||
|
||
if (response.status === 200) {
|
||
this.$message.success('商品图片修改成功!');
|
||
this.handleClose();
|
||
this.$emit('success');
|
||
} else {
|
||
this.$message.error('修改失败: ' + (response.msg || '未知错误'));
|
||
}
|
||
} catch (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;
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.edit-tip {
|
||
color: #666;
|
||
padding: 8px 12px;
|
||
background-color: #f5f7fa;
|
||
border-radius: 4px;
|
||
margin-bottom: 16px;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.sub-images-container {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 15px;
|
||
padding: 10px 0;
|
||
|
||
.sub-image-item {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 5px;
|
||
|
||
.sub-img-actions {
|
||
display: flex;
|
||
gap: 5px;
|
||
.el-button {
|
||
color: #666;
|
||
padding: 0;
|
||
&:hover { color: #409eff; }
|
||
}
|
||
}
|
||
|
||
// 隐藏所有上传组件,只通过按钮触发
|
||
.sub-image-uploader {
|
||
display: none !important;
|
||
}
|
||
}
|
||
|
||
.add-sub-image {
|
||
width: 80px;
|
||
height: 80px;
|
||
border: 1px dashed #ccc;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
cursor: pointer;
|
||
color: #999;
|
||
|
||
.el-icon-plus {
|
||
font-size: 20px;
|
||
margin-bottom: 5px;
|
||
}
|
||
|
||
&:hover {
|
||
border-color: #409eff;
|
||
color: #409eff;
|
||
}
|
||
}
|
||
}
|
||
|
||
::v-deep .el-form-item {
|
||
margin-bottom: 20px;
|
||
}
|
||
</style> |