From d68fb476c248c6c3ab974ea6b18d6bba638f12d8 Mon Sep 17 00:00:00 2001
From: peng <peng.com>
Date: 星期四, 06 十一月 2025 12:35:37 +0800
Subject: [PATCH] 页面优化

---
 pages/product/m-buy/goods.vue |  863 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 825 insertions(+), 38 deletions(-)

diff --git a/pages/product/m-buy/goods.vue b/pages/product/m-buy/goods.vue
index 22c3418..fdf0f55 100644
--- a/pages/product/m-buy/goods.vue
+++ b/pages/product/m-buy/goods.vue
@@ -1,11 +1,11 @@
 <template>
 	<div class="wrapper">
-		<u-popup class="popup" v-model="buyMask" :height="setup.height" closeable :mode="setup.mode" :border-radius="setup.radius" @close="closeMask()">
+		<u-popup class="popup" :value="buyMask" :height="setup.height" closeable :mode="setup.mode" :border-radius="setup.radius" @input="handlePopupInput" @close="closeMask()">
 			<!-- 鍟嗗搧 -->
 			<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">
 						<!-- 鏈夋椿鍔ㄥ晢鍝佷环鏍� -->
@@ -102,7 +102,98 @@
 						<uni-number-box class="uNumber" :min="1" :max="999" :disabled="goodsDetail.quantity === 0"  v-model="num"></uni-number-box>
 					</view>
 					<view class="template">
-						{{JSON.stringify(consumizetemplateInfo)}}
+						<view class="template-title" v-if="consumizetemplateInfo && consumizetemplateInfo.name">
+							<text class="title-text">{{ consumizetemplateInfo.name }}</text>
+						</view>
+						
+						<!-- 鍥剧墖閫夋嫨鍖哄煙 -->
+						<view class="template-images" v-if="consumizetemplateInfo && consumizetemplateInfo.templateImgs && consumizetemplateInfo.templateImgs.length > 0">
+							<view class="images-grid">
+								<view 
+									v-for="(img, index) in consumizetemplateInfo.templateImgs" 
+									:key="img.id"
+									class="image-item"
+									: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="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>
+						
+						<!-- 鍔ㄦ�佽〃鍗曢」 -->
+						<view class="template-form" v-if="consumizetemplateInfo && consumizetemplateInfo.templateConstomizeTitles">
+							<view 
+								v-for="(item, index) in consumizetemplateInfo.templateConstomizeTitles" 
+								:key="item.id"
+								class="form-item"
+							>
+								<text class="form-label">{{ item.templateTitle }}</text>
+								
+								<!-- 鏂囨湰杈撳叆妗� -->
+								<input 
+									v-if="item.contentType === 'TEXT'"
+									class="form-input"
+									:value="getFormValue(item.id)"
+									@input="updateFormValue(item.id, item.templateTitle, $event.target.value)"
+									:placeholder="'璇疯緭鍏�' + item.templateTitle"
+								/>
+								
+								<!-- 鍥剧墖涓婁紶锛堜笉浣跨敤u-upload缁勪欢锛� -->
+								<view v-if="item.contentType === 'IMAGE'" class="form-upload">
+									<!-- 涓婁紶鎸夐挳 -->
+									<view class="upload-btn" @click="chooseImage(item.id)">
+										<uni-icons type="plusempty" size="40" color="#999"></uni-icons>
+										<text class="upload-text">鐐瑰嚮涓婁紶</text>
+									</view>
+									
+									<!-- 鍥剧墖棰勮鍖哄煙 -->
+									<view v-if="imagePreviewUrls[item.id]" class="image-preview-container">
+										<image 
+											:src="imagePreviewUrls[item.id]" 
+											class="uploaded-image" 
+											mode="aspectFill"
+										/>
+										<uni-icons 
+											type="closeempty" 
+											class="delete-icon" 
+											@click="deleteImage(item.id)"
+											size="20"
+											color="#fff"
+										></uni-icons>
+									</view>
+									
+									<!-- 涓婁紶杩涘害鏉� -->
+									<progress 
+										v-if="uploadProgress[item.id] && uploadProgress[item.id] > 0 && uploadProgress[item.id] < 100"
+										:percent="uploadProgress[item.id]" 
+										active-mode="forwards" 
+										show-info 
+										stroke-width="6" 
+										:active="true" 
+										active-color="#ff573e" 
+										style="margin-top: 10rpx;"
+									/>
+									
+									<!-- 涓婁紶鐘舵�佷俊鎭� -->
+									<text v-if="uploadStatus[item.id]" class="upload-status">
+										{{ uploadStatus[item.id] }}
+									</text>
+								</view>
+							</view>
+						</view>
 					</view>
 				</scroll-view>
 				<!-- 鎸夐挳 -->
