1
This commit is contained in:
@ -1,35 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="flex-row-start goods-item" @click.stop="$emit('clickCard', data)">
|
<view class="goods-item" >
|
||||||
<image class="goods-img" :src="data.product_pic" mode="aspectFill" />
|
<image @click.stop="handleBuyNow" class="goods-img" :src="data.product_pic" mode="aspectFill" />
|
||||||
<view class="goods-content">
|
<view class="fs-24 app-fc-main goods-name">
|
||||||
<view class="text-multi-ellipse fs-28 app-fc-main app-font-bold goods-name">
|
|
||||||
{{ data.product_name || "" }}
|
{{ data.product_name || "" }}
|
||||||
</view>
|
</view>
|
||||||
<!-- <view class="flex-row-start label">
|
<view class="flex-row-start label">
|
||||||
<image class="hot-icon" :src="`${imgPrefix}mall-hot.png`"></image>
|
<image class="hot-icon" :src="`${imgPrefix}mall-hot.png`"></image>
|
||||||
<view class="fs-20 app-fc-main label-name">{{data.sales}}人买过</view>
|
<view class="fs-20 app-fc-main label-name">32人买过</view>
|
||||||
</view> -->
|
</view>
|
||||||
<view class="price-row">
|
<view class="flex-row-between" style="margin-top: 12rpx; align-items: baseline;">
|
||||||
<view class="flex-row-start">
|
<view class="price-wrapper">
|
||||||
<text class="fs-28 price-text">
|
<text class="fs-28" style="color: #FF19A0;">
|
||||||
¥
|
¥
|
||||||
<text class="fs-28">{{data.prices[0].original_price / 100 || 0 }}</text>
|
<text class="fs-28">{{
|
||||||
</text>
|
data.prices[0].original_price / 100 || 0
|
||||||
<!-- <text class="fs-20 price-label">到手价</text> -->
|
}}</text>
|
||||||
</view>
|
|
||||||
<text class="fs-24 origin-price" v-if="minPrice.price_shichang">
|
|
||||||
¥{{ minPrice.price_shichang || 0 }}
|
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="buy-now-btn-wrapper" @click.stop="handleBuyNow">
|
<view class="buy-now-btn" @click.stop="handleBuyNow">
|
||||||
<text class="buy-now-btn">立即购买1</text>
|
立即购买
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { imgPrefix } from '@/utils/common';
|
import {
|
||||||
|
imgPrefix
|
||||||
|
} from '@/utils/common';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
@ -45,38 +43,22 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
imgPrefix,
|
imgPrefix,
|
||||||
isAnimating: false,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
// minPrice() {
|
|
||||||
// let minPrice = {};
|
|
||||||
// let minPriceValue = 0;
|
|
||||||
// this.data.price_list.map((v) => {
|
|
||||||
// if (!minPriceValue || minPriceValue > +v.price) {
|
|
||||||
// minPriceValue = +v.price;
|
|
||||||
// minPrice = { ...v };
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// return minPrice;
|
|
||||||
// },
|
|
||||||
labelList() {
|
labelList() {
|
||||||
return this.data.label.split(",").filter((v) => !!v);
|
return (this.data?.label || "").split(",").filter((v) => !!v);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {},
|
mounted() {},
|
||||||
methods: {
|
methods: {
|
||||||
// 触发添加购物车动画
|
|
||||||
triggerAddCartAnimation() {
|
|
||||||
this.isAnimating = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
this.isAnimating = false;
|
|
||||||
}, 600);
|
|
||||||
},
|
|
||||||
// 立即购买
|
|
||||||
handleBuyNow() {
|
handleBuyNow() {
|
||||||
this.$emit('buyNow', this.data);
|
// 触发购买事件,通知父组件
|
||||||
|
this.$emit('addToCar', this.data);
|
||||||
},
|
},
|
||||||
|
triggerAddCartAnimation() {
|
||||||
|
// 保留方法以兼容父组件调用
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@ -84,28 +66,35 @@ export default {
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.goods-item {
|
.goods-item {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 40rpx;
|
border-radius: 16rpx;
|
||||||
width: 100%;
|
|
||||||
padding: 20rpx;
|
padding: 20rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 22rpx;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-bottom: 1rpx solid #F5F5F5;
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
.goods-img {
|
.goods-img {
|
||||||
border-radius: 20rpx;
|
display: block;
|
||||||
width: 160rpx;
|
width: 100%;
|
||||||
height: 160rpx;
|
max-width: 100%;
|
||||||
}
|
height: 260rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
.goods-content {
|
background: #f5f5f5;
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
margin-left: 20rpx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.goods-name {
|
.goods-name {
|
||||||
margin: 0 0 12rpx;
|
margin: 16rpx 0 12rpx 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
word-wrap: break-word;
|
||||||
|
word-break: break-all;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #3D3D3D;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
@ -113,84 +102,45 @@ export default {
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-radius: 4rpx;
|
border-radius: 4rpx;
|
||||||
margin-bottom: 12rpx;
|
padding: 4rpx 8rpx;
|
||||||
|
|
||||||
.hot-icon {
|
.hot-icon {
|
||||||
width: 28rpx;
|
width: 28rpx;
|
||||||
height: 28rpx;
|
height: 28rpx;
|
||||||
margin-right: 6rpx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.label-name {
|
.label-name {
|
||||||
padding: 4rpx 8rpx;
|
padding-left: 4rpx;
|
||||||
color: #FF19A0;
|
color: #FF19A0;
|
||||||
|
font-size: 20rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.price-row {
|
.flex-row-between {
|
||||||
margin-top: 12rpx;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.price-text {
|
.flex-row-start {
|
||||||
color: #3D3D3D;
|
|
||||||
}
|
|
||||||
|
|
||||||
.price-label {
|
|
||||||
color: #999;
|
|
||||||
margin-left: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.origin-price {
|
|
||||||
color: #999;
|
|
||||||
margin-top: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-cart-icon {
|
|
||||||
width: 44rpx;
|
|
||||||
height: 44rpx;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 20rpx;
|
|
||||||
right: 20rpx;
|
|
||||||
transition: transform 0.3s ease;
|
|
||||||
|
|
||||||
&.add-cart-icon-animate {
|
|
||||||
animation: addCartBounce 0.6s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.buy-now-btn-wrapper {
|
|
||||||
margin-top: 16rpx;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price-wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
.buy-now-btn {
|
.buy-now-btn {
|
||||||
background: linear-gradient(90deg, #FF19A0, #FF4DB8);
|
background: #FF19A0;
|
||||||
color: #FFFFFF;
|
color: #fff;
|
||||||
font-size: 24rpx;
|
font-size: 20rpx;
|
||||||
padding: 12rpx 32rpx;
|
padding: 10rpx 20rpx;
|
||||||
border-radius: 24rpx;
|
border-radius: 30rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
flex-shrink: 0;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes addCartBounce {
|
|
||||||
0% {
|
|
||||||
transform: scale(1) rotate(0deg);
|
|
||||||
}
|
|
||||||
25% {
|
|
||||||
transform: scale(1.2) rotate(-10deg);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: scale(1.3) rotate(10deg);
|
|
||||||
}
|
|
||||||
75% {
|
|
||||||
transform: scale(1.1) rotate(-5deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: scale(1) rotate(0deg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -70,8 +70,14 @@
|
|||||||
<scroll-view class="category-right" scroll-y :refresher-enabled="true"
|
<scroll-view class="category-right" scroll-y :refresher-enabled="true"
|
||||||
:refresher-triggered="refreshTriggered" @refresherrefresh="onRefresh" @scrolltolower="onLoadMore">
|
:refresher-triggered="refreshTriggered" @refresherrefresh="onRefresh" @scrolltolower="onLoadMore">
|
||||||
<view class="goods-list">
|
<view class="goods-list">
|
||||||
<good-item v-for="good in goodsList" :key="good.product_id" :ref="`goodItem_${good.product_id}`"
|
<view class="goods-list-item left">
|
||||||
:data="good" @addToCar="addToCar" @clickCard="jumpToDetail" />
|
<good-item v-for="(good, i) in leftColumnGoods" :key="2 * i" :ref="`goodItem_${good.product_id}`"
|
||||||
|
:data="good" @addToCar="addToCar" />
|
||||||
|
</view>
|
||||||
|
<view class="goods-list-item right">
|
||||||
|
<good-item v-for="(good, i) in rightColumnGoods" :key="2 * i + 1" :ref="`goodItem_${good.product_id}`"
|
||||||
|
:data="good" @addToCar="addToCar" />
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
@ -109,6 +115,7 @@ import CategoryModal from "./components/CategoryModal.vue";
|
|||||||
import {
|
import {
|
||||||
getGoodsListData
|
getGoodsListData
|
||||||
} from "../../../api/shop";
|
} from "../../../api/shop";
|
||||||
|
import { getCategoryGoodsWithCache } from "@/utils/goodsCache";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -179,6 +186,12 @@ export default {
|
|||||||
) || {}
|
) || {}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
leftColumnGoods() {
|
||||||
|
return this.goodsList.filter((v, i) => i % 2 === 0);
|
||||||
|
},
|
||||||
|
rightColumnGoods() {
|
||||||
|
return this.goodsList.filter((v, i) => i % 2 === 1);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getCategoryList();
|
this.getCategoryList();
|
||||||
@ -195,6 +208,10 @@ export default {
|
|||||||
},
|
},
|
||||||
onShow() {
|
onShow() {
|
||||||
this.getCartListData();
|
this.getCartListData();
|
||||||
|
// 页面显示时检查是否需要刷新商品数据
|
||||||
|
if (this.selectCategoryId) {
|
||||||
|
this.getShopList(false);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
selectCategoryId(val) {
|
selectCategoryId(val) {
|
||||||
@ -227,12 +244,15 @@ export default {
|
|||||||
changeCateg(item) {
|
changeCateg(item) {
|
||||||
this.changeId = item.id
|
this.changeId = item.id
|
||||||
this.selectCategoryId = item.id;
|
this.selectCategoryId = item.id;
|
||||||
|
this.page = 1; // 切换分类时重置分页
|
||||||
|
this.goodsList = []; // 清空当前商品列表
|
||||||
this.showAllCategory = false;
|
this.showAllCategory = false;
|
||||||
// console.log(item,'--')
|
this.getShopList(true); // 切换分类时强制刷新
|
||||||
|
|
||||||
},
|
},
|
||||||
// 商品列表
|
// 商品列表
|
||||||
getShopList() {
|
getShopList(forceRefresh = false) {
|
||||||
|
// 如果不是第一页,直接请求不使用缓存(分页加载)
|
||||||
|
if (this.page > 1) {
|
||||||
getGoodsListData({
|
getGoodsListData({
|
||||||
type: this.changeId,
|
type: this.changeId,
|
||||||
p: this.page,
|
p: this.page,
|
||||||
@ -242,14 +262,41 @@ export default {
|
|||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const list = res?.data || [];
|
const list = res?.data || [];
|
||||||
this.goodsList =
|
this.goodsList = [...this.goodsList, ...list];
|
||||||
this.page === 1 ? list : [...this.goodsList, ...list];
|
|
||||||
this.total = res?.count || 0;
|
this.total = res?.count || 0;
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.refreshTriggered = false;
|
this.refreshTriggered = false;
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第一页使用缓存
|
||||||
|
const params = {
|
||||||
|
type: this.changeId,
|
||||||
|
p: this.page,
|
||||||
|
num: this.size,
|
||||||
|
keyword: "",
|
||||||
|
is_tui: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
getCategoryGoodsWithCache(params, forceRefresh)
|
||||||
|
.then((res) => {
|
||||||
|
const list = res?.data || [];
|
||||||
|
// 只有当数据有变化时才更新商品列表,避免不必要的刷新
|
||||||
|
if (res.hasChanged !== false || this.goodsList.length === 0) {
|
||||||
|
this.goodsList = list;
|
||||||
|
}
|
||||||
|
this.total = res?.count || list.length || 0;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('获取商品列表失败', err);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
this.refreshTriggered = false;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
changeCategory(data) {
|
changeCategory(data) {
|
||||||
console.log(data, '--=')
|
console.log(data, '--=')
|
||||||
@ -354,7 +401,7 @@ export default {
|
|||||||
this.page = 1;
|
this.page = 1;
|
||||||
this.size = 10;
|
this.size = 10;
|
||||||
this.total = 0;
|
this.total = 0;
|
||||||
this.getShopList();
|
this.getShopList(true); // 下拉刷新时强制刷新
|
||||||
},
|
},
|
||||||
onLoadMore() {
|
onLoadMore() {
|
||||||
if (!this.isLoading && this.total > this.goodsList.length) {
|
if (!this.isLoading && this.total > this.goodsList.length) {
|
||||||
@ -589,6 +636,24 @@ export default {
|
|||||||
.category-right {
|
.category-right {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
|
.goods-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
|
||||||
|
.goods-list-item {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,6 +48,9 @@
|
|||||||
<view class="loginBtn" @click="toLogin" v-if="!userInfo.userID">
|
<view class="loginBtn" @click="toLogin" v-if="!userInfo.userID">
|
||||||
注册/登陆
|
注册/登陆
|
||||||
</view>
|
</view>
|
||||||
|
<view class="logoutBtn" @click="logout" v-if="userInfo.userID">
|
||||||
|
退出登录
|
||||||
|
</view>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
<view class="shadowBackground" />
|
<view class="shadowBackground" />
|
||||||
@ -59,11 +62,11 @@
|
|||||||
</view> -->
|
</view> -->
|
||||||
<view class="goods-list">
|
<view class="goods-list">
|
||||||
<view class="goods-list-item left">
|
<view class="goods-list-item left">
|
||||||
<good-item v-for="(good, i) in leftColumnGoods" :index="2 * i" :key="2 * i" :data="good"
|
<good-item v-for="(good, i) in leftColumnGoods" :index="2 * i" :key="2 * i" :data="good" :isHome="true"
|
||||||
@addToCar="addToCar" />
|
@addToCar="addToCar" />
|
||||||
</view>
|
</view>
|
||||||
<view class="goods-list-item right">
|
<view class="goods-list-item right">
|
||||||
<good-item v-for="(good, i) in rightColumnGoods" :index="2 * i + 1" :key="2 * i + 1" :data="good"
|
<good-item v-for="(good, i) in rightColumnGoods" :index="2 * i + 1" :key="2 * i + 1" :data="good" :isHome="true"
|
||||||
@addToCar="addToCar" />
|
@addToCar="addToCar" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -85,6 +88,9 @@ import {
|
|||||||
import {
|
import {
|
||||||
userWllet
|
userWllet
|
||||||
} from "../../../api/login";
|
} from "../../../api/login";
|
||||||
|
import {
|
||||||
|
loginOut,
|
||||||
|
} from "../../../api/user";
|
||||||
import WeChatCopyModal from "@/components/WeChatCopyModal.vue";
|
import WeChatCopyModal from "@/components/WeChatCopyModal.vue";
|
||||||
import GoodItem from "../shop/components/GoodItem.vue";
|
import GoodItem from "../shop/components/GoodItem.vue";
|
||||||
import DraggableContact from "@/components/DraggableContact.vue";
|
import DraggableContact from "@/components/DraggableContact.vue";
|
||||||
@ -92,6 +98,7 @@ import {
|
|||||||
getGoodsClassify,
|
getGoodsClassify,
|
||||||
getGoodsListData
|
getGoodsListData
|
||||||
} from "@/api/shop";
|
} from "@/api/shop";
|
||||||
|
import { getHomeGoodsWithCache } from "@/utils/goodsCache";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "HomePage",
|
name: "HomePage",
|
||||||
@ -174,19 +181,28 @@ export default {
|
|||||||
created() {
|
created() {
|
||||||
this.getGoodsList()
|
this.getGoodsList()
|
||||||
},
|
},
|
||||||
|
onShow() {
|
||||||
|
// 页面显示时检查是否需要刷新商品数据
|
||||||
|
this.getGoodsList(false);
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getGoodsList() {
|
getGoodsList(forceRefresh = false) {
|
||||||
if (this.isLoadingGoods) return;
|
if (this.isLoadingGoods) return;
|
||||||
this.isLoadingGoods = true;
|
this.isLoadingGoods = true;
|
||||||
const params = {
|
const params = {
|
||||||
type: 0
|
type: 0
|
||||||
}
|
}
|
||||||
getGoodsListData(params)
|
getHomeGoodsWithCache(params, forceRefresh)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const list = res?.data.data.products || [];
|
const list = res?.data.data.products || [];
|
||||||
|
// 只有当数据有变化时才更新商品列表,避免不必要的刷新
|
||||||
|
if (res.hasChanged !== false || this.goodsList.length === 0) {
|
||||||
this.goodsList = list;
|
this.goodsList = list;
|
||||||
console.log(this.goodsList,'???')
|
}
|
||||||
this.goodsTotal = res?.count || 0;
|
this.goodsTotal = res?.count || list.length || 0;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('获取商品列表失败', err);
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.isLoadingGoods = false;
|
this.isLoadingGoods = false;
|
||||||
@ -198,6 +214,17 @@ export default {
|
|||||||
url: "/pages/client/auth/index",
|
url: "/pages/client/auth/index",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
logout() {
|
||||||
|
loginOut();
|
||||||
|
// 清除Vuex中的用户状态
|
||||||
|
this.$store.dispatch('user/deleteToken');
|
||||||
|
this.$store.dispatch('user/clearUserInfo');
|
||||||
|
// 清除本地缓存
|
||||||
|
uni.clearStorageSync();
|
||||||
|
uni.reLaunch({
|
||||||
|
url: "/pages/client/auth/index",
|
||||||
|
});
|
||||||
|
},
|
||||||
// 统一的 token 检查方法,未登录时弹窗让用户自主选择
|
// 统一的 token 检查方法,未登录时弹窗让用户自主选择
|
||||||
async checkTokenAndExecute(callback) {
|
async checkTokenAndExecute(callback) {
|
||||||
const token = uni.getStorageSync('token');
|
const token = uni.getStorageSync('token');
|
||||||
@ -398,6 +425,7 @@ export default {
|
|||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
margin-top: 50rpx;
|
margin-top: 50rpx;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
|
||||||
.goods-list-item {
|
.goods-list-item {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -591,6 +619,16 @@ export default {
|
|||||||
margin-left: 8rpx;
|
margin-left: 8rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logoutBtn {
|
||||||
|
background: linear-gradient(270deg, #FF19A0 0%, #FF6BB3 100%);
|
||||||
|
border-radius: 218px;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 23rpx;
|
||||||
|
padding: 16rpx 24rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.shadowBackground {
|
.shadowBackground {
|
||||||
|
|||||||
@ -14,12 +14,18 @@
|
|||||||
{{ userInfo.userID && userInfo.username ? userInfo.username : '嗨,你好呀' }}
|
{{ userInfo.userID && userInfo.username ? userInfo.username : '嗨,你好呀' }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="userPhone" v-if="userInfo.phone">
|
||||||
|
{{ userInfo.phone }}
|
||||||
|
</view>
|
||||||
<!-- <view class="vipWrapper">
|
<!-- <view class="vipWrapper">
|
||||||
<image class="lableImg" :src="`${imgPrefix}home-vipLabel.png`" mode=""></image>
|
<image class="lableImg" :src="`${imgPrefix}home-vipLabel.png`" mode=""></image>
|
||||||
v{{ userInfo.vipLevel || 1 }}会员
|
v{{ userInfo.vipLevel || 1 }}会员
|
||||||
</view> -->
|
</view> -->
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="logoutBtn" @click="showLogoutModal = true">
|
||||||
|
退出登录
|
||||||
|
</view>
|
||||||
<!-- <view class="userRight">
|
<!-- <view class="userRight">
|
||||||
<view class="userRgihtItemView" @click="jumpTo('/pages/client/recharge/index?tab=points')">
|
<view class="userRgihtItemView" @click="jumpTo('/pages/client/recharge/index?tab=points')">
|
||||||
<view class="num">
|
<view class="num">
|
||||||
@ -300,6 +306,10 @@ components: {
|
|||||||
logout() {
|
logout() {
|
||||||
loginOut();
|
loginOut();
|
||||||
this.showLogoutModal = false;
|
this.showLogoutModal = false;
|
||||||
|
// 清除Vuex中的用户状态
|
||||||
|
this.$store.dispatch('user/deleteToken');
|
||||||
|
this.$store.dispatch('user/clearUserInfo');
|
||||||
|
// 清除本地缓存
|
||||||
uni.clearStorageSync();
|
uni.clearStorageSync();
|
||||||
uni.reLaunch({
|
uni.reLaunch({
|
||||||
url: "/pages/client/auth/index",
|
url: "/pages/client/auth/index",
|
||||||
@ -390,6 +400,21 @@ title: '请添加客服号',
|
|||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.userPhone {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logoutBtn {
|
||||||
|
background: linear-gradient(270deg, #FF19A0 0%, #FF6BB3 100%);
|
||||||
|
color: #fff;
|
||||||
|
padding: 16rpx 32rpx;
|
||||||
|
border-radius: 50rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.userRight {
|
.userRight {
|
||||||
|
|||||||
@ -14,23 +14,25 @@
|
|||||||
mode="aspectFill"
|
mode="aspectFill"
|
||||||
/>
|
/>
|
||||||
<view class="goods-content">
|
<view class="goods-content">
|
||||||
<view class="goods-row-first">
|
|
||||||
<view class="goods-name">{{
|
<view class="goods-name">{{
|
||||||
item.item_name || item.product_name
|
item.item_name || item.product_name
|
||||||
}}</view>
|
}}</view>
|
||||||
<text class="goods-price"
|
<view class="price-wrapper">
|
||||||
>¥{{ item.product_price || item.goods_price }}</text
|
<text class="final-price-label">到手价</text>
|
||||||
>
|
<text class="final-price">¥{{ item.product_price || item.goods_price }}</text>
|
||||||
|
<text class="original-price">
|
||||||
|
¥{{ item.original_price || (item.product_price * 1.5).toFixed(2) }}
|
||||||
|
</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="goods-row-second">
|
<view class="sales-info">
|
||||||
<text class="goods-count">共{{ item.number || 1 }}件</text>
|
<text class="sales-count">已售0件</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="info-cell pay-cell">
|
<!-- <view class="info-cell pay-cell">
|
||||||
<view class="flex-row-between pay-info">
|
<view class="flex-row-between pay-info">
|
||||||
<text class="pay-label">商品金额</text>
|
<text class="pay-label">商品金额</text>
|
||||||
<text class="pay-value">¥{{ payPrice }}</text>
|
<text class="pay-value">¥{{ payPrice }}</text>
|
||||||
@ -52,15 +54,11 @@
|
|||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- <view class="flex-row-between pay-info">
|
|
||||||
<text class="pay-label">运费</text>
|
|
||||||
<text class="pay-value">{{ sliverFee ? `¥${sliverFee}` : "包邮" }}</text>
|
|
||||||
</view> -->
|
|
||||||
<view class="flex-row-between pay-price">
|
<view class="flex-row-between pay-price">
|
||||||
<text class="pay-label">需付款</text>
|
<text class="pay-label">需付款</text>
|
||||||
<text class="pay-total">¥{{ payPrice }}</text>
|
<text class="pay-total">¥{{ payPrice }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view> -->
|
||||||
|
|
||||||
<!-- <view class="info-cell payment-method-cell">
|
<!-- <view class="info-cell payment-method-cell">
|
||||||
<view class="payment-item" @click.stop="selectOption1('1')">
|
<view class="payment-item" @click.stop="selectOption1('1')">
|
||||||
@ -517,7 +515,7 @@ export default {
|
|||||||
|
|
||||||
.goods-item {
|
.goods-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: flex-start;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 24rpx 20rpx;
|
padding: 24rpx 20rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@ -528,61 +526,66 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.goods-img {
|
.goods-img {
|
||||||
width: 100rpx;
|
width: 200rpx;
|
||||||
height: 100rpx;
|
height: 200rpx;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
margin-right: 20rpx;
|
margin-right: 20rpx;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
background: #f5f5f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.goods-content {
|
.goods-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: flex-start;
|
||||||
min-height: 100rpx;
|
min-height: 200rpx;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
padding-top: 8rpx;
|
||||||
.goods-row-first {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 12rpx;
|
|
||||||
|
|
||||||
.goods-name {
|
.goods-name {
|
||||||
flex: 1;
|
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
color: #3d3d3d;
|
color: #3d3d3d;
|
||||||
line-height: 40rpx;
|
line-height: 40rpx;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
display: -webkit-box;
|
||||||
margin-right: 20rpx;
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.goods-price {
|
.price-wrapper {
|
||||||
flex-shrink: 0;
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #3d3d3d;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.goods-row-second {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: baseline;
|
||||||
justify-content: space-between;
|
margin-bottom: 12rpx;
|
||||||
|
|
||||||
.goods-spec {
|
.final-price-label {
|
||||||
flex: 1;
|
font-size: 24rpx;
|
||||||
|
color: #ff19a0;
|
||||||
|
background: linear-gradient(to right, #ffeef7, #fff);
|
||||||
|
padding: 4rpx 12rpx;
|
||||||
|
border-radius: 4rpx 0 0 4rpx;
|
||||||
|
margin-right: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.final-price {
|
||||||
|
font-size: 36rpx;
|
||||||
|
color: #ff19a0;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-right: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.original-price {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #999;
|
color: #999;
|
||||||
margin-right: 20rpx;
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.goods-count {
|
.sales-info {
|
||||||
flex-shrink: 0;
|
.sales-count {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="goods-item" >
|
<view class="goods-item" :class="{ 'goods-item-home': isHome }">
|
||||||
<image @click.stop="handleBuyNow" class="goods-img" :src="getProductImage(data)" mode="aspectFill" />
|
<image @click.stop="handleBuyNow" class="goods-img" :src="getProductImage(data)" mode="aspectFill" />
|
||||||
<view class=" fs-24 app-fc-main goods-name">
|
<view class=" fs-24 app-fc-main goods-name">
|
||||||
{{ data.product.product_name || "" }}
|
{{ data.product.product_name || "" }}
|
||||||
@ -43,6 +43,10 @@
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
|
isHome: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -94,7 +98,7 @@
|
|||||||
.goods-item {
|
.goods-item {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
padding: 20rpx;
|
padding: 2rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin-bottom: 22rpx;
|
margin-bottom: 22rpx;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -102,15 +106,24 @@
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
&.goods-item-home {
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
.goods-img {
|
.goods-img {
|
||||||
display: block;
|
display: block;
|
||||||
|
// width: 260rpx;
|
||||||
|
height: 260rpx;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 100%;
|
// max-width: 100%;
|
||||||
height: 320rpx;
|
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
background: #f5f5f5;
|
background: #f5f5f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.goods-item-home .goods-img {
|
||||||
|
height: 145px;
|
||||||
|
}
|
||||||
|
|
||||||
.goods-name {
|
.goods-name {
|
||||||
margin: 20rpx 0;
|
margin: 20rpx 0;
|
||||||
// overflow: hidden;
|
// overflow: hidden;
|
||||||
|
|||||||
273
src/utils/goodsCache.js
Normal file
273
src/utils/goodsCache.js
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
/**
|
||||||
|
* 商品数据缓存工具
|
||||||
|
* 用于首页和分类页的商品列表缓存,避免重复请求相同数据
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { getGoodsListData } from '@/api/shop'
|
||||||
|
|
||||||
|
// 缓存存储对象
|
||||||
|
const goodsCache = {
|
||||||
|
// 首页商品缓存
|
||||||
|
home: null,
|
||||||
|
// 分类页商品缓存,key为分类ID
|
||||||
|
category: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 缓存过期时间(5分钟,单位:毫秒)
|
||||||
|
const CACHE_EXPIRE_TIME = 5 * 60 * 1000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算数据的哈希值,用于判断数据是否有变化
|
||||||
|
* @param {Array} data - 商品数据列表
|
||||||
|
* @returns {string} 数据哈希值
|
||||||
|
*/
|
||||||
|
function calculateDataHash(data) {
|
||||||
|
if (!data || !Array.isArray(data) || data.length === 0) {
|
||||||
|
return 'empty'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用商品ID、价格、更新时间等关键信息计算哈希
|
||||||
|
const keyData = data.map(item => {
|
||||||
|
const product = item.product || item
|
||||||
|
return `${product.product_id || product.id}-${product.updated_at || Date.now()}-${item.sku?.actual_amount || product.price || 0}`
|
||||||
|
}).join('|')
|
||||||
|
|
||||||
|
// 简单的字符串哈希函数
|
||||||
|
let hash = 0
|
||||||
|
for (let i = 0; i < keyData.length; i++) {
|
||||||
|
const char = keyData.charCodeAt(i)
|
||||||
|
hash = ((hash << 5) - hash) + char
|
||||||
|
hash = hash & hash // 转换为32位整数
|
||||||
|
}
|
||||||
|
return hash.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取缓存的首页商品数据
|
||||||
|
* @returns {Object|null} 缓存的商品数据,包含数据、哈希值和时间戳
|
||||||
|
*/
|
||||||
|
export function getHomeGoodsCache() {
|
||||||
|
return goodsCache.home
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置首页商品缓存
|
||||||
|
* @param {Array} data - 商品数据列表
|
||||||
|
*/
|
||||||
|
export function setHomeGoodsCache(data) {
|
||||||
|
goodsCache.home = {
|
||||||
|
data,
|
||||||
|
hash: calculateDataHash(data),
|
||||||
|
timestamp: Date.now()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定分类的商品缓存
|
||||||
|
* @param {Number|String} categoryId - 分类ID
|
||||||
|
* @returns {Object|null} 缓存的商品数据
|
||||||
|
*/
|
||||||
|
export function getCategoryGoodsCache(categoryId) {
|
||||||
|
return goodsCache.category[categoryId] || null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置指定分类的商品缓存
|
||||||
|
* @param {Number|String} categoryId - 分类ID
|
||||||
|
* @param {Array} data - 商品数据列表
|
||||||
|
*/
|
||||||
|
export function setCategoryGoodsCache(categoryId, data) {
|
||||||
|
goodsCache.category[categoryId] = {
|
||||||
|
data,
|
||||||
|
hash: calculateDataHash(data),
|
||||||
|
timestamp: Date.now()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查缓存是否有效
|
||||||
|
* @param {Object} cache - 缓存对象
|
||||||
|
* @returns {Boolean} 缓存是否有效
|
||||||
|
*/
|
||||||
|
function isCacheValid(cache) {
|
||||||
|
if (!cache) return false
|
||||||
|
|
||||||
|
const now = Date.now()
|
||||||
|
// 检查缓存是否过期
|
||||||
|
if (now - cache.timestamp > CACHE_EXPIRE_TIME) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取首页商品数据(带缓存)
|
||||||
|
* @param {Object} params - 请求参数
|
||||||
|
* @param {Boolean} forceRefresh - 是否强制刷新
|
||||||
|
* @returns {Promise} 商品数据
|
||||||
|
*/
|
||||||
|
export function getHomeGoodsWithCache(params, forceRefresh = false) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const cache = getHomeGoodsCache()
|
||||||
|
|
||||||
|
// 如果有有效缓存且不强制刷新,先返回缓存数据
|
||||||
|
if (!forceRefresh && isCacheValid(cache)) {
|
||||||
|
// 先从缓存返回数据
|
||||||
|
resolve({
|
||||||
|
data: { data: { products: cache.data } },
|
||||||
|
fromCache: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 无论是否有缓存,都请求最新数据进行对比
|
||||||
|
getGoodsListData(params).then(res => {
|
||||||
|
const newData = res?.data.data.products || []
|
||||||
|
const newHash = calculateDataHash(newData)
|
||||||
|
|
||||||
|
// 检查数据是否有变化
|
||||||
|
const hasChanged = !cache || cache.hash !== newHash
|
||||||
|
|
||||||
|
if (hasChanged || forceRefresh) {
|
||||||
|
// 更新缓存
|
||||||
|
setHomeGoodsCache(newData)
|
||||||
|
|
||||||
|
// 如果没有缓存或者数据有变化,返回最新数据
|
||||||
|
if (!cache || forceRefresh) {
|
||||||
|
resolve({
|
||||||
|
...res,
|
||||||
|
fromCache: false,
|
||||||
|
hasChanged: true
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 如果已有缓存但数据有变化,通知更新
|
||||||
|
resolve({
|
||||||
|
...res,
|
||||||
|
fromCache: false,
|
||||||
|
hasChanged: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 数据没有变化,更新缓存时间戳
|
||||||
|
cache.timestamp = Date.now()
|
||||||
|
resolve({
|
||||||
|
data: { data: { products: cache.data } },
|
||||||
|
fromCache: true,
|
||||||
|
hasChanged: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
// 如果请求失败但有缓存,返回缓存
|
||||||
|
if (cache) {
|
||||||
|
resolve({
|
||||||
|
data: { data: { products: cache.data } },
|
||||||
|
fromCache: true,
|
||||||
|
error: err
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类页商品数据(带缓存)
|
||||||
|
* @param {Object} params - 请求参数
|
||||||
|
* @param {Boolean} forceRefresh - 是否强制刷新
|
||||||
|
* @returns {Promise} 商品数据
|
||||||
|
*/
|
||||||
|
export function getCategoryGoodsWithCache(params, forceRefresh = false) {
|
||||||
|
const categoryId = params.type || params.category_id || ''
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const cache = getCategoryGoodsCache(categoryId)
|
||||||
|
|
||||||
|
// 如果有有效缓存且不强制刷新,先返回缓存数据
|
||||||
|
if (!forceRefresh && isCacheValid(cache)) {
|
||||||
|
resolve({
|
||||||
|
data: cache.data,
|
||||||
|
count: cache.data.length,
|
||||||
|
fromCache: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 无论是否有缓存,都请求最新数据进行对比
|
||||||
|
getGoodsListData(params).then(res => {
|
||||||
|
const newData = res?.data || []
|
||||||
|
const newHash = calculateDataHash(newData)
|
||||||
|
|
||||||
|
// 检查数据是否有变化
|
||||||
|
const hasChanged = !cache || cache.hash !== newHash
|
||||||
|
|
||||||
|
if (hasChanged || forceRefresh) {
|
||||||
|
// 更新缓存
|
||||||
|
setCategoryGoodsCache(categoryId, newData)
|
||||||
|
|
||||||
|
if (!cache || forceRefresh) {
|
||||||
|
resolve({
|
||||||
|
...res,
|
||||||
|
fromCache: false,
|
||||||
|
hasChanged: true
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
resolve({
|
||||||
|
...res,
|
||||||
|
fromCache: false,
|
||||||
|
hasChanged: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 数据没有变化,更新缓存时间戳
|
||||||
|
cache.timestamp = Date.now()
|
||||||
|
resolve({
|
||||||
|
data: cache.data,
|
||||||
|
count: cache.data.length,
|
||||||
|
fromCache: true,
|
||||||
|
hasChanged: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
// 如果请求失败但有缓存,返回缓存
|
||||||
|
if (cache) {
|
||||||
|
resolve({
|
||||||
|
data: cache.data,
|
||||||
|
count: cache.data.length,
|
||||||
|
fromCache: true,
|
||||||
|
error: err
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除所有商品缓存
|
||||||
|
*/
|
||||||
|
export function clearGoodsCache() {
|
||||||
|
goodsCache.home = null
|
||||||
|
goodsCache.category = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除指定分类的商品缓存
|
||||||
|
* @param {Number|String} categoryId - 分类ID
|
||||||
|
*/
|
||||||
|
export function clearCategoryGoodsCache(categoryId) {
|
||||||
|
if (goodsCache.category[categoryId]) {
|
||||||
|
delete goodsCache.category[categoryId]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
getHomeGoodsCache,
|
||||||
|
setHomeGoodsCache,
|
||||||
|
getCategoryGoodsCache,
|
||||||
|
setCategoryGoodsCache,
|
||||||
|
getHomeGoodsWithCache,
|
||||||
|
getCategoryGoodsWithCache,
|
||||||
|
clearGoodsCache,
|
||||||
|
clearCategoryGoodsCache
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user