mall-laonong/pages/index/index.vue

396 lines
12 KiB
Vue

<template>
<view>
<view class="index-page pad-x190 border-box" v-if="isLoading">
<!-- -->
<view class="index-top">
<image :src="indexBackground" mode="widthFix"></image>
</view>
<view class="index-content background-white">
<view class="index-statis-bg background-white" :style="{height:statusHeight+80+'px'}" v-if="!isShow"></view>
<!-- -->
<view class="pull-search-bg background-white radius20 pad-sx30 border-box" v-if="isShow">
<view class="pull-search radius20 flex">
<image class="img" src="/static/icon/icon-search.png" mode="widthFix"></image>
<input class="input pad-zy15 border-box font30" v-model="keyword" type="text" placeholder="搜索" confirm-type="search" @confirm="doSearch" placeholder-style="color: #666666">
</view>
</view>
<!-- 商品分类 -->
<view class="index-cate-bg pad-zy20 background-white" :class="!isShow?'show':''" id="index-cate-bg" :style="{top:statusHeight+35+'px'}">
<view class="index-cate pad-zy20 border-box" :class="!isShow?'show':''">
<view class="pull-title" v-if="isShow">
<view class="txt font32 pad-sx10">商品</view>
<view class="line background-orange"></view>
</view>
<view class="cate-list-bg">
<scroll-view scroll-x="true" :scroll-left="tabsScrollLeft" @scroll="scroll">
<view class="cate-list flex" id="tab_list" :style="{width:cateWidth}">
<view class="cate-item" :class="index==currentIndex?'color-orange':''" id="tab_item" v-for="(item,index) in cateList" :key="index" @tap="changeCateEv(index)">
<view class="img mar-sx20"><image :src="item.cover" mode="widthFix"></image></view>
<view class="txt font24">{{item.title}}</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
<!-- 商品列表 -->
<view class="commodity pad-zy20 border-box flex">
<view class="item mar-s40 radius20" v-for="(item,index) in commodityList" :key="index" @tap.stop="goDetail(item.id)">
<view class="img">
<image :src="item.cover" mode="widthFix"></image>
</view>
<view class="txt pad-all20">
<view class="title fon30 clips2">{{item.name}}</view>
<view class="price font30 mar-sx10">¥{{item.price}}</view>
<view class="bottom flex">
<view class="sold font24 color-99">{{item.amount>=1000?'999+':item.amount}}件已售</view>
<view class="btn font24 background-orange flex" @tap.stop="joinCart(index)">加入购物车</view>
</view>
</view>
</view>
</view>
<!-- 到底啦 -->
<view class="no-more font24" v-if="noMore"><text>—— 到底啦 ——</text></view>
</view>
</view>
<!-- 搜索结果 -->
<view class="pull-bg" v-if="showSearch" @tap="closeSearch"></view>
<view class="search-box border-box" v-if="showSearch" :style="{height:screenHeight-statusHeight-50+'px',top:statusHeight+50+'px'}" >
<!-- <view class="close-box" :style="{height:statusHeight+50+'px'}"></view> -->
<!-- 搜索 -->
<view class="search-bg background-white pad-sx30 border-box">
<view class="search radius20 flex">
<image class="img" src="/static/icon/icon-search.png" mode="widthFix"></image>
<input class="input pad-zy15 border-box font30" v-model="keyword" type="text" placeholder="搜索" confirm-type="search" @confirm="doSearch" placeholder-style="color: #666666">
</view>
</view>
<view class="keyword-txt background-white font30">关键词:{{searchKeyword}}</view>
<scroll-view scroll-y="true" class="search-list background-white">
<!-- 搜索列表 -->
<view class="commodity pad-zy20 border-box flex">
<view class="item mar-s40 radius20" v-for="(item,index) in searchList" :key="index" @tap.stop="goDetail(item.id)">
<view class="img">
<image :src="item.cover" mode="widthFix"></image>
</view>
<view class="txt pad-all20">
<view class="title fon30 clips2">{{item.name}}</view>
<view class="price font30 mar-sx10">¥{{item.price}}</view>
<view class="bottom flex">
<view class="sold font24 color-99">{{item.stock>=100?'99+':item.stock}}件已售</view>
<view class="btn font24 background-orange flex" @tap.stop="joinCart(index)">加入购物车</view>
</view>
</view>
</view>
</view>
<!-- 没有相关结果 -->
<view class="no-more font24 pad-sx25" style="margin: 0;" v-if="searchList.length==0"><text>—— 没有相关结果 ——</text></view>
</scroll-view>
</view>
<!-- 尾部 -->
<tabbar v-if="isLoading"></tabbar>
</view>
</template>
<script>
import tabbar from '@/components/tabbar/tabbar';
import {getCartInfo} from '@/jsFile/public-api.js';
import {mapState} from 'vuex'//引入mapState
export default {
components:{
tabbar
},
data() {
return {
screenHeight:uni.getSystemInfoSync().screenHeight,
statusHeight:uni.getSystemInfoSync().statusBarHeight,
scrollTop:0, //分类距离顶部距离
isShow: true, //显示
//分类导航
currentIndex:0,
scrollLeft:0,
tabsScrollLeft:0,
cateWidth:'',
indexBackground:'', //背景图
keyword:'', //关键词
cateList:[], //商品分类
commodityList:[], //商品列表
ifLoading:true,
page:1, //分页
size:10, //条数
total:0, //总数
noMore:false, //没有更多
vip_level:0, //是否是会员
keyword:'', //关键词
searchKeyword:'', //搜索关键词
searchList:[], //搜索结果
showSearch:false, //显示搜索结果
isLoading:false,
}
},
onLoad(op) {
if(op.invite_code){
// 缓存invite_code
uni.setStorageSync('inviteCode',op.invite_code);
}
// 获取头部背景
this.getTabbarEv();
// 获取分类列表
this.getCateEv();
},
onShow() {
// 刷新购物车信息
getCartInfo();
this.playTimer = setTimeout(()=>{
this.isplay = true;
},2000)
this.vip_level = uni.getStorageSync('vip_level');
},
onReady() {
},
onHide() {
clearTimeout(this.playTimer);
this.isplay =false;
},
onPageScroll(object){
if(object.scrollTop >= this.statusHeight+65 && object.scrollTop <= this.statusHeight+135){
this.isShow = false;
}
if(object.scrollTop <= this.statusHeight+50){
this.isShow = true;
}
},
// 分享到微信
onShareAppMessage(res) {
let shareObj = {
title:'老农极鲜',
path: uni.getStorageSync('page-path-options')+'?invite_code='+uni.getStorageSync('invite_code'),
imageUrl:'/static/img/shear-index.jpg',
}
// 返回shareObj
return shareObj;
},
// 分享到朋友圈
onShareTimeline(res){
let shareObj = {
title:'老农极鲜',
query: '?invite_code='+uni.getStorageSync('invite_code'),
path: uni.getStorageSync('page-path-options')+'?invite_code='+uni.getStorageSync('invite_code'),
imageUrl:'/static/img/shear-index.jpg',
}
// 返回shareObj
return shareObj;
},
// 触底
onReachBottom(e) {
if(!this.noMore){
this.page++;
// 查询商品列表
this.getCommodityEv(this.cateList[this.currentIndex].id);
}
},
watch: {
list() {
this.setTabList()
},
value() {
this.currentIndex = this.value
this.setTabList()
}
},
methods: {
// 获取头部背景
getTabbarEv(){
this.$requst.get('/api/index/mini-program-setting').then(res=>{
if(res.code == 0){
console.log(res,'个性装扮')
this.indexBackground = this.$hostHttp + res.data.indexBackground;
}
})
},
// 获取商品分类
getCateEv(){
this.$requst.get('/api/spu/category').then(res=>{
if(res.code == 0){
console.log(res,'商品分类')
let cateArr =[];
res.data.forEach(item=>{
let obj = {
id:item.id,
title:item.title,
cover:item.cover
}
cateArr.push(obj);
})
this.cateList = cateArr;
this.cateWidth = this.cateList.length*158 - 58 + 'rpx';
// 查询商品列表
this.getCommodityEv(this.cateList[this.currentIndex].id);
}
})
},
// 查询商品列表
getCommodityEv(id){
uni.showLoading({
title:'加载中'
})
let params = {
page:this.page,
size:this.size,
category_id:id
}
this.$requst.get('/api/spu/list',params).then(res=>{
if(res.code == 0){
console.log(res,'商品列表')
this.total = res.data.total;
let commodityArr = [];
res.data.list.forEach(item=>{
let obj = {
id:item.id,
cover:item.cover,
name:item.name,
original_price:item.original_price,
price:item.price,
tag:item.tag,
stock:item.stock,
sku_id:item.default_sku.id,
amount:item.amount,
}
commodityArr.push(obj)
})
this.commodityList = this.commodityList.concat(commodityArr);
if(this.commodityList.length==this.total){
this.noMore =true;
}
}
uni.hideLoading();
this.isLoading = true;
})
},
// 加入购物车
joinCart(index){
if(this.$toolAll.tools.judgeAuth()) {
this.$requst.post('/api/order/shopping-cart-add',{sku_id:this.commodityList[index].sku_id,num:1}).then(res=>{
if(res.code==0) {
this.$toolAll.tools.showToast('加入购物车成功(*^▽^*)');
getCartInfo();
} else {
this.$toolAll.tools.showToast(res.msg)
}
})
}
},
// 去详情页
goDetail(id){
uni.navigateTo({
url:`/pagesB/shop-detail/shop-detail?id=${id}`
})
},
// 分类选择事件
changeCateEv(index) {
if(index !== this.currentIndex){
this.isShow = true;
this.currentIndex = index;
// 获取商品列表
this.commodityList = [];
this.noMore = false;
this.getCommodityEv(this.cateList[index].id);
// 分类切换效果
this.setTabList();
}
},
// 分类切换效果
setTabList() {
this.$nextTick(() => {
if (this.cateList.length > 0) {
//计算左滑距离
this.setLeft()
// 计算顶部距离
this.setTop();
}
})
},
//计算左滑距离
setLeft() {
let lineLeft = 0;
this.getElementData('#tab_list', (data) => {
let list = data[0];
this.getElementData('#tab_item', (res) => {
let el = res[this.currentIndex]
lineLeft = el.width / 2 + (-list.left) + el.left - list.width / 2 - this.scrollLeft
this.tabsScrollLeft = this.scrollLeft + lineLeft
})
})
},
// 计算顶部距离
setTop(){
this.getElementData('#index-cate-bg', (res) => {
let el = res[0];
this.scrollTop = el.top;
if(this.scrollTop==this.statusHeight+35){
this.isShow = false;
}else{
this.isShow = true;
}
})
},
// 获取DOM距离
getElementData(el, callback) {
uni.createSelectorQuery().in(this).selectAll(el).boundingClientRect().exec((data) => {
callback(data[0]);
});
},
// 滚动
scroll(e) {
this.scrollLeft = e.detail.scrollLeft;
},
// 搜索结果
doSearch(){
this.showSearch = true;
this.searchList = [];
this.searchKeyword = this.keyword;
this.keyword = '';
this.$requst.get('/api/spu/list',{keyword:this.searchKeyword}).then(res=>{
if(res.code == 0){
console.log(res,'搜索列表')
this.total = res.data.total;
let searchArr = [];
res.data.list.forEach(item=>{
let obj = {
id:item.id,
cover:item.cover,
name:item.name,
original_price:item.original_price,
price:item.price,
tag:item.tag,
stock:item.stock,
sku_id:item.default_sku.id
}
searchArr.push(obj)
})
this.searchList = this.searchList.concat(searchArr);
}
})
},
// 关闭搜索
closeSearch(){
this.showSearch = false;
this.searchKeyword = '';
this.searchList = [];
}
}
}
</script>
<style>
</style>