Browse Source

修复收藏页面绿壳商品图片丢失问题,优化数据库查询字段和图片URL处理逻辑

pull/1/head
徐飞洋 3 months ago
parent
commit
9ce1f2259d
  1. 366
      pages/favorites/index.js
  2. 4
      pages/favorites/index.json
  3. 114
      pages/favorites/index.wxml
  4. 36
      pages/favorites/index.wxss
  5. 231
      server-example/server-mysql.js
  6. 320
      utils/api.js

366
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();
}
})

4
pages/favorites/index.json

@ -0,0 +1,4 @@
{
"usingComponents": {},
"navigationBarTitleText": "我的收藏"
}

114
pages/favorites/index.wxml

@ -0,0 +1,114 @@
<!--pages/favorites/index.wxml-->
<view class="container" style="align-items: flex-start; padding: 20rpx; width: 100%; max-width: 100vw; overflow-x: hidden; position: relative; box-sizing: border-box;">
<!-- 加载状态 -->
<view wx:if="{{loading}}" class="loading-container">
<loading>
加载中...
</loading>
</view>
<!-- 空状态 -->
<view wx:elif="{{!hasFavorites}}" class="empty-container">
<view class="empty-icon">💔</view>
<text class="empty-text">您还没有收藏任何商品</text>
</view>
<!-- 收藏列表 -->
<view wx:else class="goods-list" style="width: 100%; display: flex; flex-direction: column; align-items: flex-start; min-height: 400rpx; margin-top: 120rpx;">
<view wx:for="{{favoritesList}}" wx:key="productId" class="card" style="width: 100%; margin-top: 0; margin-bottom: 20rpx;">
<!-- 图片和信息2:3比例并排显示,整体高度固定 -->
<view style="display: flex; width: 100%; height: 200rpx; border-radius: 8rpx; overflow: hidden; background-color: #f5f5f5;">
<!-- 左侧图片区域 40%宽度(2/5),高度固定 -->
<view style="width: 40%; position: relative; height: 200rpx;">
<!-- 第一张图片 -->
<view wx:if="{{item.Product && item.Product.imageUrls && item.Product.imageUrls.length > 0}}" style="width: 100%; height: 100%;">
<image src="{{item.Product.imageUrls[0]}}" mode="aspectFill" style="width: 100%; height: 100%;" bindtap="previewImage" data-urls="{{item.Product.imageUrls}}" data-index="0"></image>
</view>
<view wx:else style="width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: #999;">
<text>暂无图片</text>
</view>
<!-- 剩余图片可滑动区域 -->
<view wx:if="{{item.Product && item.Product.imageUrls && item.Product.imageUrls.length > 0}}" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">
<swiper
class="image-swiper"
style="width: 100%; height: 100%;"
current="{{item.currentImageIndex || 0}}"
bindchange="swiperChange"
data-item-id="{{index}}">
<block wx:for="{{item.Product.imageUrls}}" wx:for-item="img" wx:for-index="idx" wx:key="idx">
<swiper-item>
<image src="{{img}}" mode="aspectFill" style="width: 100%; height: 100%;" bindtap="previewImage" data-urls="{{item.Product.imageUrls}}" data-index="{{idx}}"></image>
</swiper-item>
</block>
</swiper>
<!-- 显示页码指示器 -->
<view style="position: absolute; bottom: 10rpx; right: 10rpx; background-color: rgba(0,0,0,0.5); color: white; padding: 5rpx 10rpx; border-radius: 15rpx; font-size: 20rpx;">
{{(item.currentImageIndex || 0) + 1}}/{{item.Product.imageUrls.length}}
</view>
</view>
</view>
<!-- 右侧信息区域 60%宽度(3/5),相应调整 -->
<view style="width: 60%; display: flex; flex-direction: column; background-color: white; border-left: 1rpx solid #f0f0f0;">
<!-- 上半部分商品信息区域(60%高度),可点击查看详情 -->
<view style="flex: 0.6; padding: 0rpx 15rpx 15rpx 15rpx; cursor: pointer;" bindtap="goToGoodsDetail" data-productid="{{item.productId}}">
<view>
<view style="margin-bottom: 15rpx; margin-top: -5rpx;">
<view style="display: inline-block; margin-right: 10rpx; font-size: 18rpx; color: #fff; background-color: #DAA520; padding: 2rpx 8rpx; border-radius: 10rpx; vertical-align: middle;">金标蛋</view>
<span style="vertical-align: middle; font-size: 36rpx; font-weight: bold;">{{item.Product.productName || '未命名商品'}}</span>
</view>
<view style="font-size: 28rpx; font-weight: bold; margin-top: 30rpx;">
{{(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}}件
</view>
</view>
</view>
<!-- 下半部分按钮区域(40%高度) -->
<view style="flex: 0.4; display: flex; justify-content: space-between; align-items: center; padding: 0 20rpx;">
<!-- 价格显示 -->
<text style="color: #52c41a; font-size: 28rpx; font-weight: bold;">¥{{item.Product.price || 0}}</text>
<!-- 取消收藏按钮 -->
<button
style="background-color: #91c41aff; color: white; font-size: 24rpx; font-weight: bold; width: 150rpx; height: 60rpx; border-radius: 999rpx; display: flex; justify-content: center; align-items: center; padding: 0; border: none; margin: 0; background: none; background-color: #91c41aff;"
bindtap="cancelFavorite"
data-productid="{{item.productId}}"
>
取消收藏
</button>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 图片预览弹窗 -->
<view class="image-preview-mask" wx:if="{{showImagePreview}}" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.9); display: flex; justify-content: center; align-items: center; z-index: 10001;" catchtouchmove="true">
<view style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center;">
<swiper
style="width: 100%; height: 100%;"
current="{{previewImageIndex}}"
bindchange="onPreviewImageChange"
indicator-dots="true"
indicator-color="rgba(255,255,255,0.5)"
indicator-active-color="#fff">
<block wx:for="{{previewImageUrls}}" wx:key="*this">
<swiper-item>
<image
src="{{item}}"
mode="aspectFit"
style="width: 100%; height: 100%; transform: scale({{scale}}) translate({{offsetX}}px, {{offsetY}}px); transition: {{isScaling ? 'none' : 'transform 0.3s'}};"
bindtap="handleImageTap"
bindtouchstart="handleTouchStart"
bindtouchmove="handleTouchMove"
bindtouchend="handleTouchEnd"
bindtouchcancel="handleTouchEnd"
></image>
</swiper-item>
</block>
</swiper>
<view style="position: absolute; top: 40rpx; right: 40rpx; color: white; font-size: 40rpx;">
<text bindtap="closeImagePreview" style="background: rgba(0,0,0,0.5); padding: 10rpx 20rpx; border-radius: 50%;">×</text>
</view>
</view>
</view>

36
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%;
}

231
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) {

320
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('取消收藏失败,请稍后重试'));
});
});
}
};
Loading…
Cancel
Save