477 lines
12 KiB
Vue
477 lines
12 KiB
Vue
<template>
|
|
<view class="good-search">
|
|
<view class="header">
|
|
<view class="search-box flex jc-between ai-center">
|
|
<input
|
|
v-model.trim="search"
|
|
type="text"
|
|
:placeholder="showkey ? '' : '请输入'"
|
|
placeholder-style="color:#999"
|
|
@confirm="submit"
|
|
@blur="showHistory"
|
|
@focus="hideHistory"
|
|
@input="hideHistory"
|
|
@change="hideHistory"
|
|
@compositionstart="hideHistory"
|
|
/>
|
|
<button class="btn flex-0 flex jc-center ai-center" @click.stop="submit">
|
|
<text class="iconfont icon-sousuo2"></text>
|
|
<text>搜索</text>
|
|
</button>
|
|
<view class="swpier-bar" v-if="showkey">
|
|
<u-notice-bar
|
|
duration="4000"
|
|
@change="change"
|
|
:text="recommendKeyword"
|
|
:icon="' '"
|
|
color="#999"
|
|
fontSize="14"
|
|
bgColor="transparent"
|
|
direction="column"></u-notice-bar>
|
|
</view>
|
|
</view>
|
|
<view @click="goShoppingCart()" class="item animated bounceIn">
|
|
<view class="iconfont icon-gouwuche1">
|
|
<text class="num bg-color-lightred" v-if="CartCount > 0">{{ CartCount > 99 ? '99+' : CartCount }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view v-if="historyKey.length" class="page-content">
|
|
<view
|
|
class="title"
|
|
>
|
|
历史搜索
|
|
<u-icon
|
|
name="trash-fill"
|
|
color="#aaa"
|
|
size="20"
|
|
@click="deleteHistoryHandle"
|
|
/>
|
|
</view>
|
|
<view class="list acea-row limit-box">
|
|
<view
|
|
v-for="item of historyKey"
|
|
:key="item.id"
|
|
class="item one-t v12-font-28"
|
|
@click="toSearch(item.word)"
|
|
>
|
|
{{ item.word }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="page-content" v-if="keywords.length">
|
|
<view class="title">热门搜索</view>
|
|
<view class="list acea-row">
|
|
<view
|
|
v-for="(hot, key) in keywords"
|
|
:key="key"
|
|
class="item v12-font-28 v12-align-center"
|
|
:style="{paddingRight: hot.isNew === 1 ? '0 !important' : '24rpx !important'}"
|
|
@click="toSearch(hot.keyword)"
|
|
>
|
|
|
|
<view v-if="hot.isNew === 2">
|
|
<image :src="webUrl + '/icon/fire.png'" class="fire-icon"></image>
|
|
</view>
|
|
{{ hot.keyword }}
|
|
<view class="new-icon-box" v-if="hot.isNew === 1" >
|
|
<image class="new-icon" :src="webUrl + '/icon/new.png'"></image>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="ranking-wrap">
|
|
<view
|
|
v-for="(rankingItem, rankingIndex) in rankingArr"
|
|
:key="rankingIndex"
|
|
:style="{
|
|
'background': `linear-gradient(180deg, ${rankingItem.color} 0%, #FFFFFF 35%, #FFFFFF 100%)`
|
|
}"
|
|
class="ranking-item"
|
|
>
|
|
<view class="ranking-header">
|
|
<image
|
|
:src="rankingItem.backgroundImage"
|
|
mode="widthFix"
|
|
class="icon"
|
|
/>
|
|
<view class="name">{{ rankingItem.rankingName }}</view>
|
|
</view>
|
|
<view class="ranking-body">
|
|
<view
|
|
v-for="(good, goodIndex) in rankingItem.products"
|
|
:key="goodIndex"
|
|
class="item"
|
|
@click="goodItemClick(good)"
|
|
>
|
|
<view class="img">
|
|
<image
|
|
:src="good.productImage"
|
|
mode="widthFix|heightFix"
|
|
class="pic"
|
|
/>
|
|
</view>
|
|
<view class="info">
|
|
<view class="name more-t">
|
|
{{ good.productName }}
|
|
</view>
|
|
<view class="price-wrap " :class="{'v12-align-center' : ('' + good.price).length < 5 && ('' + good.otPrice).length < 5}">
|
|
<view class="price">
|
|
¥{{ good.price }}
|
|
</view>
|
|
<view class="ot-price" :class="{'v12-ml-1' : ('' + good.price).length < 5 && ('' + good.otPrice).length < 5}">
|
|
¥{{ good.otPrice }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import {
|
|
getSearchPageConfig
|
|
} from '@/api/search'
|
|
import {
|
|
getCartCount,
|
|
} from '@/api/store'
|
|
import { mapGetters } from 'vuex'
|
|
import {trim} from '@/utils'
|
|
export default {
|
|
name: 'GoodSearch',
|
|
data: function () {
|
|
return {
|
|
webUrl: this.$VUE_APP_RESOURCES_URL,
|
|
showkey: true,
|
|
currentSearch: '',
|
|
keywords: [],
|
|
search: '',
|
|
historyKey: [],
|
|
rankingArr: [],
|
|
recommendKeyword: [],
|
|
CartCount: 0,
|
|
keywords1: ''
|
|
}
|
|
},
|
|
computed: mapGetters(['isLogin', 'location', 'userInfo']),
|
|
mounted: function () {
|
|
this.getData()
|
|
this.getCartCount()
|
|
},
|
|
onLoad(opts){
|
|
this.search = opts.keywords
|
|
},
|
|
onShow() {
|
|
this.getHistory()
|
|
},
|
|
watch: {
|
|
search(val) {
|
|
if(val) {
|
|
this.showkey = false
|
|
} else {
|
|
// this.showkey = true
|
|
// this.currentSearch = this.recommendKeyword[0]
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
// 获取购物车数量
|
|
getCartCount () {
|
|
const isLogin = this.isLogin
|
|
if (isLogin) {
|
|
getCartCount({
|
|
numType: 0
|
|
}).then(res => {
|
|
this.CartCount = res.data.count
|
|
})
|
|
}
|
|
},
|
|
goShoppingCart() {
|
|
this.$yrouter.switchTab('/pages/cart')
|
|
},
|
|
showHistory() {
|
|
this.currentSearch = this.recommendKeyword[0]
|
|
if(this.showkey) return
|
|
if(this.search) {
|
|
this.showkey = false
|
|
return
|
|
}
|
|
this.showkey = true
|
|
},
|
|
hideHistory() {
|
|
|
|
// if(!this.search) {
|
|
// this.showkey = true
|
|
// return
|
|
// }
|
|
this.showkey = false
|
|
},
|
|
change(e) {
|
|
this.currentSearch = this.recommendKeyword[e]
|
|
},
|
|
submit() {
|
|
if (this.showkey) {
|
|
const search = trim(this.currentSearch) || ''
|
|
if (!search) return
|
|
this.setHistory(search)
|
|
// this.search = ''
|
|
this.toSearch(search)
|
|
} else {
|
|
const search = trim(this.search) || ''
|
|
if (!search) return
|
|
this.setHistory(search)
|
|
// this.search = ''
|
|
this.toSearch(search)
|
|
}
|
|
|
|
},
|
|
toSearch(s) {
|
|
this.setHistory(s)
|
|
this.$yrouter.push({path: '/pages/shop/GoodsList/index', query: {s}})
|
|
},
|
|
getData() {
|
|
getSearchPageConfig().then(res => {
|
|
const { success, data } = res
|
|
if (success) {
|
|
this.keywords = data.searchKeywords
|
|
this.rankingArr.push(data.ranking1)
|
|
this.rankingArr.push(data.ranking2)
|
|
this.recommendKeyword = data.recommendKeyword.split(',')
|
|
// const index = this.recommendKeyword.indexOf(this.keywords1)
|
|
// [this.recommendKeyword[0], this.recommendKeyword[index]] = [this.recommendKeyword[index], this.recommendKeyword[0]];
|
|
}
|
|
})
|
|
},
|
|
getHistory() {
|
|
let temp = JSON.parse(uni.getStorageSync('historyKey') || '[]')
|
|
this.historyKey = temp.slice(0, 30)
|
|
},
|
|
setHistory(word) {
|
|
const index = this.historyKey.findIndex(item => item.word === word)
|
|
if (index > -1) {
|
|
this.historyKey.splice(index, 1)
|
|
// return
|
|
}
|
|
this.historyKey.unshift({id: this.$global.generateMixed(10), word })
|
|
uni.setStorageSync('historyKey', JSON.stringify(this.historyKey))
|
|
},
|
|
deleteHistoryHandle() {
|
|
const _this = this
|
|
uni.showModal({
|
|
title: '确认删除最近的搜索记录吗?',
|
|
content: '',
|
|
showCancel: true,
|
|
cancelText: '取消',
|
|
confirmText: '确认',
|
|
success: (result) => {
|
|
if (result.confirm) {
|
|
_this.historyKey = []
|
|
uni.setStorageSync('historyKey', JSON.stringify([]))
|
|
}
|
|
}
|
|
})
|
|
},
|
|
goodItemClick(good) {
|
|
const id = good.productId
|
|
if (!id) return
|
|
this.$yrouter.push({
|
|
path: '/pages/shop/GoodsCon/index',
|
|
query: { id }
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="less">
|
|
.new-icon-box{
|
|
position: relative;
|
|
width: 50rpx;
|
|
height: 100%;
|
|
}
|
|
.fire-icon{
|
|
width: 24rpx;
|
|
height: 24rpx;
|
|
margin-right: 5rpx;
|
|
}
|
|
.new-icon{
|
|
width: 40rpx;
|
|
height: 26rpx;
|
|
left: 10rpx;
|
|
top: -5rpx;
|
|
position: absolute;
|
|
}
|
|
.iconfont{
|
|
position: relative;
|
|
}
|
|
.item .iconfont.icon-gouwuche1 .num {
|
|
right: -15rpx !important;
|
|
top: -15rpx!important;
|
|
font-size: 20rpx;
|
|
position: absolute;
|
|
width: 30rpx;
|
|
height: 30rpx;
|
|
background: #C52733 !important;
|
|
color: #fff;
|
|
border-radius: 50%;
|
|
text-align: center;
|
|
padding: 2rpx;
|
|
}
|
|
.good-search {
|
|
min-height: 100vh;
|
|
background: #fff !important;
|
|
|
|
.header {
|
|
padding: 40rpx 32rpx 32rpx;
|
|
background: #F9F9F9;
|
|
display: flex;
|
|
align-items: center;
|
|
.search-box {
|
|
width: 686rpx;
|
|
height: 72rpx;
|
|
box-sizing: border-box;
|
|
padding: 0 8rpx 0 32rpx;
|
|
border-radius: 36rpx;
|
|
background: #fff;
|
|
font-size: 24rpx;
|
|
position: relative;
|
|
.swpier-bar{
|
|
position: absolute;
|
|
width: calc(100% - 128rpx);
|
|
top: 0;
|
|
}
|
|
input {
|
|
width: 100%;
|
|
position: relative;
|
|
z-index: 9;
|
|
}
|
|
|
|
.btn {
|
|
width: 128rpx;
|
|
height: 54rpx;
|
|
background: #C52733;
|
|
border-radius: 28rpx;
|
|
color: #fff;
|
|
font-weight: bold;
|
|
padding: 0;
|
|
font-size: 26rpx;
|
|
.icon-sousuo2 {
|
|
margin-right: 4rpx;
|
|
font-size: 28rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.page-content {
|
|
padding: 0 32rpx;
|
|
|
|
.title {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
margin: 22rpx 0 24rpx;
|
|
color: #333;
|
|
font-size: 28rpx;
|
|
line-height: 40rpx;
|
|
font-weight: bold;
|
|
letter-spacing: 4px;
|
|
}
|
|
|
|
.list {
|
|
.item {
|
|
height: 48rpx;
|
|
box-sizing: border-box;
|
|
margin: 0 24rpx 20rpx 0;
|
|
padding: 0 24rpx;
|
|
border-radius: 12rpx;
|
|
background: #F2F2F2;
|
|
color: #333;
|
|
font-size: 24rpx;
|
|
line-height: 48rpx;
|
|
position: relative;
|
|
}
|
|
}
|
|
|
|
.limit-box {
|
|
max-height: 260rpx;
|
|
overflow-y: hidden;
|
|
}
|
|
}
|
|
}
|
|
.ranking-wrap {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding: 24rpx;
|
|
background-color: #F2F2F2;
|
|
.ranking-item {
|
|
width: 344rpx;
|
|
padding: 20rpx 12rpx;
|
|
box-sizing: border-box;
|
|
border-radius: 20rpx;
|
|
background-color: #fff;
|
|
.ranking-header {
|
|
display: flex;
|
|
align-items: center;
|
|
.icon {
|
|
display: block;
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
}
|
|
.name {
|
|
margin: 0 0 0 12rpx;
|
|
font-weight: bold;
|
|
font-size: 30rpx;
|
|
color: #333;
|
|
line-height: 42rpx;
|
|
}
|
|
}
|
|
.ranking-body {
|
|
padding: 24rpx 0 0 0;
|
|
.item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-around;
|
|
margin: 0 0 12rpx 0;
|
|
.img {
|
|
width: 100rpx;
|
|
height: 100rpx;
|
|
.pic {
|
|
display: block;
|
|
width: 100rpx;
|
|
height: 100rpx;
|
|
border-radius: 8rpx;
|
|
}
|
|
}
|
|
.info {
|
|
width: calc(100% - 112rpx);
|
|
margin: 0 0 0 12rpx;
|
|
.name {
|
|
height: 64rpx;
|
|
font-size: 26rpx;
|
|
color: #333;
|
|
line-height: 32rpx;
|
|
}
|
|
.price-wrap {
|
|
// display: flex;
|
|
margin: 6rpx 0 0 0;
|
|
line-height: 30rpx;
|
|
.price {
|
|
color: #E92727;
|
|
font-size: 24rpx;
|
|
}
|
|
.ot-price {
|
|
// margin: 0 0 0 20rpx;
|
|
color: #BFBFBF;
|
|
font-size: 20rpx;
|
|
text-decoration: line-through;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style> |