Files
2026-04-23 10:41:27 +08:00

207 lines
4.8 KiB
Vue

<template>
<view class="goods-cate">
<router-link :to="{ path: '/bundle/pages/shop_search/shop_search', query: { id: shopId, is_recommend: 0 } }">
<view class="header">
<u-search bg-color="#F4F4F4" :disabled="true" placeholder="搜索店内商品"></u-search>
</view>
</router-link>
<view class="category">
<view class="goods-display bg-body" style="display: flex; border-radius: 20rpx">
<view class="category-aside">
<scroll-view
:scroll-y="true"
:style="{ height: aslideH + 'px', padding: '10rpx' }"
>
<view
class="aside-item flex row-center"
:class="{ active: active == -1 }"
@click="changeActive(-1)"
>
<view
class="xs text-center"
style="width: 60rpx"
:class="{ primary: active == -1 }"
>全部商品</view>
</view>
<view
class="aside-item flex row-center"
:class="{ active: active == index }"
v-for="(item, index) in category"
:key="index"
@click="changeActive(index)"
>
<view
class="xs text-center"
style="width: 60rpx"
:class="{ primary: active == index }"
>{{ item.name }}</view>
</view>
</scroll-view>
</view>
<view class="category-row flex-1">
<mescroll-body
ref="mescrollRef"
@init="mescrollInit"
:height="meScrollH"
@down="downCallback"
@up="upCallback"
:up="upOption"
:down="{ use: false }"
>
<view class="bg-white">
<goods-list :list="goodsList" type="one"></goods-list>
</view>
</mescroll-body>
</view>
</view>
</view>
<tabbar></tabbar>
</view>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
import { getShopGoodsCategory, getCityGoodsCategory } from '@/api/shop'
import { getGoodsList } from '@/api/store'
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins.js'
export default {
mixins: [MescrollMixin],
data() {
return {
shopId: 1,
category: [],
active: -1,
upOption: {
auto: false,
empty: {
icon: '/static/images/goods_null.png',
tip: '暂无商品'
}
},
goodsList: [],
sys: {}
};
},
async onLoad() {
this.sys = uni.getSystemInfoSync()
await this.getShopGoodsCategoryFun()
this.mescroll.resetUpScroll()
uni.$on('refreshhome', this.onCityChange)
},
onUnload() {
uni.$off('refreshhome', this.onCityChange)
},
onShow() {
this.getCartNum()
},
methods: {
...mapActions(['getCartNum']),
onCityChange() {
console.log("🚀 ~ methods.onCityChange:", 'onCityChange')
this.active = -1
this.goodsList = []
this.getShopGoodsCategoryFun()
this.mescroll.resetUpScroll()
},
async getShopGoodsCategoryFun() {
const { data, code } = await getCityGoodsCategory({
city_id: (this.cityInfo && this.cityInfo.id) || 0,
})
if (code == 1) {
this.category = data
}
},
changeActive(index) {
this.active = index
this.goodsList = []
this.mescroll.resetUpScroll()
},
upCallback(page) {
const { active, category } = this
const pageNum = page.num
const pageSize = page.size
const cateId = active == -1 ? '' : category[active].id
getGoodsList({
page_size: pageSize,
page_no: pageNum,
shop_id: this.shopId,
shop_cate_id: cateId,
city_id: (this.cityInfo && this.cityInfo.id) || 0,
}).then(({ data }) => {
let curPageData = data.lists
let curPageLen = curPageData.length
let hasNext = !!data.more
if (page.num == 1) this.goodsList = []
this.goodsList = this.goodsList.concat(curPageData)
this.mescroll.endSuccess(curPageLen, hasNext)
})
}
},
computed: {
...mapGetters(['sysInfo', 'cityInfo']),
aslideH() {
const { windowHeight, safeArea } = this.sys
if (!safeArea) return 0
// 减去头部搜索栏(94rpx)、底部tabbar(50px)、安全区域
return windowHeight - uni.upx2px(94) - 50
},
meScrollH() {
return this.aslideH + 'px'
}
}
};
</script>
<style lang="scss" scoped>
$header-height: 94rpx;
page {
background-color: #fff;
height: 100%;
}
.goods-cate {
height: 100%;
.header {
box-sizing: border-box;
height: $header-height;
border-bottom: $-solid-border;
}
.category {
background-color: white;
border-radius: 20rpx;
.category-aside {
width: 150rpx;
align-self: flex-start;
.aside-item {
width: 120rpx;
padding: 20rpx 0;
&.active {
position: relative;
background-color: $-color-white;
&::before {
content: '';
width: 3rpx;
height: 80rpx;
background-color: $-color-primary;
position: absolute;
left: 0;
}
}
}
}
.category-row {
align-self: flex-start;
}
}
}
</style>