suke-mp/src/pages/mall/index.vue

323 lines
8.2 KiB
Vue

<template>
<view class='content' v-if='companyConfigInfo.mallopen==1'>
<view class='search-view'>
<view class='search-input' @click.stop='goPath("/pages/mall/subs/search/index")'>
<image :src=' assetsUrl("ic_search.png")'></image>
<input placeholder='输入名称、款号搜索' :disabled='true' />
</view>
</view>
<view class='container'>
<scroll-view class='category-list' :scroll-y='true'>
<view v-for='(item,index) in categoryList' :key='index' class='category-item'
@click.stop='changeCategory(index)'
:class="{'category-item-active': index === categorySelectedIndex}">
<text>{{ item.typeName }}</text>
</view>
</scroll-view>
<scroll-view class='goods-list' :scroll-y='true' type='custom' @scrolltolower='loadMore'>
<grid-view type='masonry' :cross-axis-count='2'>
<view v-for='(item, index) in goodsList' :key='index' class='goods-item'
@click.stop='goPath(`/pages/mall/subs/goods/detail?goodsId=${item.goodsId}`)'>
<image class='goods-image' :src='item.images||defaultImage' />
<text class='goods-name'>{{ item.goodsName || '未知' }}</text>
<text class='goods-price'>¥{{ (item.price * userInfo.userDiscount).toFixed(2) }}
<text v-if='userInfo.userDiscount>0&&userInfo.userDiscount<1'
style='text-decoration: line-through;color: #999999;font-size: 25rpx'>¥{{ item.price }}
</text>
</text>
<image class='add-image' :src='assetsUrl("ic_add_goods.png")' @click.stop='addShoppingCart(item)' />
</view>
</grid-view>
<u-empty v-if='goodsList.length === 0' text='暂无商品数据' />
</scroll-view>
</view>
<view class='shopping-cart' @click.stop='goPath("/pages/mall/subs/shoppingcart/index")'>
<image :src='assetsUrl("ic_shopping_cart.png")' />
<text v-if='totalCount>0'>{{ totalCount }}</text>
</view>
</view>
<view class='content' v-else style='align-items: center;justify-content:center;'>
<image :src='assetsUrl("bg_mall_close.png")' style='width: 200rpx; height: 200rpx;' />
</view>
<sku-dialog ref='skuDialogRef' />
</template>
<script setup lang='ts'>
import SkuDialog from '@/components/sku-dialog.vue';
import { assetsUrl, defaultImage } from '@/utils/assets';
import { goLogin, goPath, isLogin, showToast } from '@/utils';
import { getCategoryList, getGoodsList } from '@/api/goods';
import { CategoryBean, GoodsBean } from '@/api/goods/types';
import useShoppingCartStore from '@/store/modules/shoppingcart';
import { useUserStore } from '@/store';
const userStore = useUserStore();
const { userInfo,companyConfigInfo } = storeToRefs(userStore);
const shoppingCartStore = useShoppingCartStore();
const { totalCount } = storeToRefs(shoppingCartStore);
const skuDialogRef = ref();
const categoryList = ref<CategoryBean[]>([]);
const categorySelectedIndex = ref<number>(0);
const goodsList = ref<GoodsBean[]>([]);
const currentPageNum = ref<number>(1);
onLoad(() => {
if(!isLogin()) {
goLogin();
return;
}
userStore.$onAction(({ name, after }) => {
after(() => {
//更新用户信息
if(name === 'setUserInfo') {
fetchCategoryList();
shoppingCartStore.resetData();
}
});
});
fetchCategoryList();
});
const fetchCategoryList = async () => {
if(companyConfigInfo.value.mallopen == 1) {
const list = await getCategoryList();
list.unshift({ typeName: '上新精选', typeId: '2' });
list.unshift({ typeName: '热销商品', typeId: '1' });
list.unshift({ typeName: '全部分类', typeId: '0' });
categoryList.value = list;
await changeCategory(0);
}
};
const changeCategory = async (index: number) => {
categorySelectedIndex.value = index;
await fetchGoodsList();
};
const fetchGoodsList = async (refresh: boolean = true) => {
currentPageNum.value = refresh ? 1 : currentPageNum.value + 1;
let typeId = [categoryList.value[categorySelectedIndex.value].typeId];
let sort = undefined;
if(typeId[0] === '0') {
typeId = [];
sort = undefined;
} else if(typeId[0] === '1') {
typeId = [];
sort = 'good_num DESC';
} else if(typeId[0] === '2') {
typeId = [];
sort = 'update_time DESC';
}
const { rows } = await getGoodsList({
page: {
pageNum: currentPageNum.value,
pageSize: 30,
bean: {
keyword: '',
typeIds: typeId,
sort: sort
}
}
});
if(refresh) {
goodsList.value = rows;
} else {
goodsList.value = goodsList.value.concat(rows);
}
};
const loadMore = () => {
fetchGoodsList(false);
};
const randomImageHeight = () => {
const height = getRandomFloatInRange(1, 2) * 200 + 'rpx';
console.log('--------->>>', height);
return height;
};
const getRandomFloatInRange = (a: number, b: number) => {
return Math.random() * (b - a) + a;
};
const addShoppingCart = (goodsBean: GoodsBean) => {
skuDialogRef.value.show(goodsBean.goodsId, (e: GoodsBean) => {
//重新选择sku后判断当前购物中是否存在相同sku的商品
const existsIndex = shoppingCartStore.getSameGoodsIndex(e?.id || '', e.checkedStock.colorId, e.checkedStock.sizeId);
//不存在则更新当前商品sku
if(existsIndex < 0) {
shoppingCartStore.save(e);
}
//如果已存在,则更新已存在商品数量,并删除当前商品
else {
shoppingCartStore.updateCount(existsIndex, e.checkedStock.count);
}
showToast('添加购物车成功');
});
};
</script>
<style lang='scss' scoped>
.content {
display: flex;
flex-direction: column;
height: 100vh;
}
.search-view {
display: flex;
flex-direction: row;
background: white;
padding: 19rpx 30rpx;
.search-input {
display: flex;
flex-direction: row;
align-items: center;
background: #F7F7F7;
padding: 17rpx 23rpx;
font-size: 26rpx;
width: 100%;
image {
width: 32rpx;
height: 32rpx;
margin-right: 20rpx;
}
}
}
.container {
display: flex;
flex-direction: row;
margin-top: 20rpx;
.category-list {
display: flex;
flex-direction: column;
width: 280rpx;
height: 100vh;
.category-item {
display: flex;
width: 100%;
height: 92rpx;
overflow: hidden;
align-items: center;
justify-content: center;
white-space: nowrap;
text {
width: 60%;
text-align: center;
font-size: 30rpx;
text-overflow: ellipsis;
overflow: hidden;
}
}
.category-item-active {
@extend .category-item;
background: #FFFFFF;
}
.category-item-active:before {
content: '';
position: absolute;
width: 5rpx;
left: 15rpx;
height: 30rpx;
background: #333333;
color: #333333;
}
}
.goods-list {
display: flex;
background: white;
padding: 38rpx 20rpx 0 20rpx;
height: 100vh;
.goods-item {
display: flex;
flex-direction: column;
position: relative;
margin-bottom: 10rpx;
padding: 10rpx 10rpx;
.goods-image {
border-radius: 10rpx;
width: 100%;
max-height: 300rpx;
}
.goods-name {
font-size: 28rpx;
font-weight: 400;
color: #333333;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
margin-top: 10rpx;
}
.goods-price {
font-size: 36rpx;
font-weight: bold;
color: #F32B2B;
}
.add-image {
width: 42rpx;
height: 42rpx;
position: absolute;
bottom: 10rpx;
right: 10rpx;
}
}
}
}
.shopping-cart {
display: flex;
position: fixed;
bottom: 30rpx;
right: 40rpx;
width: 90rpx;
height: 90rpx;
background: #FFFFFF;
border-radius: 50%;
align-items: center;
justify-content: center;
box-shadow: 0 0 20rpx 1rpx rgba(78, 78, 78, 0.16);
image {
width: 40rpx;
height: 40rpx;
}
text {
display: flex;
min-width: 39rpx;
min-height: 39rpx;
background: #F32B2B;
align-items: center;
justify-content: center;
top: -5rpx;
right: -5rpx;
color: white;
font-size: 26rpx;
position: absolute;
border-radius: 50%;
border: 2rpx solid #FFFFFF;
}
}
</style>