@@ -120,6 +211,10 @@
 import * as API_trade from '@/api/trade.js';
 import setup from './popup';
 // import uniNumberBox from '@/components/uni-number-box'
+import { getFilePreviewUrl } from "@/api/common.js";
+import { getSTSToken } from "@/api/common.js";
+import { getFileKey } from "@/utils/file.js";
+
 export default {
 	components: {
 		// uniNumberBox
@@ -137,7 +232,26 @@
 			formatList: [],
 			currentSelected: [],
 			skuList: '',
-			isClose: false //鏄惁鍙互鐐瑰嚮閬僵鍏抽棴
+			isClose: false, //鏄惁鍙互鐐瑰嚮閬僵鍏抽棴
+			
+			// 琛ㄥ崟鐩稿叧鏁版嵁
+			selectedImages: [], // 閫変腑鐨勬ā鏉垮浘鐗�
+			selectedImageObjects: [], // 閫変腑鐨勬ā鏉垮浘鐗囧璞★紙鍖呭惈ID绛夊畬鏁翠俊鎭級
+			formValues: {
+				templateId: "", // 妯℃澘ID
+				templateName: "", // 妯℃澘鍚嶇О
+				chooseImage: "", // 閫変腑鐨勫浘鐗�
+				chooseImageId: "", // 閫変腑鍥剧墖鐨処D
+				templateForm: [] // 琛ㄥ崟鏁扮粍 [{id, templateTitle, value}]
+			}, // 琛ㄥ崟鍊�
+			imagePreviewUrls: {}, // 鍥剧墖棰勮URL
+			uploadProgress: {}, // 涓婁紶杩涘害
+			uploadStatus: {}, // 涓婁紶鐘舵�佷俊鎭�
+			cosClient: null, // COS瀹㈡埛绔�
+			bucket: '', // 瀛樺偍妗�
+			region: '', // 鍦板煙
+			endpoint: '', // COS璁块棶endpoint
+			previewUrls: {} // 鏂囦欢棰勮鍦板潃缂撳瓨
 		};
 	},
 	props: {
@@ -211,6 +325,7 @@
 		buyType: {
 			handler(val) {
 				if (val) {
+					// 浣跨敤鐩存帴璧嬪�艰�屼笉鏄痶his.$set
 					this.buyType = val;
 				}
 			},
@@ -218,39 +333,359 @@
 		},
 		selectSkuList: {
 			handler(val, oldval) {
-				this.$emit('changed', val);
+				// 浣跨敤setTimeout寤惰繜瑙﹀彂浜嬩欢锛岄伩鍏嶅奖鍝嶅脊绐�
+				setTimeout(() => {
+					this.$emit('changed', val);
+				}, 100);
 			},
 			deep: true
 		},
 		'goodsDetail.quantity': {
 			handler(val) {
 				if (val == 0) {
-					uni.showToast({
-						title: '鍟嗗搧宸插敭缃�',
-						duration: 2000,
-						icon: 'none'
-					})
+					// 浣跨敤setTimeout寤惰繜鏄剧ず鎻愮ず锛岄伩鍏嶅奖鍝嶅脊绐�
+					setTimeout(() => {
+						uni.showToast({
+							title: '鍟嗗搧宸插敭缃�',
+							duration: 2000,
+							icon: 'none'
+						});
+					}, 100);
 					this.num = 1;
 				}
 			}
+		},
+		// 鐩戝惉妯℃澘淇℃伅鍙樺寲
+		consumizetemplateInfo: {
+			handler(newVal, oldVal) {
+				if (newVal) {
+					// 浣跨敤setTimeout寤惰繜鎵ц锛岄伩鍏嶅奖鍝嶅脊绐�
+					setTimeout(() => {
+						// 棰勫姞杞芥ā鏉垮浘鐗囩殑棰勮鍦板潃
+						this.preloadTemplateImages();
+						// 鍒濆鍖栨ā鏉胯〃鍗曟暟鎹�
+						this.initTemplateFormData();
+						// 璁剧疆榛樿閫変腑绗竴寮犳ā鏉垮浘鐗�
+						this.setDefaultSelectedImage();
+					}, 100);
+				}
+			},
+			immediate: true,
+			deep: true
 		}
 	},
 
 	methods: {
+		// 鍒濆鍖栬吘璁簯COS瀹㈡埛绔�
+		initCOS() {
+			getSTSToken().then(res => {
+				const COS = require('@/lib/cos-wx-sdk-v5.js');
+				// 浣跨敤鐩存帴璧嬪�艰�屼笉鏄痶his.$set
+				this.cosClient = new COS({
+					SecretId: res.data.data.tmpSecretId,
+					SecretKey: res.data.data.tmpSecretKey,
+					SecurityToken: res.data.data.sessionToken,
+					StartTime: res.data.data.stsStartTime,
+					ExpiredTime: res.data.data.stsEndTime,
+					SimpleUploadMethod: 'putObject'
+				});
+				this.bucket = res.data.data.bucket;
+				this.region = res.data.data.region;
+				this.endpoint = res.data.data.endpoint; // 鑾峰彇endpoint
+			}).catch(err => {
+				console.error('鍒濆鍖朇OS澶辫触', err);
+				// 浣跨敤setTimeout寤惰繜鏄剧ず鎻愮ず锛岄伩鍏嶅奖鍝嶅脊绐�
+				setTimeout(() => {
+					uni.showToast({
+						title: '涓婁紶鏈嶅姟鍒濆鍖栧け璐�',
+						icon: 'none'
+					});
+				}, 100);
+			});
+		},
+		
+		// 鑾峰彇鏂囦欢棰勮鍦板潃
+		async fetchFilePreviewUrl(fileKey) {
+			// 濡傛灉鏄畬鏁寸殑URL锛岀洿鎺ヨ繑鍥�
+			if (fileKey && (fileKey.startsWith('http://') || fileKey.startsWith('https://'))) {
+				return fileKey;
+			}
+			
+			// 濡傛灉宸茬粡缂撳瓨杩囷紝鐩存帴杩斿洖缂撳瓨鍊�
+			if (this.previewUrls[fileKey]) {
+				return this.previewUrls[fileKey];
+			}
+			
+			// 璋冪敤API鑾峰彇棰勮鍦板潃
+			try {
+				const res = await getFilePreviewUrl(fileKey);
+				const previewUrl = res.data.data;
+				// 浣跨敤鐩存帴璧嬪�艰�屼笉鏄痶his.$set
+				this.previewUrls[fileKey] = previewUrl;
+				return previewUrl;
+			} catch (error) {
+				console.error('鑾峰彇鏂囦欢棰勮鍦板潃澶辫触', error);
+				return fileKey; // 濡傛灉鑾峰彇澶辫触锛岃繑鍥炲師濮嬪��
+			}
+		},
+		
+		// 閫夋嫨妯℃澘鍥剧墖锛堝崟閫夋ā寮忥級
+		selectImage(imgObject) {
+			// 妫�鏌ュ綋鍓嶉�変腑鐨勫浘鐗囨槸鍚﹀氨鏄偣鍑荤殑鍥剧墖
+			const selectedIndex = this.selectedImageObjects.findIndex(selectedImg => selectedImg.id === imgObject.id);
+			
+			if (selectedIndex > -1) {
+				// 濡傛灉鐐瑰嚮鐨勬槸宸查�変腑鐨勫浘鐗囷紝鍒欏彇娑堥�夋嫨
+				this.selectedImageObjects = [];
+				this.selectedImages = [];
+			} else {
+				// 濡傛灉鐐瑰嚮鐨勬槸鏈�変腑鐨勫浘鐗囷紝鍒欓�変腑璇ュ浘鐗囷紙娓呯┖涔嬪墠鐨勯�夋嫨锛�
+				this.selectedImageObjects = [imgObject];
+				this.selectedImages = [imgObject.imgUrl];
+			}
+			
+			// 鏇存柊formValues涓殑chooseImage鍜宑hooseImageId
+			this.formValues.chooseImage = this.selectedImages.join(',');
+			// 灏嗛�変腑鍥剧墖鐨処D涔熷瓨鍌ㄥ埌formValues涓�
+			this.formValues.chooseImageId = this.selectedImageObjects.map(img => img.id).join(',');
+			
+			// 寮哄埗鏇存柊瑙嗗浘浠ョ‘淇漊I姝g‘鍙嶆槧鏁版嵁鍙樺寲
+			this.$forceUpdate();
+		},
+		
+		// 閫夋嫨鍥剧墖锛堝弬鑰僾ideo.vue鐨勫疄鐜帮級
+		chooseImage(fieldId) {
+			if (!this.cosClient) {
+				// 浣跨敤setTimeout寤惰繜鏄剧ず鎻愮ず锛岄伩鍏嶅奖鍝嶅脊绐�
+				setTimeout(() => {
+					uni.showToast({
+						title: '涓婁紶鏈嶅姟鏈垵濮嬪寲',
+						icon: 'none'
+					});
+				}, 100);
+				// 閲嶆柊鍒濆鍖朇OS
+				this.initCOS();
+				return;
+			}
+			
+			uni.chooseImage({
+				count: 1,
+				sizeType: ['compressed'],
+				sourceType: ['album', 'camera'],
+				success: (res) => {
+					const tempFilePath = res.tempFilePaths[0];
+					
+					// 鑾峰彇鏂囦欢鍚�
+					let fileName = tempFilePath.substring(tempFilePath.lastIndexOf('/') + 1);
+					// 澶勭悊瀹夊崜鍙兘鐨刄RI缂栫爜
+					if(fileName.indexOf('%') > -1) {
+						fileName = decodeURIComponent(fileName);
+					}
+					
+					// 鐢熸垚鏂囦欢key
+					const fileKey = getFileKey(fileName);
+					
+					// 鏄剧ず棰勮鍥�
+					this.$set(this.imagePreviewUrls, fieldId, tempFilePath);
+					
+					// 鍒濆鍖栦笂浼犵姸鎬�
+					this.$set(this.uploadProgress, fieldId, 0);
+					this.$set(this.uploadStatus, fieldId, '涓婁紶涓�...');
+					
+					// 寮哄埗鏇存柊瑙嗗浘
+					this.$forceUpdate();
+					
+					// 鎵ц涓婁紶
+					this.cosClient.uploadFile({
+						Bucket: this.bucket,
+						Region: this.region,
+						Key: fileKey,
+						FilePath: tempFilePath,
+						SliceSize: 1024 * 1024 * 5, // 5M
+						onProgress: (progressData) => {
+							// 鏇存柊涓婁紶杩涘害
+							const progress = Math.round(progressData.percent * 100);
+							this.$set(this.uploadProgress, fieldId, progress);
+							
+							// 寮哄埗鏇存柊瑙嗗浘
+							this.$forceUpdate();
+						}
+					}, (err, data) => {
+						// 娓呴櫎涓婁紶杩涘害
+						// 浣跨敤Vue.delete鎴杢his.$delete鍙兘浼氳Е鍙戠粍浠舵洿鏂帮紝鏀圭敤鐩存帴鍒犻櫎
+						delete this.uploadProgress[fieldId];
+						
+						if (err) {
+							console.error('涓婁紶澶辫触', err);
+							// 鏇存柊涓婁紶鐘舵��
+							this.$set(this.uploadStatus, fieldId, '涓婁紶澶辫触');
+							// 娓呴櫎棰勮鍥�
+							this.$delete(this.imagePreviewUrls, fieldId);
+							// 娉ㄦ剰锛氳繖閲屼笉鍐嶉渶瑕佹竻闄ormValues涓殑瀛楁锛屽洜涓烘垜浠凡缁忎慨鏀逛簡鏁版嵁缁撴瀯
+							
+							// 寮哄埗鏇存柊瑙嗗浘
+							this.$forceUpdate();
+							
+							// 浣跨敤setTimeout寤惰繜鏄剧ず閿欒鎻愮ず锛岄伩鍏嶅奖鍝嶅脊绐�
+							setTimeout(() => {
+								uni.showToast({
+									title: '涓婁紶澶辫触',
+									icon: 'none'
+								});
+							}, 100);
+						} else {
+							// 鑾峰彇褰撳墠琛ㄥ崟椤圭殑淇℃伅
+							const currentItem = this.consumizetemplateInfo.templateConstomizeTitles.find(item => item.id === fieldId);
+							const templateTitle = currentItem ? currentItem.templateTitle : '';
+							
+							// 涓婁紶鎴愬姛锛屾洿鏂拌〃鍗曞��
+							this.updateFormValue(fieldId, templateTitle, fileKey);
+							
+							// 鏇存柊涓婁紶鐘舵��
+							this.$set(this.uploadStatus, fieldId, '涓婁紶鎴愬姛');
+							
+							// 寮哄埗鏇存柊瑙嗗浘
+							this.$forceUpdate();
+							
+							// 浣跨敤setTimeout寤惰繜鏄剧ず鎴愬姛鎻愮ず锛岄伩鍏嶅奖鍝嶅脊绐�
+							setTimeout(() => {
+								uni.showToast({
+									title: '涓婁紶鎴愬姛',
+									icon: 'success'
+								});
+							}, 100);
+						}
+					});
+				},
+				fail: (err) => {
+					console.error('閫夋嫨鍥剧墖澶辫触', err);
+					// 鍖哄垎鐢ㄦ埛鍙栨秷鎿嶄綔鍜岀湡姝g殑閿欒
+					// 濡傛灉鏄敤鎴蜂富鍔ㄥ彇娑堬紝涓嶆樉绀烘彁绀�
+					if (err.errMsg && err.errMsg.indexOf('cancel') === -1 && err.errMsg.indexOf('fail') !== -1) {
+						// 浣跨敤setTimeout寤惰繜鏄剧ず鎻愮ず锛岄伩鍏嶅奖鍝嶅脊绐�
+						setTimeout(() => {
+							uni.showToast({
+								title: '鏈�夋嫨鍥剧墖',
+								icon: 'none'
+							});
+						}, 100);
+					}
+				}
+			});
+		},
+		
+		// 鍒犻櫎鍥剧墖
+		deleteImage(fieldId) {
+			// 娓呴櫎棰勮鍥�
+			this.$delete(this.imagePreviewUrls, fieldId);
+			// 娓呴櫎涓婁紶鐘舵��
+			this.$delete(this.uploadStatus, fieldId);
+			// 娓呴櫎涓婁紶杩涘害
+			this.$delete(this.uploadProgress, fieldId);
+			
+			// 浠巉ormValues涓Щ闄ゅ搴旂殑琛ㄥ崟瀛楁
+			const index = this.formValues.templateForm.findIndex(item => item.id === fieldId);
+			if (index > -1) {
+				this.formValues.templateForm.splice(index, 1);
+			}
+			
+			// 浣跨敤setTimeout寤惰繜鏄剧ず鎻愮ず锛岄伩鍏嶅奖鍝嶅脊绐�
+			setTimeout(() => {
+				uni.showToast({
+					title: '鍒犻櫎鎴愬姛',
+					icon: 'success'
+				});
+			}, 100);
+			
+			// 寮哄埗鏇存柊瑙嗗浘
+			this.$forceUpdate();
+		},
+		
+		// 鑾峰彇琛ㄥ崟鍊�
+		getFormValue(fieldId) {
+			const field = this.formValues.templateForm.find(item => item.id === fieldId);
+			return field ? field.value : '';
+		},
+		
+		// 鏇存柊琛ㄥ崟鍊�
+		updateFormValue(fieldId, templateTitle, value) {
+			// 鏇存柊妯℃澘鍩烘湰淇℃伅
+			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);
+			
+			if (existingIndex > -1) {
+				// 鏇存柊鐜版湁瀛楁
+				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
+				});
+			}
+		},
+		
+		// 鏇存柊妯℃澘琛ㄥ崟鏁版嵁
+		updateTemplateFormData(fieldId, templateTitle, value) {
+			// 杩欎釜鏂规硶鐜板湪鍙互淇濇寔涓嶅彉锛屽洜涓烘垜浠凡缁忓湪updateFormValue涓鐞嗕簡formValues鐨勬洿鏂�
+			// 濡傛灉闇�瑕佸叾浠栧鐞嗭紝鍙互鍦ㄨ繖閲屾坊鍔�
+		},
+		
+		// 琛ㄥ崟鎻愪氦澶勭悊
+		handleFormSubmit() {
+			// 纭繚閫変腑鐨勫浘鐗囧璞′篃琚寘鍚湪鎻愪氦鏁版嵁涓�
+			const formData = {
+				...this.formValues,
+				selectedImageObjects: this.selectedImageObjects
+			};
+			
+			console.log('琛ㄥ崟鏁版嵁:', formData);
+			// 杩欓噷鍙互娣诲姞瀹為檯鐨勮〃鍗曟彁浜ら�昏緫
+			// 浣跨敤setTimeout寤惰繜鏄剧ず鎻愮ず锛岄伩鍏嶅奖鍝嶅脊绐�
+			setTimeout(() => {
+				uni.showToast({
+					title: '琛ㄥ崟鎻愪氦鎴愬姛',
+					icon: 'success'
+				});
+			}, 100);
+		},
+		
 		numCheck(val) {
 			if (this.wholesaleList && this.wholesaleList.length > 0) {
 				if (this.num <= this.wholesaleList[0].num) {
-					uni.showToast({
-						title: '鎵瑰彂鍟嗗搧璐拱鏁伴噺涓嶈兘灏忎簬璧锋壒鏁伴噺!',
-						duration: 2000,
-						icon: 'none'
-					});
+					// 浣跨敤setTimeout寤惰繜鏄剧ず鎻愮ず锛岄伩鍏嶅奖鍝嶅脊绐�
+					setTimeout(() => {
+						uni.showToast({
+							title: '鎵瑰彂鍟嗗搧璐拱鏁伴噺涓嶈兘灏忎簬璧锋壒鏁伴噺!',
+							duration: 2000,
+							icon: 'none'
+						});
+					}, 100);
 					this.num = this.wholesaleList[0].num;
 				}
 			}
 		},
 		closeMask() {
 			this.$emit('closeBuy', false);
+		},
+		
+		// 澶勭悊寮圭獥杈撳叆浜嬩欢锛岄伩鍏嶇洿鎺ヤ慨鏀筽rop
+		handlePopupInput(val) {
+			this.$emit('closeBuy', val);
 		},
 		
 		/**鐐瑰嚮瑙勬牸 */
