386 lines
9.4 KiB
Vue
386 lines
9.4 KiB
Vue
<template>
|
|
<view class="goods-search u-relative">
|
|
|
|
<view class="header-wrap">
|
|
<u-sticky offset-top="0" h5-nav-height="0">
|
|
<view class="search">
|
|
<u-search v-model="keyword" @focus="showHistory = true" :focus="showHistory" @search="onSearch" bg-color="#F4F4F4"></u-search>
|
|
</view>
|
|
</u-sticky>
|
|
</view>
|
|
<view v-show="showHistory" class="content bg-white">
|
|
<view v-if="hotList.length" class="search-words">
|
|
<view class="title">热门搜索</view>
|
|
<view class="words row wrap">
|
|
<view v-for="(item, index) in hotList" :key="index" class="item br60 mr20 mb20 lighter sm line1" @tap="onChangeKeyword(item)">{{item}}</view>
|
|
</view>
|
|
</view>
|
|
<view v-if="historyList.length" class="search-words">
|
|
<view class="title row-between">
|
|
<view>历史搜索</view>
|
|
<view class="xs muted mr20" style="padding: 10rpx 20rpx" @tap="clearSearchFun">清空</view>
|
|
</view>
|
|
<view class="words row wrap">
|
|
<view v-for="(item, index) in historyList" :key="index" class="item br60 mr20 mb20 lighter sm line1" @tap="onChangeKeyword(item)">{{item}}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view v-show="!showHistory" class="content">
|
|
<mescroll-body ref="mescroll" @init="mescrollInit" @down="downCallback" :up="upOption" :down="downOption" @up="upCallback">
|
|
<view v-for="(item, index) in goodsList" :key="index">
|
|
<navigator :url="`/pages/shop/shop?id=${item.id}`" hover-class="none" class="bg-white row u-m-b-20 u-p-20">
|
|
<!-- <view class="bg-white row u-m-b-20 u-p-20"> -->
|
|
<view class="">
|
|
<u-image :src="item.image" width="136" height="136" border-radius="16"></u-image>
|
|
</view>
|
|
<view class="u-m-l-16 w-full row-start u-row-between">
|
|
<view>
|
|
<view class="u-line-2 u-p-t-10">{{item.name}}</view>
|
|
<view class="u-p-t-20 row-between">
|
|
<view class="row">
|
|
<view class="primary">
|
|
<price-format :price="item.price" :subscriptSize="22" :firstSize="34" :secondSize="26"></price-format>
|
|
</view>
|
|
<view class="u-m-l-8">
|
|
<price-format :price="item.market_price" :lineThrough="true" color="#C0C0C0" :subscriptSize="22" :firstSize="22" :secondSize="22"></price-format>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="column-end">
|
|
<view @click.stop="addCartFun(item)">
|
|
<u-icon name="plus-circle-fill" color="#254062" size="48"></u-icon>
|
|
</view>
|
|
<!-- <u-button
|
|
@click.stop="openSpec(item)"
|
|
hover-class="none"
|
|
:customStyle="{width: '116rpx', height: '46rpx', lineHeight: '46rpx', fontSize: '24rpx', backgroundColor: themeColor, color: '#fff', border: 'none', paddingTop: '8rpx'}"
|
|
:hair-line="false"
|
|
shape="circle">
|
|
选规格
|
|
</u-button> -->
|
|
</view>
|
|
</view>
|
|
<!-- </view> -->
|
|
</navigator>
|
|
</view>
|
|
</mescroll-body>
|
|
|
|
<view class="buy mx40 px40 br60 row-between">
|
|
<view class="row" @tap="showCart = true">
|
|
<view class="u-relative">
|
|
<u-image :src="cloudPath + 'img/icon_cart.png'" width="80" height="80"></u-image>
|
|
<view class="u-absolute top-0 right-0 text-fff number u-text-center xxs" v-if="buyNumber">
|
|
{{ buyNumber }}
|
|
</view>
|
|
</view>
|
|
<view class="text-fff u-m-l-32">未选购商品</view>
|
|
</view>
|
|
<view class="text-999">去结算</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 购物车 -->
|
|
<u-popup v-model="showCart" mode="bottom" :border-radius="16">
|
|
<view style="max-height: 800rpx;">
|
|
<view class="px20 text-999 mt20">
|
|
温馨提示:请适量点餐
|
|
</view>
|
|
<view>
|
|
<scroll-view style="height: 700rpx;" scroll-y="true" scroll-with-animation="true">
|
|
<view class="row-start u-row-between u-p-t-20 u-padding-bottom-20 px20" v-for="(item, index) in 20" :key="index">
|
|
<view class="row-start">
|
|
<view>
|
|
<u-image :src="cloudPath + 'img/banner.png'" width="136" height="136" border-radius="16"></u-image>
|
|
</view>
|
|
<view class="ml20">
|
|
<view class="u-line-2 u-p-t-10">葱烩海鲜卷边披萨</view>
|
|
<view class="primary u-p-t-40">
|
|
<price-format :price="12.9" :subscriptSize="22" :firstSize="34" :secondSize="26"></price-format>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view>
|
|
<view class="u-text-right">
|
|
<u-icon class="u-p-t-10" name="trash" size="32"></u-icon>
|
|
</view>
|
|
<view class="u-p-t-30">
|
|
<u-number-box min="1" v-model="numberVal" @change="changeNumber"></u-number-box>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
</view>
|
|
</u-popup>
|
|
|
|
<shop-spec v-model="showSpec" :name="goodsName" :spec="goodsSpec" @close="showSpec = false" @confirm="confirmSpec"></shop-spec>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import {
|
|
getGoodsSearch,
|
|
getSearchpage,
|
|
clearSearch,
|
|
addCart,
|
|
} from '@/api/store'
|
|
import {
|
|
trottle,
|
|
loadingFun,
|
|
getRect
|
|
} from '@/utils/tools'
|
|
import {
|
|
loadingType
|
|
} from '@/utils/type'
|
|
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins"
|
|
export default {
|
|
mixins: [MescrollMixin],
|
|
data() {
|
|
return {
|
|
keyword: '',
|
|
status: loadingType.LOADING,
|
|
page: 1,
|
|
goodsType: 'double',
|
|
goodsList: [],
|
|
priceSort: '',
|
|
saleSort: '',
|
|
showHistory: false,
|
|
hotList: [],
|
|
historyList: [],
|
|
downOption: {
|
|
auto: false
|
|
},
|
|
upOption:{
|
|
auto: false,
|
|
noMoreSize: 4,
|
|
empty:{
|
|
tip: '~ 空空如也 ~', // 提示
|
|
btnText: ''
|
|
},
|
|
textNoMore: '没有更多了'
|
|
},
|
|
|
|
numberVal: 1,
|
|
showCart: false,
|
|
showSpec: false,
|
|
count: 0,
|
|
goodsName: '',
|
|
goodsSpec: [],
|
|
};
|
|
},
|
|
onLoad(options) {
|
|
this.onNormal = trottle(this.onNormal, 500, this);
|
|
this.onPriceSort = trottle(this.onPriceSort, 500, this);
|
|
this.onSaleSort = trottle(this.onSaleSort, 500, this);
|
|
this.onSearch = trottle(this.onSearch, 500, this);
|
|
this.init(options);
|
|
},
|
|
methods: {
|
|
init(option) {
|
|
let {
|
|
id,
|
|
name,
|
|
type
|
|
} = option;
|
|
this.type = type;
|
|
if (id) {
|
|
uni.setNavigationBarTitle({
|
|
title: name
|
|
});
|
|
this.id = id;
|
|
this.getGoodsSearchFun();
|
|
} else {
|
|
uni.setNavigationBarTitle({
|
|
title: '搜索'
|
|
});
|
|
this.showHistory = true
|
|
}
|
|
},
|
|
|
|
upCallback(page) {
|
|
let pageNum = page.num;
|
|
let pageSize = page.size;
|
|
let {goodsList, keyword} = this
|
|
const params = {
|
|
page_size: pageSize,
|
|
page_no: pageNum,
|
|
keyword,
|
|
}
|
|
getGoodsSearch(params).then(({
|
|
data
|
|
}) => {
|
|
if (page.num == 1) this.goodsList = [];
|
|
let curPageData = data.list
|
|
let curPageLen = curPageData.length;
|
|
let hasNext = !!data.more;
|
|
this.goodsList = this.goodsList.concat(curPageData);
|
|
this.mescroll.endSuccess(curPageLen, hasNext);
|
|
}).catch(() => {
|
|
this.mescroll.endErr()
|
|
})
|
|
},
|
|
|
|
// 清空搜索
|
|
clearSearchFun() {
|
|
clearSearch().then(res => {
|
|
if (res.code == 1) {
|
|
this.getSearchpageFun();
|
|
}
|
|
});
|
|
},
|
|
|
|
// 获取历史搜索
|
|
getSearchpageFun() {
|
|
getSearchpage().then(res => {
|
|
if (res.code == 1) {
|
|
let {
|
|
history_lists,
|
|
hot_lists
|
|
} = res.data;
|
|
this.hotList = hot_lists
|
|
this.historyList = history_lists
|
|
}
|
|
});
|
|
},
|
|
|
|
onClear() {
|
|
if (this.id) {
|
|
this.onSearch();
|
|
}
|
|
},
|
|
|
|
onSearch() {
|
|
this.onRefresh()
|
|
},
|
|
|
|
onRefresh() {
|
|
this.goodsList = []
|
|
this.showHistory = false
|
|
this.mescroll.resetUpScroll();
|
|
},
|
|
|
|
onChangeKeyword(item) {
|
|
this.keyword = item
|
|
this.showHistory = false
|
|
this.onRefresh();
|
|
},
|
|
|
|
// 打开弹框
|
|
openSpec(item) {
|
|
console.log("123>>>", 123);
|
|
|
|
this.showSpec = true
|
|
this.goodsName = item.name
|
|
this.goodsSpec = item.goods_spec
|
|
},
|
|
|
|
// 确认选择的商品规格
|
|
confirmSpec() {
|
|
|
|
},
|
|
|
|
// 选择商品
|
|
async addCartFun(item) {
|
|
const {
|
|
code,
|
|
data,
|
|
msg
|
|
} = await addCart({
|
|
item_id: item.id,
|
|
goods_num: 1
|
|
});
|
|
if (code == 1) {
|
|
this.getCartListFun()
|
|
}
|
|
}
|
|
},
|
|
watch: {
|
|
keyword(value, old) {
|
|
if (!value && !this.id) {
|
|
this.showHistory = true
|
|
}
|
|
},
|
|
showHistory(value) {
|
|
if (value) {
|
|
this.getSearchpageFun();
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
comprehensive() {
|
|
const {
|
|
priceSort,
|
|
saleSort
|
|
} = this
|
|
if (priceSort == '' && saleSort == '') {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
},
|
|
buyNumber() {
|
|
if (this.count > 0) {
|
|
return this.count > 99 ? '99+' : this.count
|
|
}
|
|
|
|
return ''
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
<style lang="scss">
|
|
.goods-search {
|
|
.header-wrap {
|
|
.search {
|
|
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.03);
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.header {
|
|
height: 80rpx;
|
|
|
|
.tag {
|
|
height: 100%;
|
|
flex: 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
.content {
|
|
.search-words {
|
|
padding-left: 24rpx;
|
|
padding-bottom: 20rpx;
|
|
|
|
.title {
|
|
padding: 26rpx 0;
|
|
}
|
|
|
|
.words {
|
|
.item {
|
|
line-height: 52rpx;
|
|
height: 52rpx;
|
|
padding: 0 24rpx;
|
|
background-color: #F5F5F5;
|
|
}
|
|
}
|
|
}
|
|
|
|
.goods-list {
|
|
overflow: hidden;
|
|
}
|
|
}
|
|
|
|
.buy {
|
|
position: fixed;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: env(safe-area-inset-bottom);
|
|
height: 100rpx;
|
|
background-color: #212526;
|
|
}
|
|
}
|
|
</style>
|