// pages/buyer/index.js const API = require('../../utils/api.js') console.log('API对象内容:', API) console.log('API方法列表:', Object.keys(API)) // 格式化毛重显示的辅助函数 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参数'); // 保持原始字符串类型,不再强制转换为数字 console.log('返回结果:', grossWeight); return grossWeight; } // 如果grossWeight无效,尝试使用weight字段 if (weight !== null && weight !== undefined && weight !== '') { console.log('使用weight参数'); // 保持原始字符串类型 console.log('返回结果:', weight); return weight; } // 3. 新增逻辑:如果grossWeight和weight都无效,返回空字符串以支持文字输入 console.log('两个参数都无效,返回空字符串'); return ""; // 返回空字符串以支持文字输入 } Page({ data: { goods: [], searchKeyword: '', filteredGoods: [], selectedCategory: '全部', // 默认显示全部商品 showCustomToast: false, // 控制自定义弹窗显示 toastAnimation: {}, // 存储动画对象 // 图片预览相关状态 showImagePreview: false, // 控制图片预览弹窗显示 previewImageUrls: [], // 预览的图片URL列表 previewImageIndex: 0, // 当前预览图片的索引 // 图片缩放相关状态 scale: 1, // 当前缩放比例 lastScale: 1, // 上一次缩放比例 startDistance: 0, // 双指起始距离 doubleTapTimer: null, // 双击计时器 lastTapTime: 0, // 上一次单击时间 isScaling: false, // 是否正在缩放中 offsetX: 0, // X轴偏移量 offsetY: 0, // Y轴偏移量 initialTouch: null, // 初始触摸点 // 用于强制刷新的键 goodsListKey: Date.now(), forceUpdateTime: Date.now(), // 已预约商品ID列表 reservedGoodsIds: [], // 分页相关状态 page: 1, pageSize: 10, hasMoreData: true, loadingMore: false, totalGoods: 0, totalPages: 1, // 授权登录相关状态 showAuthModal: false, // 控制未授权提示弹窗显示 showOneKeyLoginModal: false, // 控制一键登录弹窗显示 pendingUserType: 'buyer', // 记录用户即将选择的身份类型 avatarUrl: '/images/default-avatar.png', // 默认头像 showUserInfoForm: false, // 控制用户信息填写表单显示 currentGoodsId: null, // 记录当前点击的商品ID // 商品详情相关状态 showGoodsDetail: false, // 控制商品详情弹窗显示 currentGoodsDetail: {} // 当前显示的商品详情 }, onLoad() { console.log('买家页面加载完成') // 从本地存储加载已预约商品ID列表 const reservedGoodsIds = wx.getStorageSync('reservedGoodsIds') || [] this.setData({ reservedGoodsIds }) // ✅ 修改:使用新的分页方式加载数据 this.setData({ page: 1, hasMoreData: true, goods: [], filteredGoods: [], loadingMore: false }, () => { this.loadGoods().then(() => { console.log('onLoad加载商品数据完成'); }).catch(err => { console.error('onLoad加载商品数据失败:', err); this.fallbackToLocalStorageWithPagination(); }); }); }, // 点击"我想要"按钮 onClickWant: function (e) { const goodsId = e.currentTarget.dataset.id; console.log('用户点击了"我想要"按钮,商品ID:', goodsId, '类型:', typeof goodsId); // 保存当前商品ID this.setData({ currentGoodsId: goodsId }); // 检查用户登录状态 const openid = wx.getStorageSync('openid'); const userInfo = wx.getStorageSync('userInfo'); const userId = wx.getStorageSync('userId'); console.log('检查用户授权状态 - openid:', !!openid, 'userInfo:', !!userInfo, 'userId:', !!userId); if (!openid || !userId || !userInfo) { console.log('用户未登录,显示一键登录弹窗'); // 显示一键登录弹窗,让用户确认是否要登录 this.showOneKeyLogin(); return; } // 点击"我想要"后,将用户类型设置为buyer const API = require('../../utils/api.js'); API.updateUserType('buyer'); // 1. 前置验证 if (!goodsId) { console.error('商品ID为空,无法预约'); wx.showToast({ title: '商品信息不完整', icon: 'error', duration: 2000 }); return; } // 2. 确保商品ID是字符串格式 const goodsIdStr = String(goodsId); if (!goodsIdStr || goodsIdStr === 'undefined' || goodsIdStr === 'null') { console.error('无效的商品ID:', goodsIdStr); wx.showToast({ title: '商品信息不完整', icon: 'error', duration: 2000 }); return; } // 3. 查找商品信息 const goodsItem = this.findGoodsItemById(goodsIdStr); if (!goodsItem) { console.error('未找到对应商品信息,ID:', goodsIdStr); wx.showToast({ title: '商品信息已更新,请刷新页面', icon: 'error', duration: 2000 }); // 主动刷新页面数据 this.refreshGoodsList(); return; } console.log('找到商品信息:', goodsItem) // 检查商品是否已预约 if (goodsItem.isReserved) { console.log('商品已预约,无需重复操作'); return; } // 构建完整的product对象,包含所有必要字段 const product = { productId: String(goodsItem.productId || goodsItem.id), // 确保为字符串 id: String(goodsItem.productId || goodsItem.id), // 同时设置id字段,与productId保持一致 productName: goodsItem.name || goodsItem.productName || '未命名商品', name: goodsItem.name || goodsItem.productName || '未命名商品', quantity: goodsItem.minOrder || 1, // 使用商品的最小订单数量作为实际件数,如果没有则默认为1 price: goodsItem.price || '', // 确保价格有默认值,使用空字符串支持字符串类型 specification: goodsItem.spec || goodsItem.specification || '', grossWeight: goodsItem.grossWeight !== null && goodsItem.grossWeight !== undefined ? goodsItem.grossWeight : (goodsItem.weight || ''), // 使用空字符串支持字符串类型 yolk: goodsItem.yolk || '', testMode: false } console.log('找到的完整商品信息:', goodsItem) wx.showLoading({ title: '正在预约...' }) // 调用API增加预约人数 console.log('准备调用API.addToCart,传递完整的product对象'); API.addToCart(product) .then(res => { wx.hideLoading() console.log('增加预约人数成功:', res) console.log('API.addToCart返回的数据结构:', JSON.stringify(res)) // 增强的成功检测逻辑:即使服务器没有明确返回success:true,也尝试更新UI const isSuccess = res && (res.success || res.code === 200 || res.status === 'success'); if (isSuccess) { // 更新已预约商品ID列表 this.updateReservedGoodsList(goodsItem) // 直接更新当前商品的状态,避免整页刷新带来的延迟感 // 1. 找到当前商品在列表中的索引 - 增强版,处理多种ID格式 const goodsIndex = this.data.filteredGoods.findIndex(item => String(item.id) === goodsIdStr || String(item.productId) === goodsIdStr ); if (goodsIndex !== -1) { // 2. 更新商品的isReserved状态为true const updateData = {}; updateData[`filteredGoods[${goodsIndex}].isReserved`] = true; // 3. 更新预约人数(如果API返回了最新的预约人数) // 优先使用服务器返回的selected字段,保持与商品列表加载时的逻辑一致 const newReservedCount = res.selected !== undefined ? res.selected : (res.reservedCount !== undefined ? res.reservedCount : (res.reservationCount || (this.data.filteredGoods[goodsIndex].reservationCount + 1))); // 同时更新selected、reservedCount和reservationCount字段,确保数据一致性 updateData[`filteredGoods[${goodsIndex}].selected`] = newReservedCount; updateData[`filteredGoods[${goodsIndex}].reservedCount`] = newReservedCount; updateData[`filteredGoods[${goodsIndex}].reservationCount`] = newReservedCount; // 4. 应用更新并验证 console.log('准备更新商品状态:', updateData); this.setData(updateData, () => { console.log('商品状态更新成功'); console.log('更新后商品状态:', this.data.filteredGoods[goodsIndex].isReserved); }); } else { console.warn('未找到对应商品索引,无法即时更新UI状态'); } // 优化:点击"我想要"后,不立即刷新商品列表,而是使用本地更新的值 // 这样可以避免服务器数据未及时同步导致预约人数回退 // 仅在用户主动刷新页面或下次进入页面时才从服务器获取最新数据 // 记录成功的预约行为 this.recordBehavior('want_success', 'goods', goodsId) // 显示"稍后会有专员联系"的弹窗 this.showContactToast() } else { // 失败时可以考虑添加日志,但不显示弹窗 console.error('预约失败:', res.message); } }) .catch(err => { wx.hideLoading() console.error('增加预约人数失败:', err); // 增强的错误详情日志,包含新增的错误属性 console.error('错误详情:', { message: err.message, stack: err.stack, isForeignKeyError: err.isForeignKeyError, productId: err.productId, // 增强的错误信息 timestamp: err.timestamp, // 增强的错误信息 originalError: err.originalError, // 增强的错误信息 statusCode: err.statusCode, needRelogin: err.needRelogin }); // 检查是否需要重新登录 if (err.needRelogin || err.message.includes('重新登录')) { console.warn('检测到需要重新登录'); wx.showModal({ title: '登录状态失效', content: '您的登录已过期,请重新授权登录', showCancel: false, success: (res) => { if (res.confirm) { // 清除本地存储的用户信息 wx.removeStorageSync('openid'); wx.removeStorageSync('userId'); // 跳转到登录页面 wx.navigateTo({ url: '/pages/login/index' }); } } }); return; // 结束后续处理 } // 对于需要处理的特殊情况,仍然在后台默默处理 if (err.isForeignKeyError) { console.log('检测到外键约束错误,自动刷新商品列表', { productId: err.productId }); // 先尝试在本地更新商品状态为预约中,提供即时反馈 const goodsItem = this.findGoodsItemById(String(goodsId)); if (goodsItem) { const goodsIndex = this.data.filteredGoods.findIndex(item => String(item.id) === String(goodsId) || String(item.productId) === String(goodsId) ); if (goodsIndex !== -1) { const updateData = {}; updateData[`filteredGoods[${goodsIndex}].isReserved`] = true; if (this.data.filteredGoods[goodsIndex].reservationCount !== undefined) { updateData[`filteredGoods[${goodsIndex}].reservationCount`] = this.data.filteredGoods[goodsIndex].reservationCount + 1; } console.log('临时更新商品状态,等待刷新确认:', updateData); this.setData(updateData); } } // 后台静默刷新商品列表 setTimeout(() => { this.refreshGoodsList(); }, 500); } else if (err.message.includes('刷新')) { console.log('需要刷新商品列表'); // 后台静默刷新商品列表 setTimeout(() => { this.refreshGoodsList(); }, 500); } // 其他错误情况下可以显示一个简单的提示 else { wx.showToast({ title: '操作失败,请稍后重试', icon: 'none', duration: 2000 }); } }) // 记录用户行为 this.recordBehavior('want_intent', 'goods', goodsId) }, // 根据ID查找商品信息的辅助方法 - 增强版,支持多种ID格式和来源 findGoodsItemById: function (goodsIdStr) { // 1. 首先从页面数据中查找 console.log('尝试从页面数据中查找商品,ID:', goodsIdStr); let goodsItem = this.data.goods.find(item => String(item.id) === goodsIdStr || String(item.productId) === goodsIdStr ); // 2. 如果页面数据中找不到,从本地存储中查找 if (!goodsItem) { console.log('页面数据中未找到商品,尝试从本地存储中查找'); const localGoods = wx.getStorageSync('goods') || []; goodsItem = localGoods.find(item => String(item.id) === goodsIdStr || String(item.productId) === goodsIdStr ); } // 3. 如果仍未找到,尝试从最新加载的缓存中查找 if (!goodsItem) { console.log('本地存储中未找到商品,尝试从原始数据中查找'); // 可以添加更多的查找策略,例如临时缓存等 } return goodsItem; }, // 更新已预约商品列表的辅助方法 updateReservedGoodsList: function (goodsItem) { // 添加到已预约商品ID列表 const { reservedGoodsIds } = this.data // 确保商品ID为字符串类型,避免类型不匹配问题 const actualGoodsId = String(goodsItem.productId || goodsItem.id) // 检查是否已存在,同样进行类型转换确保匹配 const isAlreadyReserved = reservedGoodsIds.some(id => String(id) === actualGoodsId) if (!isAlreadyReserved) { const newReservedGoodsIds = [...reservedGoodsIds, actualGoodsId] this.setData({ reservedGoodsIds: newReservedGoodsIds }) // 保存到本地存储 wx.setStorageSync('reservedGoodsIds', newReservedGoodsIds) console.log('已更新预约列表:', newReservedGoodsIds) } else { console.log('商品已在预约列表中') } }, // 刷新商品列表 refreshGoodsList() { console.log('刷新商品列表 - 重置分页状态并重新加载') // 重置分页状态 this.setData({ page: 1, hasMoreData: true, loadingMore: false, // ✅ 添加这行 goods: [], filteredGoods: [] }, () => { // 调用loadGoods函数重新加载第一页数据 this.loadGoods().then(() => { console.log('刷新商品列表完成'); // 调用调试函数检查创建时间字段 this.debugCreatedAtFields(); }).catch(err => { console.error('刷新商品列表失败:', err); }); }); }, onShow() { console.log('页面显示,开始重新加载数据 - 使用分页加载') // 确保用户身份被设置为买家 const userId = wx.getStorageSync('userId'); if (userId) { // 更新用户类型 let users = wx.getStorageSync('users'); if (typeof users !== 'object' || users === null) { users = {}; } if (!users[userId]) { users[userId] = {}; } users[userId].type = 'buyer'; wx.setStorageSync('users', users); // 更新标签 let tags = wx.getStorageSync('tags'); if (typeof tags !== 'object' || tags === null) { tags = {}; } tags[userId] = tags[userId] || []; tags[userId] = tags[userId].filter(tag => !tag.startsWith('身份:')); tags[userId].push(`身份:buyer`); wx.setStorageSync('tags', tags); } // ✅ 修改:重置分页状态并清空数据 this.setData({ page: 1, hasMoreData: true, goods: [], filteredGoods: [], loadingMore: false }, () => { // 调用loadGoods函数加载第一页数据 this.loadGoods().then((result) => { console.log('onShow加载商品数据完成'); // 记录浏览行为 this.recordBehavior('browse', 'goods'); }).catch(err => { console.error('onShow加载商品数据失败:', err); // ✅ 修改:错误处理 - 使用本地数据作为后备,但也要支持分页 this.fallbackToLocalStorageWithPagination(); this.recordBehavior('browse', 'goods'); }); }); // 更新自定义tabBar状态 if (typeof this.getTabBar === 'function' && this.getTabBar()) { this.getTabBar().setData({ selected: 1 }); } // 更新全局tab状态 const app = getApp(); app.updateCurrentTab('buyer'); }, // 带分页的本地存储回退函数 fallbackToLocalStorageWithPagination() { const localGoods = wx.getStorageSync('goods') || []; const reservedGoodsIds = wx.getStorageSync('reservedGoodsIds') || []; const { page, pageSize } = this.data; // ✅ 修改:对本地数据进行分页处理 const startIndex = (page - 1) * pageSize; const endIndex = startIndex + pageSize; const pagedLocalGoods = localGoods.slice(startIndex, endIndex); console.log('本地存储分页信息:', { 当前页码: page, 每页大小: pageSize, 起始索引: startIndex, 结束索引: endIndex, 分页后商品数量: pagedLocalGoods.length, 本地总商品数量: localGoods.length }); // 为本地商品添加是否已预约的标志和格式化毛重 const goodsWithReservedStatus = pagedLocalGoods.map(item => { // 增强的预约人数计算逻辑 const selectedValue = item.selected; const reservedCountValue = item.reservedCount; const reservationCountValue = item.reservationCount; const finalReservationCount = selectedValue !== undefined && selectedValue !== null ? selectedValue : (reservedCountValue !== undefined && reservedCountValue !== null ? reservedCountValue : (reservationCountValue || 0)); return { ...item, displayGrossWeight: formatGrossWeight(item.grossWeight, item.weight), isReserved: reservedGoodsIds.some(id => String(id) === String(item.id) || String(id) === String(item.productId) ), reservedCount: finalReservationCount, currentImageIndex: item.currentImageIndex || 0 }; }); // ✅ 修改:判断是否还有更多本地数据 const hasMoreLocalData = endIndex < localGoods.length; const nextPage = page + 1; console.log('本地数据分页状态:', { 是否有更多数据: hasMoreLocalData, 下一页码: nextPage, 本地数据总数: localGoods.length }); // 更新页面状态 this.setData({ goods: goodsWithReservedStatus, filteredGoods: goodsWithReservedStatus, reservedGoodsIds: reservedGoodsIds, page: nextPage, // 更新页码 hasMoreData: hasMoreLocalData, // 根据本地数据判断是否还有更多 loadingMore: false }); }, // 下拉刷新处理函数 onPullDownRefresh() { console.log('触发下拉刷新,重置分页状态并重新加载商品数据'); const openid = wx.getStorageSync('openid'); // 检查openid是否存在,但不再显示登录提示 if (!openid) { console.warn('openid不存在,使用本地数据或空列表'); } // ✅ 修改:重置分页状态 this.setData({ page: 1, hasMoreData: true, loadingMore: false, goods: [], filteredGoods: [] }, () => { // 无论是否有openid,都尝试加载商品数据 this.loadGoods().then((result) => { console.log('下拉刷新加载商品数据完成'); // 加载完成后停止下拉刷新动画 wx.stopPullDownRefresh(); console.log('===== 下拉刷新动画停止 ======'); }).catch(err => { console.error('下拉刷新加载商品失败:', err); // ✅ 修改:错误处理 - 使用带分页的本地数据回退 this.fallbackToLocalStorageWithPagination(); // 不显示提示,只记录日志 console.log('已使用缓存数据'); // 出错时也要停止下拉刷新动画 wx.stopPullDownRefresh(); console.log('===== 下拉刷新动画停止 ======'); }); }); }, // 加载货源数据(为了兼容性添加的函数) loadSupplies() { console.log('调用loadSupplies函数 - 重定向到onPullDownRefresh') this.onPullDownRefresh(); }, // 从服务器加载货源数据(为了兼容性添加的函数) loadSuppliesFromServer() { console.log('调用loadSuppliesFromServer函数 - 重定向到API.getProductList') return new Promise((resolve, reject) => { const openid = wx.getStorageSync('openid'); console.log('loadSuppliesFromServer - openid:', openid); // 不再因为没有openid而阻止加载数据,允许未登录用户查看商品 if (!openid) { console.warn('openid不存在,将尝试加载公开商品数据'); } const reservedGoodsIds = wx.getStorageSync('reservedGoodsIds') || []; // ✅ 修改:添加分页参数 const { pageSize } = this.data; API.getProductList('published', { viewMode: 'shopping', page: 1, // 第一页 pageSize: pageSize // 使用配置的页面大小 }) .then(res => { console.log('loadSuppliesFromServer - 获取商品列表成功:', res); if (res.success && res.products) { // 将服务器返回的商品数据转换为需要的格式 const goods = res.products.map(product => { // 处理grossWeight为null或无效的情况 const grossWeightValue = product.grossWeight !== null && product.grossWeight !== undefined ? product.grossWeight : ''; // 计算预约人数,增强逻辑确保能正确处理各种情况 let reservedCount = 0; if (product.selected !== undefined && product.selected !== null) { reservedCount = product.selected; } else if (product.reservedCount !== undefined && product.reservedCount !== null) { reservedCount = product.reservedCount; } else if (product.reservationCount !== undefined && product.reservationCount !== null) { reservedCount = product.reservationCount; } return { id: String(product.id), // 确保ID为字符串类型 productId: String(product.productId || product.id), // 添加productId字段并确保为字符串类型 name: product.productName, // 品种 productName: product.productName, // 确保包含productName字段 price: product.price, minOrder: product.quantity, yolk: product.yolk, spec: product.specification, region: product.region || '', // 【新增】添加地区字段 grossWeight: grossWeightValue, // 确保不为null displayGrossWeight: formatGrossWeight(grossWeightValue, product.weight), seller: product.seller && product.seller.nickName ? product.seller.nickName : '未知卖家', status: product.status || 'published', imageUrls: product.imageUrls || [], reservedCount: reservedCount, createdAt: product.created_at || product.createTime || null, isReserved: reservedGoodsIds.some(id => String(id) === String(product.id) || String(id) === String(product.productId) ), currentImageIndex: 0 }; }); // 过滤掉hidden状态的商品 const filteredGoods = goods.filter(item => { const itemStatus = (item.status || '').toLowerCase(); return itemStatus !== 'hidden'; }); console.log('loadSuppliesFromServer过滤后商品数量:', filteredGoods.length, '原始商品数量:', goods.length); // ✅ 修改:保存到本地存储(分页数据) wx.setStorageSync('goods', filteredGoods); wx.setStorageSync('goodsTimestamp', Date.now()); // 更新页面数据 this.setData({ goods: filteredGoods, filteredGoods: filteredGoods, forceUpdateTime: Date.now(), goodsListKey: Date.now(), reservedGoodsIds: reservedGoodsIds, // ✅ 修改:更新分页状态 page: 2, // 加载第一页后,下一页是第2页 hasMoreData: res.totalPages > 1, // 根据总页数判断是否有更多数据 totalGoods: res.total || 0, totalPages: res.totalPages || 1 }); // 记录浏览行为 this.recordBehavior('browse', 'goods'); resolve({ success: true, products: filteredGoods }); } else { console.error('获取商品列表失败:', res); // 如果获取失败,使用本地缓存的数据 this.fallbackToLocalStorage(); resolve({ success: false }); } }) .catch(err => { console.error('获取商品列表失败:', err); // 错误处理:使用本地数据 this.fallbackToLocalStorage(); reject(err); }); }); }, // 加载商品列表 - 修复分页重复问题 loadGoods(isLoadMore = false) { const openid = wx.getStorageSync('openid'); console.log('loadGoods - openid:', openid); // 不再因为没有openid而返回空列表,允许未登录用户查看商品 if (!openid) { console.warn('openid不存在,将尝试加载公开商品数据或本地缓存'); } // 如果是加载更多且已经没有更多数据,则直接返回 if (isLoadMore && !this.data.hasMoreData) { console.log('没有更多数据可加载'); return Promise.resolve(); } // 如果是加载更多且正在加载中,则直接返回 if (isLoadMore && this.data.loadingMore) { console.log('正在加载中,请稍后再试'); return Promise.resolve(); } // ✅ 修复:确定当前请求的页码和页面大小 let currentPage; let currentPageSize = this.data.pageSize; // 使用配置的页面大小 if (isLoadMore) { // 加载更多时使用当前页码 currentPage = this.data.page; } else { // 刷新或首次加载时重置为第1页 currentPage = 1; } console.log('分页请求参数:', { 当前页码: currentPage, 每页大小: currentPageSize, 加载更多: isLoadMore }); // 设置加载中状态 if (isLoadMore) { this.setData({ loadingMore: true }); } // 记录请求开始时间,用于性能监控 const requestStartTime = Date.now(); // 添加时间戳参数防止请求缓存 const timestamp = new Date().getTime(); // 添加参数检查 if (!API || typeof API.getProductList !== 'function') { console.error('API.getProductList 方法不存在'); // 如果API不可用,尝试使用本地缓存数据 this.fallbackToLocalStorageWithPagination(); return Promise.reject(new Error('API不可用')); } console.log('准备调用API.getProductList,无论是否登录都尝试获取公开商品'); return API.getProductList('published', { timestamp: timestamp, viewMode: 'shopping', page: currentPage, pageSize: currentPageSize, // 增加搜索关键词参数 keyword: this.data.searchKeyword, category: this.data.selectedCategory === '全部' ? '' : this.data.selectedCategory }) .then(res => { // 记录请求结束时间和耗时 const requestEndTime = Date.now(); console.log(`API请求耗时: ${requestEndTime - requestStartTime}ms`); wx.hideLoading(); console.log('从服务器获取商品列表成功:', res) if (res.success && res.products) { console.log(`从服务器获取到 ${res.products.length} 个商品`); // ✅ 修复:使用实际返回的商品数量进行计算 const pagedProducts = res.products; const totalGoods = res.total || 0; const totalPages = res.totalPages || Math.ceil(totalGoods / currentPageSize); console.log('分页信息:', { 请求页码: currentPage, 请求每页大小: currentPageSize, 实际返回商品数量: pagedProducts.length, 总商品数量: totalGoods, 计算总页数: totalPages, 服务器返回总页数: res.totalPages }); // ✅ 修复:如果返回的商品数量为0,说明没有更多数据 if (pagedProducts.length === 0) { console.log('服务器返回空数据,没有更多商品'); this.setData({ hasMoreData: false, loadingMore: false }); return { success: true, hasMoreData: false }; } // 从本地存储获取已预约商品ID列表 const reservedGoodsIds = wx.getStorageSync('reservedGoodsIds') || [] // 将服务器返回的商品数据转换为本地需要的格式 const newGoods = pagedProducts.map(product => { // 处理grossWeight为null或无效的情况,返回空字符串以支持文字输入 const grossWeightValue = product.grossWeight !== null && product.grossWeight !== undefined ? product.grossWeight : ''; // 确保商品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)); return { id: productIdStr, productId: productIdStr, name: product.productName, price: product.price, minOrder: product.quantity, yolk: product.yolk, spec: product.specification, region: product.region || '', // 【新增】添加地区字段 grossWeight: grossWeightValue, displayGrossWeight: formatGrossWeight(grossWeightValue, product.weight), seller: product.seller && product.seller.nickName ? product.seller.nickName : '未知卖家', status: product.status || 'published', imageUrls: product.imageUrls || [], createdAt: product.created_at || product.createTime || null, reservedCount: finalReservationCount, product_contact: product.product_contact || '', // 【新增】添加联系人字段 contact_phone: product.contact_phone || '', // 【新增】添加联系人电话字段 debugInfo: { originalSelected: selectedValue, originalReservedCount: reservedCountValue, originalReservationCount: reservationCountValue }, isReserved: reservedGoodsIds.some(id => String(id) === productIdStr || String(id) === String(product.id) ), currentImageIndex: 0 }; }); // 过滤掉hidden状态的商品 const filteredNewGoods = newGoods.filter(item => { const itemStatus = (item.status || '').toLowerCase(); return itemStatus !== 'hidden'; }); console.log('过滤后商品数量:', filteredNewGoods.length, '原始商品数量:', newGoods.length); // ✅ 修复:数据处理逻辑 - 根据是否是加载更多决定数据合并方式 let updatedGoods = []; let updatedFilteredGoods = []; if (isLoadMore) { // 加载更多:合并数据,但要去重 const existingIds = new Set(this.data.goods.map(item => item.id)); const uniqueNewGoods = filteredNewGoods.filter(item => !existingIds.has(item.id)); updatedGoods = [...this.data.goods, ...uniqueNewGoods]; updatedFilteredGoods = [...this.data.filteredGoods, ...uniqueNewGoods]; console.log('去重信息:', { 新数据数量: filteredNewGoods.length, 去重后数量: uniqueNewGoods.length, 重复数量: filteredNewGoods.length - uniqueNewGoods.length }); } else { // 刷新:替换数据 updatedGoods = filteredNewGoods; updatedFilteredGoods = filteredNewGoods; } // ✅ 修复:准确判断是否还有更多数据 const hasMoreData = currentPage < totalPages && filteredNewGoods.length > 0; const nextPage = currentPage + 1; console.log('分页状态:', { 当前页商品数: filteredNewGoods.length, 更新后总数: updatedGoods.length, 总商品数: totalGoods, 当前页码: currentPage, 下一页码: nextPage, 总页数: totalPages, 是否有更多数据: hasMoreData }); // 更新页面状态 this.setData({ goods: updatedGoods, filteredGoods: updatedFilteredGoods, reservedGoodsIds: reservedGoodsIds, page: nextPage, // 更新为下一页 hasMoreData: hasMoreData, loadingMore: false, totalGoods: totalGoods, totalPages: totalPages }, () => { console.log('页面数据更新完成'); // 调用调试函数检查创建时间字段 this.debugCreatedAtFields(); }); // 记录浏览行为 this.recordBehavior('browse', 'goods') return { success: true, hasMoreData }; } else { console.error('获取商品列表失败:', res); // 更新加载状态 this.setData({ loadingMore: false }); // 如果获取失败,使用本地缓存的数据 this.fallbackToLocalStorage(); return { success: false }; } }) .catch(err => { console.error('获取商品列表失败:', err) // 更新加载状态 this.setData({ loadingMore: false }); // 错误处理:使用本地数据 this.fallbackToLocalStorage(); return Promise.reject(err); }) }, // 上拉加载更多 onReachBottom() { console.log('触发上拉加载更多,当前页码:', this.data.page, '是否有更多数据:', this.data.hasMoreData); if (this.data.hasMoreData && !this.data.loadingMore) { this.loadGoods(true).then(result => { if (result && result.success) { console.log('上拉加载更多成功'); } }).catch(err => { console.error('上拉加载更多失败:', err); wx.showToast({ title: '加载失败,请重试', icon: 'none', duration: 1500 }); }); } else { console.log('没有更多数据或正在加载中'); if (!this.data.hasMoreData) { wx.showToast({ title: '没有更多商品了', icon: 'none', duration: 1500 }); } } }, // 预加载下一页数据 - 优化版本 preloadNextPage() { // 当滚动到距离底部一定距离时,预加载下一页数据 const { hasMoreData, loadingMore } = this.data; if (!hasMoreData || loadingMore) return; console.log('预加载下一页数据'); // 添加延时,避免频繁触发预加载 setTimeout(() => { // 再次检查状态,确保没有被其他操作更改 if (!this.data.loadingMore && this.data.hasMoreData) { this.loadGoods(true); } }, 1000); // 增加延迟时间到1秒,减少重复加载 }, // 监听滚动事件,实现预加载 onScroll(e) { const { scrollHeight, scrollTop, clientHeight } = e.detail; const threshold = 800; // 增加阈值到800rpx,提前触发预加载 // 计算当前滚动位置距离底部的距离 const distanceToBottom = scrollHeight - scrollTop - clientHeight; // 当距离底部小于阈值且有更多数据时,触发预加载 if (distanceToBottom < threshold && this.data.hasMoreData && !this.data.loadingMore) { this.preloadNextPage(); } }, // 回退到本地存储数据 - 修改为支持分页 fallbackToLocalStorage() { const localGoods = wx.getStorageSync('goods') || []; const reservedGoodsIds = wx.getStorageSync('reservedGoodsIds') || []; const { page, pageSize } = this.data; // ✅ 修改:对本地数据进行分页处理 const startIndex = (page - 1) * pageSize; const endIndex = startIndex + pageSize; const pagedLocalGoods = localGoods.slice(startIndex, endIndex); console.log('本地存储回退分页信息:', { 当前页码: page, 每页大小: pageSize, 分页后商品数量: pagedLocalGoods.length, 本地总商品数量: localGoods.length }); // 为本地商品添加是否已预约的标志和格式化毛重 const goodsWithReservedStatus = pagedLocalGoods.map(item => { const selectedValue = item.selected; const reservedCountValue = item.reservedCount; const reservationCountValue = item.reservationCount; const finalReservationCount = selectedValue !== undefined && selectedValue !== null ? selectedValue : (reservedCountValue !== undefined && reservedCountValue !== null ? reservedCountValue : (reservationCountValue || 0)); return { ...item, displayGrossWeight: formatGrossWeight(item.grossWeight, item.weight), isReserved: reservedGoodsIds.some(id => String(id) === String(item.id) || String(id) === String(item.productId) ), reservedCount: finalReservationCount, currentImageIndex: item.currentImageIndex || 0, createdAt: item.createdAt || item.created_at || item.createTime || null }; }); // 过滤掉hidden状态的商品 const filteredGoods = goodsWithReservedStatus.filter(item => { const itemStatus = (item.status || '').toLowerCase(); return itemStatus !== 'hidden'; }); // ✅ 修改:判断是否还有更多本地数据 const hasMoreLocalData = endIndex < localGoods.length; console.log('本地存储回退时分页商品数量:', filteredGoods.length, '本地总商品数量:', localGoods.length); // 更新页面状态 this.setData({ goods: filteredGoods, filteredGoods: filteredGoods, forceUpdateTime: Date.now(), // ✅ 修改:回退时也更新分页状态 hasMoreData: hasMoreLocalData }); }, // 清除搜索 clearSearch() { this.setData({ searchKeyword: '', page: 1, hasMoreData: true, selectedCategory: '全部' }, () => { // 重新加载第一页数据 this.loadGoods().then(() => { console.log('清除搜索后数据加载完成'); }).catch(err => { console.error('清除搜索后数据加载失败:', err); this.fallbackToLocalStorageWithPagination(); }); }); }, // 搜索输入处理 onSearchInput(e) { const searchKeyword = e.detail.value this.setData({ searchKeyword: searchKeyword }) const { goods } = this.data // 如果搜索词为空,重置分页并重新加载所有数据 if (!searchKeyword.trim()) { console.log('搜索词为空,重置分页状态并重新加载数据'); this.setData({ page: 1, hasMoreData: true, selectedCategory: '全部' }, () => { // 重新加载第一页数据 this.loadGoods().then(() => { console.log('重置搜索后数据加载完成'); }).catch(err => { console.error('重置搜索后数据加载失败:', err); this.fallbackToLocalStorageWithPagination(); }); }); return } // ✅ 修改:只搜索商品名称字段(对应数据库product表的productName字段) const filtered = goods.filter(item => item.name && item.name.toLowerCase().includes(searchKeyword.toLowerCase()) ) this.setData({ filteredGoods: filtered }) }, // 搜索商品 searchGoods() { const { searchKeyword, goods, totalGoods } = this.data // 如果搜索词为空,重置分页并重新加载 if (!searchKeyword.trim()) { console.log('搜索词为空,重置分页状态并重新加载数据'); this.setData({ page: 1, hasMoreData: true, selectedCategory: '全部' }, () => { this.loadGoods().then(() => { console.log('搜索重置后数据加载完成'); }).catch(err => { console.error('搜索重置后数据加载失败:', err); this.fallbackToLocalStorageWithPagination(); }); }); return } // ✅ 添加:搜索范围提示 if (goods.length < totalGoods) { wx.showToast({ title: `正在${goods.length}个已加载商品中搜索`, icon: 'none', duration: 1500 }); } // ✅ 修改:只搜索商品名称字段(对应数据库product表的productName字段) const filtered = goods.filter(item => item.name && item.name.toLowerCase().includes(searchKeyword.toLowerCase()) ) this.setData({ filteredGoods: filtered }) }, // 调试商品数据中的创建时间字段 debugCreatedAtFields() { console.log('=== 商品数据创建时间调试 ==='); if (this.data.goods && this.data.goods.length > 0) { const firstGoods = this.data.goods.slice(0, 3); // 只检查前3个商品 firstGoods.forEach((item, index) => { console.log(`商品${index + 1}:`); console.log(' 原始数据:', JSON.stringify(item, null, 2)); console.log(' createdAt:', item.createdAt); console.log(' created_at:', item.created_at); console.log(' createTime:', item.createTime); }); } }, // 清除本地缓存并重新加载数据 clearCacheAndReload() { console.log('清除本地缓存并重新加载数据...'); wx.removeStorageSync('goods'); wx.removeStorageSync('reservedGoodsIds'); // ✅ 修改:重置分页状态后重新加载 this.setData({ page: 1, hasMoreData: true, goods: [], filteredGoods: [], loadingMore: false }, () => { this.loadGoods(); }); }, // 切换图片 swiperChange(e) { const current = e.detail.current const itemId = e.currentTarget.dataset.itemId // 更新对应商品项的currentImageIndex this.setData({ [`filteredGoods[${itemId}].currentImageIndex`]: current }) }, // 预览图片 previewImage(e) { const { urls, index } = e.currentTarget.dataset this.setData({ showImagePreview: true, previewImageUrls: urls, previewImageIndex: parseInt(index) }) }, // 预览图片 previewImage(e) { const { urls, index } = e.currentTarget.dataset this.setData({ showImagePreview: true, previewImageUrls: urls, previewImageIndex: parseInt(index) }) }, // 关闭图片预览 closeImagePreview() { this.setData({ showImagePreview: false }) this.resetZoom() }, // 重置缩放状态 resetZoom() { this.setData({ scale: 1, lastScale: 1, offsetX: 0, offsetY: 0, initialTouch: null }) }, // 处理图片点击事件(单击/双击判断) handleImageTap(e) { const currentTime = Date.now() const lastTapTime = this.data.lastTapTime // 判断是否为双击(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) }) } }, // 处理触摸开始事件 handleTouchStart(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) { 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) { this.setData({ isScaling: false, lastScale: this.data.scale, initialTouch: null }) }, // 计算两点之间的距离 calculateDistance(touch1, touch2) { const dx = touch2.clientX - touch1.clientX const dy = touch2.clientY - touch1.clientY return Math.sqrt(dx * dx + dy * dy) }, // 切换预览图片 onPreviewImageChange(e) { this.setData({ previewImageIndex: e.detail.current }) // 切换图片时重置缩放状态 this.resetZoom() }, // 显示联系提示弹窗 showContactToast() { this.setData({ showCustomToast: true }) // 3秒后自动隐藏 setTimeout(() => { this.setData({ showCustomToast: false }) }, 800) }, // 微信登录 doWechatLogin: function (userType) { console.log('开始微信登录,用户类型:', userType); // 显示加载提示 wx.showLoading({ title: '登录中...', mask: true }); // 调用微信登录接口 wx.login({ success: (res) => { if (res.code) { console.log('获取登录code成功:', res.code); // 保存登录code到本地 wx.setStorageSync('loginCode', res.code); // 获取openid和session_key this.getOpenid(res.code, userType); } else { console.error('登录失败:', res.errMsg); wx.hideLoading(); wx.showToast({ title: '登录失败,请重试', icon: 'none' }); } }, fail: (err) => { console.error('调用login接口失败:', err); wx.hideLoading(); wx.showToast({ title: '网络错误,请重试', icon: 'none' }); } }); }, // 获取openid getOpenid: function (code, userType) { console.log('获取openid,用户类型:', userType); API.getOpenid(code) .then(res => { console.log('获取openid成功:', res); if (res.success) { // 保存openid到本地 wx.setStorageSync('openid', res.data.openid); wx.setStorageSync('session_key', res.data.session_key); // 验证登录状态并获取用户信息 this.validateLoginAndGetUserInfo(userType); } else { console.error('获取openid失败:', res.message); wx.hideLoading(); wx.showToast({ title: '登录失败,请重试', icon: 'none' }); } }) .catch(err => { console.error('获取openid异常:', err); wx.hideLoading(); wx.showToast({ title: '网络错误,请重试', icon: 'none' }); }); }, // 验证登录状态并获取用户信息 validateLoginAndGetUserInfo: function (userType) { console.log('验证登录状态,用户类型:', userType); const openid = wx.getStorageSync('openid'); if (!openid) { console.error('openid不存在'); wx.hideLoading(); return; } API.getUserInfo(openid) .then(res => { console.log('获取用户信息结果:', res); wx.hideLoading(); if (res.success) { // 检查用户是否已存在 if (res.data && res.data.id) { // 用户已存在,保存用户信息 const userInfo = { userId: res.data.id, openid: openid, nickname: res.data.nickname || '', avatarUrl: res.data.avatar || '', type: res.data.type }; // 保存用户信息到本地 wx.setStorageSync('userInfo', userInfo); wx.setStorageSync('userId', res.data.id); // 显示成功提示 wx.showToast({ title: '登录成功', icon: 'success' }); // 登录成功后,重新执行"我想要"操作 this.handleLoginSuccess(); } else { // 用户不存在,需要获取用户信息授权 this.processUserInfoAuth(userType); } } else { // 获取用户信息失败,可能是新用户 console.log('用户可能是新用户,开始授权流程'); this.processUserInfoAuth(userType); } }) .catch(err => { console.error('验证登录状态异常:', err); wx.hideLoading(); // 发生异常,尝试获取用户信息授权 this.processUserInfoAuth(userType); }); }, // 处理用户信息授权 processUserInfoAuth: function (userType) { console.log('处理用户信息授权,用户类型:', userType); // 存储待设置的用户类型 this.setData({ pendingUserType: userType, showAuthModal: true }); }, // 处理登录成功 handleLoginSuccess: function () { console.log('登录成功,检查是否有待执行的操作'); // 登录成功后,重新执行"我想要"操作 if (this.data.currentGoodsId) { console.log('有未完成的操作,执行预约'); setTimeout(() => { const goodsItem = this.findGoodsItemById(String(this.data.currentGoodsId)); if (goodsItem) { // 重新调用onClickWant,但这次用户已登录 this.onClickWant({ currentTarget: { dataset: { id: this.data.currentGoodsId } } }); } }, 500); } }, // 记录用户行为 // 显示一键登录弹窗 showOneKeyLogin: function () { console.log('显示一键登录弹窗'); this.setData({ showAuthModal: false, showOneKeyLoginModal: true }); }, // 关闭授权弹窗 closeAuthModal: function () { console.log('关闭授权弹窗'); this.setData({ showAuthModal: false }); }, // 关闭一键登录弹窗 closeOneKeyLoginModal: function () { console.log('关闭一键登录弹窗'); this.setData({ showOneKeyLoginModal: false }); }, // 选择头像 onChooseAvatar: function (e) { console.log('选择头像:', e); const { avatarUrl } = e.detail; this.setData({ avatarUrl }); }, // 获取用户名 getUserName: function (e) { console.log('获取用户名:', e); const { nickname } = e.detail.value; if (!nickname || nickname.trim() === '') { wx.showToast({ title: '昵称不能为空', icon: 'none' }); return; } const userInfo = { nickname: nickname.trim(), avatarUrl: this.data.avatarUrl }; this.saveUserInfo(userInfo, this.data.pendingUserType); }, // 取消用户信息表单 cancelUserInfoForm: function () { console.log('取消用户信息表单'); this.setData({ showUserInfoForm: false }); }, // 显示商品详情 showGoodsDetail: function (e) { // 检查用户是否登录 const openid = wx.getStorageSync('openid'); const userId = wx.getStorageSync('userId'); if (!openid || !userId) { console.log('用户未登录,显示登录提示和弹窗'); // 提示登录后才可查看详情 wx.showToast({ title: '登录后才可查看详情', icon: 'none', duration: 1500 }); // 显示登录弹窗 setTimeout(() => { this.showOneKeyLogin(); }); return; } const goodsItem = e.currentTarget.dataset.item; this.setData({ currentGoodsDetail: goodsItem, showGoodsDetail: true }); // 隐藏底部导航栏 - 通过更新全局数据 const app = getApp(); if (app && app.globalData) { app.globalData.showTabBar = false; } // 同时尝试直接更新tabBar的选中状态 if (typeof this.getTabBar === 'function' && this.getTabBar()) { const tabBar = this.getTabBar(); if (tabBar.setData) { tabBar.setData({ show: false }); } } // 调用后端API执行商品联系人更新 console.log('开始调用API.updateProductContacts()'); API.updateProductContacts().then(function(res) { console.log('商品联系人更新成功:', res); }).catch(function(err) { console.error('商品联系人更新失败:', err); } ); }, // 关闭商品详情 closeGoodsDetail: function () { this.setData({ showGoodsDetail: false, currentGoodsDetail: {} }); // 显示底部导航栏 - 通过更新全局数据 const app = getApp(); if (app && app.globalData) { app.globalData.showTabBar = true; } // 同时尝试直接更新tabBar的选中状态 if (typeof this.getTabBar === 'function' && this.getTabBar()) { const tabBar = this.getTabBar(); if (tabBar.setData) { tabBar.setData({ show: true }); } } }, // 在详情弹窗中点击"我想要"按钮 onClickWantInDetail: function (e) { const goodsId = e.currentTarget.dataset.id; // 先关闭详情弹窗 this.closeGoodsDetail(); // 然后调用原来的"我想要"方法 this.onClickWant({ currentTarget: { dataset: { id: goodsId } } }); }, // 获取手机号并登录 onGetPhoneNumber: function (e) { console.log('获取手机号:', e); if (e.detail.errMsg !== 'getPhoneNumber:ok') { console.log('用户拒绝授权手机号'); this.setData({ showOneKeyLoginModal: false }); return; } const encryptedData = e.detail.encryptedData; const iv = e.detail.iv; // 调用API进行登录 API.login(encryptedData, iv) .then(res => { console.log('登录成功:', res); if (res.success) { // 保存登录信息 wx.setStorageSync('openid', res.data.openid); wx.setStorageSync('userId', res.data.userId); wx.setStorageSync('sessionKey', res.data.sessionKey || ''); // 登录成功后立即获取用户微信名称 wx.getUserProfile({ desc: '用于完善会员资料', success: (userProfile) => { console.log('获取用户信息成功:', userProfile); // 构建用户信息 const userInfo = { openid: res.data.openid, userId: res.data.userId, nickname: userProfile.userInfo.nickName, avatarUrl: userProfile.userInfo.avatarUrl, type: this.data.pendingUserType }; // 保存用户信息到本地存储 wx.setStorageSync('userInfo', userInfo); // 上传用户信息到服务器 API.uploadUserInfo(userInfo) .then(uploadRes => { console.log('用户信息上传成功:', uploadRes); // 关闭登录弹窗 this.setData({ showOneKeyLoginModal: false }); // 登录成功后,重新执行"我想要"操作 this.handleLoginSuccess(); }) .catch(uploadErr => { console.error('用户信息上传失败:', uploadErr); // 即使上传失败,也关闭登录弹窗 this.setData({ showOneKeyLoginModal: false }); // 登录成功后,重新执行"我想要"操作 this.handleLoginSuccess(); }); }, fail: (profileErr) => { console.error('获取用户信息失败:', profileErr); // 即使获取用户信息失败,也构建基本用户信息对象 const userInfo = { openid: res.data.openid, userId: res.data.userId, nickname: '微信用户', avatarUrl: '/images/default-avatar.png', type: this.data.pendingUserType }; // 保存用户信息到本地存储 wx.setStorageSync('userInfo', userInfo); // 关闭登录弹窗 this.setData({ showOneKeyLoginModal: false }); // 登录成功后,重新执行"我想要"操作 this.handleLoginSuccess(); } }); } else { wx.showToast({ title: '登录失败,请重试', icon: 'none' }); this.setData({ showOneKeyLoginModal: false }); } }) .catch(err => { console.error('登录失败:', err); wx.showToast({ title: '网络错误,请重试', icon: 'none' }); this.setData({ showOneKeyLoginModal: false }); }); }, // 保存用户信息 saveUserInfo: function (userInfo, type) { console.log('保存用户信息:', userInfo, '类型:', type); const openid = wx.getStorageSync('openid'); const userId = wx.getStorageSync('userId'); if (!openid || !userId) { wx.showToast({ title: '登录信息已过期,请重新登录', icon: 'none' }); return; } userInfo.userId = userId; userInfo.openid = openid; userInfo.type = type; // 保存到本地存储 wx.setStorageSync('userInfo', userInfo); // 上传到服务器 this.uploadUserInfoToServer(userInfo, userId, type); }, // 上传用户信息到服务器 uploadUserInfoToServer: function (userInfo, userId, type) { console.log('上传用户信息到服务器:', userInfo); API.saveUserInfo(userInfo, type) .then(res => { console.log('上传用户信息成功:', res); this.setData({ showUserInfoForm: false }); // 登录成功后,重新执行"我想要"操作 if (this.data.currentGoodsId) { // 模拟点击"我想要"按钮,使用新的商品ID const goodsItem = this.findGoodsItemById(String(this.data.currentGoodsId)); if (goodsItem) { // 重新调用onClickWant,但这次用户已登录 this.onClickWant({ currentTarget: { dataset: { id: this.data.currentGoodsId } } }); } } }) .catch(err => { console.error('上传用户信息失败:', err); // 即使上传失败,也标记为已登录 this.setData({ showUserInfoForm: false }); // 尝试执行"我想要"操作 if (this.data.currentGoodsId) { const goodsItem = this.findGoodsItemById(String(this.data.currentGoodsId)); if (goodsItem) { // 重新调用onClickWant,但这次用户已登录 this.onClickWant({ currentTarget: { dataset: { id: this.data.currentGoodsId } } }); } } }); }, recordBehavior(behaviorType, targetType, targetId) { try { console.log(`记录行为: ${behaviorType}, ${targetType}, ${targetId || '无ID'}`) // 可以在这里添加更复杂的行为记录逻辑,如发送到服务器等 } catch (error) { console.error('记录行为失败:', error) } }, // 格式化时间为北京时间(UTC+8)并转换为 年-月-日-时:分 格式 formatTimeToBeijing: function (timeValue) { if (!timeValue) { return '未知'; } try { // 创建Date对象 const date = new Date(timeValue); // 检查日期是否有效 if (isNaN(date.getTime())) { return '未知'; } // 使用Date对象的方法直接获取UTC时间,然后加8小时计算北京时间 const utcYear = date.getUTCFullYear(); const utcMonth = date.getUTCMonth(); const utcDate = date.getUTCDate(); const utcHours = date.getUTCHours() + 8; // 直接加8小时 // 创建北京时间Date对象 const beijingTime = new Date(Date.UTC(utcYear, utcMonth, utcDate, utcHours, date.getUTCMinutes())); // 格式化时间,使用连字符分隔 const year = beijingTime.getFullYear(); const month = (beijingTime.getMonth() + 1).toString().padStart(2, '0'); const day = beijingTime.getDate().toString().padStart(2, '0'); const hours = beijingTime.getHours().toString().padStart(2, '0'); const minutes = beijingTime.getMinutes().toString().padStart(2, '0'); // 返回格式:年-月-日-时:分 return `${year}-${month}-${day}-${hours}:${minutes}`; } catch (error) { console.error('北京时间格式化错误:', error); return '未知'; } }, // 拨打电话功能 makePhoneCall(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' }); } }); } } }); } } });