diff --git a/custom-tab-bar/index.wxss b/custom-tab-bar/index.wxss index 2027b4b..673f7f4 100644 --- a/custom-tab-bar/index.wxss +++ b/custom-tab-bar/index.wxss @@ -72,26 +72,6 @@ position: relative; } -/* 未读标记样式 */ -.tab-bar-badge { - position: absolute; - top: -5px; - right: -5px; - min-width: 16px; - height: 16px; - padding: 0 4px; - border-radius: 8px; - background-color: #ff4757; - color: white; - font-size: 10px; - line-height: 16px; - text-align: center; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - - .tab-bar-text { font-size: 28rpx; diff --git a/images/logo.svg b/images/logo.svg deleted file mode 100644 index 9e92c4c..0000000 --- a/images/logo.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/images/你有好蛋.png b/images/你有好蛋.png deleted file mode 100644 index 7fd1071..0000000 Binary files a/images/你有好蛋.png and /dev/null differ diff --git a/images/生成鸡蛋贸易平台图片.png b/images/生成鸡蛋贸易平台图片.png deleted file mode 100644 index c9f0212..0000000 Binary files a/images/生成鸡蛋贸易平台图片.png and /dev/null differ diff --git a/pages/buyer/index.js b/pages/buyer/index.js index 99297b5..dbb8105 100644 --- a/pages/buyer/index.js +++ b/pages/buyer/index.js @@ -145,12 +145,11 @@ Page({ // 检查用户登录状态 const openid = wx.getStorageSync('openid'); - const userInfo = wx.getStorageSync('userInfo'); const userId = wx.getStorageSync('userId'); - console.log('检查用户授权状态 - openid:', !!openid, 'userInfo:', !!userInfo, 'userId:', !!userId); + console.log('检查用户授权状态 - openid:', !!openid, 'userId:', !!userId); - if (!openid || !userId || !userInfo) { + if (!openid || !userId) { console.log('用户未登录,显示一键登录弹窗'); // 显示一键登录弹窗,让用户确认是否要登录 this.showOneKeyLogin(); @@ -1250,42 +1249,27 @@ Page({ // 预览图片 previewImage(e) { // 登录验证 - const userInfo = wx.getStorageSync('userInfo') || null - const userId = wx.getStorageSync('userId') || null - if (!userInfo || !userId) { - // 未登录,显示授权登录弹窗 - this.setData({ - showAuthModal: true, - pendingUserType: 'buyer' - }) - return + const openid = wx.getStorageSync('openid'); + const userId = wx.getStorageSync('userId'); + + if (!openid || !userId) { + console.log('用户未登录,直接显示授权登录弹窗'); + // 直接显示授权登录弹窗 + this.showOneKeyLogin(); + return; } // 已登录,执行图片预览 - const { urls, index } = e.currentTarget.dataset - this.setData({ - showImagePreview: true, - previewImageUrls: urls, - previewImageIndex: parseInt(index) - }) - }, - - // 预览图片 - previewImage(e) { - // 登录验证 - const userInfo = wx.getStorageSync('userInfo') || null - const userId = wx.getStorageSync('userId') || null - if (!userInfo || !userId) { - // 未登录,显示授权登录弹窗 - this.setData({ - showAuthModal: true, - pendingUserType: 'buyer' - }) - return + const { item, index } = e.currentTarget.dataset; + console.log('预览图片参数:', item, index); + + // 从item中获取图片URL列表 + const urls = item.imageUrls || []; + if (urls.length === 0) { + console.error('没有图片可预览'); + return; } - // 已登录,执行图片预览 - const { urls, index } = e.currentTarget.dataset this.setData({ showImagePreview: true, previewImageUrls: urls, @@ -1614,6 +1598,9 @@ Page({ } }, 500); } + + // 登录成功后,加载用户收藏列表,更新商品收藏状态 + this.loadUserFavorites(); }, // 记录用户行为 @@ -1687,17 +1674,9 @@ Page({ const userId = wx.getStorageSync('userId'); if (!openid || !userId) { - console.log('用户未登录,显示登录提示和弹窗'); - // 提示登录后才可查看详情 - wx.showToast({ - title: '登录后才可查看详情', - icon: 'none', - duration: 1500 - }); - // 显示登录弹窗 - setTimeout(() => { - this.showOneKeyLogin(); - }); + console.log('用户未登录,直接显示授权登录弹窗'); + // 直接显示授权登录弹窗 + this.showOneKeyLogin(); return; } @@ -1728,118 +1707,249 @@ Page({ // 获取手机号并登录 - onGetPhoneNumber: function (e) { + async onGetPhoneNumber(e) { console.log('获取手机号:', e); - + + // 首先检查用户是否拒绝授权 if (e.detail.errMsg !== 'getPhoneNumber:ok') { console.log('用户拒绝授权手机号'); + wx.showToast({ + title: '您已拒绝授权,操作已取消', + icon: 'none' + }); 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.showLoading({ + title: '登录中...', + mask: true + }); + + try { + // 引入API服务 + const API = require('../../utils/api.js'); + + // 1. 先执行微信登录获取code + const loginRes = await new Promise((resolve, reject) => { + wx.login({ + success: resolve, + fail: reject + }); + }); + + if (!loginRes.code) { + throw new Error('获取登录code失败'); + } + + console.log('获取登录code成功:', loginRes.code); + + // 2. 使用code换取openid + const openidRes = await API.getOpenid(loginRes.code); + + // 增强版响应处理逻辑,支持多种返回格式 + let openid = null; + let userId = null; + let sessionKey = null; + + // 优先从data字段获取数据 + if (openidRes && openidRes.data && typeof openidRes.data === 'object') { + openid = openidRes.data.openid || openidRes.data.OpenID || null; + userId = openidRes.data.userId || openidRes.data.userid || null; + sessionKey = openidRes.data.session_key || openidRes.data.sessionKey || null; + } + + // 如果data为空或不存在,尝试从响应对象直接获取 + if (!openid && openidRes && typeof openidRes === 'object') { + console.warn('服务器返回格式可能不符合预期,data字段为空或不存在,但尝试从根对象提取信息:', openidRes); + openid = openidRes.openid || openidRes.OpenID || null; + userId = openidRes.userId || openidRes.userid || null; + sessionKey = openidRes.session_key || openidRes.sessionKey || null; + } + + // 检查服务器状态信息 + const isSuccess = openidRes && (openidRes.success === true || openidRes.code === 200); + + if (!openid) { + throw new Error('获取openid失败: ' + (openidRes && openidRes.message ? openidRes.message : '未知错误')); + } + + // 存储openid和session_key + wx.setStorageSync('openid', openid); + if (sessionKey) { + wx.setStorageSync('sessionKey', sessionKey); + } + + // 确保始终使用从服务器获取的正式用户ID,不再生成临时ID + if (userId) { + wx.setStorageSync('userId', userId); + } else { + const app = getApp(); + if (app.globalData.userInfo && app.globalData.userInfo.userId) { + const serverUserId = String(app.globalData.userInfo.userId); + wx.setStorageSync('userId', serverUserId); + userId = serverUserId; + console.log('使用从全局获取的正式用户ID:', serverUserId); + } else { + console.warn('未找到有效的用户ID,请确保用户已授权登录'); + } + } + + console.log('获取openid成功并存储:', openid); + + // 3. 上传手机号加密数据到服务器解密 + const phoneData = { + ...e.detail, + openid: openid, + sessionKey: sessionKey || '' + }; + + console.log('准备上传手机号加密数据到服务器'); + const phoneRes = await API.uploadPhoneNumberData(phoneData); + + // 改进手机号解密结果的处理逻辑 + if (!phoneRes || (!phoneRes.success && !phoneRes.phoneNumber)) { + // 如果服务器返回格式不标准但包含手机号,也接受 + if (!(phoneRes && phoneRes.phoneNumber)) { + throw new Error('获取手机号失败: ' + (phoneRes && phoneRes.message ? phoneRes.message : '未知错误')); + } + } + + // 检查是否有手机号冲突 + const hasPhoneConflict = phoneRes.phoneNumberConflict || false; + const isNewPhone = phoneRes.isNewPhone || true; + const phoneNumber = phoneRes.phoneNumber || null; + + console.log('手机号解密结果:', { + phoneNumber: phoneNumber, + hasPhoneConflict: hasPhoneConflict, + isNewPhone: isNewPhone + }); + + // 4. 获取用户微信名称和头像 + let userProfile = null; + try { + userProfile = await new Promise((resolve, reject) => { wx.getUserProfile({ desc: '用于完善会员资料', - success: (userProfile) => { - console.log('获取用户信息成功:', userProfile); - - // 构建用户信息 - const userInfo = { - openid: res.data.openid, - userId: res.data.userId, - name: userProfile.userInfo.name || 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, - name: '微信用户', - 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' + success: resolve, + fail: reject }); - this.setData({ - showOneKeyLoginModal: false - }); - } - }) - .catch(err => { - console.error('登录失败:', err); + }); + console.log('获取用户信息成功:', userProfile); + } catch (err) { + console.warn('获取用户信息失败:', err); + // 如果获取失败,使用默认值 + } + + // 5. 创建用户信息 + const app = getApp(); + const existingUserInfo = app.globalData.userInfo || wx.getStorageSync('userInfo') || {}; + const userInfo = { + // 优先使用最新获取的微信头像和昵称,如果没有获取到则使用本地存储的 + name: (userProfile ? (userProfile.userInfo.name || userProfile.userInfo.nickName) : existingUserInfo.name) || '微信用户', + avatarUrl: (userProfile ? userProfile.userInfo.avatarUrl : existingUserInfo.avatarUrl) || 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0', + gender: (userProfile ? userProfile.userInfo.gender : existingUserInfo.gender) || 0, + country: (userProfile ? userProfile.userInfo.country : existingUserInfo.country) || '', + province: (userProfile ? userProfile.userInfo.province : existingUserInfo.province) || '', + city: (userProfile ? userProfile.userInfo.city : existingUserInfo.city) || '', + language: (userProfile ? userProfile.userInfo.language : existingUserInfo.language) || 'zh_CN', + phoneNumber: phoneNumber + }; + + // 6. 获取用户类型 + const users = wx.getStorageSync('users') || {}; + let currentUserType = users[userId] && users[userId].type ? users[userId].type : ''; + + // 如果没有用户类型,使用pendingUserType或从全局获取 + if (!currentUserType) { + currentUserType = this.data.pendingUserType || app.globalData.userType || ''; + } + + // 7. 保存用户信息并等待上传完成 + console.log('开始保存用户信息并上传到服务器...'); + await this.uploadUserInfoToServer(userInfo, userId, currentUserType); + console.log('用户信息保存并上传完成'); + + // 更新本地和全局用户信息 + app.globalData.userInfo = userInfo; + wx.setStorageSync('userInfo', userInfo); + + // 确保users存储结构存在 + let usersStorage = wx.getStorageSync('users') || {}; + if (!usersStorage[userId]) { + usersStorage[userId] = {}; + } + + // 保存手机号到users对象中 + usersStorage[userId].phoneNumber = phoneNumber; + usersStorage[userId].type = currentUserType; + wx.setStorageSync('users', usersStorage); + + wx.hideLoading(); + + // 关闭登录弹窗 + this.setData({ + showOneKeyLoginModal: false + }); + + // 登录成功后,重新执行"我想要"操作 + this.handleLoginSuccess(); + + // 根据服务器返回的结果显示不同的提示 + if (hasPhoneConflict) { wx.showToast({ - title: '网络错误,请重试', - icon: 'none' + title: '登录成功,但手机号已被其他账号绑定', + icon: 'none', + duration: 3000 }); - this.setData({ - showOneKeyLoginModal: false + } else { + wx.showToast({ + title: '登录成功,手机号已绑定', + icon: 'success', + duration: 2000 }); + } + + } catch (error) { + wx.hideLoading(); + console.error('登录过程中发生错误:', error); + + // 更具体的错误提示 + let errorMsg = '登录失败,请重试'; + if (error.message.includes('网络')) { + errorMsg = '网络连接失败,请检查网络后重试'; + } else if (error.message.includes('服务器')) { + errorMsg = '服务器连接失败,请稍后重试'; + } else if (error.message.includes('openid')) { + errorMsg = '获取登录信息失败,请重试'; + } else if (error.message.includes('手机号')) { + errorMsg = '获取手机号失败,请重试'; + } + + wx.showToast({ + title: errorMsg, + icon: 'none', + duration: 3000 }); + + // 关闭登录弹窗 + this.setData({ + showOneKeyLoginModal: false + }); + + // 清除可能已经保存的不完整信息 + try { + wx.removeStorageSync('openid'); + wx.removeStorageSync('sessionKey'); + wx.removeStorageSync('userId'); + } catch (e) { + console.error('清除临时登录信息失败:', e); + } + } }, // 保存用户信息 @@ -1869,44 +1979,48 @@ Page({ }, // 上传用户信息到服务器 - uploadUserInfoToServer: function (userInfo, userId, type) { - console.log('上传用户信息到服务器:', userInfo); - - API.saveUserInfo(userInfo, type) - .then(res => { - console.log('上传用户信息成功:', res); - - this.setData({ - showUserInfoForm: false - }); + uploadUserInfoToServer(userInfo, userId, type) { + // 返回Promise以便调用者可以进行错误处理 + return new Promise((resolve, reject) => { + try { + // 引入API服务 + const API = require('../../utils/api.js'); - // 登录成功后,重新执行"我想要"操作 - if (this.data.currentGoodsId) { - // 模拟点击"我想要"按钮,使用新的商品ID - const goodsItem = this.findGoodsItemById(String(this.data.currentGoodsId)); - if (goodsItem) { - // 重新调用onClickWant,但这次用户已登录 - this.onClickWant({ currentTarget: { dataset: { id: this.data.currentGoodsId } } }); - } + // 获取openid + const openid = wx.getStorageSync('openid'); + + // 验证必要参数 + if (!userId || !openid) { + const error = new Error('缺少必要的用户信息'); + console.error('用户信息上传失败:', error); + reject(error); + return; } - }) - .catch(err => { - console.error('上传用户信息失败:', err); - // 即使上传失败,也标记为已登录 - this.setData({ - showUserInfoForm: false + // 构造上传数据(包含所有必要字段,包括phoneNumber和头像URL) + const uploadData = { + userId: userId, + openid: openid, + name: userInfo.name, + avatarUrl: userInfo.avatarUrl, // 添加头像URL字段 + phoneNumber: userInfo.phoneNumber, // 添加phoneNumber字段,满足服务器要求 + type: type, + timestamp: Date.now() + }; + + // 调用API上传用户信息 + API.uploadUserInfo(uploadData).then(res => { + console.log('用户信息上传成功:', res); + resolve(res); + }).catch(err => { + console.error('用户信息上传失败:', err); + reject(err); }); - - // 尝试执行"我想要"操作 - if (this.data.currentGoodsId) { - const goodsItem = this.findGoodsItemById(String(this.data.currentGoodsId)); - if (goodsItem) { - // 重新调用onClickWant,但这次用户已登录 - this.onClickWant({ currentTarget: { dataset: { id: this.data.currentGoodsId } } }); - } - } - }); + } catch (error) { + console.error('上传用户信息时发生异常:', error); + reject(error); + } + }); }, recordBehavior(behaviorType, targetType, targetId) { diff --git a/pages/buyer/index.wxml b/pages/buyer/index.wxml index 44aca3f..7ec3b49 100644 --- a/pages/buyer/index.wxml +++ b/pages/buyer/index.wxml @@ -69,7 +69,7 @@ - 已有{{item.reservedCount || 0}}人收藏 + 已有{{item.reservedCount || 0}}人收藏 @@ -198,4 +198,35 @@ + + + + + + + + + + + + + × + + + \ No newline at end of file diff --git a/pages/favorites/index.js b/pages/favorites/index.js index 3a98797..71c1e62 100644 --- a/pages/favorites/index.js +++ b/pages/favorites/index.js @@ -120,9 +120,26 @@ Page({ loading: true }); - // 获取手机号码 - const phoneNumber = wx.getStorageSync('phoneNumber') || '18482694520'; // 默认使用测试手机号 + // 获取手机号码 - 使用与API.js一致的获取方式 + const users = wx.getStorageSync('users') || {}; + const userId = wx.getStorageSync('userId'); + let phoneNumber = null; + // 尝试从users中获取手机号 + if (userId && users[userId] && users[userId].phoneNumber) { + phoneNumber = users[userId].phoneNumber; + } else { + // 尝试从全局用户信息获取 + const userInfo = wx.getStorageSync('userInfo'); + if (userInfo && userInfo.phoneNumber) { + phoneNumber = userInfo.phoneNumber; + } else { + // 尝试从直接存储的phoneNumber获取 + phoneNumber = wx.getStorageSync('phoneNumber'); + } + } + + // 检查用户是否登录 if (!phoneNumber) { // 用户未登录,显示提示 wx.showToast({ @@ -141,12 +158,25 @@ Page({ API.getFavorites(phoneNumber).then(res => { console.log('获取收藏列表成功:', res); - const favorites = res.data && res.data.favorites ? res.data.favorites : []; - this.setData({ - favoritesList: favorites, - hasFavorites: favorites.length > 0, - loading: false - }); + // 检查API返回是否成功 + if (res && res.code === 200 && res.data) { + const favorites = res.data.favorites || []; + this.setData({ + favoritesList: favorites, + hasFavorites: favorites.length > 0, + loading: false + }); + } else { + // API返回格式不正确 + this.setData({ + loading: false, + hasFavorites: false + }); + wx.showToast({ + title: '数据获取失败', + icon: 'none' + }); + } }).catch(err => { console.error('获取收藏列表失败:', err); wx.showToast({ @@ -209,9 +239,26 @@ Page({ * 跳转到商品详情页 */ goToGoodsDetail: function (e) { - const productId = e.currentTarget.dataset.productid; + // 检查用户是否登录 + const openid = wx.getStorageSync('openid'); + const userId = wx.getStorageSync('userId'); + + if (!openid || !userId) { + console.log('用户未登录,需要授权登录'); + // 显示授权登录弹窗 + wx.showToast({ + title: '请先登录', + icon: 'none' + }); + return; + } + + const goodsItem = e.currentTarget.dataset.item; + // 获取嵌套在Product对象中的商品数据 + const productData = goodsItem.Product; + // 跳转到商品详情页面,并传递商品数据,使用encodeURIComponent编码JSON字符串 wx.navigateTo({ - url: '/pages/goods-detail/goods-detail?productId=' + productId + url: '/pages/goods-detail/goods-detail?goodsData=' + encodeURIComponent(JSON.stringify(productData)) }); }, diff --git a/pages/favorites/index.json b/pages/favorites/index.json index 21582e1..1d29455 100644 --- a/pages/favorites/index.json +++ b/pages/favorites/index.json @@ -1,4 +1,6 @@ { "usingComponents": {}, - "navigationBarTitleText": "我的收藏" + "navigationBarTitleText": "我的收藏", + "enablePullDownRefresh": true, + "backgroundTextStyle": "dark" } \ No newline at end of file diff --git a/pages/favorites/index.wxml b/pages/favorites/index.wxml index 29b1b11..8fef310 100644 --- a/pages/favorites/index.wxml +++ b/pages/favorites/index.wxml @@ -8,13 +8,13 @@ - + 💔 您还没有收藏任何商品 - + @@ -51,7 +51,7 @@ - + 金标蛋 diff --git a/pages/goods-detail/goods-detail.js b/pages/goods-detail/goods-detail.js index d931d47..e1fadf8 100644 --- a/pages/goods-detail/goods-detail.js +++ b/pages/goods-detail/goods-detail.js @@ -56,49 +56,14 @@ Page({ 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 || product.name, - 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' - }; + const productIdStr = String(goodsData.productId || goodsData.id); + + // 无论是否有传递数据,都调用API获取最新的商品详情(特别是联系人信息) + this.loadGoodsDetail(productIdStr); - // 设置商品详情数据和来源标识 + // 设置来源标识 this.setData({ - goodsDetail: formattedGoods, fromSeller: fromSeller }); } catch (error) { @@ -180,7 +145,8 @@ Page({ isReserved: reservedGoodsIds.some(itemId => String(itemId) === productIdStr), reservedCount: finalReservationCount, created_at: product.created_at || product.createdAt, - updated_at: product.updated_at || product.updatedAt + updated_at: product.updated_at || product.updatedAt, + status: product.status }; this.setData({ diff --git a/server-example/update-product-contacts.js b/server-example/update-product-contacts.js index e621a10..a238432 100644 --- a/server-example/update-product-contacts.js +++ b/server-example/update-product-contacts.js @@ -132,3 +132,8 @@ async function updateProductContacts() { // 导出函数供其他模块使用 module.exports = updateProductContacts; + +// 如果直接运行此文件,则执行更新操作 +if (require.main === module) { + updateProductContacts(); +} diff --git a/utils/api.js b/utils/api.js index 31ac565..c33a597 100644 --- a/utils/api.js +++ b/utils/api.js @@ -317,11 +317,29 @@ module.exports = { // 添加商品到购物车 - 增强版本,即使本地找不到商品也尝试直接请求服务器 addToCart: function (goodsItem) { return new Promise((resolve, reject) => { - var openid = wx.getStorageSync('openid'); - console.log('API.addToCart - openid:', openid, 'goodsItem:', goodsItem); + // 获取用户信息,包含手机号 + const users = wx.getStorageSync('users') || {}; + const userId = wx.getStorageSync('userId'); + let userPhone = null; + + // 尝试从users中获取手机号 + if (userId && users[userId] && users[userId].phoneNumber) { + userPhone = users[userId].phoneNumber; + } else { + // 尝试从全局用户信息获取 + const userInfo = wx.getStorageSync('userInfo'); + if (userInfo && userInfo.phoneNumber) { + userPhone = userInfo.phoneNumber; + } else { + // 尝试从直接存储的phoneNumber获取 + userPhone = wx.getStorageSync('phoneNumber'); + } + } + + console.log('API.addToCart - userPhone:', userPhone, 'goodsItem:', goodsItem); // 1. 验证用户登录状态 - if (!openid) { + if (!userPhone) { return reject(new Error('用户未登录')); } @@ -358,7 +376,7 @@ module.exports = { console.log(`尝试添加到购物车,第${attempts}/${maxAttempts}次尝试`); // 总是先尝试直接向服务器发送请求(这是修复新创建货源的关键) - this.sendAddToCartRequest(openid, basicProduct).then(resolve).catch(err => { + this.sendAddToCartRequest(userPhone, basicProduct).then(resolve).catch(err => { console.error('添加到购物车请求失败:', err.message, '尝试次数:', attempts); // 检查是否为外键约束错误或者服务器找不到商品的情况 @@ -386,13 +404,13 @@ module.exports = { console.log('使用的商品信息:', updatedProduct); // 直接再次尝试,不再经过复杂的判断 - this.sendAddToCartRequest(openid, updatedProduct).then(resolve).catch(reject); + this.sendAddToCartRequest(userPhone, updatedProduct).then(resolve).catch(reject); }).catch(innerErr => { console.error('刷新商品列表失败:', innerErr); // 刷新失败也尝试再次发送请求,不轻易放弃 if (attempts < maxAttempts) { console.log('刷新失败,但仍尝试再次发送请求'); - this.sendAddToCartRequest(openid, basicProduct).then(resolve).catch(reject); + this.sendAddToCartRequest(userPhone, basicProduct).then(resolve).catch(reject); } else { reject(new Error('商品信息已更新,请稍后重试')); } @@ -441,12 +459,12 @@ module.exports = { }, // 发送添加到购物车请求的辅助方法 - 完全符合服务器格式版 - sendAddToCartRequest: function (openid, product) { + sendAddToCartRequest: function (userPhone, product) { return new Promise((resolve, reject) => { - // 重要:直接使用传入的openid参数,不再本地重新获取 + // 重要:直接使用传入的userPhone参数 console.log('构建的product对象:', product); console.log('发送添加到购物车请求,productId:', product.productId, '类型:', typeof product.productId); - console.log('用户openid:', openid); + console.log('用户手机号:', userPhone); console.log('请求URL:', '/api/cart/add'); // 前置验证:确保productId存在且类型正确 @@ -483,10 +501,10 @@ module.exports = { name: product.productName || '未命名商品' }; - // 根据服务器端代码分析,服务器期望的格式就是 { openid, product: {...} } + // 根据服务器端代码分析,服务器期望的格式是 { user_phone, product: {...} } // 这是最简单直接的格式,服务器会自动从product对象中提取数据 const requestData = { - openid: openid, + user_phone: userPhone, product: safeProduct }; console.log('最终发送的请求数据完整结构:', requestData); @@ -1567,9 +1585,14 @@ module.exports = { }); }, - // 微信登录函数 - 增强版,支持手机号一键登录 + // 微信登录函数 - 增强版,强制要求手机号授权登录 login: function (encryptedData = null, iv = null) { return new Promise((resolve, reject) => { + // 强制要求手机号授权 + if (!encryptedData || !iv) { + return reject(new Error('登录必须进行手机号授权')); + } + // 1. 调用微信登录接口获取code wx.login({ success: loginRes => { @@ -1818,11 +1841,8 @@ module.exports = { }); }).catch(phoneErr => { console.error('手机号上传失败:', phoneErr); - // 手机号上传失败不影响登录,仍然返回登录成功 - resolve({ - success: true, - data: { openid, userId, sessionKey, phoneError: phoneErr } - }); + // 手机号上传失败导致登录失败 + reject(new Error('手机号授权失败: ' + (phoneErr.message || '未知错误'))); }); } else { // 没有手机号信息,直接返回登录成功 @@ -1974,11 +1994,8 @@ module.exports = { const sessionKey = wx.getStorageSync('sessionKey'); if (!openid) { - // 如果没有openid,先执行登录 - return this.login().then(loginRes => { - // 重新尝试上传 - return tryUpload(); - }); + // 如果没有openid,返回错误,不自动登录 + return Promise.reject(new Error('用户未登录')); } // 检查是否包含openid,如果没有则添加 @@ -2023,7 +2040,6 @@ module.exports = { addFavorite: function (productId) { console.log('API.addFavorite - productId:', productId); return new Promise((resolve, reject) => { - const openid = wx.getStorageSync('openid'); const userId = wx.getStorageSync('userId'); // 获取用户信息,包含手机号 @@ -2038,18 +2054,15 @@ module.exports = { const userInfo = wx.getStorageSync('userInfo'); if (userInfo && userInfo.phoneNumber) { userPhone = userInfo.phoneNumber; + } else { + // 尝试从直接存储的phoneNumber获取 + userPhone = wx.getStorageSync('phoneNumber'); } } - // 如果没有openid,直接返回未登录错误 - if (!openid) { - reject(new Error('用户未登录,无法添加收藏')); - return; - } - // 如果没有手机号,直接返回错误 if (!userPhone) { - reject(new Error('无法获取用户手机号,无法添加收藏')); + reject(new Error('请先登录并绑定手机号')); return; } @@ -2077,8 +2090,6 @@ module.exports = { cancelFavorite: function (productId) { console.log('API.cancelFavorite - productId:', productId); return new Promise((resolve, reject) => { - const openid = wx.getStorageSync('openid'); - // 获取用户信息,包含手机号 const users = wx.getStorageSync('users') || {}; const userId = wx.getStorageSync('userId'); @@ -2092,18 +2103,15 @@ module.exports = { const userInfo = wx.getStorageSync('userInfo'); if (userInfo && userInfo.phoneNumber) { userPhone = userInfo.phoneNumber; + } else { + // 尝试从直接存储的phoneNumber获取 + userPhone = wx.getStorageSync('phoneNumber'); } } - // 如果没有openid,直接返回未登录错误 - if (!openid) { - reject(new Error('用户未登录,无法取消收藏')); - return; - } - // 如果没有手机号,直接返回错误 if (!userPhone) { - reject(new Error('无法获取用户手机号,无法取消收藏')); + reject(new Error('请先登录并绑定手机号')); return; } @@ -2125,38 +2133,16 @@ module.exports = { }, // 获取用户收藏列表 - getFavorites: function () { - console.log('API.getFavorites'); + getFavorites: function (user_phone) { + console.log('API.getFavorites - user_phone:', user_phone); return new Promise((resolve, reject) => { - const openid = wx.getStorageSync('openid'); - - // 获取用户信息,包含手机号 - const users = wx.getStorageSync('users') || {}; - const userId = wx.getStorageSync('userId'); - let userPhone = null; - - // 尝试从users中获取手机号 - if (userId && users[userId] && users[userId].phoneNumber) { - userPhone = users[userId].phoneNumber; - } else { - // 尝试从全局用户信息获取 - const userInfo = wx.getStorageSync('userInfo'); - if (userInfo && userInfo.phoneNumber) { - userPhone = userInfo.phoneNumber; - } - } - - // 如果没有openid,直接返回未登录错误 - if (!openid) { - reject(new Error('用户未登录,无法获取收藏列表')); + // 必须传入user_phone参数且不能为空 + if (!user_phone) { + reject(new Error('参数错误:必须传入有效的手机号')); return; } - // 如果没有手机号,直接返回错误 - if (!userPhone) { - reject(new Error('无法获取用户手机号,无法获取收藏列表')); - return; - } + const userPhone = user_phone; const requestData = { user_phone: userPhone @@ -2164,7 +2150,8 @@ module.exports = { console.log('获取收藏列表请求数据:', requestData); - request('/api/favorites/list', 'GET', requestData).then(res => { + // 将GET请求改为POST请求,因为GET请求通常不处理请求体 + request('/api/favorites/list', 'POST', requestData).then(res => { console.log('获取收藏列表成功:', res); resolve(res); }).catch(error => { @@ -2333,13 +2320,21 @@ module.exports = { // 验证用户登录状态 validateUserLogin: function () { const openid = wx.getStorageSync('openid'); - console.log('API.validateUserLogin - openid:', openid); + const phoneNumber = wx.getStorageSync('phoneNumber') || ''; + console.log('API.validateUserLogin - openid:', openid, 'phoneNumber:', phoneNumber); + + // 验证登录状态和手机号 if (!openid) { return Promise.reject(new Error('用户未登录')); } + + if (!phoneNumber) { + return Promise.reject(new Error('用户未完成手机号授权')); + } return request('/api/user/validate', 'POST', { - openid: openid + openid: openid, + phoneNumber: phoneNumber }); }, @@ -2703,6 +2698,12 @@ module.exports = { updateProductContacts: function () { return request('/api/products/update-contacts', 'POST'); }, + + // 获取产品详情 + getProductDetail: function ({ productId }) { + console.log('API.getProductDetail - productId:', productId); + return request('/api/products/detail', 'POST', { productId: productId }); + }, // 预约商品 reserveProduct: function ({ id }) { @@ -2804,8 +2805,6 @@ module.exports = { cancelFavorite: function (productId) { console.log('API.cancelFavorite - productId:', productId); return new Promise((resolve, reject) => { - const openid = wx.getStorageSync('openid'); - // 获取用户信息,包含手机号 const users = wx.getStorageSync('users') || {}; const userId = wx.getStorageSync('userId'); @@ -2819,18 +2818,15 @@ module.exports = { const userInfo = wx.getStorageSync('userInfo'); if (userInfo && userInfo.phoneNumber) { userPhone = userInfo.phoneNumber; + } else { + // 尝试从直接存储的phoneNumber获取 + userPhone = wx.getStorageSync('phoneNumber'); } } - // 如果没有openid,直接返回未登录错误 - if (!openid) { - reject(new Error('用户未登录,无法取消收藏')); - return; - } - // 如果没有手机号,直接返回错误 if (!userPhone) { - reject(new Error('无法获取用户手机号,无法取消收藏')); + reject(new Error('请先登录并绑定手机号')); return; }