// pages/goods-detail/goods-detail.js const API = require('../../utils/api.js') // 格式化毛重显示的辅助函数 function formatGrossWeight(grossWeight, weight) { console.log('===== formatGrossWeight 函数调用 ====='); console.log('输入参数:'); console.log('- grossWeight:', grossWeight, '(类型:', typeof grossWeight, ')'); console.log('- weight:', weight, '(类型:', typeof weight, ')'); // 1. 优先使用grossWeight,只要它不是null、不是undefined、不是空字符串 if (grossWeight !== null && grossWeight !== undefined && grossWeight !== '') { console.log('使用grossWeight参数'); return grossWeight; } // 如果grossWeight无效,尝试使用weight字段 if (weight !== null && weight !== undefined && weight !== '') { console.log('使用weight参数'); return weight; } // 3. 新增逻辑:如果grossWeight和weight都无效,返回空字符串以支持文字输入 console.log('两个参数都无效,返回空字符串'); return ""; } Page({ data: { goodsDetail: {}, // 当前商品详情 showImagePreview: false, // 控制图片预览弹窗显示 previewImageUrls: [], // 预览的图片URL列表 previewImageIndex: 0, // 当前预览图片的索引 fromSeller: false, // 是否来自seller页面 // 图片缩放相关状态 scale: 1, // 当前缩放比例 lastScale: 1, // 上一次缩放比例 startDistance: 0, // 双指起始距离 doubleTapTimer: null, // 双击计时器 lastTapTime: 0, // 上一次单击时间 isScaling: false, // 是否正在缩放中 offsetX: 0, // X轴偏移量 offsetY: 0, // Y轴偏移量 initialTouch: null, // 初始触摸点 }, onLoad(options) { console.log('商品详情页面加载,参数:', options); // 检查是否来自seller页面 const fromSeller = options.fromSeller === '1' ? true : false; // 支持两种参数传递方式:直接传递商品数据或仅传递商品ID if (options.goodsData) { try { // 解析JSON字符串为商品对象 const goodsData = JSON.parse(decodeURIComponent(options.goodsData)); console.log('解析后的商品数据:', goodsData); // 从本地存储获取已预约商品ID列表 const reservedGoodsIds = wx.getStorageSync('reservedGoodsIds') || []; const product = goodsData; // 确保商品ID的一致性 const productIdStr = String(product.productId || product.id); // 增强的预约人数计算逻辑 const selectedValue = product.selected; const reservedCountValue = product.reservedCount; const reservationCountValue = product.reservationCount; const finalReservationCount = selectedValue !== undefined && selectedValue !== null ? selectedValue : (reservedCountValue !== undefined && reservedCountValue !== null ? reservedCountValue : (reservationCountValue || 0)); // 处理grossWeight为null或无效的情况,返回空字符串以支持文字输入 const grossWeightValue = product.grossWeight !== null && product.grossWeight !== undefined ? product.grossWeight : ''; // 转换商品数据格式,与loadGoodsDetail保持一致 const formattedGoods = { id: productIdStr, productId: productIdStr, name: product.productName, price: product.price, minOrder: product.minOrder || product.quantity, yolk: product.yolk, spec: product.spec || product.specification, region: product.region, contact_phone: product.contact_phone || product.contactPhone, product_contact: product.product_contact || product.contactName, imageUrls: product.imageUrls || product.images || [], displayGrossWeight: formatGrossWeight(grossWeightValue, product.weight), isReserved: reservedGoodsIds.some(itemId => String(itemId) === productIdStr), reservedCount: finalReservationCount, created_at: product.created_at || product.createdAt, updated_at: product.updated_at || product.updatedAt, status: product.status || 'published' }; // 设置商品详情数据和来源标识 this.setData({ goodsDetail: formattedGoods, fromSeller: fromSeller }); } catch (error) { console.error('解析商品数据失败:', error); wx.showToast({ title: '数据解析错误', icon: 'none', duration: 2000 }); // 2秒后返回上一页 setTimeout(() => { wx.navigateBack(); }, 2000); } } else if (options.id) { // 如果只传递了商品ID,则从服务器加载商品详情 this.loadGoodsDetail(options.id); // 设置来源标识 this.setData({ fromSeller: fromSeller }); } else { wx.showToast({ title: '参数错误', icon: 'none', duration: 2000 }); // 2秒后返回上一页 setTimeout(() => { wx.navigateBack(); }, 2000); } }, // 加载商品详情 loadGoodsDetail(goodsId) { wx.showLoading({ title: '加载中', }); API.getProductDetail({ productId: goodsId }) .then(res => { console.log('获取商品详情成功:', res); if (res && res.code === 200 && res.data) { // 从本地存储获取已预约商品ID列表 const reservedGoodsIds = wx.getStorageSync('reservedGoodsIds') || []; const product = res.data; // 确保商品ID的一致性 const productIdStr = String(product.productId || product.id); // 增强的预约人数计算逻辑 const selectedValue = product.selected; const reservedCountValue = product.reservedCount; const reservationCountValue = product.reservationCount; const finalReservationCount = selectedValue !== undefined && selectedValue !== null ? selectedValue : (reservedCountValue !== undefined && reservedCountValue !== null ? reservedCountValue : (reservationCountValue || 0)); // 处理grossWeight为null或无效的情况,返回空字符串以支持文字输入 const grossWeightValue = product.grossWeight !== null && product.grossWeight !== undefined ? product.grossWeight : ''; // 转换商品数据格式 const formattedGoods = { id: productIdStr, productId: productIdStr, name: product.productName, price: product.price, minOrder: product.minOrder || product.quantity, yolk: product.yolk, spec: product.spec || product.specification, region: product.region, contact_phone: product.contact_phone || product.contactPhone, product_contact: product.product_contact || product.contactName, imageUrls: product.imageUrls || product.images || [], displayGrossWeight: formatGrossWeight(grossWeightValue, product.weight), isReserved: reservedGoodsIds.some(itemId => String(itemId) === productIdStr), reservedCount: finalReservationCount, created_at: product.created_at || product.createdAt, updated_at: product.updated_at || product.updatedAt }; this.setData({ goodsDetail: formattedGoods }); } else { wx.showToast({ title: '获取商品详情失败', icon: 'none', duration: 2000 }); } }) .catch(err => { console.error('获取商品详情失败:', err); wx.showToast({ title: '获取商品详情失败', icon: 'none', duration: 2000 }); }) .finally(() => { wx.hideLoading(); }); }, // 预览图片 previewImage(e) { console.log('预览图片事件:', e); const { urls, index } = e.currentTarget.dataset; if (!urls || urls.length === 0) { wx.showToast({ title: '没有图片可预览', icon: 'none' }); return; } this.setData({ showImagePreview: true, previewImageUrls: urls, previewImageIndex: parseInt(index || 0) }); this.resetZoom(); }, // 关闭图片预览 closeImagePreview() { this.setData({ showImagePreview: false }); this.resetZoom(); }, // 重置缩放状态 resetZoom() { this.setData({ scale: 1, offsetX: 0, offsetY: 0, lastScale: 1, startDistance: 0, isScaling: false, initialTouch: null, lastTapTime: 0 }); }, // 图片预览切换 onPreviewImageChange(e) { console.log('图片预览切换:', e); this.setData({ previewImageIndex: e.detail.current }); // 切换图片时重置缩放状态 this.resetZoom(); }, // 处理图片点击事件(单击/双击判断) handleImageTap(e) { console.log('图片点击事件:', e); const currentTime = Date.now(); const lastTapTime = this.data.lastTapTime || 0; // 判断是否为双击(300ms内连续点击) if (currentTime - lastTapTime < 300) { // 双击事件 if (this.data.doubleTapTimer) { clearTimeout(this.data.doubleTapTimer); } // 切换放大/缩小状态 const newScale = this.data.scale === 1 ? 2 : 1; this.setData({ scale: newScale, lastScale: newScale, offsetX: 0, offsetY: 0, lastTapTime: 0 // 重置双击状态 }); } else { // 单击事件,设置延迟来检测是否会成为双击 if (this.data.doubleTapTimer) { clearTimeout(this.data.doubleTapTimer); } this.setData({ lastTapTime: currentTime, doubleTapTimer: setTimeout(() => { // 确认是单击,关闭图片预览 this.closeImagePreview(); }, 300) }); } }, // 计算两点之间的距离 calculateDistance(touch1, touch2) { const dx = touch2.clientX - touch1.clientX; const dy = touch2.clientY - touch1.clientY; return Math.sqrt(dx * dx + dy * dy); }, // 处理触摸开始事件 handleTouchStart(e) { console.log('触摸开始事件:', e); const touches = e.touches; if (touches.length === 1) { // 单指:准备拖动 this.setData({ initialTouch: { x: touches[0].clientX, y: touches[0].clientY } }); } else if (touches.length === 2) { // 双指:记录起始距离,准备缩放 const distance = this.calculateDistance(touches[0], touches[1]); this.setData({ startDistance: distance, isScaling: true, lastScale: this.data.scale }); } }, // 处理触摸移动事件 handleTouchMove(e) { console.log('触摸移动事件:', e); const touches = e.touches; if (touches.length === 1 && this.data.initialTouch && this.data.scale !== 1) { // 单指拖动(只有在缩放状态下才允许拖动) const deltaX = touches[0].clientX - this.data.initialTouch.x; const deltaY = touches[0].clientY - this.data.initialTouch.y; // 计算新的偏移量 let newOffsetX = this.data.offsetX + deltaX; let newOffsetY = this.data.offsetY + deltaY; // 边界限制 const windowWidth = wx.getSystemInfoSync().windowWidth; const windowHeight = wx.getSystemInfoSync().windowHeight; const maxOffsetX = (windowWidth * (this.data.scale - 1)) / 2; const maxOffsetY = (windowHeight * (this.data.scale - 1)) / 2; newOffsetX = Math.max(-maxOffsetX, Math.min(maxOffsetX, newOffsetX)); newOffsetY = Math.max(-maxOffsetY, Math.min(maxOffsetY, newOffsetY)); this.setData({ offsetX: newOffsetX, offsetY: newOffsetY, initialTouch: { x: touches[0].clientX, y: touches[0].clientY } }); } else if (touches.length === 2) { // 双指缩放 const currentDistance = this.calculateDistance(touches[0], touches[1]); const scale = (currentDistance / this.data.startDistance) * this.data.lastScale; // 限制缩放范围在0.5倍到3倍之间 const newScale = Math.max(0.5, Math.min(3, scale)); this.setData({ scale: newScale, isScaling: true }); } }, // 处理触摸结束事件 handleTouchEnd(e) { console.log('触摸结束事件:', e); this.setData({ isScaling: false, lastScale: this.data.scale, initialTouch: null }); }, // 拨打电话 makePhoneCall(e) { console.log('拨打电话事件:', e); const phoneNumber = e.currentTarget.dataset.phone; if (phoneNumber) { wx.showModal({ title: '联系人电话', content: phoneNumber, showCancel: true, cancelText: '取消', confirmText: '拨打', success: (res) => { if (res.confirm) { wx.makePhoneCall({ phoneNumber: phoneNumber, success: () => { console.log('拨打电话成功'); }, fail: (err) => { console.error('拨打电话失败', err); wx.showToast({ title: '拨打电话失败', icon: 'none' }); } }); } } }); } }, // 我想要(预约) onClickWantInDetail(e) { console.log('我想要事件:', e); const { id } = e.currentTarget.dataset; if (!id) return; // 从本地存储获取openid const openid = wx.getStorageSync('openid'); console.log('openid:', openid); // 检查是否已登录 if (!openid) { // 如果未登录,显示授权登录弹窗 this.setData({ showAuthModal: true }); return; } // 获取已预约商品ID列表 let reservedGoodsIds = wx.getStorageSync('reservedGoodsIds') || []; // 检查是否已经预约过 if (reservedGoodsIds.some(itemId => String(itemId) === String(id))) { wx.showToast({ title: '您已经预约过该商品', icon: 'none', duration: 1500 }); return; } // 添加到已预约列表 reservedGoodsIds.push(id); wx.setStorageSync('reservedGoodsIds', reservedGoodsIds); // 更新页面状态 this.setData({ 'goodsDetail.isReserved': true }); // 调用API记录预约 API.reserveProduct({ id: id }) .then(res => { console.log('预约成功:', res); wx.showToast({ title: '预约成功', icon: 'success', duration: 1500 }); }) .catch(err => { console.error('预约失败:', err); // 如果API调用失败,从本地列表中移除 reservedGoodsIds = reservedGoodsIds.filter(itemId => String(itemId) !== String(id)); wx.setStorageSync('reservedGoodsIds', reservedGoodsIds); // 更新页面状态 this.setData({ 'goodsDetail.isReserved': false }); wx.showToast({ title: '预约失败,请重试', icon: 'none', duration: 1500 }); }); }, // 返回上一页 goBack() { wx.navigateBack(); } });