| | |
| | | <!-- 商品 --> |
| | | <view class="goods-box bottom"> |
| | | <view class="goods-header"> |
| | | <view class="goods-img"> |
| | | <!-- <u-image width="200rpx" border-radius="20" class="uimage" height="200rpx" :src="selectedSpecImg ? selectedSpecImg : goodsDetail.thumbnail"></u-image> --> |
| | | <view class="goods-img" v-if="goodsDetail.specList && goodsDetail.specList.length > 0 && goodsDetail.specList[0].specImage.length > 0" @click="previewImageSpec"> |
| | | <u-image width="200rpx" border-radius="20" class="uimage" height="200rpx" :src="selectedSpecImg ? selectedSpecImg : goodsDetail.thumbnail"></u-image> |
| | | </view> |
| | | <view class="goods-skus"> |
| | | <!-- 有活动商品价格 --> |
| | |
| | | v-for="(img, index) in consumizetemplateInfo.templateImgs" |
| | | :key="img.id" |
| | | class="image-item" |
| | | :class="{ selected: selectedImages.includes(img.imgUrl) }" |
| | | @click="selectImage(img.imgUrl)" |
| | | :class="{ selected: selectedImageObjects.some(selectedImg => selectedImg.id === img.id) }" |
| | | @click="handleImageClick(img, index)" |
| | | > |
| | | <image |
| | | :src="getFilePreviewUrlSync(img.imgUrl)" |
| | | class="image-preview" |
| | | mode="aspectFill" |
| | | /> |
| | | <view v-if="selectedImages.includes(img.imgUrl)" class="selected-overlay"> |
| | | <view v-if="selectedImageObjects.some(selectedImg => selectedImg.id === img.id)" class="selected-overlay"> |
| | | <uni-icons type="checkmarkempty" size="30" color="#fff"></uni-icons> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 查看选中图片按钮 --> |
| | | <view class="view-selected-image" v-if="selectedImageObjects.length > 0" @click="viewSelectedImage"> |
| | | 查看选中模板图片 |
| | | </view> |
| | | </view> |
| | | |
| | |
| | | |
| | | // 表单相关数据 |
| | | selectedImages: [], // 选中的模板图片 |
| | | selectedImageObjects: [], // 选中的模板图片对象(包含ID等完整信息) |
| | | formValues: { |
| | | templateId: "", // 模板ID |
| | | templateName: "", // 模板名称 |
| | | chooseImage: "", // 选中的图片 |
| | | chooseImageId: "", // 选中图片的ID |
| | | templateForm: [] // 表单数组 [{id, templateTitle, value}] |
| | | }, // 表单值 |
| | | imagePreviewUrls: {}, // 图片预览URL |
| | |
| | | cosClient: null, // COS客户端 |
| | | bucket: '', // 存储桶 |
| | | region: '', // 地域 |
| | | endpoint: '', // COS访问endpoint |
| | | previewUrls: {} // 文件预览地址缓存 |
| | | }; |
| | | }, |
| | |
| | | this.preloadTemplateImages(); |
| | | // 初始化模板表单数据 |
| | | this.initTemplateFormData(); |
| | | // 设置默认选中第一张模板图片 |
| | | this.setDefaultSelectedImage(); |
| | | }, 100); |
| | | } |
| | | }, |
| | |
| | | }); |
| | | this.bucket = res.data.data.bucket; |
| | | this.region = res.data.data.region; |
| | | this.endpoint = res.data.data.endpoint; // 获取endpoint |
| | | }).catch(err => { |
| | | console.error('初始化COS失败', err); |
| | | // 使用setTimeout延迟显示提示,避免影响弹窗 |
| | |
| | | } |
| | | }, |
| | | |
| | | // 选择模板图片 |
| | | selectImage(imgUrl) { |
| | | const index = this.selectedImages.indexOf(imgUrl); |
| | | if (index > -1) { |
| | | // 如果已选中,则取消选择 |
| | | this.selectedImages.splice(index, 1); |
| | | // 选择模板图片(单选模式) |
| | | selectImage(imgObject) { |
| | | // 检查当前选中的图片是否就是点击的图片 |
| | | const selectedIndex = this.selectedImageObjects.findIndex(selectedImg => selectedImg.id === imgObject.id); |
| | | |
| | | if (selectedIndex > -1) { |
| | | // 如果点击的是已选中的图片,则取消选择 |
| | | this.selectedImageObjects = []; |
| | | this.selectedImages = []; |
| | | } else { |
| | | // 否则添加到选中列表 |
| | | this.selectedImages.push(imgUrl); |
| | | // 如果点击的是未选中的图片,则选中该图片(清空之前的选择) |
| | | this.selectedImageObjects = [imgObject]; |
| | | this.selectedImages = [imgObject.imgUrl]; |
| | | } |
| | | // 更新formValues中的chooseImage |
| | | |
| | | // 更新formValues中的chooseImage和chooseImageId |
| | | this.formValues.chooseImage = this.selectedImages.join(','); |
| | | // 将选中图片的ID也存储到formValues中 |
| | | this.formValues.chooseImageId = this.selectedImageObjects.map(img => img.id).join(','); |
| | | |
| | | // 强制更新视图以确保UI正确反映数据变化 |
| | | this.$forceUpdate(); |
| | | }, |
| | | |
| | | // 选择图片(参考video.vue的实现) |
| | |
| | | this.formValues.templateId = this.consumizetemplateInfo.id; |
| | | this.formValues.templateName = this.consumizetemplateInfo.name; |
| | | |
| | | // 查找对应的模板字段以获取contentType |
| | | const templateItem = this.consumizetemplateInfo.templateConstomizeTitles.find(item => item.id === fieldId); |
| | | const contentType = templateItem ? templateItem.contentType : ''; |
| | | |
| | | // 查找是否已存在该字段 |
| | | const existingIndex = this.formValues.templateForm.findIndex(item => item.id === fieldId); |
| | | |
| | |
| | | this.$set(this.formValues.templateForm, existingIndex, { |
| | | id: fieldId, |
| | | templateTitle: templateTitle, |
| | | contentType: contentType, // 添加contentType |
| | | value: value |
| | | }); |
| | | } else { |
| | |
| | | this.formValues.templateForm.push({ |
| | | id: fieldId, |
| | | templateTitle: templateTitle, |
| | | contentType: contentType, // 添加contentType |
| | | value: value |
| | | }); |
| | | } |
| | |
| | | |
| | | // 表单提交处理 |
| | | handleFormSubmit() { |
| | | // 使用新的formValues数据结构 |
| | | const formData = this.formValues; |
| | | // 确保选中的图片对象也被包含在提交数据中 |
| | | const formData = { |
| | | ...this.formValues, |
| | | selectedImageObjects: this.selectedImageObjects |
| | | }; |
| | | |
| | | console.log('表单数据:', formData); |
| | | // 这里可以添加实际的表单提交逻辑 |
| | |
| | | * 添加到购物车或购买 |
| | | */ |
| | | addToCartOrBuy(val) { |
| | | // 检查商品是否需要模板并且模板数据是否完整 |
| | | if (this.consumizetemplateInfo && this.consumizetemplateInfo.id) { |
| | | const isValid = this.validateTemplateData(); |
| | | if (!isValid) { |
| | | return; |
| | | } |
| | | } |
| | | |
| | | console.log(JSON.stringify(this.formValues)) |
| | | if (!this.selectSkuList) { |
| | | // 使用setTimeout延迟显示提示,避免影响弹窗 |
| | |
| | | data.cartType = 'BUY_NOW'; |
| | | } |
| | | |
| | | // 创建包含图片ID的完整表单数据 |
| | | const templateData = { |
| | | ...this.formValues, |
| | | selectedImageObjects: this.selectedImageObjects |
| | | }; |
| | | |
| | | API_trade.addToCart(data).then(res => { |
| | | if (res.data.code == 200) { |
| | | // 使用setTimeout延迟跳转,避免影响弹窗 |
| | | setTimeout(() => { |
| | | uni.navigateTo({ |
| | | url: `/pages/order/fillorder?way=${data.cartType}&addr=${this.addr.id || ''}&template=${encodeURIComponent(JSON.stringify(this.formValues))}&parentOrder=${encodeURIComponent(JSON.stringify(this.parentOrder))}` |
| | | url: `/pages/order/fillorder?way=${data.cartType}&addr=${this.addr.id || ''}&template=${encodeURIComponent(JSON.stringify(templateData))}&parentOrder=${encodeURIComponent(JSON.stringify(this.parentOrder))}` |
| | | }); |
| | | }, 100); |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | | |
| | | /** |
| | | * 验证模板数据是否完整 |
| | | */ |
| | | validateTemplateData() { |
| | | // 检查模板图片是否已选择(如果有模板图片) |
| | | if (this.consumizetemplateInfo.templateImgs && |
| | | this.consumizetemplateInfo.templateImgs.length > 0 && |
| | | this.selectedImageObjects.length === 0) { |
| | | setTimeout(() => { |
| | | uni.showToast({ |
| | | title: '请选择模板图片', |
| | | icon: 'none' |
| | | }); |
| | | }, 100); |
| | | return false; |
| | | } |
| | | |
| | | // 检查动态表单项是否已填写 |
| | | if (this.consumizetemplateInfo.templateConstomizeTitles) { |
| | | for (const item of this.consumizetemplateInfo.templateConstomizeTitles) { |
| | | const formItem = this.formValues.templateForm.find(formItem => formItem.id === item.id); |
| | | |
| | | // 如果表单项不存在或者值为空 |
| | | if (!formItem || !formItem.value || formItem.value.trim() === '') { |
| | | setTimeout(() => { |
| | | uni.showToast({ |
| | | title: `请填写${item.templateTitle}`, |
| | | icon: 'none' |
| | | }); |
| | | }, 100); |
| | | return false; |
| | | } |
| | | |
| | | // 特别检查图片类型的表单项是否有上传 |
| | | if (item.contentType === 'IMAGE' && |
| | | (!this.imagePreviewUrls[item.id] || this.imagePreviewUrls[item.id].trim() === '')) { |
| | | setTimeout(() => { |
| | | uni.showToast({ |
| | | title: `请上传${item.templateTitle}`, |
| | | icon: 'none' |
| | | }); |
| | | }, 100); |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | }, |
| | | formatSku(list) { |
| | | // 格式化数据 |
| | |
| | | if (this.previewUrls && this.previewUrls[fileKey]) { |
| | | return this.previewUrls[fileKey]; |
| | | } |
| | | // 如果没有http前缀,需要拼接endpoint进行显示 |
| | | if (fileKey && !fileKey.startsWith('http://') && !fileKey.startsWith('https://')) { |
| | | // 使用endpoint拼接完整的URL |
| | | if (this.endpoint) { |
| | | return this.endpoint + '/' + fileKey; |
| | | } |
| | | } |
| | | // 否则返回原始值 |
| | | return fileKey; |
| | | }, |
| | |
| | | this.formValues.templateId = this.consumizetemplateInfo.id; |
| | | this.formValues.templateName = this.consumizetemplateInfo.name; |
| | | this.formValues.chooseImage = ""; |
| | | this.formValues.chooseImageId = ""; |
| | | this.formValues.templateForm = []; |
| | | |
| | | // 初始化选中的图片对象数组和图片URL数组 |
| | | this.selectedImageObjects = []; |
| | | this.selectedImages = []; |
| | | } |
| | | }, |
| | | // 预览模板图片 |
| | | previewImageSpec() { |
| | | // 只预览当前选中的图片 |
| | | const url = this.selectedSpecImg ? this.selectedSpecImg : this.goodsDetail.thumbnail |
| | | const urls = [url]; |
| | | |
| | | // 调用uniapp原生API预览图片 |
| | | uni.previewImage({ |
| | | current: 0, // 当前显示图片的索引(只有一张图片,所以是0) |
| | | urls: urls, // 需要预览的图片链接列表 |
| | | indicator: 'default', // 显示索引指示器 |
| | | loop: false // 只有一张图片,不需要循环预览 |
| | | }); |
| | | }, |
| | | // 预览模板图片 |
| | | previewImage(imgObject, index) { |
| | | // 只预览当前选中的图片 |
| | | const urls = [this.getFilePreviewUrlSync(imgObject.imgUrl)]; |
| | | |
| | | // 调用uniapp原生API预览图片 |
| | | uni.previewImage({ |
| | | current: 0, // 当前显示图片的索引(只有一张图片,所以是0) |
| | | urls: urls, // 需要预览的图片链接列表 |
| | | indicator: 'default', // 显示索引指示器 |
| | | loop: false // 只有一张图片,不需要循环预览 |
| | | }); |
| | | }, |
| | | |
| | | // 处理模板图片点击事件(既可以预览又可以选中) |
| | | handleImageClick(imgObject, index) { |
| | | // 检查当前图片是否已选中 |
| | | const isSelected = this.selectedImageObjects.some(selectedImg => selectedImg.id === imgObject.id); |
| | | |
| | | if (isSelected) { |
| | | // 如果已选中,则预览图片 |
| | | this.previewImage(imgObject, index); |
| | | } else { |
| | | // 如果未选中,则选中图片 |
| | | this.selectImage(imgObject); |
| | | } |
| | | }, |
| | | |
| | | // 查看选中的图片 |
| | | viewSelectedImage() { |
| | | // 检查是否有选中的图片 |
| | | if (this.selectedImageObjects.length > 0) { |
| | | // 获取第一个选中的图片(因为是单选模式) |
| | | const selectedImage = this.selectedImageObjects[0]; |
| | | // 预览选中的图片 |
| | | this.previewImage(selectedImage, 0); |
| | | } |
| | | }, |
| | | |
| | | // 设置默认选中第一张模板图片 |
| | | setDefaultSelectedImage() { |
| | | // 检查是否有模板图片且当前没有选中任何图片 |
| | | if (this.consumizetemplateInfo && |
| | | this.consumizetemplateInfo.templateImgs && |
| | | this.consumizetemplateInfo.templateImgs.length > 0 && |
| | | this.selectedImageObjects.length === 0) { |
| | | // 选中第一张图片 |
| | | const firstImage = this.consumizetemplateInfo.templateImgs[0]; |
| | | this.selectImage(firstImage); |
| | | } |
| | | } |
| | | }, |
| | |
| | | |
| | | // 初始化模板表单数据 |
| | | this.initTemplateFormData(); |
| | | |
| | | // 默认选中第一张模板图片 |
| | | this.setDefaultSelectedImage(); |
| | | |
| | | console.log("goodsDetail",this.goodsDetail) |
| | | }, 100); |
| | |
| | | .title-text { |
| | | font-size: 36rpx; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | // 查看选中图片按钮样式 |
| | | .view-selected-image { |
| | | margin-top: 20rpx; |
| | | padding: 30rpx; |
| | | text-align: center; |
| | | background-color: #f0f0f0; |
| | | border-radius: 10rpx; |
| | | color: #333; |
| | | font-size: 28rpx; |
| | | } |
| | | |
| | | // 图片选择区域 |