From 9ce1f2259dee75b4f8494c42d736f63db2403f1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=BE=90=E9=A3=9E=E6=B4=8B?=
<15778543+xufeiyang6017@user.noreply.gitee.com>
Date: Wed, 17 Dec 2025 14:48:42 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=94=B6=E8=97=8F=E9=A1=B5?=
=?UTF-8?q?=E9=9D=A2=E7=BB=BF=E5=A3=B3=E5=95=86=E5=93=81=E5=9B=BE=E7=89=87?=
=?UTF-8?q?=E4=B8=A2=E5=A4=B1=E9=97=AE=E9=A2=98=EF=BC=8C=E4=BC=98=E5=8C=96?=
=?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E6=9F=A5=E8=AF=A2=E5=AD=97=E6=AE=B5?=
=?UTF-8?q?=E5=92=8C=E5=9B=BE=E7=89=87URL=E5=A4=84=E7=90=86=E9=80=BB?=
=?UTF-8?q?=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pages/favorites/index.js | 366 +++++++++++++++++++++++++++++++++
pages/favorites/index.json | 4 +
pages/favorites/index.wxml | 114 ++++++++++
pages/favorites/index.wxss | 36 ++++
server-example/server-mysql.js | 231 +++++++++++++++++++++
utils/api.js | 320 +++++++++++++++++++++++++++-
6 files changed, 1066 insertions(+), 5 deletions(-)
create mode 100644 pages/favorites/index.js
create mode 100644 pages/favorites/index.json
create mode 100644 pages/favorites/index.wxml
create mode 100644 pages/favorites/index.wxss
diff --git a/pages/favorites/index.js b/pages/favorites/index.js
new file mode 100644
index 0000000..62415d0
--- /dev/null
+++ b/pages/favorites/index.js
@@ -0,0 +1,366 @@
+// pages/favorites/index.js
+const API = require('../../utils/api.js');
+
+Page({
+
+ /**
+ * 页面的初始数据
+ */
+ data: {
+ favoritesList: [],
+ loading: true,
+ hasFavorites: false,
+
+ // 图片预览相关状态
+ 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 // 初始触摸点
+ },
+
+ /**
+ * 生命周期函数--监听页面加载
+ */
+ onLoad(options) {
+ this.loadFavorites();
+ },
+
+ /**
+ * 生命周期函数--监听页面初次渲染完成
+ */
+ onReady() {
+
+ },
+
+ /**
+ * 生命周期函数--监听页面显示
+ */
+ onShow() {
+ // 每次显示页面时重新加载收藏列表
+ this.loadFavorites();
+ },
+
+ /**
+ * 生命周期函数--监听页面隐藏
+ */
+ onHide() {
+
+ },
+
+ /**
+ * 生命周期函数--监听页面卸载
+ */
+ onUnload() {
+
+ },
+
+ /**
+ * 页面相关事件处理函数--监听用户下拉动作
+ */
+ onPullDownRefresh() {
+ // 下拉刷新时重新加载收藏列表
+ this.loadFavorites(true);
+ },
+
+ /**
+ * 页面上拉触底事件的处理函数
+ */
+ onReachBottom() {
+
+ },
+
+ /**
+ * 用户点击右上角分享
+ */
+ onShareAppMessage() {
+
+ },
+
+ /**
+ * 加载收藏列表
+ */
+ loadFavorites: function (isPullDown = false) {
+ this.setData({
+ loading: true
+ });
+
+ // 获取手机号码
+ const phoneNumber = wx.getStorageSync('phoneNumber') || '18482694520'; // 默认使用测试手机号
+
+ if (!phoneNumber) {
+ // 用户未登录,显示提示
+ wx.showToast({
+ title: '请先登录',
+ icon: 'none'
+ });
+ this.setData({
+ loading: false,
+ hasFavorites: false
+ });
+ if (isPullDown) {
+ wx.stopPullDownRefresh();
+ }
+ return;
+ }
+
+ 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
+ });
+ }).catch(err => {
+ console.error('获取收藏列表失败:', err);
+ wx.showToast({
+ title: '获取收藏列表失败',
+ icon: 'none'
+ });
+ this.setData({
+ loading: false,
+ hasFavorites: false
+ });
+ }).finally(() => {
+ // 停止下拉刷新
+ if (isPullDown) {
+ wx.stopPullDownRefresh();
+ }
+ });
+ },
+
+ /**
+ * 取消收藏
+ */
+ cancelFavorite: function (e) {
+ const productId = e.currentTarget.dataset.productid;
+ wx.showLoading({
+ title: '正在取消收藏',
+ mask: true
+ });
+
+ API.cancelFavorite(productId).then(res => {
+ console.log('取消收藏成功:', res);
+ // 从收藏列表中移除该商品
+ const updatedList = this.data.favoritesList.filter(item => item.productId !== productId);
+ this.setData({
+ favoritesList: updatedList,
+ hasFavorites: updatedList.length > 0
+ });
+ wx.showToast({
+ title: '取消收藏成功',
+ icon: 'success'
+ });
+ }).catch(err => {
+ console.error('取消收藏失败:', err);
+ wx.showToast({
+ title: '取消收藏失败',
+ icon: 'none'
+ });
+ }).finally(() => {
+ wx.hideLoading();
+ });
+ },
+
+ /**
+ * 跳转到商品详情页
+ */
+ goToGoodsDetail: function (e) {
+ const productId = e.currentTarget.dataset.productid;
+ wx.navigateTo({
+ url: '/pages/goods-detail/goods-detail?productId=' + productId
+ });
+ },
+
+ // 轮播图切换
+ swiperChange(e) {
+ const current = e.detail.current;
+ const itemId = e.currentTarget.dataset.itemId;
+
+ // 更新对应商品项的currentImageIndex
+ this.setData({
+ [`favoritesList[${itemId}].currentImageIndex`]: current
+ });
+ },
+
+ // 预览图片
+ 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 { 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();
+ }
+})
\ No newline at end of file
diff --git a/pages/favorites/index.json b/pages/favorites/index.json
new file mode 100644
index 0000000..21582e1
--- /dev/null
+++ b/pages/favorites/index.json
@@ -0,0 +1,4 @@
+{
+ "usingComponents": {},
+ "navigationBarTitleText": "我的收藏"
+}
\ No newline at end of file
diff --git a/pages/favorites/index.wxml b/pages/favorites/index.wxml
new file mode 100644
index 0000000..29b1b11
--- /dev/null
+++ b/pages/favorites/index.wxml
@@ -0,0 +1,114 @@
+
+
+
+
+
+ 加载中...
+
+
+
+
+
+ 💔
+ 您还没有收藏任何商品
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 暂无图片
+
+
+
+
+
+
+
+
+
+
+
+
+ {{(item.currentImageIndex || 0) + 1}}/{{item.Product.imageUrls.length}}
+
+
+
+
+
+
+
+
+
+
+ 金标蛋
+ {{item.Product.productName || '未命名商品'}}
+
+
+ {{(item.Product.spec && item.Product.spec !== '无') ? item.Product.spec : (item.Product.specification && item.Product.specification !== '无') ? item.Product.specification : '无'}} | {{item.Product.yolk || '无'}} | {{item.Product.minOrder || item.Product.quantity || 1}}件
+
+
+
+
+
+
+
+ ¥{{item.Product.price || 0}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ×
+
+
+
\ No newline at end of file
diff --git a/pages/favorites/index.wxss b/pages/favorites/index.wxss
new file mode 100644
index 0000000..f8e9f28
--- /dev/null
+++ b/pages/favorites/index.wxss
@@ -0,0 +1,36 @@
+/* pages/favorites/index.wxss */
+.container {
+ min-height: 100vh;
+ background-color: #f5f5f5;
+}
+
+.loading-container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 50vh;
+}
+
+.empty-container {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ height: 50vh;
+ color: #999;
+}
+
+.empty-icon {
+ font-size: 100rpx;
+ margin-bottom: 20rpx;
+}
+
+.empty-text {
+ font-size: 28rpx;
+}
+
+/* 图片轮播样式 */
+.image-swiper {
+ width: 100%;
+ height: 100%;
+}
\ No newline at end of file
diff --git a/server-example/server-mysql.js b/server-example/server-mysql.js
index 4b0e284..589696f 100644
--- a/server-example/server-mysql.js
+++ b/server-example/server-mysql.js
@@ -813,6 +813,33 @@ CartItem.init({
timestamps: false
});
+// 收藏模型
+class Favorite extends Model { }
+Favorite.init({
+ id: {
+ type: DataTypes.INTEGER,
+ autoIncrement: true,
+ primaryKey: true
+ },
+ user_phone: {
+ type: DataTypes.STRING(20),
+ allowNull: false
+ },
+ productId: {
+ type: DataTypes.STRING(100),
+ allowNull: false
+ },
+ date: {
+ type: DataTypes.DATE,
+ defaultValue: Sequelize.NOW
+ }
+}, {
+ sequelize,
+ modelName: 'Favorite',
+ tableName: 'favorites',
+ timestamps: false
+});
+
// 联系人表模型
class Contact extends Model { }
Contact.init({
@@ -957,6 +984,21 @@ Product.hasMany(CartItem, {
onUpdate: 'CASCADE' // 级联更新
});
+// 收藏与商品的关系 (收藏属于商品)
+Favorite.belongsTo(Product, {
+ foreignKey: 'productId',
+ targetKey: 'productId', // 目标键,使用productId字段(STRING类型)而非默认的id字段(INTEGER类型)
+ as: 'Product' // 别名,与收藏列表API中使用的一致
+});
+
+// 商品与收藏的一对多关系 (商品可以被多个用户收藏)
+Product.hasMany(Favorite, {
+ foreignKey: 'productId',
+ as: 'favorites', // 别名,表示商品的收藏列表
+ onDelete: 'CASCADE', // 级联删除
+ onUpdate: 'CASCADE' // 级联更新
+});
+
CartItem.belongsTo(Product, {
foreignKey: 'productId',
as: 'product' // 购物车项中的商品
@@ -3250,6 +3292,195 @@ async function handleAddImagesToExistingProduct(req, res, existingProductId, upl
// 其他路由...
+// 收藏相关API端点
+// 添加收藏
+app.post('/api/favorites/add', async (req, res) => {
+ try {
+ const { user_phone, productId } = req.body;
+
+ console.log('收到添加收藏请求:', { user_phone, productId });
+
+ // 验证参数
+ if (!user_phone || !productId) {
+ return res.status(400).json({
+ success: false,
+ code: 400,
+ message: '缺少必要参数',
+ data: { user_phone, productId }
+ });
+ }
+
+ // 检查是否已存在收藏记录
+ const existingFavorite = await Favorite.findOne({
+ where: {
+ user_phone,
+ productId
+ }
+ });
+
+ if (existingFavorite) {
+ return res.status(200).json({
+ success: true,
+ code: 200,
+ message: '已经收藏过该商品',
+ data: existingFavorite
+ });
+ }
+
+ // 创建新的收藏记录
+ const newFavorite = await Favorite.create({
+ user_phone,
+ productId
+ });
+
+ console.log('收藏添加成功:', newFavorite);
+
+ res.status(200).json({
+ success: true,
+ code: 200,
+ message: '收藏添加成功',
+ data: newFavorite
+ });
+ } catch (error) {
+ console.error('添加收藏失败:', error);
+ res.status(500).json({
+ success: false,
+ code: 500,
+ message: '添加收藏失败',
+ error: error.message
+ });
+ }
+});
+
+// 取消收藏
+app.post('/api/favorites/remove', async (req, res) => {
+ try {
+ const { user_phone, productId } = req.body;
+
+ console.log('收到取消收藏请求:', { user_phone, productId });
+
+ // 验证参数
+ if (!user_phone || !productId) {
+ return res.status(400).json({
+ success: false,
+ code: 400,
+ message: '缺少必要参数'
+ });
+ }
+
+ // 删除收藏记录
+ const result = await Favorite.destroy({
+ where: {
+ user_phone,
+ productId
+ }
+ });
+
+ if (result === 0) {
+ return res.status(404).json({
+ success: false,
+ code: 404,
+ message: '收藏记录不存在'
+ });
+ }
+
+ console.log('收藏取消成功:', { user_phone, productId });
+
+ res.status(200).json({
+ success: true,
+ code: 200,
+ message: '收藏取消成功'
+ });
+ } catch (error) {
+ console.error('取消收藏失败:', error);
+ res.status(500).json({
+ success: false,
+ code: 500,
+ message: '取消收藏失败',
+ error: error.message
+ });
+ }
+});
+
+// 获取收藏列表
+app.post('/api/favorites/list', async (req, res) => {
+ try {
+ const { user_phone } = req.body;
+
+ console.log('收到获取收藏列表请求:', { user_phone });
+
+ // 验证参数
+ if (!user_phone) {
+ return res.status(400).json({
+ success: false,
+ code: 400,
+ message: '缺少必要参数'
+ });
+ }
+
+ // 获取收藏列表,并关联查询商品信息
+ const favorites = await Favorite.findAll({
+ where: { user_phone },
+ include: [
+ {
+ model: Product,
+ as: 'Product', // 与关联定义中的别名一致
+ attributes: ['productId', 'productName', 'price', 'quantity', 'grossWeight', 'imageUrls', 'created_at', 'specification', 'yolk']
+ }
+ ],
+ order: [['date', 'DESC']]
+ });
+
+ console.log('获取收藏列表成功,数量:', favorites.length);
+
+ // 处理图片URL,确保是数组格式(与商品详情API保持一致的处理逻辑)
+ const processedFavorites = favorites.map(favorite => {
+ const favoriteJSON = favorite.toJSON();
+ if (favoriteJSON.Product) {
+ // 关键修复:将存储在数据库中的JSON字符串反序列化为JavaScript数组
+ if (favoriteJSON.Product.imageUrls) {
+ if (typeof favoriteJSON.Product.imageUrls === 'string') {
+ console.log('【关键修复】将数据库中的JSON字符串反序列化为JavaScript数组');
+ try {
+ favoriteJSON.Product.imageUrls = JSON.parse(favoriteJSON.Product.imageUrls);
+ console.log('反序列化后的imageUrls类型:', typeof favoriteJSON.Product.imageUrls);
+ } catch (parseError) {
+ console.error('反序列化imageUrls失败:', parseError);
+ // 如果解析失败,使用空数组确保前端不会崩溃
+ favoriteJSON.Product.imageUrls = [];
+ }
+ } else if (!Array.isArray(favoriteJSON.Product.imageUrls)) {
+ // 如果不是数组类型,也转换为空数组
+ favoriteJSON.Product.imageUrls = [];
+ }
+ } else {
+ // 确保imageUrls始终是数组
+ favoriteJSON.Product.imageUrls = [];
+ }
+ }
+ return favoriteJSON;
+ });
+
+ res.status(200).json({
+ success: true,
+ code: 200,
+ message: '获取收藏列表成功',
+ data: {
+ favorites: processedFavorites,
+ count: processedFavorites.length
+ }
+ });
+ } catch (error) {
+ console.error('获取收藏列表失败:', error);
+ res.status(500).json({
+ success: false,
+ code: 500,
+ message: '获取收藏列表失败',
+ error: error.message
+ });
+ }
+});
+
// 辅助函数:清理临时文件
function cleanTempFiles(filePaths) {
if (!filePaths || filePaths.length === 0) {
diff --git a/utils/api.js b/utils/api.js
index e06d9a3..8356359 100644
--- a/utils/api.js
+++ b/utils/api.js
@@ -1998,20 +1998,20 @@ module.exports = {
// 清除过期的登录信息
try {
wx.removeStorageSync('openid');
+ wx.removeStorageSync('userId');
wx.removeStorageSync('sessionKey');
} catch (e) {
console.error('清除过期登录信息失败:', e);
}
// 重新登录后重试
- return this.login().then(() => {
- console.log('重新登录成功,准备重试上传手机号数据');
+ return this.login().then(loginRes => {
return tryUpload();
});
+ } else {
+ // 其他错误或重试次数用完,直接抛出
+ throw error;
}
-
- // 其他错误直接抛出
- throw error;
});
};
@@ -2019,6 +2019,231 @@ module.exports = {
return tryUpload();
},
+ // 添加收藏
+ addFavorite: function (productId) {
+ console.log('API.addFavorite - productId:', productId);
+ return new Promise((resolve, reject) => {
+ const openid = wx.getStorageSync('openid');
+ const userId = wx.getStorageSync('userId');
+
+ // 获取用户信息,包含手机号
+ const users = wx.getStorageSync('users') || {};
+ 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) {
+ return this.login().then(loginRes => {
+ // 重新尝试添加收藏
+ return this.addFavorite(productId);
+ }).catch(loginErr => {
+ reject(new Error('用户未登录,无法添加收藏'));
+ });
+ }
+
+ // 如果没有手机号,需要先获取
+ if (!userPhone) {
+ // 尝试获取用户信息
+ return this.getUserInfo(openid).then(userInfoRes => {
+ let phoneNumber = null;
+ if (userInfoRes.data && userInfoRes.data.phoneNumber) {
+ phoneNumber = userInfoRes.data.phoneNumber;
+ }
+
+ if (!phoneNumber) {
+ reject(new Error('无法获取用户手机号,无法添加收藏'));
+ } else {
+ // 保存手机号到本地
+ if (userId) {
+ users[userId] = users[userId] || {};
+ users[userId].phoneNumber = phoneNumber;
+ wx.setStorageSync('users', users);
+ }
+ // 重新尝试添加收藏
+ return this.addFavorite(productId);
+ }
+ }).catch(err => {
+ reject(new Error('无法获取用户信息,无法添加收藏'));
+ });
+ }
+
+ // 构建收藏数据
+ const favoriteData = {
+ user_phone: userPhone,
+ productId: productId,
+ date: new Date().toISOString() // 当前时间
+ };
+
+ console.log('添加收藏请求数据:', favoriteData);
+
+ // 发送请求到服务器
+ request('/api/favorites/add', 'POST', favoriteData).then(res => {
+ console.log('添加收藏成功:', res);
+ resolve(res);
+ }).catch(error => {
+ console.error('添加收藏失败:', error);
+ reject(new Error('添加收藏失败,请稍后重试'));
+ });
+ });
+ },
+
+ // 取消收藏
+ 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');
+ 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;
+ }
+ }
+
+ if (!openid) {
+ return this.login().then(loginRes => {
+ // 重新尝试取消收藏
+ return this.cancelFavorite(productId);
+ }).catch(loginErr => {
+ reject(new Error('用户未登录,无法取消收藏'));
+ });
+ }
+
+ // 如果没有手机号,需要先获取
+ if (!userPhone) {
+ // 尝试获取用户信息
+ return this.getUserInfo(openid).then(userInfoRes => {
+ let phoneNumber = null;
+ if (userInfoRes.data && userInfoRes.data.phoneNumber) {
+ phoneNumber = userInfoRes.data.phoneNumber;
+ }
+
+ if (!phoneNumber) {
+ reject(new Error('无法获取用户手机号,无法取消收藏'));
+ } else {
+ // 保存手机号到本地
+ if (userId) {
+ users[userId] = users[userId] || {};
+ users[userId].phoneNumber = phoneNumber;
+ wx.setStorageSync('users', users);
+ }
+ // 重新尝试取消收藏
+ return this.cancelFavorite(productId);
+ }
+ }).catch(err => {
+ reject(new Error('无法获取用户信息,无法取消收藏'));
+ });
+ }
+
+ const cancelData = {
+ user_phone: userPhone,
+ productId: productId
+ };
+
+ console.log('取消收藏请求数据:', cancelData);
+
+ request('/api/favorites/cancel', 'POST', cancelData).then(res => {
+ console.log('取消收藏成功:', res);
+ resolve(res);
+ }).catch(error => {
+ console.error('取消收藏失败:', error);
+ reject(new Error('取消收藏失败,请稍后重试'));
+ });
+ });
+ },
+
+ // 获取用户收藏列表
+ getFavorites: function () {
+ console.log('API.getFavorites');
+ 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;
+ }
+ }
+
+ if (!openid) {
+ return this.login().then(loginRes => {
+ // 重新尝试获取收藏列表
+ return this.getFavorites();
+ }).catch(loginErr => {
+ reject(new Error('用户未登录,无法获取收藏列表'));
+ });
+ }
+
+ // 如果没有手机号,需要先获取
+ if (!userPhone) {
+ // 尝试获取用户信息
+ return this.getUserInfo(openid).then(userInfoRes => {
+ let phoneNumber = null;
+ if (userInfoRes.data && userInfoRes.data.phoneNumber) {
+ phoneNumber = userInfoRes.data.phoneNumber;
+ }
+
+ if (!phoneNumber) {
+ reject(new Error('无法获取用户手机号,无法获取收藏列表'));
+ } else {
+ // 保存手机号到本地
+ if (userId) {
+ users[userId] = users[userId] || {};
+ users[userId].phoneNumber = phoneNumber;
+ wx.setStorageSync('users', users);
+ }
+ // 重新尝试获取收藏列表
+ return this.getFavorites();
+ }
+ }).catch(err => {
+ reject(new Error('无法获取用户信息,无法获取收藏列表'));
+ });
+ }
+
+ const requestData = {
+ user_phone: userPhone
+ };
+
+ console.log('获取收藏列表请求数据:', requestData);
+
+ request('/api/favorites/list', 'GET', requestData).then(res => {
+ console.log('获取收藏列表成功:', res);
+ resolve(res);
+ }).catch(error => {
+ console.error('获取收藏列表失败:', error);
+ reject(new Error('获取收藏列表失败,请稍后重试'));
+ });
+ });
+ },
+
// 上传用户信息到服务器
uploadUserInfo: function (userInfo) {
console.log('API.uploadUserInfo - userInfo:', userInfo);
@@ -2633,5 +2858,90 @@ module.exports = {
});
},
+ // 获取收藏商品列表
+ getFavorites: function (phoneNumber) {
+ console.log('API.getFavorites - phoneNumber:', phoneNumber);
+ if (!phoneNumber) {
+ return Promise.reject(new Error('用户未登录'));
+ }
+
+ return request('/api/favorites/list', 'POST', {
+ user_phone: phoneNumber
+ });
+ },
+
+ // 取消收藏商品
+ 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');
+ 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;
+ }
+ }
+
+ if (!openid) {
+ return this.login().then(loginRes => {
+ // 重新尝试取消收藏
+ return this.cancelFavorite(productId);
+ }).catch(loginErr => {
+ reject(new Error('用户未登录,无法取消收藏'));
+ });
+ }
+
+ // 如果没有手机号,需要先获取
+ if (!userPhone) {
+ // 尝试获取用户信息
+ return this.getUserInfo(openid).then(userInfoRes => {
+ let phoneNumber = null;
+ if (userInfoRes.data && userInfoRes.data.phoneNumber) {
+ phoneNumber = userInfoRes.data.phoneNumber;
+ }
+
+ if (!phoneNumber) {
+ reject(new Error('无法获取用户手机号,无法取消收藏'));
+ } else {
+ // 保存手机号到本地
+ if (userId) {
+ users[userId] = users[userId] || {};
+ users[userId].phoneNumber = phoneNumber;
+ wx.setStorageSync('users', users);
+ }
+ // 重新尝试取消收藏
+ return this.cancelFavorite(productId);
+ }
+ }).catch(err => {
+ reject(new Error('无法获取用户信息,无法取消收藏'));
+ });
+ }
+
+ const requestData = {
+ user_phone: userPhone,
+ productId: productId
+ };
+
+ console.log('取消收藏请求数据:', requestData);
+
+ request('/api/favorites/remove', 'POST', requestData).then(res => {
+ console.log('取消收藏成功:', res);
+ resolve(res);
+ }).catch(error => {
+ console.error('取消收藏失败:', error);
+ reject(new Error('取消收藏失败,请稍后重试'));
+ });
+ });
+ }
};
\ No newline at end of file