mirror of
http://git.coreshop.cn/jianweie/coreshoppro.git
synced 2026-02-05 04:59:48 +08:00
uniapp【修复】: 修复页面下拉刷新时数据重复问题
This commit is contained in:
@@ -1,64 +1,64 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="props.type == 'horizontal' ? 'horizontal-good-card-box' : 'vertical-good-card-box'">
|
<view :class="props.type == 'horizontal' ? 'horizontal-good-card-box' : 'vertical-good-card-box'">
|
||||||
<view class="img-box" :style="{ 'width': props.imgWidth, 'height': props.imgHeight }" @click="hanldeClickGoods">
|
<view class="img-box" :style="{ 'width': props.imgWidth, 'height': props.imgHeight }" @click="hanldeClickGoods">
|
||||||
<image class="good-img" :src="props.goodsData.image"></image>
|
<image class="good-img" :src="props.goodsData.image"></image>
|
||||||
<view class="recommend" v-if="props.goodsData.isRecommend">推荐</view>
|
<view class="recommend" v-if="props.goodsData.isRecommend">推荐</view>
|
||||||
<view class="hot" v-if="props.goodsData.isHot">热门</view>
|
<view class="hot" v-if="props.goodsData.isHot">热门</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="good-msg"
|
<view class="good-msg"
|
||||||
:style="{ 'width': props.type == 'horizontal' ? `calc(100% - 10px - ${props.imgWidth})` : props.imgWidth}">
|
:style="{ 'width': props.type == 'horizontal' ? `calc(100% - 10px - ${props.imgWidth})` : props.imgWidth}">
|
||||||
<view v-if="props.goodsData.name" :class="props.nameOverflow === 1 ? 'name' : 'name-two'"
|
<view v-if="props.goodsData.name" :class="props.nameOverflow === 1 ? 'name' : 'name-two'"
|
||||||
@click="hanldeClickGoods">
|
@click="hanldeClickGoods">
|
||||||
{{ props.goodsData.name }}
|
{{ props.goodsData.name }}
|
||||||
</view>
|
</view>
|
||||||
<view v-if="props.goodsData.brief" :class="props.briefOverflow === 1 ? 'desc' : 'desc-two'"
|
<view v-if="props.goodsData.brief" :class="props.briefOverflow === 1 ? 'desc' : 'desc-two'"
|
||||||
@click="hanldeClickGoods">
|
@click="hanldeClickGoods">
|
||||||
{{ props.goodsData.brief }}
|
{{ props.goodsData.brief }}
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<slot name="goodTag"></slot>
|
<slot name="goodTag"></slot>
|
||||||
|
|
||||||
<slot name="goodPrice">
|
<slot name="goodPrice">
|
||||||
<view class="price-msg">
|
<view class="price-msg">
|
||||||
<view class="price-box">
|
<view class="price-box">
|
||||||
<view class="price">
|
<view class="price">
|
||||||
<text class="symbol">¥</text>
|
<text class="symbol">¥</text>
|
||||||
<text class="num">{{ props.goodsData.price }}</text>
|
<text class="num">{{ props.goodsData.price }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="underlin-price">¥{{ props.goodsData.mktprice }}</view>
|
<view class="underlin-price">¥{{ props.goodsData.mktprice }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="btn">
|
<view class="btn">
|
||||||
立即购买
|
立即购买
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</slot>
|
</slot>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<slot name="other"></slot>
|
<slot name="other"></slot>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
type : 'vertical' | 'horizontal',
|
type ?: 'vertical' | 'horizontal',
|
||||||
imgWidth : string,
|
imgWidth ?: string,
|
||||||
imgHeight : string,
|
imgHeight ?: string,
|
||||||
nameOverflow : number,
|
nameOverflow ?: number,
|
||||||
briefOverflow : number,
|
briefOverflow ?: number,
|
||||||
goodsData : any,
|
goodsData ?: any,
|
||||||
}>(), {
|
}>(), {
|
||||||
type: 'horizontal', // vertical 垂直 horizontal 水平
|
type: 'horizontal', // vertical 垂直 horizontal 水平
|
||||||
imgWidth: '190rpx',
|
imgWidth: '190rpx',
|
||||||
imgHeight: '190rpx',
|
imgHeight: '190rpx',
|
||||||
nameOverflow: 1,
|
nameOverflow: 1,
|
||||||
briefOverflow: 1,
|
briefOverflow: 1,
|
||||||
goodsData: {},
|
goodsData: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['hanldeClickGoods']);
|
const emit = defineEmits(['hanldeClickGoods']);
|
||||||
|
|
||||||
const hanldeClickGoods = () => {
|
const hanldeClickGoods = () => {
|
||||||
emit('hanldeClickGoods', props.goodsData)
|
emit('hanldeClickGoods', props.goodsData)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import './coreshop-goods-card.scss';
|
@import './coreshop-goods-card.scss';
|
||||||
</style>
|
</style>
|
||||||
@@ -1,39 +1,39 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="more-box" @click="hanldeClickViewMore">
|
<view class="more-box" @click="hanldeClickViewMore">
|
||||||
<text class="more-text" :style="{ 'color': props.color }">{{ props.title }}</text>
|
<text class="more-text" :style="{ 'color': props.color }">{{ props.title }}</text>
|
||||||
<view class="more-icon">
|
<view class="more-icon">
|
||||||
<uv-icon name="arrow-right" :color="props.color" :size="15"></uv-icon>
|
<uv-icon name="arrow-right" :color="props.color" :size="15"></uv-icon>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
title : string,
|
title ?: string,
|
||||||
color : string,
|
color ?: string,
|
||||||
}>(), {
|
}>(), {
|
||||||
title: '查看更多',
|
title: '查看更多',
|
||||||
color: '#6E737D'
|
color: '#6E737D'
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['hanldeClickViewMore']);
|
const emit = defineEmits(['hanldeClickViewMore']);
|
||||||
|
|
||||||
const hanldeClickViewMore = () => {
|
const hanldeClickViewMore = () => {
|
||||||
emit('hanldeClickViewMore');
|
emit('hanldeClickViewMore');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.more-box {
|
.more-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.more-text {
|
.more-text {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.more-icon {
|
.more-icon {
|
||||||
width: 30rpx;
|
width: 30rpx;
|
||||||
height: 30rpx;
|
height: 30rpx;
|
||||||
margin-top: 2rpx;
|
margin-top: 2rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -3,3 +3,6 @@ export const onHomePageShow = "onHomePageShow";
|
|||||||
|
|
||||||
/** 监听分类onHide需要的常量字段 */
|
/** 监听分类onHide需要的常量字段 */
|
||||||
export const onClassifyPageHide = "onClassifyPageHide";
|
export const onClassifyPageHide = "onClassifyPageHide";
|
||||||
|
|
||||||
|
/** 监听上拉刷新onPullDownRefresh要的常量字段 */
|
||||||
|
export const onClassifyPagePullDownRefresh = "onClassifyPagePullDownRefresh";
|
||||||
|
|||||||
@@ -240,6 +240,7 @@
|
|||||||
onPullDownRefresh(async () => {
|
onPullDownRefresh(async () => {
|
||||||
state.page = 1;
|
state.page = 1;
|
||||||
state.totalPages = 1;
|
state.totalPages = 1;
|
||||||
|
state.goodsList = [[], []];
|
||||||
await handleuQueryProduct(queryParams);
|
await handleuQueryProduct(queryParams);
|
||||||
uni.stopPullDownRefresh();
|
uni.stopPullDownRefresh();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,410 +1,416 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="layout-classify" :style="{ height: `${props.height}px` }">
|
<view class="layout-classify" :style="{ height: `${props.height}px` }">
|
||||||
<!-- 头部大分类 -->
|
<!-- 头部大分类 -->
|
||||||
<view class="big-classify">
|
<view class="big-classify">
|
||||||
<view class="scroll-view-box">
|
<view class="scroll-view-box">
|
||||||
<scroll-view class="scroll-view" enable-flex :scroll-x="true" :scroll-left="state.topScrollLeft"
|
<scroll-view class="scroll-view" enable-flex :scroll-x="true" :scroll-left="state.topScrollLeft"
|
||||||
:scroll-with-animation="true">
|
:scroll-with-animation="true">
|
||||||
<view :class="['item', { 'on': state.topTabId === item.id }]"
|
<view :class="['item', { 'on': state.topTabId === item.id }]"
|
||||||
v-for="item, index in state.classifyData" :key="index" @click="hanldeChangeTopTab(item, index)">
|
v-for="item, index in state.classifyData" :key="index" @click="hanldeChangeTopTab(item, index)">
|
||||||
<view class="img-box">
|
<view class="img-box">
|
||||||
<image class="img" :src="item.imageUrl"></image>
|
<image class="img" :src="item.imageUrl"></image>
|
||||||
</view>
|
</view>
|
||||||
<view>
|
<view>
|
||||||
<text class="tit">{{ item.name }}</text>
|
<text class="tit">{{ item.name }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
<view class="all-big-classify" @click="hanldeShowBigClassifyPop">
|
<view class="all-big-classify" @click="hanldeShowBigClassifyPop">
|
||||||
<text class="tit">全部</text>
|
<text class="tit">全部</text>
|
||||||
<image class="img" :src="handleStaticResources('/static/images/icon/all-drop-down.png')"></image>
|
<image class="img" :src="handleStaticResources('/static/images/icon/all-drop-down.png')"></image>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="classify-box" :style="{ height: `${props.height - state.bigClassifyH}px` }">
|
<view class="classify-box" :style="{ height: `${props.height - state.bigClassifyH}px` }">
|
||||||
<view class="classify-left">
|
<view class="classify-left">
|
||||||
<scroll-view class="scroll-view" enable-flex :scroll-y="true">
|
<scroll-view class="scroll-view" enable-flex :scroll-y="true">
|
||||||
<view :class="['item', { 'on': state.leftTabId === item.id }]"
|
<view :class="['item', { 'on': state.leftTabId === item.id }]"
|
||||||
v-for="item, index in state.leftTabList" :key="index" @click="hanldeChangeLeftTab(item)">
|
v-for="item, index in state.leftTabList" :key="index" @click="hanldeChangeLeftTab(item)">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</view>
|
</view>
|
||||||
<view class="no-more"></view>
|
<view class="no-more"></view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
<view class="classify-right">
|
<view class="classify-right">
|
||||||
<view class="right-tab-box">
|
<view class="right-tab-box">
|
||||||
<view>
|
<view>
|
||||||
<coreshop-tabs :list="state.rightTabList"
|
<coreshop-tabs :list="state.rightTabList"
|
||||||
@hanldeClickTab="hanldeChangeRightTab"></coreshop-tabs>
|
@hanldeClickTab="hanldeChangeRightTab"></coreshop-tabs>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<scroll-view class="scroll-view" enable-flex
|
<scroll-view class="scroll-view" enable-flex
|
||||||
:style="{ 'height': `${props.height - state.bigClassifyH - state.rightTabH}px` }" :scroll-y="true"
|
:style="{ 'height': `${props.height - state.bigClassifyH - state.rightTabH}px` }" :scroll-y="true"
|
||||||
@scrolltolower="handleScrolltolower">
|
@scrolltolower="handleScrolltolower">
|
||||||
<view class="advert-box radius-15">
|
<view class="advert-box radius-15">
|
||||||
<coreshop-advert :code="advertPosition.goodsClassifyBanner"></coreshop-advert>
|
<coreshop-advert :code="advertPosition.goodsClassifyBanner"></coreshop-advert>
|
||||||
</view>
|
</view>
|
||||||
<view class="data-box" v-if="state.goodsList.length > 0">
|
<view class="data-box" v-if="state.goodsList.length > 0">
|
||||||
<view class="item-box" v-for="item in state.goodsList" :key="item.id">
|
<view class="item-box" v-for="item in state.goodsList" :key="item.id">
|
||||||
<coreshop-goods-card imgWidth="150rpx" imgHeight="150rpx"
|
<coreshop-goods-card imgWidth="150rpx" imgHeight="150rpx"
|
||||||
:goodsData="hanldeCombinationGoodsData(item)" @hanldeClickGoods="hanldeClickGoods">
|
:goodsData="hanldeCombinationGoodsData(item)" @hanldeClickGoods="hanldeClickGoods">
|
||||||
<template #goodPrice>
|
<template #goodPrice>
|
||||||
<view class="price-msg">
|
<view class="price-msg">
|
||||||
<view class="price-box">
|
<view class="price-box">
|
||||||
<view class="price">
|
<view class="price">
|
||||||
<text class="symbol">¥</text>
|
<text class="symbol">¥</text>
|
||||||
<text class="num">{{ item.price }}</text>
|
<text class="num">{{ item.price }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="underlin-price">¥{{ item.mktprice }}</view>
|
<view class="underlin-price">¥{{ item.mktprice }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="btn" @click="handleSelectSku(item.id)">
|
<view class="btn" @click="handleSelectSku(item.id)">
|
||||||
<image class="img" :src="handleStaticResources('/static/images/cart.png')">
|
<image class="img" :src="handleStaticResources('/static/images/cart.png')">
|
||||||
</image>
|
</image>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</coreshop-goods-card>
|
</coreshop-goods-card>
|
||||||
</view>
|
</view>
|
||||||
<view class="no-more">
|
<view class="no-more">
|
||||||
<uv-divider :dashed="true"
|
<uv-divider :dashed="true"
|
||||||
:text="state.totalPages > state.page ? '下滑加载更多' : '没有更多了'"></uv-divider>
|
:text="state.totalPages > state.page ? '下滑加载更多' : '没有更多了'"></uv-divider>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-else>
|
<view v-else>
|
||||||
<coreshop-empty></coreshop-empty>
|
<coreshop-empty></coreshop-empty>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 购物车盒子 -->
|
<!-- 购物车盒子 -->
|
||||||
<view class="shopping-box">
|
<view class="shopping-box">
|
||||||
<view class="shopping-Bag">
|
<view class="shopping-Bag">
|
||||||
<view class="bag-box">
|
<view class="bag-box">
|
||||||
<image class="img" :src="handleStaticResources('/static/images/cart-bag.png')"></image>
|
<image class="img" :src="handleStaticResources('/static/images/cart-bag.png')"></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="price-box">
|
<view class="price-box">
|
||||||
<text class="num">购物车数量:{{ state.cartCount }}</text>
|
<text class="num">购物车数量:{{ state.cartCount }}</text>
|
||||||
<text class="price">¥{{ state.cartMoney }}</text>
|
<text class="price">¥{{ state.cartMoney }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="btn-buy" @click="handleGoPay">
|
<view class="btn-buy" @click="handleGoPay">
|
||||||
去结算
|
去结算
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 商品sku弹框 -->
|
<!-- 商品sku弹框 -->
|
||||||
<GoodsDetailSkuPopup :showSku="state.showSku" :goodsDetailData="state.goodsDetailData"
|
<GoodsDetailSkuPopup :showSku="state.showSku" :goodsDetailData="state.goodsDetailData"
|
||||||
:safeAreaInsetBottom="false" :buyNowNowloading="buyNowLoading" :addCartloading="addCartLoading"
|
:safeAreaInsetBottom="false" :buyNowNowloading="buyNowLoading" :addCartloading="addCartLoading"
|
||||||
@handleChangePopup="handleChangePopup" @handleAddCart="handleAddCart" @handleBuyNow="handleBuyNow">
|
@handleChangePopup="handleChangePopup" @handleAddCart="handleAddCart" @handleBuyNow="handleBuyNow">
|
||||||
</GoodsDetailSkuPopup>
|
</GoodsDetailSkuPopup>
|
||||||
|
|
||||||
<!-- 头部大分类的弹框 -->
|
<!-- 头部大分类的弹框 -->
|
||||||
<uv-popup ref="bigClassifyPop" mode="top" :safeAreaInsetBottom="false">
|
<uv-popup ref="bigClassifyPop" mode="top" :safeAreaInsetBottom="false">
|
||||||
<view class="big-classify-pop" :style="{ 'padding-top': `${props.statusBarHeight}px` }">
|
<view class="big-classify-pop" :style="{ 'padding-top': `${props.statusBarHeight}px` }">
|
||||||
<view class="title">全部分类</view>
|
<view class="title">全部分类</view>
|
||||||
<view class="item-box">
|
<view class="item-box">
|
||||||
<view :class="['item', { 'on': state.topTabId === item.id }]"
|
<view :class="['item', { 'on': state.topTabId === item.id }]"
|
||||||
v-for="item, index in state.classifyData" :key="index" @click="hanldeChangeTopTab(item, index)">
|
v-for="item, index in state.classifyData" :key="index" @click="hanldeChangeTopTab(item, index)">
|
||||||
<view class="img-box">
|
<view class="img-box">
|
||||||
<image class="img" :src="item.imageUrl"></image>
|
<image class="img" :src="item.imageUrl"></image>
|
||||||
</view>
|
</view>
|
||||||
<view>
|
<view>
|
||||||
<text class="tit">{{ item.name }}</text>
|
<text class="tit">{{ item.name }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="put-away" @click="hanlderHidebigClassifyPop">点击收起<uv-icon name="arrow-up" size="15px"
|
<view class="put-away" @click="hanlderHidebigClassifyPop">点击收起<uv-icon name="arrow-up" size="15px"
|
||||||
color="6E737D"></uv-icon></view>
|
color="6E737D"></uv-icon></view>
|
||||||
</view>
|
</view>
|
||||||
</uv-popup>
|
</uv-popup>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, watch, ref, onMounted, getCurrentInstance, nextTick } from 'vue';
|
import { reactive, watch, ref, onMounted, getCurrentInstance, nextTick } from 'vue';
|
||||||
import { advertPosition, UserToken, onClassifyPageHide } from '@/core/consts';
|
import { advertPosition, UserToken, onClassifyPageHide, onClassifyPagePullDownRefresh } from '@/core/consts';
|
||||||
import { useLoginStore } from '@/core/store';
|
import { useLoginStore } from '@/core/store';
|
||||||
import { queryGoodsPageList, queryCartNumAndMoney, queryGoodsDetailByToken, queryGoodsDetail, queryAddCart } from '@/core/api';
|
import { queryGoodsPageList, queryCartNumAndMoney, queryGoodsDetailByToken, queryGoodsDetail, queryAddCart } from '@/core/api';
|
||||||
import type { CategoriesType, Response, GoodsListType, GoodsType } from '@/core/models';
|
import type { CategoriesType, Response, GoodsListType, GoodsType } from '@/core/models';
|
||||||
import { getDomInfo, handleStaticResources, handleRouteNavigateTo, handleShowToast, handleRouteSwitchTab } from '@/core/utils';
|
import { getDomInfo, handleStaticResources, handleRouteNavigateTo, handleShowToast, handleRouteSwitchTab } from '@/core/utils';
|
||||||
import { AddCartEnum, PaymentTypeEnum, RouteSwitchTabEnum } from '@/core/enum';
|
import { AddCartEnum, PaymentTypeEnum, RouteSwitchTabEnum } from '@/core/enum';
|
||||||
import GoodsDetailSkuPopup from '@/pages/components/goods-detail/components/goods-detail-sku/goods-detail-sku.vue';
|
import GoodsDetailSkuPopup from '@/pages/components/goods-detail/components/goods-detail-sku/goods-detail-sku.vue';
|
||||||
import { useLoadingFn } from '@/core/hooks';
|
import { useLoadingFn } from '@/core/hooks';
|
||||||
|
|
||||||
const instance = getCurrentInstance();
|
const instance = getCurrentInstance();
|
||||||
|
|
||||||
/** 登录store */
|
/** 登录store */
|
||||||
const _useLoginStore = useLoginStore();
|
const _useLoginStore = useLoginStore();
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
data : Array<CategoriesType>,
|
data : Array<CategoriesType>,
|
||||||
height : number,
|
height : number,
|
||||||
statusBarHeight : number,
|
statusBarHeight : number,
|
||||||
}>(), {
|
}>(), {
|
||||||
data: () => [],
|
data: () => [],
|
||||||
height: 0,
|
height: 0,
|
||||||
statusBarHeight: 0,
|
statusBarHeight: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const bigClassifyPop = ref();
|
const bigClassifyPop = ref();
|
||||||
|
|
||||||
const state = reactive<{
|
const state = reactive<{
|
||||||
classifyData : Array<CategoriesType>;
|
classifyData : Array<CategoriesType>;
|
||||||
topTabId : number;
|
topTabId : number;
|
||||||
topScrollLeft : number;
|
topScrollLeft : number;
|
||||||
leftTabId : number;
|
leftTabId : number;
|
||||||
leftTabList : Array<CategoriesType>;
|
leftTabList : Array<CategoriesType>;
|
||||||
rightTabList : Array<CategoriesType>;
|
rightTabList : Array<CategoriesType>;
|
||||||
catId : number;
|
catId : number;
|
||||||
goodsList : Array<GoodsType>;
|
goodsList : Array<GoodsType>;
|
||||||
page : number;
|
page : number;
|
||||||
totalPages : number;
|
totalPages : number;
|
||||||
bigClassifyH : number; // 大分类盒子的高度
|
bigClassifyH : number; // 大分类盒子的高度
|
||||||
rightTabH : number; // 右侧tab盒子的高度
|
rightTabH : number; // 右侧tab盒子的高度
|
||||||
cartCount : number;
|
cartCount : number;
|
||||||
cartMoney : number,
|
cartMoney : number,
|
||||||
showSku : boolean;
|
showSku : boolean;
|
||||||
goodsDetailData : any;
|
goodsDetailData : any;
|
||||||
}>({
|
}>({
|
||||||
classifyData: [],
|
classifyData: [],
|
||||||
topTabId: 0,
|
topTabId: 0,
|
||||||
topScrollLeft: 0,
|
topScrollLeft: 0,
|
||||||
leftTabId: 0,
|
leftTabId: 0,
|
||||||
leftTabList: [],
|
leftTabList: [],
|
||||||
rightTabList: [],
|
rightTabList: [],
|
||||||
catId: 0,
|
catId: 0,
|
||||||
goodsList: [],
|
goodsList: [],
|
||||||
page: 1,
|
page: 1,
|
||||||
totalPages: 0,
|
totalPages: 0,
|
||||||
bigClassifyH: 0,
|
bigClassifyH: 0,
|
||||||
rightTabH: 0,
|
rightTabH: 0,
|
||||||
cartCount: 0,
|
cartCount: 0,
|
||||||
cartMoney: 0,
|
cartMoney: 0,
|
||||||
showSku: false,
|
showSku: false,
|
||||||
goodsDetailData: {},
|
goodsDetailData: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const buyNowLoading = ref(false);
|
const buyNowLoading = ref(false);
|
||||||
const addCartLoading = ref(false);
|
const addCartLoading = ref(false);
|
||||||
|
|
||||||
const handleBuyNow = useLoadingFn(onBuyNow, buyNowLoading);
|
const handleBuyNow = useLoadingFn(onBuyNow, buyNowLoading);
|
||||||
const handleAddCart = useLoadingFn(onAddCart, addCartLoading)
|
const handleAddCart = useLoadingFn(onAddCart, addCartLoading)
|
||||||
|
|
||||||
|
|
||||||
watch(() => props.data, (newVal : Array<CategoriesType>) => {
|
watch(() => props.data, (newVal : Array<CategoriesType>) => {
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
state.classifyData = newVal.map((item : CategoriesType) => {
|
state.classifyData = newVal.map((item : CategoriesType) => {
|
||||||
item.child.forEach((cell : CategoriesType) => {
|
item.child.forEach((cell : CategoriesType) => {
|
||||||
cell.child.unshift({
|
cell.child.unshift({
|
||||||
name: "全部",
|
name: "全部",
|
||||||
id: cell.id,
|
id: cell.id,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
|
|
||||||
state.topTabId = state.classifyData[0]?.id;
|
state.topTabId = state.classifyData[0]?.id;
|
||||||
state.leftTabId = state.classifyData[0]?.child[0]?.id;
|
state.leftTabId = state.classifyData[0]?.child[0]?.id;
|
||||||
state.leftTabList = state.classifyData[0]?.child;
|
state.leftTabList = state.classifyData[0]?.child;
|
||||||
state.rightTabList = state.classifyData[0]?.child[0]?.child;
|
state.rightTabList = state.classifyData[0]?.child[0]?.child;
|
||||||
|
|
||||||
state.catId = state.classifyData[0].child[0]?.id;
|
state.catId = state.classifyData[0]?.child[0]?.id;
|
||||||
getGoodsPageList();
|
getGoodsPageList();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (uni.getStorageSync(UserToken)) {
|
if (uni.getStorageSync(UserToken)) {
|
||||||
getCartNumAndMoney();
|
getCartNumAndMoney();
|
||||||
}
|
}
|
||||||
|
|
||||||
uni.$on(onClassifyPageHide, () => {
|
uni.$on(onClassifyPagePullDownRefresh, () => {
|
||||||
state.showSku = false;
|
state.page = 1;
|
||||||
})
|
state.totalPages = 1;
|
||||||
|
state.goodsList = [];
|
||||||
|
})
|
||||||
|
|
||||||
nextTick(async () => {
|
uni.$on(onClassifyPageHide, () => {
|
||||||
state.bigClassifyH = ((await getDomInfo('.big-classify', instance.proxy)) as { height : number }).height;
|
state.showSku = false;
|
||||||
setTimeout(async () => {
|
})
|
||||||
state.rightTabH = ((await getDomInfo('.right-tab-box', instance.proxy)) as { height : number }).height;
|
|
||||||
}, 100)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// 获取商品列表数据
|
nextTick(async () => {
|
||||||
const getGoodsPageList = async () => {
|
state.bigClassifyH = ((await getDomInfo('.big-classify', instance.proxy)) as { height : number }).height;
|
||||||
|
setTimeout(async () => {
|
||||||
|
state.rightTabH = ((await getDomInfo('.right-tab-box', instance.proxy)) as { height : number }).height;
|
||||||
|
}, 100)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
const goodsPageList : Response<GoodsListType> = await queryGoodsPageList({
|
// 获取商品列表数据
|
||||||
page: state.page,
|
const getGoodsPageList = async () => {
|
||||||
limit: 10,
|
if (!state.catId) { return; }
|
||||||
where: `{"catId":${state.catId}}`
|
const goodsPageList : Response<GoodsListType> = await queryGoodsPageList({
|
||||||
});
|
page: state.page,
|
||||||
if (goodsPageList.status) {
|
limit: 10,
|
||||||
state.totalPages = goodsPageList.data?.totalPages;
|
where: `{"catId":${state.catId}}`
|
||||||
state.goodsList = state.goodsList.concat(goodsPageList.data?.list);
|
});
|
||||||
}
|
if (goodsPageList.status) {
|
||||||
}
|
state.totalPages = goodsPageList.data?.totalPages;
|
||||||
|
state.goodsList = state.goodsList.concat(goodsPageList.data?.list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 获取购物车数量和价格 */
|
/** 获取购物车数量和价格 */
|
||||||
const getCartNumAndMoney = async () => {
|
const getCartNumAndMoney = async () => {
|
||||||
const cartNumAndMoney : Response<{ count : number, money : number }> = await queryCartNumAndMoney();
|
const cartNumAndMoney : Response<{ count : number, money : number }> = await queryCartNumAndMoney();
|
||||||
state.cartCount = cartNumAndMoney?.data?.count || 0;
|
state.cartCount = cartNumAndMoney?.data?.count || 0;
|
||||||
state.cartMoney = cartNumAndMoney?.data?.money || 0;
|
state.cartMoney = cartNumAndMoney?.data?.money || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 选择sku */
|
/** 选择sku */
|
||||||
const handleSelectSku = (id : number) => {
|
const handleSelectSku = (id : number) => {
|
||||||
_useLoginStore.checkLogin(async () => {
|
_useLoginStore.checkLogin(async () => {
|
||||||
let goodsDetail : any = null;
|
let goodsDetail : any = null;
|
||||||
if (uni.getStorageSync(UserToken)) {
|
if (uni.getStorageSync(UserToken)) {
|
||||||
goodsDetail = await queryGoodsDetailByToken({
|
goodsDetail = await queryGoodsDetailByToken({
|
||||||
id: id,
|
id: id,
|
||||||
data: true,
|
data: true,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
goodsDetail = await queryGoodsDetail({
|
goodsDetail = await queryGoodsDetail({
|
||||||
id: id,
|
id: id,
|
||||||
data: true,
|
data: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
state.goodsDetailData = goodsDetail.data;
|
state.goodsDetailData = goodsDetail.data;
|
||||||
state.showSku = true;
|
state.showSku = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 底部按钮去结算 */
|
/** 底部按钮去结算 */
|
||||||
const handleGoPay = () => {
|
const handleGoPay = () => {
|
||||||
_useLoginStore.checkLogin(() => {
|
_useLoginStore.checkLogin(() => {
|
||||||
handleRouteSwitchTab(RouteSwitchTabEnum.cart);
|
handleRouteSwitchTab(RouteSwitchTabEnum.cart);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 添加购物车 */
|
/** 添加购物车 */
|
||||||
async function onAddCart({ productId, nums } : any) {
|
async function onAddCart({ productId, nums } : any) {
|
||||||
const addCart : Response<number> = await queryAddCart({
|
const addCart : Response<number> = await queryAddCart({
|
||||||
productId,
|
productId,
|
||||||
nums,
|
nums,
|
||||||
type: AddCartEnum.add,
|
type: AddCartEnum.add,
|
||||||
});
|
});
|
||||||
if (addCart.status) {
|
if (addCart.status) {
|
||||||
handleShowToast(addCart.msg, "success");
|
handleShowToast(addCart.msg, "success");
|
||||||
/** 添加成功后,重新获取购物车数量和价格 */
|
/** 添加成功后,重新获取购物车数量和价格 */
|
||||||
getCartNumAndMoney();
|
getCartNumAndMoney();
|
||||||
/** 关闭sku弹框 */
|
/** 关闭sku弹框 */
|
||||||
handleChangePopup(false);
|
handleChangePopup(false);
|
||||||
} else {
|
} else {
|
||||||
handleShowToast(addCart.msg);
|
handleShowToast(addCart.msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 立即购买 */
|
/** 立即购买 */
|
||||||
async function onBuyNow({ productId, nums } : any) {
|
async function onBuyNow({ productId, nums } : any) {
|
||||||
const addCart : Response<number> = await queryAddCart({
|
const addCart : Response<number> = await queryAddCart({
|
||||||
productId,
|
productId,
|
||||||
nums,
|
nums,
|
||||||
type: AddCartEnum.buy,
|
type: AddCartEnum.buy,
|
||||||
cartType: PaymentTypeEnum.common,
|
cartType: PaymentTypeEnum.common,
|
||||||
});
|
});
|
||||||
if (addCart.status) {
|
if (addCart.status) {
|
||||||
handleRouteNavigateTo(`/pages/order/submit/submit?cartIds=${addCart.data}`)
|
handleRouteNavigateTo(`/pages/order/submit/submit?cartIds=${addCart.data}`)
|
||||||
/** 关闭sku弹框 */
|
/** 关闭sku弹框 */
|
||||||
handleChangePopup(false);
|
handleChangePopup(false);
|
||||||
} else {
|
} else {
|
||||||
handleShowToast(addCart.msg);
|
handleShowToast(addCart.msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** sku弹框显示隐藏 */
|
/** sku弹框显示隐藏 */
|
||||||
const handleChangePopup = (show : boolean) => {
|
const handleChangePopup = (show : boolean) => {
|
||||||
state.showSku = show;
|
state.showSku = show;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 切换顶部tab */
|
/** 切换顶部tab */
|
||||||
const hanldeChangeTopTab = (item : CategoriesType, index : number) => {
|
const hanldeChangeTopTab = (item : CategoriesType, index : number) => {
|
||||||
if (state.leftTabId != item.id) {
|
if (state.leftTabId != item.id) {
|
||||||
state.topTabId = item.id;
|
state.topTabId = item.id;
|
||||||
state.catId = item.id;
|
state.catId = item.id;
|
||||||
|
|
||||||
state.leftTabId = item?.child[0].id;
|
state.leftTabId = item?.child[0].id;
|
||||||
state.leftTabList = item?.child;
|
state.leftTabList = item?.child;
|
||||||
state.rightTabList = item?.child[0]?.child;
|
state.rightTabList = item?.child[0]?.child;
|
||||||
calculationTopMovingDistance(index);
|
calculationTopMovingDistance(index);
|
||||||
handleResetGoodsList();
|
handleResetGoodsList();
|
||||||
hanlderHidebigClassifyPop();
|
hanlderHidebigClassifyPop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 显示顶部大分类弹框 */
|
/** 显示顶部大分类弹框 */
|
||||||
const hanldeShowBigClassifyPop = () => {
|
const hanldeShowBigClassifyPop = () => {
|
||||||
bigClassifyPop.value.open();
|
bigClassifyPop.value.open();
|
||||||
}
|
}
|
||||||
/** 隐藏顶部大分类弹框 */
|
/** 隐藏顶部大分类弹框 */
|
||||||
const hanlderHidebigClassifyPop = () => {
|
const hanlderHidebigClassifyPop = () => {
|
||||||
bigClassifyPop.value.close();
|
bigClassifyPop.value.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 计算顶部tab移动的距离 */
|
/** 计算顶部tab移动的距离 */
|
||||||
const calculationTopMovingDistance = (index : number) => {
|
const calculationTopMovingDistance = (index : number) => {
|
||||||
let topScrollLeft = 0;
|
let topScrollLeft = 0;
|
||||||
for (let i = 0; i < index - 1; i++) {
|
for (let i = 0; i < index - 1; i++) {
|
||||||
topScrollLeft += 60
|
topScrollLeft += 60
|
||||||
};
|
};
|
||||||
state.topScrollLeft = topScrollLeft
|
state.topScrollLeft = topScrollLeft
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 切换左侧tab */
|
/** 切换左侧tab */
|
||||||
const hanldeChangeLeftTab = (item : CategoriesType) => {
|
const hanldeChangeLeftTab = (item : CategoriesType) => {
|
||||||
if (state.leftTabId != item.id) {
|
if (state.leftTabId != item.id) {
|
||||||
state.leftTabId = item.id;
|
state.leftTabId = item.id;
|
||||||
state.catId = item.id;
|
state.catId = item.id;
|
||||||
state.rightTabList = item?.child;
|
state.rightTabList = item?.child;
|
||||||
handleResetGoodsList();
|
handleResetGoodsList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 切换右侧tab */
|
/** 切换右侧tab */
|
||||||
const hanldeChangeRightTab = (item : CategoriesType) => {
|
const hanldeChangeRightTab = (item : CategoriesType) => {
|
||||||
state.catId = item.id;
|
state.catId = item.id;
|
||||||
handleResetGoodsList();
|
handleResetGoodsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 组合商品数据传入组件 */
|
/** 组合商品数据传入组件 */
|
||||||
const hanldeCombinationGoodsData = (item : GoodsType) => {
|
const hanldeCombinationGoodsData = (item : GoodsType) => {
|
||||||
return {
|
return {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
image: item.image,
|
image: item.image,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
brief: item.brief,
|
brief: item.brief,
|
||||||
price: item.price,
|
price: item.price,
|
||||||
mktprice: item.mktprice,
|
mktprice: item.mktprice,
|
||||||
isRecommend: item.isRecommend,
|
isRecommend: item.isRecommend,
|
||||||
isHot: item.isHot,
|
isHot: item.isHot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const hanldeClickGoods = (item : GoodsType) => {
|
const hanldeClickGoods = (item : GoodsType) => {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: `/pages/goods/detail?id=${item.id}`
|
url: `/pages/goods/detail?id=${item.id}`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 加载下一页数据 */
|
/** 加载下一页数据 */
|
||||||
const handleScrolltolower = () => {
|
const handleScrolltolower = () => {
|
||||||
if (state.totalPages > state.page) {
|
if (state.totalPages > state.page) {
|
||||||
state.page++;
|
state.page++;
|
||||||
getGoodsPageList();
|
getGoodsPageList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 重置商品列表数据 */
|
/** 重置商品列表数据 */
|
||||||
const handleResetGoodsList = () => {
|
const handleResetGoodsList = () => {
|
||||||
state.page = 1;
|
state.page = 1;
|
||||||
state.goodsList = [];
|
state.goodsList = [];
|
||||||
getGoodsPageList();
|
getGoodsPageList();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import './classify-five.scss';
|
@import './classify-five.scss';
|
||||||
</style>
|
</style>
|
||||||
@@ -1,301 +1,307 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="classify-box" :style="{ height: `${props.height}px` }">
|
<view class="classify-box" :style="{ height: `${props.height}px` }">
|
||||||
<view class="classify-left">
|
<view class="classify-left">
|
||||||
<scroll-view class="scroll-view" :scroll-y="true">
|
<scroll-view class="scroll-view" :scroll-y="true">
|
||||||
<view :class="['item', { 'on': state.leftTabId === item.id }]" v-for="item, index in state.classifyData"
|
<view :class="['item', { 'on': state.leftTabId === item.id }]" v-for="item, index in state.classifyData"
|
||||||
:key="index" @click="hanldeChangeLeftTab(item)">
|
:key="index" @click="hanldeChangeLeftTab(item)">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</view>
|
</view>
|
||||||
<view class="no-more"></view>
|
<view class="no-more"></view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
<view class="classify-right">
|
<view class="classify-right">
|
||||||
<view class="right-tab-box">
|
<view class="right-tab-box">
|
||||||
<coreshop-tabs :list="state.rightTabList" @hanldeClickTab="hanldeChangeRightTab"></coreshop-tabs>
|
<coreshop-tabs :list="state.rightTabList" @hanldeClickTab="hanldeChangeRightTab"></coreshop-tabs>
|
||||||
</view>
|
</view>
|
||||||
<view class="right-data-list">
|
<view class="right-data-list">
|
||||||
<scroll-view class="scroll-view" :scroll-y="true" @scrolltolower="handleScrolltolower">
|
<scroll-view class="scroll-view" :scroll-y="true" @scrolltolower="handleScrolltolower">
|
||||||
<view class="advert-box radius-15">
|
<view class="advert-box radius-15">
|
||||||
<coreshop-advert :code="advertPosition.goodsClassifyBanner"></coreshop-advert>
|
<coreshop-advert :code="advertPosition.goodsClassifyBanner"></coreshop-advert>
|
||||||
</view>
|
</view>
|
||||||
<view class="data-box" v-if="state.goodsList.length > 0">
|
<view class="data-box" v-if="state.goodsList.length > 0">
|
||||||
<view class="item-box" v-for="item in state.goodsList" :key="item.id">
|
<view class="item-box" v-for="item in state.goodsList" :key="item.id">
|
||||||
<coreshop-goods-card imgWidth="150rpx" imgHeight="150rpx"
|
<coreshop-goods-card imgWidth="150rpx" imgHeight="150rpx"
|
||||||
:goodsData="hanldeCombinationGoodsData(item)" @hanldeClickGoods="hanldeClickGoods">
|
:goodsData="hanldeCombinationGoodsData(item)" @hanldeClickGoods="hanldeClickGoods">
|
||||||
<template #goodPrice>
|
<template #goodPrice>
|
||||||
<view class="price-msg">
|
<view class="price-msg">
|
||||||
<view class="price-box">
|
<view class="price-box">
|
||||||
<view class="price">
|
<view class="price">
|
||||||
<text class="symbol">¥</text>
|
<text class="symbol">¥</text>
|
||||||
<text class="num">{{ item.price }}</text>
|
<text class="num">{{ item.price }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="underlin-price">¥{{ item.mktprice }}</view>
|
<view class="underlin-price">¥{{ item.mktprice }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="btn" @click="handleSelectSku(item.id)">
|
<view class="btn" @click="handleSelectSku(item.id)">
|
||||||
<image class="img" :src="handleStaticResources('/static/images/cart.png')">
|
<image class="img" :src="handleStaticResources('/static/images/cart.png')">
|
||||||
</image>
|
</image>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</coreshop-goods-card>
|
</coreshop-goods-card>
|
||||||
</view>
|
</view>
|
||||||
<view class="no-more">
|
<view class="no-more">
|
||||||
<uv-divider :dashed="true"
|
<uv-divider :dashed="true"
|
||||||
:text="state.totalPages > state.page ? '下滑加载更多' : '没有更多了'"></uv-divider>
|
:text="state.totalPages > state.page ? '下滑加载更多' : '没有更多了'"></uv-divider>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-else>
|
<view v-else>
|
||||||
<coreshop-empty></coreshop-empty>
|
<coreshop-empty></coreshop-empty>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="shopping-box">
|
<view class="shopping-box">
|
||||||
<view class="shopping-Bag">
|
<view class="shopping-Bag">
|
||||||
<view class="bag-box">
|
<view class="bag-box">
|
||||||
<image class="img" :src="handleStaticResources('/static/images/cart-bag.png')"></image>
|
<image class="img" :src="handleStaticResources('/static/images/cart-bag.png')"></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="price-box">
|
<view class="price-box">
|
||||||
<text class="num">购物车数量:{{ state.cartCount }}</text>
|
<text class="num">购物车数量:{{ state.cartCount }}</text>
|
||||||
<text class="price">¥{{ state.cartMoney }}</text>
|
<text class="price">¥{{ state.cartMoney }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="btn-buy" @click="handleGoPay">
|
<view class="btn-buy" @click="handleGoPay">
|
||||||
去结算
|
去结算
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 商品sku弹框 -->
|
<!-- 商品sku弹框 -->
|
||||||
<GoodsDetailSkuPopup :showSku="state.showSku" :goodsDetailData="state.goodsDetailData"
|
<GoodsDetailSkuPopup :showSku="state.showSku" :goodsDetailData="state.goodsDetailData"
|
||||||
:safeAreaInsetBottom="false" :buyNowNowloading="buyNowLoading" :addCartloading="addCartLoading"
|
:safeAreaInsetBottom="false" :buyNowNowloading="buyNowLoading" :addCartloading="addCartLoading"
|
||||||
@handleChangePopup="handleChangePopup" @handleAddCart="handleAddCart" @handleBuyNow="handleBuyNow">
|
@handleChangePopup="handleChangePopup" @handleAddCart="handleAddCart" @handleBuyNow="handleBuyNow">
|
||||||
</GoodsDetailSkuPopup>
|
</GoodsDetailSkuPopup>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, reactive, ref, watch, nextTick } from 'vue';
|
import { onMounted, reactive, ref, watch } from 'vue';
|
||||||
import { UserToken, advertPosition, onClassifyPageHide } from '@/core/consts';
|
import { UserToken, advertPosition, onClassifyPageHide, onClassifyPagePullDownRefresh } from '@/core/consts';
|
||||||
import { queryGoodsPageList, queryCartNumAndMoney, queryGoodsDetailByToken, queryGoodsDetail, queryAddCart } from '@/core/api';
|
import { queryGoodsPageList, queryCartNumAndMoney, queryGoodsDetailByToken, queryGoodsDetail, queryAddCart } from '@/core/api';
|
||||||
import type { CategoriesType, Response, GoodsListType, GoodsType } from '@/core/models';
|
import type { CategoriesType, Response, GoodsListType, GoodsType } from '@/core/models';
|
||||||
import { handleStaticResources, handleRouteNavigateTo, handleShowToast, handleRouteSwitchTab } from '@/core/utils';
|
import { handleStaticResources, handleRouteNavigateTo, handleShowToast, handleRouteSwitchTab } from '@/core/utils';
|
||||||
import { useLoginStore } from '@/core/store'
|
import { useLoginStore } from '@/core/store'
|
||||||
import { AddCartEnum, PaymentTypeEnum, RouteSwitchTabEnum } from '@/core/enum';
|
import { AddCartEnum, PaymentTypeEnum, RouteSwitchTabEnum } from '@/core/enum';
|
||||||
import GoodsDetailSkuPopup from '@/pages/components/goods-detail/components/goods-detail-sku/goods-detail-sku.vue';
|
import GoodsDetailSkuPopup from '@/pages/components/goods-detail/components/goods-detail-sku/goods-detail-sku.vue';
|
||||||
import { useLoadingFn } from '@/core/hooks';
|
import { useLoadingFn } from '@/core/hooks';
|
||||||
|
|
||||||
/** 登录store */
|
/** 登录store */
|
||||||
const _useLoginStore = useLoginStore();
|
const _useLoginStore = useLoginStore();
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
data : Array<CategoriesType>,
|
data : Array<CategoriesType>,
|
||||||
height : number,
|
height : number,
|
||||||
}>(), {
|
}>(), {
|
||||||
data: () => [],
|
data: () => [],
|
||||||
height: 0,
|
height: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const state = reactive<{
|
const state = reactive<{
|
||||||
classifyData : Array<CategoriesType>;
|
classifyData : Array<CategoriesType>;
|
||||||
leftTabId : number;
|
leftTabId : number;
|
||||||
rightTabList : Array<CategoriesType>;
|
rightTabList : Array<CategoriesType>;
|
||||||
catId : number;
|
catId : number;
|
||||||
goodsList : Array<GoodsType>;
|
goodsList : Array<GoodsType>;
|
||||||
page : number;
|
page : number;
|
||||||
totalPages : number;
|
totalPages : number;
|
||||||
cartCount : number;
|
cartCount : number;
|
||||||
cartMoney : number,
|
cartMoney : number,
|
||||||
showSku : boolean;
|
showSku : boolean;
|
||||||
goodsDetailData : any;
|
goodsDetailData : any;
|
||||||
}>({
|
}>({
|
||||||
classifyData: [],
|
classifyData: [],
|
||||||
leftTabId: 0,
|
leftTabId: 0,
|
||||||
rightTabList: [],
|
rightTabList: [],
|
||||||
catId: 0,
|
catId: 0,
|
||||||
goodsList: [],
|
goodsList: [],
|
||||||
page: 1,
|
page: 1,
|
||||||
totalPages: 0,
|
totalPages: 0,
|
||||||
cartCount: 0,
|
cartCount: 0,
|
||||||
cartMoney: 0,
|
cartMoney: 0,
|
||||||
showSku: false,
|
showSku: false,
|
||||||
goodsDetailData: {},
|
goodsDetailData: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const buyNowLoading = ref(false);
|
const buyNowLoading = ref(false);
|
||||||
const addCartLoading = ref(false);
|
const addCartLoading = ref(false);
|
||||||
|
|
||||||
const handleBuyNow = useLoadingFn(onBuyNow, buyNowLoading);
|
const handleBuyNow = useLoadingFn(onBuyNow, buyNowLoading);
|
||||||
const handleAddCart = useLoadingFn(onAddCart, addCartLoading)
|
const handleAddCart = useLoadingFn(onAddCart, addCartLoading)
|
||||||
|
|
||||||
watch(() => props.data, (newVal : Array<CategoriesType>) => {
|
watch(() => props.data, (newVal : Array<CategoriesType>) => {
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
state.classifyData = newVal.map((item : CategoriesType) => {
|
state.classifyData = newVal.map((item : CategoriesType) => {
|
||||||
item.child.unshift({
|
item.child.unshift({
|
||||||
name: "全部",
|
name: "全部",
|
||||||
id: item.id,
|
id: item.id,
|
||||||
})
|
})
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
|
|
||||||
state.leftTabId = state.classifyData[0]?.id;
|
state.leftTabId = state.classifyData[0]?.id;
|
||||||
state.catId = state.classifyData[0]?.id;
|
state.catId = state.classifyData[0]?.id;
|
||||||
state.rightTabList = state.classifyData[0]?.child;
|
state.rightTabList = state.classifyData[0]?.child;
|
||||||
|
|
||||||
getGoodsPageList();
|
getGoodsPageList();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (uni.getStorageSync(UserToken)) {
|
if (uni.getStorageSync(UserToken)) {
|
||||||
getCartNumAndMoney();
|
getCartNumAndMoney();
|
||||||
}
|
}
|
||||||
|
|
||||||
uni.$on(onClassifyPageHide, () => {
|
uni.$on(onClassifyPagePullDownRefresh, () => {
|
||||||
state.showSku = false;
|
state.page = 1;
|
||||||
})
|
state.totalPages = 1;
|
||||||
});
|
state.goodsList = [];
|
||||||
|
})
|
||||||
|
|
||||||
/** 获取商品列表数据 */
|
uni.$on(onClassifyPageHide, () => {
|
||||||
const getGoodsPageList = async () => {
|
state.showSku = false;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
const goodsPageList : Response<GoodsListType> = await queryGoodsPageList({
|
/** 获取商品列表数据 */
|
||||||
page: state.page,
|
const getGoodsPageList = async () => {
|
||||||
limit: 10,
|
if (!state.catId) { return; }
|
||||||
where: `{"catId":${state.catId}}`
|
const goodsPageList : Response<GoodsListType> = await queryGoodsPageList({
|
||||||
});
|
page: state.page,
|
||||||
if (goodsPageList.status) {
|
limit: 10,
|
||||||
state.totalPages = goodsPageList.data?.totalPages;
|
where: `{"catId":${state.catId}}`
|
||||||
state.goodsList = state.goodsList.concat(goodsPageList.data?.list);
|
});
|
||||||
}
|
if (goodsPageList.status) {
|
||||||
}
|
state.totalPages = goodsPageList.data?.totalPages;
|
||||||
|
state.goodsList = state.goodsList.concat(goodsPageList.data?.list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 获取购物车数量和价格 */
|
/** 获取购物车数量和价格 */
|
||||||
const getCartNumAndMoney = async () => {
|
const getCartNumAndMoney = async () => {
|
||||||
const cartNumAndMoney : Response<{ count : number, money : number }> = await queryCartNumAndMoney();
|
const cartNumAndMoney : Response<{ count : number, money : number }> = await queryCartNumAndMoney();
|
||||||
state.cartCount = cartNumAndMoney?.data?.count || 0;
|
state.cartCount = cartNumAndMoney?.data?.count || 0;
|
||||||
state.cartMoney = cartNumAndMoney?.data?.money || 0;
|
state.cartMoney = cartNumAndMoney?.data?.money || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 选择sku */
|
/** 选择sku */
|
||||||
const handleSelectSku = (id : number) => {
|
const handleSelectSku = (id : number) => {
|
||||||
_useLoginStore.checkLogin(async () => {
|
_useLoginStore.checkLogin(async () => {
|
||||||
let goodsDetail : any = null;
|
let goodsDetail : any = null;
|
||||||
if (uni.getStorageSync(UserToken)) {
|
if (uni.getStorageSync(UserToken)) {
|
||||||
goodsDetail = await queryGoodsDetailByToken({
|
goodsDetail = await queryGoodsDetailByToken({
|
||||||
id: id,
|
id: id,
|
||||||
data: true,
|
data: true,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
goodsDetail = await queryGoodsDetail({
|
goodsDetail = await queryGoodsDetail({
|
||||||
id: id,
|
id: id,
|
||||||
data: true,
|
data: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
state.goodsDetailData = goodsDetail.data;
|
state.goodsDetailData = goodsDetail.data;
|
||||||
state.showSku = true;
|
state.showSku = true;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 底部按钮去结算 */
|
/** 底部按钮去结算 */
|
||||||
const handleGoPay = () => {
|
const handleGoPay = () => {
|
||||||
_useLoginStore.checkLogin(() => {
|
_useLoginStore.checkLogin(() => {
|
||||||
handleRouteSwitchTab(RouteSwitchTabEnum.cart);
|
handleRouteSwitchTab(RouteSwitchTabEnum.cart);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 添加购物车 */
|
/** 添加购物车 */
|
||||||
async function onAddCart({ productId, nums } : any) {
|
async function onAddCart({ productId, nums } : any) {
|
||||||
const addCart : Response<number> = await queryAddCart({
|
const addCart : Response<number> = await queryAddCart({
|
||||||
productId,
|
productId,
|
||||||
nums,
|
nums,
|
||||||
type: AddCartEnum.add,
|
type: AddCartEnum.add,
|
||||||
});
|
});
|
||||||
if (addCart.status) {
|
if (addCart.status) {
|
||||||
handleShowToast(addCart.msg, 'success');
|
handleShowToast(addCart.msg, 'success');
|
||||||
/** 添加成功后,重新获取购物车数量和价格 */
|
/** 添加成功后,重新获取购物车数量和价格 */
|
||||||
await getCartNumAndMoney();
|
await getCartNumAndMoney();
|
||||||
/** 关闭sku弹框 */
|
/** 关闭sku弹框 */
|
||||||
handleChangePopup(false);
|
handleChangePopup(false);
|
||||||
} else {
|
} else {
|
||||||
handleShowToast(addCart.msg);
|
handleShowToast(addCart.msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 立即购买 */
|
/** 立即购买 */
|
||||||
async function onBuyNow({ productId, nums } : any) {
|
async function onBuyNow({ productId, nums } : any) {
|
||||||
const addCart : Response<number> = await queryAddCart({
|
const addCart : Response<number> = await queryAddCart({
|
||||||
productId,
|
productId,
|
||||||
nums,
|
nums,
|
||||||
type: AddCartEnum.buy,
|
type: AddCartEnum.buy,
|
||||||
cartType: PaymentTypeEnum.common,
|
cartType: PaymentTypeEnum.common,
|
||||||
});
|
});
|
||||||
if (addCart.status) {
|
if (addCart.status) {
|
||||||
handleRouteNavigateTo(`/pages/order/submit/submit?cartIds=${addCart.data}`)
|
handleRouteNavigateTo(`/pages/order/submit/submit?cartIds=${addCart.data}`)
|
||||||
/** 关闭sku弹框 */
|
/** 关闭sku弹框 */
|
||||||
handleChangePopup(false);
|
handleChangePopup(false);
|
||||||
} else {
|
} else {
|
||||||
handleShowToast(addCart.msg);
|
handleShowToast(addCart.msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** sku弹框显示隐藏 */
|
/** sku弹框显示隐藏 */
|
||||||
const handleChangePopup = (show : boolean) => {
|
const handleChangePopup = (show : boolean) => {
|
||||||
state.showSku = show;
|
state.showSku = show;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 切换左侧tab */
|
/** 切换左侧tab */
|
||||||
const hanldeChangeLeftTab = (item : CategoriesType) => {
|
const hanldeChangeLeftTab = (item : CategoriesType) => {
|
||||||
if (state.leftTabId != item.id) {
|
if (state.leftTabId != item.id) {
|
||||||
state.leftTabId = item.id;
|
state.leftTabId = item.id;
|
||||||
state.catId = item.id;
|
state.catId = item.id;
|
||||||
state.rightTabList = item?.child;
|
state.rightTabList = item?.child;
|
||||||
handleResetGoodsList();
|
handleResetGoodsList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 切换右侧tab */
|
/** 切换右侧tab */
|
||||||
const hanldeChangeRightTab = (item : CategoriesType) => {
|
const hanldeChangeRightTab = (item : CategoriesType) => {
|
||||||
state.catId = item.id;
|
state.catId = item.id;
|
||||||
handleResetGoodsList();
|
handleResetGoodsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 组合商品数据传入组件 */
|
/** 组合商品数据传入组件 */
|
||||||
const hanldeCombinationGoodsData = (item : any) => {
|
const hanldeCombinationGoodsData = (item : any) => {
|
||||||
return {
|
return {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
image: item.image,
|
image: item.image,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
brief: item.brief,
|
brief: item.brief,
|
||||||
price: item.price,
|
price: item.price,
|
||||||
mktprice: item.mktprice,
|
mktprice: item.mktprice,
|
||||||
isRecommend: item.isRecommend,
|
isRecommend: item.isRecommend,
|
||||||
isHot: item.isHot,
|
isHot: item.isHot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 加载下一页数据 */
|
/** 加载下一页数据 */
|
||||||
const handleScrolltolower = () => {
|
const handleScrolltolower = () => {
|
||||||
if (state.totalPages > state.page) {
|
if (state.totalPages > state.page) {
|
||||||
state.page++;
|
state.page++;
|
||||||
getGoodsPageList();
|
getGoodsPageList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 重置商品列表数据 */
|
/** 重置商品列表数据 */
|
||||||
const handleResetGoodsList = () => {
|
const handleResetGoodsList = () => {
|
||||||
state.page = 1;
|
state.page = 1;
|
||||||
state.goodsList = [];
|
state.goodsList = [];
|
||||||
getGoodsPageList();
|
getGoodsPageList();
|
||||||
}
|
}
|
||||||
|
|
||||||
const hanldeClickGoods = (item : GoodsType) => {
|
const hanldeClickGoods = (item : GoodsType) => {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: `/pages/goods/detail?id=${item.id}`
|
url: `/pages/goods/detail?id=${item.id}`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import './classify-four.scss';
|
@import './classify-four.scss';
|
||||||
</style>
|
</style>
|
||||||
@@ -1,72 +1,74 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="classify-box" :style="{height: `${height}px`}">
|
<view class="classify-box" :style="{height: `${height}px`}">
|
||||||
<view class="classify-left">
|
<view class="classify-left">
|
||||||
<scroll-view class="scroll-view" enable-flex :scroll-y="true">
|
<scroll-view class="scroll-view" enable-flex :scroll-y="true">
|
||||||
<view :class="['item', { 'on': state.leftTabId === item.id }]" v-for="item, index in props.data"
|
<view :class="['item', { 'on': state.leftTabId === item.id }]" v-for="item, index in props.data"
|
||||||
:key="index" @click="hanldeChangeLeftTab(item)">
|
:key="index" @click="hanldeChangeLeftTab(item)">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
<view class="classify-right">
|
<view class="classify-right">
|
||||||
<scroll-view class="scroll-view" enable-flex :scroll-y="true">
|
<scroll-view class="scroll-view" enable-flex :scroll-y="true">
|
||||||
<view class="advert-box radius-15">
|
<view class="advert-box radius-15">
|
||||||
<coreshop-advert :code="advertPosition.goodsClassifyBanner"></coreshop-advert>
|
<coreshop-advert :code="advertPosition.goodsClassifyBanner"></coreshop-advert>
|
||||||
</view>
|
</view>
|
||||||
<view class="data-box" v-if="state.list.length > 0">
|
<view class="data-box" v-if="state.list && state.list.length > 0">
|
||||||
<view class="item-box" v-for="item,index in state.list" :key="index"
|
<view class="item-box" v-for="item,index in state.list" :key="index"
|
||||||
@click="handleGoCategory(item.id)">
|
@click="handleGoCategory(item.id)">
|
||||||
<image class="img" :src="item.imageUrl"></image>
|
<image class="img" :src="item.imageUrl"></image>
|
||||||
<view class="name">{{ item.name }}</view>
|
<view class="name">{{ item.name }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-else>
|
<view v-else>
|
||||||
<coreshop-empty></coreshop-empty>
|
<coreshop-empty></coreshop-empty>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, watch } from 'vue';
|
import { reactive, watch } from 'vue';
|
||||||
import type { CategoriesType } from '@/core/models';
|
import type { CategoriesType } from '@/core/models';
|
||||||
import { advertPosition } from '@/core/consts';
|
import { advertPosition } from '@/core/consts';
|
||||||
import { handleRouteNavigateTo } from '@/core/utils';
|
import { handleRouteNavigateTo } from '@/core/utils';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
data : Array<CategoriesType>,
|
data : Array<CategoriesType>,
|
||||||
height : number,
|
height : number,
|
||||||
}>(), {
|
}>(), {
|
||||||
data: () => [],
|
data: () => [],
|
||||||
height: 0,
|
height: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const state = reactive<{
|
const state = reactive<{
|
||||||
leftTabId : number;
|
leftTabId : number;
|
||||||
list : Array<CategoriesType>
|
list : Array<CategoriesType>
|
||||||
}>({
|
}>({
|
||||||
leftTabId: 0,
|
leftTabId: 0,
|
||||||
list: [],
|
list: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(() => props.data, (newVal : Array<CategoriesType>) => {
|
watch(() => props.data, (newVal : Array<CategoriesType>) => {
|
||||||
state.leftTabId = newVal[0]?.id;
|
if(newVal){
|
||||||
state.list = newVal[0]?.child;
|
state.leftTabId = newVal[0]?.id;
|
||||||
})
|
state.list = newVal[0]?.child;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const hanldeChangeLeftTab = (item : CategoriesType) => {
|
const hanldeChangeLeftTab = (item : CategoriesType) => {
|
||||||
if (state.leftTabId != item.id) {
|
if (state.leftTabId != item.id) {
|
||||||
state.leftTabId = item.id;
|
state.leftTabId = item.id;
|
||||||
state.list = item?.child;
|
state.list = item?.child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleGoCategory = (id : number) => {
|
const handleGoCategory = (id : number) => {
|
||||||
handleRouteNavigateTo(`/pages/category/category?catId=${id}`)
|
handleRouteNavigateTo(`/pages/category/category?catId=${id}`)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import './classify-three.scss';
|
@import './classify-three.scss';
|
||||||
</style>
|
</style>
|
||||||
@@ -1,115 +1,118 @@
|
|||||||
<template>
|
<template>
|
||||||
<coreshop-page :isBack="false" bgColor="rgba(0,0,0,0)" :isShowStatusBarHeight="false" showLoginModalDom
|
<coreshop-page :isBack="false" bgColor="rgba(0,0,0,0)" :isShowStatusBarHeight="false" showLoginModalDom
|
||||||
needLoadingPage :loadingPage="loading">
|
needLoadingPage :loadingPage="loading">
|
||||||
<view class="layout-classify-page">
|
<view class="layout-classify-page">
|
||||||
<!-- #ifndef MP-ALIPAY -->
|
<!-- #ifndef MP-ALIPAY -->
|
||||||
<uv-navbar bgColor="#EEF3F7" :height="menuButtonHeight+'px'">
|
<uv-navbar bgColor="#EEF3F7" :height="menuButtonHeight+'px'">
|
||||||
<template #left>
|
<template #left>
|
||||||
<!-- #ifdef MP -->
|
<!-- #ifdef MP -->
|
||||||
<view class="search-box" style="max-width: 500rpx;">
|
<view class="search-box" style="max-width: 500rpx;">
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<!-- #ifdef APP -->
|
<!-- #ifdef APP -->
|
||||||
<view class="search-box" style="width: 700rpx;">
|
<view class="search-box" style="width: 700rpx;">
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<view class="page-name">分类</view>
|
<view class="page-name">分类</view>
|
||||||
<uv-input v-model="state.keyWord" @confirm="handleSearch" shape="circle"
|
<uv-input v-model="state.keyWord" @confirm="handleSearch" shape="circle"
|
||||||
placeholder="请输入关键词" prefixIcon="search"
|
placeholder="请输入关键词" prefixIcon="search"
|
||||||
:customStyle="{ 'background-color': '#fff' ,'padding':'3px 9px'}"
|
:customStyle="{ 'background-color': '#fff' ,'padding':'3px 9px'}"
|
||||||
prefixIconStyle="font-size: 22px;color: #909399">
|
prefixIconStyle="font-size: 22px;color: #909399">
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<view class="search-tit" @click.stop="handleSearch">搜索</view>
|
<view class="search-tit" @click.stop="handleSearch">搜索</view>
|
||||||
</template>
|
</template>
|
||||||
</uv-input>
|
</uv-input>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</uv-navbar>
|
</uv-navbar>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<view class="content-box" :style="{'height': `${state.height}px` }">
|
<view class="content-box" :style="{'height': `${state.height}px` }">
|
||||||
<classifyOne v-if="shopConfigStore.config.cateStyle == GoodsListEnum.one" :data="state.categoriesList">
|
<classifyOne v-if="shopConfigStore.config.cateStyle == GoodsListEnum.one" :data="state.categoriesList">
|
||||||
</classifyOne>
|
</classifyOne>
|
||||||
<classifyTwo v-else-if="shopConfigStore.config.cateStyle == GoodsListEnum.two"
|
<classifyTwo v-else-if="shopConfigStore.config.cateStyle == GoodsListEnum.two"
|
||||||
:data="state.categoriesList">
|
:data="state.categoriesList">
|
||||||
</classifyTwo>
|
</classifyTwo>
|
||||||
<classifyThree v-else-if="shopConfigStore.config.cateStyle == GoodsListEnum.three"
|
<classifyThree v-else-if="shopConfigStore.config.cateStyle == GoodsListEnum.three"
|
||||||
:data="state.categoriesList" :height="state.height"></classifyThree>
|
:data="state.categoriesList" :height="state.height"></classifyThree>
|
||||||
<classifyFour v-else-if="shopConfigStore.config.cateStyle == GoodsListEnum.four"
|
<classifyFour v-else-if="shopConfigStore.config.cateStyle == GoodsListEnum.four"
|
||||||
:data="state.categoriesList" :height="state.height">
|
:data="state.categoriesList" :height="state.height">
|
||||||
</classifyFour>
|
</classifyFour>
|
||||||
<classifyFive v-else-if="shopConfigStore.config.cateStyle == GoodsListEnum.five"
|
<classifyFive v-else-if="shopConfigStore.config.cateStyle == GoodsListEnum.five"
|
||||||
:data="state.categoriesList" :height="state.height" :statusBarHeight="statusBarHeight">
|
:data="state.categoriesList" :height="state.height" :statusBarHeight="statusBarHeight">
|
||||||
</classifyFive>
|
</classifyFive>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</coreshop-page>
|
</coreshop-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, reactive, watchEffect, ref } from 'vue';
|
import { onMounted, reactive, watchEffect, ref } from 'vue';
|
||||||
import { onHide, onPullDownRefresh } from '@dcloudio/uni-app';
|
import { onHide, onPullDownRefresh } from '@dcloudio/uni-app';
|
||||||
import { useShopConfigStore } from '@/core/store';
|
import { useShopConfigStore } from '@/core/store';
|
||||||
import { queryAllCategories } from '@/core/api';
|
import { queryAllCategories } from '@/core/api';
|
||||||
import { GoodsListEnum } from '@/core/enum';
|
import { GoodsListEnum } from '@/core/enum';
|
||||||
import { handleRouteNavigateTo } from '@/core/utils';
|
import { handleRouteNavigateTo } from '@/core/utils';
|
||||||
import { onClassifyPageHide } from '@/core/consts';
|
import { onClassifyPageHide, onClassifyPagePullDownRefresh } from '@/core/consts';
|
||||||
import type { Response, ShopConfigStoreType, CategoriesType } from '@/core/models';
|
import type { Response, ShopConfigStoreType, CategoriesType } from '@/core/models';
|
||||||
import classifyOne from './classify-page/classify-one/classify-one.vue';
|
import classifyOne from './classify-page/classify-one/classify-one.vue';
|
||||||
import classifyTwo from './classify-page/classify-two/classify-two.vue';
|
import classifyTwo from './classify-page/classify-two/classify-two.vue';
|
||||||
import classifyThree from './classify-page/classify-three/classify-three.vue';
|
import classifyThree from './classify-page/classify-three/classify-three.vue';
|
||||||
import classifyFour from './classify-page/classify-four/classify-four.vue';
|
import classifyFour from './classify-page/classify-four/classify-four.vue';
|
||||||
import classifyFive from './classify-page/classify-five/classify-five.vue';
|
import classifyFive from './classify-page/classify-five/classify-five.vue';
|
||||||
import { useLoadingFn, useSystemInfo } from '@/core/hooks';
|
import { useLoadingFn, useSystemInfo } from '@/core/hooks';
|
||||||
|
|
||||||
// 获取项目配置
|
// 获取项目配置
|
||||||
const shopConfigStore : ShopConfigStoreType = useShopConfigStore();
|
const shopConfigStore : ShopConfigStoreType = useShopConfigStore();
|
||||||
|
|
||||||
// 获取自定义导航栏高度
|
// 获取自定义导航栏高度
|
||||||
const { statusBarHeight, systemInfo, menuButtonHeight } = useSystemInfo();
|
const { statusBarHeight, systemInfo, menuButtonHeight } = useSystemInfo();
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
|
|
||||||
const state = reactive<{
|
const state = reactive<{
|
||||||
categoriesList : Array<CategoriesType>,
|
categoriesList : Array<CategoriesType>,
|
||||||
height : number,
|
height : number,
|
||||||
keyWord : string;
|
keyWord : string;
|
||||||
}>({
|
}>({
|
||||||
categoriesList: [],
|
categoriesList: [],
|
||||||
height: 0,
|
height: 0,
|
||||||
keyWord: "",
|
keyWord: "",
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleuAllCategories = useLoadingFn(getAllCategories, loading);
|
const handleuAllCategories = useLoadingFn(getAllCategories, loading);
|
||||||
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
handleuAllCategories();
|
handleuAllCategories();
|
||||||
})
|
})
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
state.height = systemInfo.value.windowHeight - statusBarHeight.value ;
|
state.height = systemInfo.value.windowHeight - statusBarHeight.value;
|
||||||
})
|
})
|
||||||
|
|
||||||
onHide(() => {
|
onHide(() => {
|
||||||
/** 触发自定义onhide事件,让后代组件监听页面是关闭 */
|
/** 触发自定义onhide事件,让后代组件监听页面是关闭 */
|
||||||
uni.$emit(onClassifyPageHide);
|
uni.$emit(onClassifyPageHide);
|
||||||
});
|
});
|
||||||
|
|
||||||
onPullDownRefresh(async () => {
|
onPullDownRefresh(async () => {
|
||||||
await handleuAllCategories()
|
/** 触发onPullDownRefresh事件,让后代组件监听页面是下拉刷新 */
|
||||||
uni.stopPullDownRefresh();
|
uni.$emit(onClassifyPagePullDownRefresh);
|
||||||
});
|
state.categoriesList = [];
|
||||||
|
await handleuAllCategories()
|
||||||
|
uni.stopPullDownRefresh();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/** 获取购物车数量价格 */
|
/** 获取购物车数量价格 */
|
||||||
async function getAllCategories() {
|
async function getAllCategories() {
|
||||||
const allCategories : Response<Array<CategoriesType>> = await queryAllCategories();
|
const allCategories : Response<Array<CategoriesType>> = await queryAllCategories();
|
||||||
state.categoriesList = allCategories.data || [];
|
state.categoriesList = allCategories.data || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 搜索 */
|
/** 搜索 */
|
||||||
const handleSearch = () => {
|
const handleSearch = () => {
|
||||||
handleRouteNavigateTo(`/pages/category/category?key=${state.keyWord}`);
|
handleRouteNavigateTo(`/pages/category/category?key=${state.keyWord}`);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import './classify.scss';
|
@import './classify.scss';
|
||||||
</style>
|
</style>
|
||||||
@@ -1,39 +1,39 @@
|
|||||||
<template>
|
<template>
|
||||||
<swiper class="swiper m-b-25" v-if="props.data.list.length > 0" :vertical="false" :indicator-dots="props.dotsSelect"
|
<swiper class="swiper m-b-25" v-if="props.data.list.length > 0" :vertical="false" :indicator-dots="props.dotsSelect"
|
||||||
:autoplay="props.autoplaySelect" :interval="props.data.duration" :circular="props.circularSelect"
|
:autoplay="props.autoplaySelect" :interval="props.data.duration" :circular="props.circularSelect"
|
||||||
:indicator-color="props.indicatorColor" :indicator-active-color="props.indicatorColorActive">
|
:indicator-color="props.indicatorColor" :indicator-active-color="props.indicatorColorActive">
|
||||||
<swiper-item v-for="item, index in props.data.list" :key="index" @click="hanldeClickImage(item)">
|
<swiper-item v-for="item, index in props.data.list" :key="index" @click="hanldeClickImage(item)">
|
||||||
<image class="swiper-img" :src="item.image"></image>
|
<image class="swiper-img" :src="item.image"></image>
|
||||||
</swiper-item>
|
</swiper-item>
|
||||||
</swiper>
|
</swiper>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { PageConfigItemsImgSlideType } from '@/core/models';
|
import type { PageConfigItemsImgSlideType } from '@/core/models';
|
||||||
import { handleAdvertiseDetail } from '@/core/utils';
|
import { handleAdvertiseDetail } from '@/core/utils';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
data : any,
|
data ?: any,
|
||||||
dotsSelect : boolean,
|
dotsSelect ?: boolean,
|
||||||
autoplaySelect : boolean,
|
autoplaySelect ?: boolean,
|
||||||
intervalSelect : number,
|
intervalSelect ?: number,
|
||||||
circularSelect : boolean,
|
circularSelect ?: boolean,
|
||||||
indicatorColor : string,
|
indicatorColor ?: string,
|
||||||
indicatorColorActive : string,
|
indicatorColorActive ?: string,
|
||||||
}>(), {
|
}>(), {
|
||||||
data: {},
|
data: {},
|
||||||
dotsSelect: true,
|
dotsSelect: true,
|
||||||
autoplaySelect: true,
|
autoplaySelect: true,
|
||||||
intervalSelect: 3000,
|
intervalSelect: 3000,
|
||||||
circularSelect: true,
|
circularSelect: true,
|
||||||
indicatorColor: '#EEF2F6',
|
indicatorColor: '#EEF2F6',
|
||||||
indicatorColorActive: '#E74435'
|
indicatorColorActive: '#E74435'
|
||||||
});
|
});
|
||||||
|
|
||||||
const hanldeClickImage = (item : PageConfigItemsImgSlideType) => {
|
const hanldeClickImage = (item : PageConfigItemsImgSlideType) => {
|
||||||
handleAdvertiseDetail(Number(item.linkType), item.linkValue);
|
handleAdvertiseDetail(Number(item.linkType), item.linkValue);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "./home-swiper.scss";
|
@import "./home-swiper.scss";
|
||||||
</style>
|
</style>
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="title-box" v-if="state.formInfo?.description">
|
<view class="title-box" v-if="state.formInfo?.description">
|
||||||
<view calss="title">{{ state.formInfo?.description }}1</view>
|
<view calss="title">{{ state.formInfo?.description }}</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 表单主体内容 -->
|
<!-- 表单主体内容 -->
|
||||||
<view class="form-content">
|
<view class="form-content">
|
||||||
|
|||||||
Reference in New Issue
Block a user