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