You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
yanzong_qianduan/pages/shopList/shopPage.vue

689 lines
16 KiB

<template>
<view class="shop">
<view class="navbarContent">
<u-navbar :is-back="false" :background="background" :border-bottom="false">
<uni-icons type="left" size="24" color="#fff" class="back" @click="back"></uni-icons>
<view class="search-box">
<view @click="search" class="search-model"></view>
<u-search shape="round" :disabled="true" placeholder="搜索本品牌商品" bg-color="#ffffff"
:show-action="false"></u-search>
</view>
</u-navbar>
</view>
<view class="page">
<view class="shop-tip">
<image :src="storeInfo.logoImage ? storeInfo.logoImage.preview_url : ''" mode="aspectFill" class="logo"></image>
<text>{{ storeInfo.store_name }}</text>
<view class="tip">
<image src="/static/shop/t1.png" mode="aspectFill"></image>
100%正品
</view>
<view class="tip">
<image src="/static/shop/t2.png" mode="aspectFill"></image>
天天有特价
</view>
<view class="tip">
<image src="/static/shop/t3.png" mode="aspectFill"></image>
退货无忧
</view>
</view>
<view class="shop-info">
<image :src="shopDetail.logoImage && shopDetail.logoImage[0].external_url" mode="aspectFill" class="logo"></image>
<view class="info-box">
<view class="name">{{ shopDetail.shop_name }}</view>
<view class="intro">
<text class="label">{{ shopDetail.shop_label }}</text>
<view v-if="shopDetail.is_show_license == 1" @click="toCer">
<image src="/static/cer.png" mode="aspectFill"></image>
证照
</view>
</view>
</view>
<button open-type="share" class="share-btn">
<image src="@/static/share.png" mode="aspectFill"></image>
分享
</button>
</view>
<view v-if="firstCate" class="shop-goods">
<view v-if="goodsCate.filter(v => v.category_id === firstCate)[0].children.length > 0" class="second-cate">
<scroll-view class="second-cate-tabs" scroll-x>
<view v-for="(item, index) in goodsCate.filter(v => v.category_id === firstCate)[0].children" :key="index" class="cate-item" :class="{active: secondCate === item.category_id}" @click="secondCate = item.category_id">
{{ item.name }}
</view>
</scroll-view>
</view>
<view class="goods-content">
<view class="first-cate">
<scroll-view class="first-cate-tabs" scroll-y>
<view
v-for="(item, index) in goodsCate"
:key="index"
class="cate-item"
:class="{
active: firstCate === item.category_id,
prev: goodsCate[index + 1] && goodsCate[index + 1].category_id === firstCate,
next: goodsCate[index - 1] && goodsCate[index - 1].category_id === firstCate,
}"
@click="firstCate = item.category_id;secondCate = '';"
>
{{ item.name }}
</view>
</scroll-view>
</view>
<view class="content">
<view class="filter-box">
<view v-for="(item, index) in filterList" :key="index" class="filter-item" :class="{ active: activeFilter === item.value}" @click="changeFilter(item.value)">
{{ item.name }}
<text v-if="item.value === 'price'" class="down" :class="{ on: activeFilter === 'price' && filterDirection === 'DESC'}" style="top: 22rpx;"></text>
<text v-if="item.value === 'price'" class="up" :class="{ on: activeFilter === 'price' && filterDirection === 'ASC'}"></text>
</view>
</view>
<view class="goods-list">
<view v-for="(item, index) in goods" :key="index" class="good" @click="onGoodDetail(item.goods_id)">
<image :src="item.goods_image" mode="aspectFill"></image>
<view class="name">{{ item.goods_name }}</view>
<view class="price">
<text class="now-price">¥{{ item.goods_price_min>0?Number(item.goods_price_min):0.00 }}</text>
<text v-if="item.line_price_min > 0" class="origin-price">¥{{ item.line_price_min>0?Number(item.line_price_min):'' }}</text>
</view>
</view>
</view>
<view v-if="goods.length && !loading" class="finished">{{ loadTitle }}</view>
<view v-if="finished && !goods.length" class="empty">
<image mode="aspectFill" src="@/static/empty.png" alt="暂无商品" />
<view>暂无商品</view>
</view>
</view>
</view>
</view>
<view class="toCart" @click.stop="toCart">
<image src="@/static/shop/cart.png"></image>
</view>
<view class="toTop" v-if="isTop" @click="openScrollTo()">
<image :src="$picUrl+'/static/toTop.png?=1'"></image>
</view>
</view>
</view>
</template>
<script>
import styleColor from '../styleColor';
import * as Api from '@/api/shop/index';
import * as cstegory from '@/api/category'
import * as GoodsApi from '@/api/goods'
import { debounce } from 'lodash';
export default {
data() {
return {
background: {
background: 'url(https://www.royaum.com.cn/static/shop/shop-page-bg.png) center top no-repeat',
backgroundSize: '100% auto',
},
id: '',
scrollTop: 0,
shopDetail: {},
goodsCate: [],
firstCate: '',
secondCate: '',
activeFilter: 'all',
filterDirection: 'ASC',
filterList: [
{ name: '综合', value: 'all' },
{ name: '价格', value: 'price' },
// { name: '折扣', value: 'discount' },
{ name: '销量', value: 'sales' }],
isTop: false,
page: 1,
limit: 10,
loadTitle: '',
loading: false,
finished: true,
goods: []
};
},
computed: {
storeInfo() {
return JSON.parse(uni.getStorageSync('storeInfo') || '{}');
},
// styleIndex() {
// const index = uni.getStorageSync('styleIndex') || '';
// return index;
// },
// navBgColor() {
// return this.styleIndex ? (styleColor.shopNavBgColor[this.styleIndex - 1] || '#FFA3B2') : '#FFA3B2'
// }
},
watch: {
firstCate() {
this.goods = [];
this.page = 1;
this.loading = false;
this.finished = false;
this.getGoodsList();
},
secondCate() {
this.goods = [];
this.page = 1;
this.loading = false;
this.finished = false;
this.getGoodsList();
},
},
onPageScroll(e) {
if (e.scrollTop <= 200) { // 当滚动到顶部且向下滑动时为true
this.isTop = false
} else {
this.isTop = true
}
},
onLoad({ id }) {
this.id = id;
this.getShopDetail()
this.getGoodsTypeList();
},
onReachBottom() {
this.getGoodsList();
},
methods: {
back() {
let pages = getCurrentPages();
if (pages.length > 1) {
uni.navigateBack();
} else {
uni.reLaunch({
url: "/pages/index/index"
})
}
},
search() {
// 跳转商品搜索
uni.navigateTo({
url: `/pages/search/index?merchantId=${this.id}`
})
},
changeFilter(item) {
if (item !== this.activeFilter) {
this.activeFilter = item;
this.filterDirection = 'ASC';
} else if (item === 'price') {
this.filterDirection = this.filterDirection === 'ASC' ? 'DESC' : 'ASC';
}
this.goods = [];
this.page = 1;
this.loading = false;
this.finished = false;
this.getGoodsList();
},
openScrollTo() {
uni.pageScrollTo({
scrollTop: 0
})
},
toCer() {
uni.navigateTo({
url: `/pages/shopList/certificate?id=${this.id}`,
});
},
async getShopDetail() {
Api.getShopDetail({
id: this.id
})
.then(result => {
console.log(result);
this.shopDetail = result.data.detail;
})
.finally(() => this.loading = false)
},
getGoodsTypeList() {
const that = this;
return new Promise((resolve, reject) => {
cstegory.listmerchant({
merchantId: this.id
})
.then(res => {
// 合并新数据
console.log(res, '分类数据')
that.goodsCate = res.data.list;
that.firstCate = res.data.list[0].category_id;
})
.catch(reject)
})
},
/**
* 获取商品列表
* @param {number} pageNo 页码
*/
getGoodsList: debounce(function() {
if (this.loading || this.finished) {
return;
}
this.loadTitle = "";
const param = {
sortType: this.activeFilter,
sortPrice: this.filterDirection === 'DESC' ? 1 : 0,
categoryId: this.secondCate || this.firstCate,
merchantId: this.id,
page: this.page++,
}
GoodsApi.list(param)
.then(result => {
// 合并新数据
const data = result.data.list.data;
console.log(data);
this.goods = this.goods.concat(data);
this.finished = data.length < 10;
this.loadTitle = this.finished ? "我是有底线的哦~" : "上拉加载更多";
})
}, 500),
toCart() {
uni.reLaunch({
url: '/pages/cart/index'
})
},
// 跳转商品详情页
onGoodDetail(goodsId) {
this.$navTo('pages/goods/detail', {
goodsId
})
},
/**
* 分享当前页面
*/
onShareAppMessage() {
const app = this
// 构建页面参数
const params = app.$getShareUrlParams({ id: app.id });
return {
title: app.shopDetail.shop_name,
path: "/pages/shopList/shopPage?" + params
}
},
/**
* 分享到朋友圈
* 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta)
*/
onShareTimeline() {
const app = this
// 构建页面参数
const params = app.$getShareUrlParams({ id: app.id });
return {
title: app.shopDetail.shop_name,
path: "/pages/shopList/shopPage?" + params
}
}
}
};
</script>
<style lang="scss" scoped>
.shop {
height: 100vh;
display: flex;
flex-direction: column;
background: url(https://www.royaum.com.cn/static/shop/shop-page-bg.png) center top no-repeat;
background-size: 100% auto;
.navbarContent {
display: flex;
justify-content: flex-start;
align-items: center;
.back {
margin-right: 24rpx;
margin-left: 12rpx;
}
.search-box {
position: relative;
.search-model {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 100;
}
}
&::v-deep .u-navbar-inner {
position: relative;
margin-right: 0 !important;
display: flex;
.search-box {
width: 442rpx;
}
}
}
.page {
flex: 1;
display: flex;
flex-direction: column;
padding-top: 30rpx;
.shop-tip {
padding: 0 24rpx;
display: flex;
align-items: center;
>text {
font-size: 24rpx;
color: #fff;
margin-right: auto;
}
.logo {
width: 50rpx;
height: 50rpx;
margin-right: 10rpx;
}
.tip {
font-size: 22rpx;
color: #fff;
margin-left: 20rpx;
display: flex;
align-items: center;
image {
width: 26rpx;
height: 26rpx;
margin-right: 8rpx;
}
}
}
.shop-info {
display: flex;
align-items: center;
margin-top: 30rpx;
padding: 0 24rpx;
.logo {
width: 90rpx;
height: 90rpx;
border-radius: 10rpx;
margin-right: 10rpx;
}
.info-box {
flex: 1;
.name {
font-size: 30rpx;
color: #fff;
margin-bottom: 18rpx;
}
.intro {
display: flex;
align-items: center;
.label {
height: 36rpx;
background: #F34A40;
border-radius: 4rpx;
padding: 0 7rpx;
line-height: 36rpx;
text-align: center;
font-size: 24rpx;
color: #fff;
margin-right: 20rpx;
}
>view {
width: 90rpx;
height: 36rpx;
background: rgba(0, 0, 0, 0.2);
border-radius: 4rpx;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 24rpx;
>image {
width: 21rpx;
height: 20rpx;
margin-right: 7rpx;
}
}
}
}
.share-btn {
width: 130rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 20rpx;
color: #fff;
background: #F34A40;
border-radius: 30rpx;
padding: 0;
>image {
width: 26rpx;
height: 22rpx;
margin-right: 12rpx;
}
}
}
.shop-goods {
flex: 1;
display: flex;
flex-direction: column;
margin-top: 30rpx;
background: #F0F4F3;
border-radius: 20rpx 20rpx 0 0;
padding-top: 24rpx;
.second-cate {
padding: 0 24rpx;
margin-bottom: 24rpx;
.second-cate-tabs {
height: 80rpx;
align-items: center;
white-space: nowrap;
width: 100%;
overflow-x: auto;
overflow-y: hidden;
.cate-item {
display: inline-block;
height: 80rpx;
padding: 0 26rpx;
background: #FFFFFF;
border-radius: 10rpx;
line-height: 80rpx;
margin-right: 20rpx;
color: #333333;
font-size: 28rpx;
&:last-child {
margin-right: 0;
}
&.active {
background: #F34A40;
color: #fff;
}
}
}
}
.goods-content {
flex: 1;
display: flex;
.first-cate {
height: 100%;
width: 108rpx;
.first-cate-tabs {
overflow-x: hidden;
overflow-y: auto;
background: #fff;
.cate-item {
width: 100%;
padding: 20rpx 30rpx;
color: #999999;
font-size: 24rpx;
position: relative;
background: #F0F4F3;
&.prev {
border-radius: 0 0 30rpx 0;
}
&.next {
border-radius: 0 30rpx 0 0;
}
&.active {
background: transparent;
&::before {
content: '';
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 0;
width: 4rpx;
height: calc(100% - 60rpx);
background: #F34A40;
}
}
}
}
}
.content {
background: #fff;
height: 100%;
width: calc(100% - 108rpx);
display: flex;
flex-direction: column;
.filter-box {
height: 88rpx;
padding: 0 40rpx;
display: flex;
justify-content: space-between;
align-items: center;
.filter-item {
color: #333;
font-size: 28rpx;
position: relative;
display: flex;
justify-content: center;
&.active {
color: #F34A40;
}
text {
width: 0;
height: 0;
border: 10rpx solid;
border-color: #000 transparent transparent transparent;
vertical-align: top;
position: absolute;
left: 60rpx;
top: 15rpx;
&.up {
border-color: transparent transparent #000 transparent;
top: -1rpx;
&.on {
border-color: transparent transparent #F34A40 transparent;
}
}
&.down.on {
border-color: #F34A40 transparent transparent transparent;
}
}
}
}
.goods-list {
padding: 0 20rpx;
overflow-x: hidden;
overflow-y: auto;
display: flex;
flex-wrap: wrap;
.good {
width: 290rpx;
height: 422rpx;
background: #FFFFFF;
border-radius: 10rpx;
border: 1px solid #EAEAEA;
margin-right: 22rpx;
margin-bottom: 20rpx;
border-radius: 10rpx;
border: 1px solid #EAEAEA;
&:nth-child(2n) {
margin-right: 0;
}
>image {
width: 100%;
height: 287rpx;
}
.name {
color: #333333;
font-size: 26rpx;
margin: 30rpx 0 24rpx;
line-height: 26rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding: 0 24rpx;
}
.price {
padding: 0 24rpx;
.now-price {
color: #E53623;
font-size: 34rpx;
}
.origin-price {
text-decoration: line-through;
color: #999999;
font-size: 24rpx;
margin-left: 10;
}
}
}
}
.finished,
.loading {
font-size: 28rpx;
line-height: 100rpx;
text-align: center;
color: #bbb;
}
.empty {
margin-top: 100rpx;
font-size: 28rpx;
text-align: center;
color: #bbb;
}
.empty image {
display: block;
width: 306rpx;
height: 200rpx;
margin: 0 auto 20rpx;
pointer-events: none;
}
}
}
}
.toCart {
position: fixed;
bottom: 170rpx;
right: 26rpx;
width: 100rpx;
height: 100rpx;
border-radius: 50%;
opacity: 1;
z-index: 999;
display: flex;
align-items: center;
justify-content: center;
image {
width: 100%;
height: 100%;
}
}
.toTop {
position: fixed;
bottom: 65rpx;
right: 26rpx;
width: 100rpx;
height: 100rpx;
border-radius: 50%;
opacity: 1;
z-index: 999;
display: flex;
align-items: center;
justify-content: center;
image {
width: 100%;
height: 100%;
}
}
}
}
</style>