393 lines
9.7 KiB
Vue
393 lines
9.7 KiB
Vue
<template>
|
|
<view class="store-index">
|
|
<view class="store-header" :style="{ 'background-image': `url(${shopInfo.background})`}">
|
|
<u-navbar :border-bottom="false" :background="{ 'background-image': `url(${shopInfo.background})`, 'background-repeat': 'no-repeat', 'background-size': '100% auto'}"
|
|
:back-bg="'rgba(255, 255, 255, 0.45)'" :back-icon-color="'rgb(255,255,255)'" :is-fixed="true">
|
|
<view class="store-search flex-1">
|
|
<u-search v-model="keyword" bg-color="white" shape="round" placeholder="搜索店内商品" wrap-bg-color="transparent" @search="refresh">
|
|
</u-search>
|
|
</view>
|
|
</u-navbar>
|
|
<view class="store-info m-t-20">
|
|
<view class="flex row-between">
|
|
<view class="flex">
|
|
<u-image width="100rpx" height="100rpx" border-radius="50%" :src="shopInfo.logo" />
|
|
<view class="m-l-20 flex-col col-top">
|
|
<router-link :to="{path: '/pages/store_detail/store_detail', query: {id: shopInfo.id}}">
|
|
<view class="lg white line-1 bold" style="width: 420rpx;">
|
|
{{shopInfo.name}}
|
|
<u-icon name="arrow-right"></u-icon>
|
|
</view>
|
|
</router-link>
|
|
<view class="store-tag xxs m-t-10 white" v-if="shopInfo.type == 1">
|
|
自营
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="flex row-center white br60 sm flex-none subscribe-btn" :class="{'gray': shopInfo.shop_follow_status === 1}" @tap="changeShopFollowFun">
|
|
{{shopInfo.shop_follow_status === 1 ? '已关注' : '+ 关注'}}
|
|
</view>
|
|
</view>
|
|
<view class="sale-info flex row-between m-t-10">
|
|
<view class="flex">
|
|
<view style="width: 100rpx;" />
|
|
<view class="white m-l-20 xs">
|
|
在售商品:{{shopInfo.on_sale_count}}件
|
|
</view>
|
|
</view>
|
|
<view class="white xs">
|
|
{{shopInfo.visited_num}}人进店
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="content">
|
|
<view class="content-wrap">
|
|
<view>
|
|
<get-coupon :wrap-style="{'border-bottom': '1px solid #E5E5E5'}" :shop-id="shopInfo.id"></get-coupon>
|
|
</view>
|
|
<view class="store-hot-goods bg-white m-b-20" v-if="shopInfo.goods_list.length">
|
|
<view class="store-hot-header flex">
|
|
<view class="column-line m-r-20" />
|
|
<view class="md" style="font-weight: 500;">
|
|
店铺推荐
|
|
</view>
|
|
</view>
|
|
<view class="store-hot-content">
|
|
<scroll-view :scroll-x="true">
|
|
<view class="goods p-l-20 p-r-20">
|
|
<goods-list :list="shopInfo.goods_list" type="row"></goods-list>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="goods-display flex bg-body">
|
|
<view class="category-aside">
|
|
<u-sticky bg-color="rgba(255, 255, 255, 0)" :enable="enableFix" :offset-top="navHeight" :h5-nav-height="0">
|
|
<scroll-view :scroll-y="true" :style="{'height': aslideH + 'px'}">
|
|
<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>
|
|
</u-sticky>
|
|
</view>
|
|
<view class="category-row flex-1">
|
|
<u-sticky bg-color="rgba(255, 255, 255, 0)" :enable="enableFix" :offset-top="navHeight" :h5-nav-height="0">
|
|
<sort-nav v-model="sortConfig" :show-type="false"></sort-nav>
|
|
</u-sticky>
|
|
<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" width="285rpx"></goods-list>
|
|
</view>
|
|
</mescroll-body>
|
|
</view>
|
|
</view>
|
|
|
|
</view>
|
|
<loading-view v-if="isFirstLoading"></loading-view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import {
|
|
mapGetters
|
|
} from 'vuex'
|
|
import {
|
|
getShopInfo,
|
|
getShopGoodsCategory,
|
|
changeShopFollow
|
|
} from '@/api/shop'
|
|
import {getGoodsList} from '@/api/store'
|
|
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
|
|
export default {
|
|
mixins: [MescrollMixin], // 使用mixin
|
|
data() {
|
|
return {
|
|
isFirstLoading: true,
|
|
navOpacity: 0,
|
|
shopInfo: {
|
|
goods_list: []
|
|
},
|
|
category: [],
|
|
active: -1,
|
|
upOption: {
|
|
auto: false,
|
|
empty: {
|
|
icon: '/static/images/goods_null.png',
|
|
tip: "暂无商品",
|
|
}
|
|
},
|
|
goodsList: [],
|
|
sortConfig: {
|
|
priceSort: '',
|
|
saleSort: '',
|
|
},
|
|
keyword: '',
|
|
sys: {},
|
|
enableFix: true,
|
|
id: ''
|
|
}
|
|
},
|
|
async onLoad() {
|
|
this.id = this.$Route.query.id
|
|
this.sys = uni.getSystemInfoSync()
|
|
await this.getShopInfoFun()
|
|
await this.getShopGoodsCategoryFun()
|
|
this.isFirstLoading = false
|
|
this.mescroll.resetUpScroll();
|
|
},
|
|
onHide() {
|
|
// #ifdef H5
|
|
this.enableFix = false
|
|
// #endif
|
|
},
|
|
onShow() {
|
|
// #ifdef H5
|
|
this.enableFix = true
|
|
// #endif
|
|
},
|
|
onShareAppMessage() {
|
|
return {
|
|
title: this.shopInfo.name,
|
|
path: `pages/store_index/store_index?invite_code=${this.inviteCode}&id=${this.id}`
|
|
};
|
|
},
|
|
methods: {
|
|
async changeShopFollowFun() {
|
|
if (!this.isLogin) return this.$Router.push('/pages/login/login')
|
|
const {code, msg} = await changeShopFollow({
|
|
shop_id: this.id
|
|
})
|
|
if(code == 1) {
|
|
this.$toast({
|
|
title: msg
|
|
})
|
|
this.getShopInfoFun()
|
|
}
|
|
},
|
|
async getShopInfoFun() {
|
|
const {
|
|
data,
|
|
code
|
|
} = await getShopInfo({
|
|
shop_id: this.id
|
|
})
|
|
if (code == 1) {
|
|
this.shopInfo = data
|
|
}
|
|
},
|
|
async getShopGoodsCategoryFun() {
|
|
|
|
const {
|
|
data,
|
|
code
|
|
} = await getShopGoodsCategory({
|
|
shop_id: this.id
|
|
})
|
|
if (code == 1) {
|
|
this.category = data
|
|
}
|
|
},
|
|
changeActive(index) {
|
|
this.active = index
|
|
this.refresh()
|
|
},
|
|
refresh() {
|
|
this.goodsList = []
|
|
this.mescroll.resetUpScroll();
|
|
},
|
|
/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
|
|
upCallback(page) {
|
|
//联网加载数据
|
|
let {
|
|
goodsList,
|
|
keyword,
|
|
sortConfig: {
|
|
priceSort,
|
|
saleSort,
|
|
},
|
|
active,
|
|
category
|
|
} = this;
|
|
const pageNum = page.num; // 页码, 默认从1开始
|
|
const pageSize = page.size; // 页长, 默认每页10条
|
|
const cateId = active == -1 ? '' : category[active].id
|
|
getGoodsList({
|
|
page_size: pageSize,
|
|
page_no: pageNum,
|
|
shop_id: this.id,
|
|
shop_cate_id: cateId,
|
|
sort_by_price: priceSort,
|
|
sort_by_sales: saleSort,
|
|
keyword
|
|
}).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']),
|
|
navHeight() {
|
|
return this.sysInfo.navHeight + 'px'
|
|
},
|
|
aslideH() {
|
|
const {
|
|
windowHeight,
|
|
navHeight,
|
|
safeArea
|
|
} = this.sys
|
|
if(!safeArea) return 0
|
|
return windowHeight - this.sysInfo.navHeight
|
|
},
|
|
meScrollH() {
|
|
return this.aslideH - uni.upx2px(80) + 'px'
|
|
}
|
|
},
|
|
watch:{
|
|
sortConfig: {
|
|
deep: true,
|
|
handler(val) {
|
|
|
|
console.log(val)
|
|
this.refresh()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
page {
|
|
padding: 0;
|
|
}
|
|
.store-index {
|
|
.store-header {
|
|
padding-bottom: 60rpx;
|
|
background-repeat: no-repeat;
|
|
background-size: 100% auto;
|
|
.store-info {
|
|
padding-right: 30rpx;
|
|
padding-left: 24rpx;
|
|
|
|
.store-tag {
|
|
background: linear-gradient(267deg, #FF2C3C 0%, #F52E99 100%);
|
|
border-radius: 6rpx;
|
|
padding: 4rpx 9rpx;
|
|
}
|
|
|
|
.subscribe-btn {
|
|
background: linear-gradient(97deg, #FF5784 0%, #FF2C3C 100%);
|
|
height: 52rpx;
|
|
width: 128rpx;
|
|
&.gray {
|
|
background: #ccc;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.content {
|
|
margin-top: -30rpx;
|
|
.content-wrap {
|
|
border-radius: 20rpx 20rpx 0px 0px;
|
|
overflow: hidden;
|
|
}
|
|
.store-hot-goods {
|
|
overflow: hidden;
|
|
.store-hot-header {
|
|
padding: 20rpx;
|
|
|
|
.column-line {
|
|
width: 6rpx;
|
|
height: 32rpx;
|
|
background-color: $-color-primary;
|
|
}
|
|
}
|
|
|
|
.store-hot-content {
|
|
.goods {
|
|
display: inline-block;
|
|
}
|
|
.hot-goods-item {
|
|
width: 200rpx;
|
|
|
|
.hot-goods-info {
|
|
.hot-goods-price {
|
|
margin-top: 5rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.goods-display {
|
|
.category-aside {
|
|
width: 120rpx;
|
|
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;
|
|
width: 630rpx;
|
|
|
|
.sort-tool-bar {
|
|
.sort-item {
|
|
flex: 1;
|
|
height: 80rpx;
|
|
}
|
|
}
|
|
|
|
.goods-lists {
|
|
padding: 20rpx;
|
|
|
|
.item {
|
|
width: 285rpx;
|
|
border-radius: 10rpx;
|
|
overflow: hidden;
|
|
|
|
&:nth-of-type(2n) {
|
|
margin-left: 20rpx;
|
|
}
|
|
|
|
.goods-info {
|
|
padding: 10rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
</style>
|