This commit is contained in:
左哥 2025-12-07 14:15:32 +08:00
parent 347d97495b
commit d8c6c26c34
4 changed files with 247 additions and 18 deletions

View File

@ -91,7 +91,7 @@
<text>{{ formatPrice(item.skus[0].price) }}</text>
<text class="original-price">{{ formatPrice(item.skus[0].original_price) }}</text>
</view>
<view class="sku-operation flex">
<view class="sku-operation flex" v-if="isLoggedIn">
<button class="sku-num" @click.stop="handelLike(item)">
<text v-if="item.is_liked" class="iconfont icon-xin heart-filled"></text>
<text v-else class="iconfont icon-xin1 heart-outline"></text>
@ -101,7 +101,7 @@
@click.stop="currentShareItem = item">
<text class="iconfont icon-zhifeiji1"></text>
</button>
<button class="shop-cart">
<button class="shop-cart" @click.stop="handleAddToCart(item)">
<text class="iconfont icon-gouwuche"></text> 加入购物车
</button>
</view>
@ -228,11 +228,23 @@ export default {
is_limited: '',
shopList: '',
currentShareItem: null,
isLoggedIn: false,
}
},
onLoad() {
this.checkLoginStatus()
this.getShopList()
},
onShow() {
//
const previousLoginStatus = this.isLoggedIn
//
this.checkLoginStatus()
//
if (!previousLoginStatus && this.isLoggedIn) {
this.getShopList()
}
},
//
onShareAppMessage(res) {
const item = this.currentShareItem || (res.target && res.target.dataset && res.target.dataset.item) || {};
@ -243,6 +255,11 @@ export default {
};
},
methods: {
//
checkLoginStatus() {
const token = uni.getStorageSync('access_token')
this.isLoggedIn = !!token
},
//
formatPrice(value) {
if (!value) {
@ -253,8 +270,13 @@ export default {
//
return value.toFixed(2);
},
getShopList() {
request('xcx/products', 'get', {
async getShopList() {
//
const token = await uni.getStorageSync('access_token')
//
const apiUrl = token ? 'xcx/auth_products' : 'xcx/products'
request(apiUrl, 'get', {
page: this.page,
page_size: this.page_size
}).then((res) => {
@ -299,11 +321,78 @@ export default {
},
async goShopDetail(item) {
//
const token = await uni.getStorageSync('access_token')
if (!token) {
//
await uni.setStorageSync('product_info', item)
await uni.setStorageSync('redirect_url', `/pages/shopDetail/index?id=${item.id}`)
//
uni.navigateTo({
url: '/pages/login/index'
})
return
}
//
await uni.setStorageSync('product_info', item)
uni.navigateTo({
url: `/pages/shopDetail/index?id=${item.id}`
})
},
//
async handleAddToCart(item) {
//
const token = await uni.getStorageSync('access_token')
if (!token) {
uni.showToast({
title: '请先登录',
icon: 'none'
})
uni.navigateTo({
url: '/pages/login/index'
})
return
}
// SKU
if (!item.skus || item.skus.length === 0) {
uni.showToast({
title: '该商品暂无库存',
icon: 'none'
})
return
}
// SKU
const firstSku = item.skus[0]
if (!firstSku.sku_id && !firstSku.id) {
uni.showToast({
title: '商品信息不完整',
icon: 'none'
})
return
}
try {
//
await request('xcx/cart', 'POST', {
product_id: item.id,
sku_id: firstSku.sku_id || firstSku.id,
quantity: 1
})
uni.showToast({
title: '已加入购物车',
icon: 'success'
})
} catch (error) {
console.error('加入购物车失败:', error)
uni.showToast({
title: error.message || '加入购物车失败',
icon: 'none'
})
}
},
// handeShare(item) {
// //
// // 使 open-type="share" + onShareAppMessage

View File

@ -68,13 +68,20 @@ export default {
const result = await request('xcx/quick_login', 'POST', loginData);
await wx.setStorageSync('access_token', result.token);
await wx.setStorageSync('is_personal_information_complete', result.is_personal_information_complete);
// if (result.is_personal_information_complete) {
wx.navigateBack();
// } else {
// wx.navigateTo({
// url: `/pages/my/editInfo/index`,
// });
// }
//
const redirectUrl = await uni.getStorageSync('redirect_url');
if (redirectUrl) {
//
await uni.removeStorageSync('redirect_url');
//
uni.navigateTo({
url: redirectUrl
});
} else {
//
uni.navigateBack();
}
// token
// if (result.token) {
// wx.setStorageSync('access_token', result.token);

View File

@ -39,9 +39,9 @@
<view class="signin-header">
<view class="signin-headline">
<text class="signin-title">每日签到</text>
<text class="signin-desc">已连续签到 {{ signInfo.continuousDays }} </text>
<text class="signin-desc">已连续签到 {{ consecutive_days }} </text>
</view>
<view class="signin-badge">+{{ signInfo.todayReward || 0 }} 积分</view>
<view class="signin-badge">+{{ total_points || 0 }} 积分</view>
</view>
<view class="signin-calendar">
<view class="signin-calendar-header">
@ -59,7 +59,7 @@
</view>
</view>
<view class="signin-footer">
<view class="signin-stats">
<!-- <view class="signin-stats">
<view class="signin-stat">
<text class="signin-stat-value">{{ signInfo.totalPoints }}</text>
<text class="signin-stat-label">累计积分</text>
@ -68,7 +68,7 @@
<text class="signin-stat-value">{{ signInfo.continuousDays }}</text>
<text class="signin-stat-label">连续天数</text>
</view>
</view>
</view> -->
<button class="signin-btn" :class="{ disabled: signInfo.signedToday || signLoading }"
@click="handleSignIn" :disabled="signInfo.signedToday || signLoading">
{{ signInfo.signedToday ? '今日已签到' : (signLoading ? '签到中...' : '立即签到') }}
@ -249,6 +249,8 @@ export default {
monthLabel: '',
monthSignedDays: 0
},
consecutive_days: 0,
total_points: 0,
signCalendar: [],
signLoading: false,
weekdayLabels: ['日', '一', '二', '三', '四', '五', '六'],
@ -576,7 +578,8 @@ export default {
//
const checkinList = info.list || [];
const monthLabel = this.getMonthLabel();
this.consecutive_days = info.consecutive_days || 0;
this.total_points = info.total_points || 0;
//
const today = new Date();
const todayStr = `${today.getFullYear()}-${this.padZero(today.getMonth() + 1)}-${this.padZero(today.getDate())}`;

View File

@ -16,6 +16,12 @@
<view class="swiper-nav next" @click="nextImage" v-if="productImages.length > 1">
<text></text>
</view>
<!-- 分享按钮 -->
<view class="share-btn-top">
<button class="share-btn-inner-top" open-type="share" :data-item="productInfo" @click.stop="currentShareItem = productInfo">
<text class="iconfont icon-zhifeiji1"></text>
</button>
</view>
</view>
<!-- 商品信息 -->
@ -28,7 +34,13 @@
</view>
<!-- 商品名称 -->
<view class="product-name">{{ productInfo.name || '玫瑰香水盲盒' }}</view>
<view class="product-name-row">
<view class="product-name">{{ productInfo.name || '玫瑰香水盲盒' }}</view>
<view class="like-btn-top" @click="handleLike">
<text v-if="productInfo.is_liked" class="iconfont icon-xin heart-filled"></text>
<text v-else class="iconfont icon-xin1 heart-outline"></text>
</view>
</view>
<!-- <view class="product-sub-title">{{ productInfo.description.sub_title || '玫瑰香水盲盒' }}</view> -->
<!-- 评分和喜欢 -->
@ -339,6 +351,7 @@ export default {
showPurchaseModal: false,
purchaseAction: 'cart', // 'cart' 'buy'
cartSelectedCount: 0,
currentShareItem: null,
fragranceNotes: {
top: '柠檬、佛手柑、粉红胡椒',
middle: '玫瑰、茉莉、牡丹',
@ -399,6 +412,15 @@ export default {
onShow() {
this.fetchCartSelectedCount();
},
//
onShareAppMessage(res) {
const item = this.currentShareItem || (res.target && res.target.dataset && res.target.dataset.item) || this.productInfo || {};
return {
title: item.name || '香氛团购',
imageUrl: item.main_image_url || (this.productImages && this.productImages[0]) || '/static/images/home/icon-1.png',
path: item.id ? `/pages/shopDetail/index?id=${item.id}` : '/pages/index/index'
};
},
methods: {
//
@ -538,6 +560,27 @@ export default {
})
}
},
// /
async handleLike() {
await this.userIsLogin().then((res) => {
request('xcx/product/like', 'post', {
product_id: this.productInfo.id || this.productId,
type: this.productInfo.is_liked ? 2 : 1
}).then((res) => {
const liked = !this.productInfo.is_liked
this.productInfo.is_liked = liked
if (liked) {
this.productInfo.like_count = (this.productInfo.like_count || 0) + 1
} else if (this.productInfo.like_count > 0) {
this.productInfo.like_count -= 1
}
}).catch((error) => {
console.error('收藏操作失败:', error)
})
}).catch((err) => {
console.log(err)
})
},
// -
async addToCart() {
await this.userIsLogin().then(async (res) => {
@ -785,6 +828,38 @@ export default {
line-height: 1;
}
/* 右上角分享按钮 */
.share-btn-top {
position: absolute;
top: 24rpx;
right: 24rpx;
z-index: 20;
width: 80rpx;
height: 80rpx;
background-color: rgba(0, 0, 0, 0.3);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.share-btn-inner-top {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: transparent;
border: 0!important;
padding: 0;
box-shadow: none!important;
}
.share-btn-inner-top .iconfont {
font-size: 40rpx;
color: #fff;
}
/* 商品信息 */
.product-info {
background-color: #fff;
@ -808,12 +883,40 @@ export default {
background-color: transparent;
}
.product-name-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
}
.product-name {
font-size: 36rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
line-height: 1.4;
flex: 1;
}
.like-btn-top {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
margin-left: 20rpx;
}
.like-btn-top .iconfont {
font-size: 44rpx;
}
.like-btn-top .heart-filled {
color: #e7000b;
}
.like-btn-top .heart-outline {
color: #ccc;
}
.product-sub-title {
@ -1417,6 +1520,33 @@ export default {
margin-bottom: 4rpx;
}
.bar-btn .heart-filled {
color: #e7000b;
}
.bar-btn .heart-outline {
color: #ccc;
}
.share-btn-inner {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: transparent;
border: 0;
padding: 0;
font-size: 24rpx;
color: #666;
}
.share-btn-inner .iconfont {
font-size: 36rpx;
margin-bottom: 4rpx;
}
.bar-btn.cart-btn {
flex: 2;
background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);