@@ -285,11 +720,14 @@
 					goodsId: this.goodsDetail.goodsId
 				});
 			} else {
-				uni.showToast({
-					title: '鏆傛棤璇ュ晢鍝�!',
-					duration: 2000,
-					icon: 'none'
-				});
+				// 浣跨敤setTimeout寤惰繜鏄剧ず鎻愮ず锛岄伩鍏嶅奖鍝嶅脊绐�
+				setTimeout(() => {
+					uni.showToast({
+						title: '鏆傛棤璇ュ晢鍝�!',
+						duration: 2000,
+						icon: 'none'
+					});
+				}, 100);
 			}
 		},
 
@@ -299,9 +737,12 @@
 		buy(data) {
 			API_trade.addToCart(data).then(res => {
 				if (res.data.success) {
-					uni.navigateTo({
-						url: `/pages/order/fillorder?way=${data.cartType}&addr=${''}&parentOrder=${encodeURIComponent(JSON.stringify(this.parentOrder))}`
-					});
+					// 浣跨敤setTimeout寤惰繜璺宠浆锛岄伩鍏嶅奖鍝嶅脊绐�
+					setTimeout(() => {
+						uni.navigateTo({
+							url: `/pages/order/fillorder?way=${data.cartType}&addr=${''}&parentOrder=${encodeURIComponent(JSON.stringify(this.parentOrder))}`
+						});
+					}, 100);
 				}
 			});
 		},
