Files

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>