323 lines
8.2 KiB
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>
|