@@ -310,11 +751,23 @@
 		 * 娣诲姞鍒拌喘鐗╄溅鎴栬喘涔�
 		 */
 		addToCartOrBuy(val) {
+			// 妫�鏌ュ晢鍝佹槸鍚﹂渶瑕佹ā鏉垮苟涓旀ā鏉挎暟鎹槸鍚﹀畬鏁�
+			if (this.consumizetemplateInfo && this.consumizetemplateInfo.id) {
+				const isValid = this.validateTemplateData();
+				if (!isValid) {
+					return;
+				}
+			}
+			
+			console.log(JSON.stringify(this.formValues))
 			if (!this.selectSkuList) {
-				uni.showToast({
-					title: '璇烽�夋嫨瑙勬牸鍟嗗搧',
-					icon: 'none'
-				});
+				// 浣跨敤setTimeout寤惰繜鏄剧ず鎻愮ず锛岄伩鍏嶅奖鍝嶅脊绐�
+				setTimeout(() => {
+					uni.showToast({
+						title: '璇烽�夋嫨瑙勬牸鍟嗗搧',
+						icon: 'none'
+					});
+				}, 100);
 				return;
 			}
 			let data = {
@@ -325,10 +778,13 @@
 			if (val == 'cart') {
 				API_trade.addToCart(data).then(res => {
 					if (res.data.code == 200) {
-						uni.showToast({
-							title: '鍟嗗搧宸叉坊鍔犲埌璐墿杞�',
-							icon: 'none'
-						});
+						// 浣跨敤setTimeout寤惰繜鏄剧ず鎻愮ず锛岄伩鍏嶅奖鍝嶅脊绐�
+						setTimeout(() => {
+							uni.showToast({
+								title: '鍟嗗搧宸叉坊鍔犲埌璐墿杞�',
+								icon: 'none'
+							});
+						}, 100);
 
 						this.$emit('queryCart');
 						this.closeMask();
@@ -344,14 +800,73 @@
 					data.cartType = 'BUY_NOW';
 				}
 
+				// 鍒涘缓鍖呭惈鍥剧墖ID鐨勫畬鏁磋〃鍗曟暟鎹�
+				const templateData = {
+					...this.formValues,
+					selectedImageObjects: this.selectedImageObjects
+				};
+
 				API_trade.addToCart(data).then(res => {
 					if (res.data.code == 200) {
-						uni.navigateTo({
-							url: `/pages/order/fillorder?way=${data.cartType}&addr=${this.addr.id || ''}&parentOrder=${encodeURIComponent(JSON.stringify(this.parentOrder))}`
-						});
+						// 浣跨敤setTimeout寤惰繜璺宠浆锛岄伩鍏嶅奖鍝嶅脊绐�
+						setTimeout(() => {
+							uni.navigateTo({
+								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) {
 			// 鏍煎紡鍖栨暟鎹�
@@ -380,6 +895,7 @@
 								return i.value === values.value;
 							})
 						) {
+							// 浣跨敤鐩存帴璧嬪�艰�屼笉鏄痶his.$set
 							arrItem.values.push(values);
 						}
 
@@ -387,6 +903,7 @@
 							return key.name;
 						});
 						if (!keys.includes(name)) {
+							// 浣跨敤鐩存帴璧嬪�艰�屼笉鏄痶his.$set
 							arr.push({
 								name: name,
 								values: [values]
@@ -397,6 +914,7 @@
 			});
 
 			arr.shift();
+			// 浣跨敤鐩存帴璧嬪�艰�屼笉鏄痶his.$set
 			this.formatList = arr;
 
 			list.forEach(item => {
@@ -405,6 +923,7 @@
 					item.specValues
 						.filter(i => i.specName !== 'images')
 						.forEach((value, _index) => {
+							// 浣跨敤鐩存帴璧嬪�艰�屼笉鏄痶his.$set
 							this.currentSelected[_index] = value.specValue;
 
 							this.selectName = value.specValue;
@@ -417,15 +936,140 @@
 				}
 			});
 
+			// 浣跨敤鐩存帴璧嬪�艰�屼笉鏄痶his.$set
 			this.skuList = list;
 			// console.log(" this.skuList", this.skuList)
+		},
+		
+		// 棰勫姞杞芥ā鏉垮浘鐗囩殑棰勮鍦板潃
+		async preloadTemplateImages() {
+			if (this.consumizetemplateInfo && this.consumizetemplateInfo.templateImgs) {
+				for (const img of this.consumizetemplateInfo.templateImgs) {
+					await this.fetchFilePreviewUrl(img.imgUrl);
+				}
+			}
+		},
+		
+		// 鑾峰彇鏂囦欢棰勮鍦板潃(鍚屾鐗堟湰)
+		getFilePreviewUrlSync(fileKey) {
+			// 濡傛灉鏄畬鏁寸殑URL锛岀洿鎺ヨ繑鍥�
+			if (fileKey && (fileKey.startsWith('http://') || fileKey.startsWith('https://'))) {
+				return fileKey;
+			}
+			// 濡傛灉鏈夐瑙堝湴鍧�锛岃繑鍥為瑙堝湴鍧�
+			if (this.previewUrls && this.previewUrls[fileKey]) {
+				return this.previewUrls[fileKey];
+			}
+			// 濡傛灉娌℃湁http鍓嶇紑锛岄渶瑕佹嫾鎺ndpoint杩涜鏄剧ず
+			if (fileKey && !fileKey.startsWith('http://') && !fileKey.startsWith('https://')) {
+				// 浣跨敤endpoint鎷兼帴瀹屾暣鐨刄RL
+				if (this.endpoint) {
+					return this.endpoint + '/' + fileKey;
+				}
+			}
+			// 鍚﹀垯杩斿洖鍘熷鍊�
+			return fileKey;
+		},
+		
+		// 鍒濆鍖栨ā鏉胯〃鍗曟暟鎹�
+		initTemplateFormData() {
+			if (this.consumizetemplateInfo && this.consumizetemplateInfo.templateConstomizeTitles) {
+				// 鍒濆鍖杅ormValues鐨勫熀鏈俊鎭�
+				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);
+			}
 		}
 	},
 
 	mounted() {
-		this.formatSku(this.goodsSpec);
+		// 浣跨敤setTimeout寤惰繜鎵ц锛岄伩鍏嶅奖鍝嶅脊绐�
+		setTimeout(() => {
+			this.formatSku(this.goodsSpec);
+			this.initCOS(); // 鍒濆鍖朇OS瀹㈡埛绔�
+			
+			// 棰勫姞杞芥ā鏉垮浘鐗囩殑棰勮鍦板潃
+			this.preloadTemplateImages();
 
-		console.log("goodsDetail",this.goodsDetail)
+			// 鍒濆鍖栨ā鏉胯〃鍗曟暟鎹�
+			this.initTemplateFormData();
+			
+			// 榛樿閫変腑绗竴寮犳ā鏉垮浘鐗�
+			this.setDefaultSelectedImage();
+
+			console.log("goodsDetail",this.goodsDetail)
+		}, 100);
 	}
 };
 </script>
@@ -580,4 +1224,147 @@
 		color: #333;
 	}
 }
-</style>
+
+// 妯℃澘鏍峰紡
+.template {
+	padding: 20rpx;
+}
+
+.template-title {
+	margin-bottom: 30rpx;
+	text-align: center;
+}
+
+.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;
+}
+
+// 鍥剧墖閫夋嫨鍖哄煙
+.template-images {
+	margin-bottom: 40rpx;
+}
+
+.images-grid {
+	display: flex;
+	flex-wrap: wrap;
+	gap: 20rpx;
+}
+
+.image-item {
+	width: calc((100% - 40rpx) / 3);
+	height: 200rpx;
+	border: 2rpx solid #e0e0e0;
+	border-radius: 10rpx;
+	overflow: hidden;
+	position: relative;
+	
+	&.selected {
+		border-color: #ff6b00;
+		box-shadow: 0 0 10rpx rgba(255, 107, 0, 0.5);
+	}
+}
+
+.selected-overlay {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	background-color: rgba(0, 0, 0, 0.3);
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.image-preview {
+	width: 100%;
+	height: 100%;
+}
+
+// 琛ㄥ崟鍖哄煙
+.template-form {
+	
+}
+
+.form-item {
+	margin-bottom: 30rpx;
+}
+
+.form-label {
+	display: block;
+	margin-bottom: 15rpx;
+	font-size: 28rpx;
+	color: #333;
+}
+
+.form-input {
+	width: 100%;
+	height: 80rpx;
+	padding: 0 20rpx;
+	border: 2rpx solid #e0e0e0;
+	border-radius: 10rpx;
+	font-size: 28rpx;
+	box-sizing: border-box;
+}
+
+.form-upload {
+	margin-top: 15rpx;
+}
+
+// 鍥剧墖涓婁紶鏍峰紡
+.upload-btn {
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+	width: 150rpx;
+	height: 150rpx;
+	border: 2rpx dashed #ccc;
+	border-radius: 10rpx;
+	background-color: #f8f8f8;
+}
+
+.upload-text {
+	font-size: 24rpx;
+	color: #999;
+	margin-top: 10rpx;
+}
+
+.image-preview-container {
+	position: relative;
+	width: 150rpx;
+	height: 150rpx;
+	margin-top: 10rpx;
+}
+
+.uploaded-image {
+	width: 100%;
+	height: 100%;
+	border-radius: 10rpx;
+}
+
+.delete-icon {
+	position: absolute;
+	top: -10rpx;
+	right: -10rpx;
+	background-color: #ff6b00;
+	border-radius: 50%;
+	width: 30rpx;
+	height: 30rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+</style>
\ No newline at end of file

--
Gitblit v1.8.0