You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
588 lines
16 KiB
Vue
588 lines
16 KiB
Vue
<template>
|
|
<view class="container">
|
|
<!--店铺切换-->
|
|
<Location v-if="storeInfo" :storeInfo="storeInfo"/>
|
|
|
|
<!-- 搜索框 -->
|
|
<Search tips="请输入搜索关键字..." @event="$navTo('pages/search/index')" />
|
|
|
|
<view class="cate-content dis-flex" v-if="list.length > 0">
|
|
<!-- 左侧 分类 -->
|
|
<scroll-view class="cate-left f-28" :scroll-y="true" :style="{ height: `${scrollHeight}px` }">
|
|
<view v-for="(item, index) in list" :key="index">
|
|
<text class="cart-badge" v-if="item.total">{{ item.total }}</text>
|
|
<view class="type-nav" :class="{ selected: curIndex == index }" @click="handleSelectNav(index)">
|
|
<image class="logo" lazy-load :lazy-load-margin="0" v-if="item.logo" :src="item.logo"></image>
|
|
<view class="name">{{ item.name }}</view>
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
|
|
<!-- 右侧 商品 -->
|
|
<scroll-view class="cate-right b-f" :scroll-top="scrollTop" :scroll-y="true" :style="{ height: `${scrollHeight}px` }">
|
|
<view v-if="list[curIndex]">
|
|
<view class="cate-right-cont">
|
|
<view class="cate-two-box">
|
|
<view v-if="list[curIndex].goodsList.length" class="cate-cont-box">
|
|
<view class="flex-five item" v-for="(item, idx) in list[curIndex].goodsList" :key="idx">
|
|
<view class="cate-img">
|
|
<image v-if="item.logo" lazy-load :lazy-load-margin="0" :src="item.logo" @click="onTargetGoods(item.id)"></image>
|
|
</view>
|
|
<view class="cate-info">
|
|
<view class="base">
|
|
<text class="name text">{{ item.name }}</text>
|
|
<text class="stock text">库存:{{ item.stock ? item.stock : 0 }} 已售:{{ item.initSale ? item.initSale : 0 }}</text>
|
|
</view>
|
|
<view class="action">
|
|
<text class="price">¥{{ item.price ? item.price : 0 }}</text>
|
|
<view class="cart">
|
|
<view v-if="item.isSingleSpec === 'Y'" class="singleSpec">
|
|
<view class="ii do-minus" v-if="item.buyNum" @click="onSaveCart(item.id, '-')"></view>
|
|
<view class="ii num" v-if="item.buyNum">{{ (item.buyNum != undefined) ? item.buyNum : 0 }}</view>
|
|
<view class="ii do-add" v-if="item.stock > 0" @click="onSaveCart(item.id, '+')"></view>
|
|
</view>
|
|
<view v-if="item.isSingleSpec === 'N'" class="multiSpec">
|
|
<text class="num-badge" v-if="item.buyNum">{{ item.buyNum }}</text>
|
|
<view class="select-spec" @click="onShowSkuPopup(2, item.id)">选规格</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<empty v-if="!list[curIndex].goodsList.length" :isLoading="isLoading" tips="暂无商品~"></empty>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
|
|
</view>
|
|
|
|
<!-- 商品SKU弹窗 -->
|
|
<SkuPopup v-if="!isLoading" v-model="showSkuPopup" :skuMode="skuMode" :goods="goods" @addCart="onAddCart"/>
|
|
|
|
<view class="flow-fixed-footer b-f m-top10">
|
|
<view class="dis-flex chackout-box">
|
|
<view class="chackout-left pl-12">
|
|
<view class="col-amount-do">总金额:<text class="amount">¥{{ totalPrice.toFixed(2) }}</text></view>
|
|
<view class="col-amount-view">共计:{{ totalNum }} 件</view>
|
|
</view>
|
|
<view class="chackout-right" @click="doSubmit()">
|
|
<view class="flow-btn f-32">去结算</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<empty v-if="!list.length" :isLoading="isLoading" />
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { setCartTabBadge, setCartTotalNum } from '@/utils/app'
|
|
import * as CartApi from '@/api/cart'
|
|
import * as GoodsApi from '@/api/goods'
|
|
import * as settingApi from '@/api/setting'
|
|
import Search from '@/components/search'
|
|
import Empty from '@/components/empty'
|
|
import SkuPopup from './components/SkuPopup'
|
|
import Location from '@/components/page/location'
|
|
|
|
const App = getApp()
|
|
|
|
export default {
|
|
components: {
|
|
Search,
|
|
SkuPopup,
|
|
Empty,
|
|
Location
|
|
},
|
|
data() {
|
|
return {
|
|
goodsCart: [],
|
|
totalNum: 0,
|
|
totalPrice: 0.00,
|
|
// 列表高度
|
|
scrollHeight: 500,
|
|
// 一级分类:指针
|
|
curIndex: 0,
|
|
// 内容区竖向滚动条位置
|
|
scrollTop: 0,
|
|
// 分类列表
|
|
list: [],
|
|
// 正在加载中
|
|
isLoading: true,
|
|
showSkuPopup: false,
|
|
skuMode: 1,
|
|
goods: {},
|
|
storeInfo: null
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 生命周期函数--监听页面加载
|
|
*/
|
|
onLoad() {
|
|
const app = this
|
|
// 设置分类列表高度
|
|
app.setListHeight()
|
|
},
|
|
|
|
/**
|
|
* 生命周期函数--监听页面显示
|
|
*/
|
|
onShow() {
|
|
const app = this;
|
|
// 获取页面数据
|
|
app.getPageData();
|
|
app.onGetStoreInfo();
|
|
uni.getLocation({
|
|
type: 'gcj02',
|
|
success(res){
|
|
uni.setStorageSync('latitude', res.latitude);
|
|
uni.setStorageSync('longitude', res.longitude);
|
|
app.onGetStoreInfo();
|
|
},
|
|
fail(e) {
|
|
// empty
|
|
}
|
|
})
|
|
},
|
|
|
|
methods: {
|
|
/**
|
|
* 获取页面数据
|
|
*/
|
|
getPageData() {
|
|
const app = this
|
|
app.isLoading = true
|
|
Promise.all([
|
|
// 获取分类列表
|
|
GoodsApi.cateList(),
|
|
// 获取购物车列表
|
|
CartApi.list()
|
|
])
|
|
.then(result => {
|
|
// 初始化分类列表数据
|
|
app.list = result[0].data;
|
|
app.totalNum = result[1].data.totalNum;
|
|
app.goodsCart = result[1].data.list;
|
|
setCartTotalNum(app.totalNum);
|
|
setCartTabBadge();
|
|
})
|
|
.finally(() => {
|
|
app.isLoading = false
|
|
app.totalPrice = 0
|
|
app.list.forEach(function(item, index) {
|
|
let total = 0
|
|
item.goodsList.forEach(function(goods, key) {
|
|
let totalBuyNum = 0
|
|
app.goodsCart.forEach(function(cart){
|
|
if (goods.id == cart.goodsId) {
|
|
total = total + cart.num
|
|
totalBuyNum = totalBuyNum + cart.num
|
|
app.totalPrice = app.totalPrice + (cart.goodsInfo.price * cart.num)
|
|
}
|
|
})
|
|
app.$set(app.list[index].goodsList[key], 'buyNum', totalBuyNum)
|
|
})
|
|
app.$set(app.list[index], 'total', total)
|
|
})
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 获取默认店铺
|
|
* */
|
|
onGetStoreInfo() {
|
|
const app = this
|
|
settingApi.systemConfig()
|
|
.then(result => {
|
|
app.storeInfo = result.data.storeInfo
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 跳转商品详情
|
|
*/
|
|
onTargetGoods(goodsId) {
|
|
this.$navTo(`pages/goods/detail`, { goodsId })
|
|
},
|
|
|
|
/**
|
|
* 设置分类列表高度
|
|
*/
|
|
setListHeight() {
|
|
const app = this
|
|
uni.getSystemInfo({
|
|
success(res) {
|
|
app.scrollHeight = res.windowHeight - 120
|
|
}
|
|
})
|
|
},
|
|
|
|
// 一级分类:选中分类
|
|
handleSelectNav(index) {
|
|
const app = this;
|
|
app.curIndex = index;
|
|
app.scrollTop = 0;
|
|
},
|
|
|
|
// 更新购物车
|
|
onSaveCart(goodsId, action) {
|
|
const app = this
|
|
return new Promise((resolve, reject) => {
|
|
CartApi.save(goodsId, action)
|
|
.then(result => {
|
|
app.getPageData();
|
|
resolve(result);
|
|
})
|
|
.catch(err => {
|
|
console.log(err);
|
|
})
|
|
})
|
|
},
|
|
// 更新购物车数量
|
|
onAddCart(total) {
|
|
this.getPageData();
|
|
this.$toast("添加购物车成功");
|
|
},
|
|
// 结算
|
|
doSubmit() {
|
|
if (this.totalPrice > 0) {
|
|
this.$navTo('pages/cart/index')
|
|
} else {
|
|
this.$error("请先选择商品")
|
|
}
|
|
},
|
|
onShowSkuPopup(skuMode, goodsId) {
|
|
const app = this
|
|
app.isLoading = true
|
|
return new Promise((resolve, reject) => {
|
|
GoodsApi.detail(goodsId)
|
|
.then(result => {
|
|
const goodsData = result.data
|
|
|
|
if (goodsData.skuList) {
|
|
goodsData.skuList.forEach(function(sku, index) {
|
|
goodsData.skuList[index].specIds = sku.specIds.split('-')
|
|
goodsData.skuList[index].skuId = sku.id
|
|
})
|
|
}
|
|
|
|
app.goods = goodsData
|
|
app.skuMode = skuMode
|
|
app.showSkuPopup = !app.showSkuPopup
|
|
|
|
console.log(app.skuMode)
|
|
|
|
app.isLoading = false
|
|
|
|
resolve(result)
|
|
})
|
|
.catch(err => reject(err))
|
|
})
|
|
},
|
|
},
|
|
|
|
/**
|
|
* 设置分享内容
|
|
*/
|
|
onShareAppMessage() {
|
|
const app = this
|
|
return {
|
|
title: _this.templet.shareTitle,
|
|
path: '/pages/category/index?' + app.$getShareUrlParams()
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 分享到朋友圈
|
|
* 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta)
|
|
* https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html
|
|
*/
|
|
onShareTimeline() {
|
|
const app = this
|
|
return {
|
|
title: _this.templet.shareTitle,
|
|
path: '/pages/category/index?' + app.$getShareUrlParams()
|
|
}
|
|
}
|
|
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
page {
|
|
background: #fff;
|
|
}
|
|
</style>
|
|
<style lang="scss" scoped>
|
|
.cate-content {
|
|
background: #fff;
|
|
margin-top: 118rpx;
|
|
/* #ifdef H5 */
|
|
margin-top: 124rpx;
|
|
/* #endif */
|
|
}
|
|
|
|
.cate-wrapper {
|
|
padding: 0 20rpx 20rpx 20rpx;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* 分类内容 */
|
|
.cate-content {
|
|
width: 100%;
|
|
}
|
|
|
|
.cate-left {
|
|
flex-direction: column;
|
|
display: flex;
|
|
width: 200rpx;
|
|
color: #444;
|
|
height: 100%;
|
|
background: #f8f8f8;
|
|
margin-bottom: 120rpx;
|
|
.cart-badge {
|
|
position: absolute;
|
|
right: 1rpx;
|
|
margin-top: 10rpx;
|
|
margin-right: 5rpx;
|
|
font-size: 18rpx;
|
|
background: #fa5151;
|
|
z-index: 999;
|
|
text-align: center;
|
|
line-height: 28rpx;
|
|
color: #ffffff;
|
|
border-radius: 50%;
|
|
min-width: 32rpx;
|
|
padding: 5rpx 13rpx 5rpx 13rpx;
|
|
}
|
|
}
|
|
|
|
.cate-right {
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 550rpx;
|
|
height: 100%;
|
|
overflow: hidden;
|
|
margin-bottom: 80rpx;
|
|
}
|
|
|
|
.cate-right-cont {
|
|
width: 100%;
|
|
display: flex;
|
|
flex-flow: row wrap;
|
|
align-content: flex-start;
|
|
padding-top: 10rpx;
|
|
}
|
|
|
|
.type-nav {
|
|
position: relative;
|
|
height: 140rpx;
|
|
text-align: center;
|
|
z-index: 10;
|
|
display: block;
|
|
font-size: 26rpx;
|
|
padding: 20rpx 0rpx 126rpx 0rpx;
|
|
.logo {
|
|
width: 60rpx;
|
|
height: 60rpx;
|
|
border-radius: 60rpx;
|
|
margin: 0rpx;
|
|
padding: 0rpx;
|
|
}
|
|
.name {
|
|
margin-top: 2rpx;
|
|
width: 100%;
|
|
overflow-x: hidden;
|
|
height: 40rpx;
|
|
line-height: 40rpx;
|
|
text-align: center;
|
|
}
|
|
}
|
|
|
|
.type-nav.selected {
|
|
color: #666666;
|
|
background: #ffffff;
|
|
border-right: none;
|
|
border-left: solid 10rpx #f03c3c;
|
|
font-weight: bold;
|
|
font-size: 28rpx;
|
|
}
|
|
|
|
.cate-cont-box {
|
|
margin-bottom: 10rpx;
|
|
padding-bottom: 10rpx;
|
|
overflow: hidden;
|
|
height: auto;
|
|
display: block;
|
|
.item {
|
|
height: 220rpx;
|
|
display: block;
|
|
padding-top: 5rpx;
|
|
border-radius: 3rpx;
|
|
margin-bottom: 5rpx;
|
|
}
|
|
}
|
|
|
|
.cate-cont-box .cate-img {
|
|
padding: 13rpx 10rpx 4rpx 10rpx;
|
|
display: block;
|
|
}
|
|
|
|
.cate-cont-box .cate-img image {
|
|
width: 160rpx;
|
|
height: 150rpx;
|
|
float: left;
|
|
border-radius: 5rpx;
|
|
display: block;
|
|
border: #cccccc solid 1rpx;
|
|
margin-top: 5rpx;
|
|
}
|
|
|
|
.cate-cont-box .cate-info {
|
|
text-align: left;
|
|
display: block;
|
|
font-size: 26rpx;
|
|
margin-left: 168rpx;
|
|
padding-bottom: 14rpx;
|
|
color: #444;
|
|
padding: 0 15rpx 30rpx 15rpx;
|
|
.base {
|
|
height: 100%;
|
|
display: block;
|
|
.text {
|
|
display: block;
|
|
float: left;
|
|
width: 100%;
|
|
}
|
|
.name {
|
|
font-weight: bold;
|
|
width: 100%;
|
|
font-size: 26rpx;
|
|
overflow: hidden;
|
|
display: -webkit-box;
|
|
-webkit-box-orient: vertical;
|
|
-webkit-line-clamp: 2;
|
|
}
|
|
.stock {
|
|
margin-top: 10rpx;
|
|
color: #999;
|
|
}
|
|
}
|
|
.action {
|
|
display: block;
|
|
height: 50rpx;
|
|
.price {
|
|
margin-top: 20rpx;
|
|
color: #f03c3c;
|
|
float: left;
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
}
|
|
.cart {
|
|
margin-top: 20rpx;
|
|
float: right;
|
|
font-size: 30rpx;
|
|
height: 60rpx;
|
|
.ii {
|
|
float: left;
|
|
text-align: center;
|
|
width: 60rpx;
|
|
cursor: pointer;
|
|
}
|
|
.do-add {
|
|
background: url('~@/static/icon/add.png') no-repeat;
|
|
background-size: 100% 100%;
|
|
width: 45rpx;
|
|
height: 45rpx;
|
|
}
|
|
.do-minus {
|
|
background-image: url('~@/static/icon/minus.png');
|
|
background-size: 100% 100%;
|
|
width: 45rpx;
|
|
height: 45rpx;
|
|
}
|
|
.multiSpec {
|
|
.num-badge {
|
|
position: absolute;
|
|
margin-top: 10rpx;
|
|
margin-right: 25rpx;
|
|
font-size: 18rpx;
|
|
background: #f03c3c;
|
|
text-align: center;
|
|
line-height: 36rpx;
|
|
color: #ffffff;
|
|
border-radius: 50%;
|
|
min-width: 36rpx;
|
|
padding: 2rpx;
|
|
}
|
|
.select-spec {
|
|
border: solid 1rpx $fuint-theme;
|
|
padding: 10rpx 20rpx 10rpx 36rpx;
|
|
font-size: 25rpx;
|
|
border-radius: 5rpx;
|
|
color: #ffffff;
|
|
background: $fuint-theme;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.cate-two-box {
|
|
width: 100%;
|
|
padding: 0 2px;
|
|
}
|
|
|
|
// 底部操作栏
|
|
.flow-fixed-footer {
|
|
position: fixed;
|
|
bottom: var(--window-bottom);
|
|
width: 100%;
|
|
background: #fff;
|
|
border-top: 1px solid #eee;
|
|
z-index: 11;
|
|
padding-top: 8rpx;
|
|
.chackout-left {
|
|
font-size: 28rpx;
|
|
height: 98rpx;
|
|
color: #777;
|
|
flex: 4;
|
|
padding-left: 12px;
|
|
text-align: right;
|
|
padding-right: 40rpx;
|
|
.col-amount-do {
|
|
font-size: 35rpx;
|
|
margin-top: 5rpx;
|
|
margin-bottom:5rpx;
|
|
.amount {
|
|
color: #f03c3c;
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
}
|
|
|
|
.chackout-right {
|
|
font-size: 34rpx;
|
|
flex: 2;
|
|
}
|
|
|
|
// 提交按钮
|
|
.flow-btn {
|
|
background: linear-gradient(to right, $fuint-theme, $fuint-theme);
|
|
color: #fff;
|
|
text-align: center;
|
|
line-height: 92rpx;
|
|
display: block;
|
|
font-size: 28rpx;
|
|
border-radius: 5rpx;
|
|
margin-right: 20rpx;
|
|
// 禁用按钮
|
|
&.disabled {
|
|
background: #ff9779;
|
|
}
|
|
}
|
|
}
|
|
</style>
|