首页入口
进入搜索页
搜索结果页
后台提供三个接口
<?php/** * 搜索商品 */class SearchAction extends CommonAction{ public function _initialize(){ parent::_initialize(); } /** * 获取搜索历史和热门搜索 */ public function getHotAndHistory() { if (!$uid = $_POST['uid']) { $this->json->setErr('10001', '缺少用户id'); $this->json->Send(); } // 历史 $data['history'] = []; $search_history = M('search_history'); $search_history_list = $search_history->where(['uid'=>$uid,'status'=>1])->order('id desc')->select(); foreach ($search_history_list as $k=>$v) { $data['history'][] = $v['keywords']; } // 热门 $configs = M('configs'); $hot_search = $configs->where(['this_key'=>'hot_search'])->getField('this_value'); $data['hot'] = explode(',',$hot_search); // 爆炸成数组 $this->json->S($data); } /** * 搜索数据 */ public function searchData() { if (!$uid = $_POST['uid']) { $this->json->setErr('10001', '缺少用户id'); $this->json->Send(); } if (!$keywords = $_POST['keywords']) { $this->json->setErr('10001', '请输入要查询的内容'); $this->json->Send(); } if (!isset($_POST['page']) || $_POST['page'] < 1) { $_POST['page'] = 1; } if (!isset($_POST['page_size']) || $_POST['page_size'] < 1) { $_POST['page_size'] = C('PAGE_NORMAL_COUNT'); } $page = $_POST['page']; $page_size = $_POST['page_size']; if ($page == 1) { // 删除之前的记录 $search_history = M('search_history'); $search_history->where(['uid'=>$uid,'keywords'=>$keywords])->save(['status'=>0,'update_time'=>time()]); // 添加新的记录 $search_history->add(['uid'=>$uid,'keywords'=>$keywords,'update_time'=>time(),'create_time'=>time()]); } $where['title'] = ['like','%'.$keywords.'%']; $where['status'] = 1; // 显示 $where['is_del'] = 0; // 未删除 $where['spec_main'] = 1; // 是否主商品 // 获取总数 $product = M('product'); $count = $product->where($where)->count(); $total_page = ceil($count / $page_size); if ($page > $total_page) { $return_data = ['data_list' => [], 'total_page' => $total_page, 'current_page' => $page]; $this->json->S($return_data, '没有更多了'); } $data_list = $product->where($where) ->order('id desc') ->limit((($page - 1) * $page_size) . ',' . $page_size) ->field('id,title,title_img,sales_count,price') ->select(); if ($data_list) { vendor('Func.Math'); foreach ($data_list as $k => &$v) { $v['price'] = Math::div($v['price'], 100); } } $out_data = $data_list ?: []; $return_data = ['data_list' => $out_data, 'total_page' => $total_page, 'current_page' => $page]; $this->json->S($return_data); } /** * 清除数据 */ public function clearData() { if (!$uid = $_POST['uid']) { $this->json->setErr('10001', '缺少用户id'); $this->json->Send(); } // 删除之前的记录 $search_history = M('search_history'); $clear_res = $search_history->where(['uid'=>$uid])->save(['status'=>0,'update_time'=>time()]); if ($clear_res !== false) { $this->json->S(); } else { $this->json->E('清理失败'); } }}
搜索页面
<view class="search"> <view class="search-container"> <view class="search-left"> <image class="search-image" src="/images/index/search.png" /> <input class="search-input" placeholder="请输入你喜欢的商品" bindinput='watchSearch'/> </view> <view class="search-btn" data-keywords="{{keywords}}" bindtap="go_to_search_result">搜索</view> </view></view><view class="history"> <view class="history-title"> <view class="history-title-left">搜索历史</view> <view class="history-title-right" bindtap="clearSearchHistory">清除历史</view> </view> <view class="history-content"> <block wx:if="{{index_data.history != false}}"> <block wx:for="{{index_data.history}}" wx:key="id"> <view class="history-item" data-keywords="{{item}}" bindtap="go_to_search_result">{{item}}</view> </block> </block> </view></view><view class="hot"> <view class="hot-title">热门搜索</view> <view class="hot-content"> <block wx:if="{{index_data.hot != false}}"> <block wx:for="{{index_data.hot}}" wx:key="id"> <view class="hot-item" data-keywords="{{item}}" bindtap="go_to_search_result">{{item}}</view> </block> </block> </view></view>
搜索页面业务逻辑
import { initNoPage } from "../../common/requestData";import Storage from "../../common/auth/Storage";import tips from "../../common/tips";import request from "../../common/request";const app = getApp();Page({ /** * 页面的初始数据 */ data: { index_data: [], keywords: '' }, // 清理 clearSearchHistory: function () { tips.showConfirm("您确认清理搜索历史吗").then(() => { const uid = app.globalData.uid || Storage.get().uid; request("clearData", { uid: uid }) .then(() => { tips.showMsg("清理成功"); this.setData({ "index_data.history": [] }); }) .catch(({ errdesc }) => { return tips.showMsg(errdesc); }); }); }, // 监听输入 watchSearch: function (event) { console.log(event.detail.value); let keywords = event.detail.value; // 设置值 this.setData({ "keywords": keywords }); }, go_to_search_result({ currentTarget: { dataset: { keywords } } }) { console.log(keywords); if (keywords == '') { return tips.showMsg("请输入要搜索的内容"); } wx.navigateTo({ url: "/pages/search/result/index?keywords=" + keywords }); }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { }, /** * 展示 */ onShow: function (options) { const uid = app.globalData.uid || Storage.get().uid; console.log(uid); // 初始化 initNoPage(this, [ { api: "getHotAndHistory", outDataName: "index_data", inData: { 'uid': uid } } ]); setTimeout(() => { this.setData({ wo_title: app.globalData.wo_title }); }, 300); }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 用户点击右上角分享 */ onShareAppMessage() { },});
搜索页面样式
.search { height: 124rpx; background-color: #F7F7F7; display: flex; justify-content: center; .search-container { margin-top: 30rpx; height: 64rpx; // border:1px solid red; margin-left:22rpx; margin-right:33rpx; width: 695rpx; display: flex; .search-left { display: flex; background-color: #FFFFFF; border-radius: 32rpx; .search-input { // border:1px solid blue; height: 64rpx; line-height: 64rpx; font-size: 28rpx; width: 500rpx; } .search-image { width:34rpx; height: 34rpx; margin-left: 30rpx; margin-top:15rpx; margin-right: 15rpx; } } .search-btn { font-size: 32rpx; line-height: 64rpx; font-weight: bold; color:#313131; text-align: center; margin-left:30rpx; } }}.history { margin:0 auto; width: 710rpx; margin-top:30rpx; .history-title { display: flex; justify-content: space-between; .history-title-left { font-size: 28rpx; color:#313131; } .history-title-right { font-size: 28rpx; color:#AAAAAA; } margin-bottom: 15rpx; } .history-content { display: flex; flex-wrap: wrap; overflow: hidden; .history-item { margin-top:15rpx; margin-left:10rpx; margin-right:10rpx; padding-left:20rpx; padding-right: 20rpx; height: 48rpx; background-color: #eeeeee; border-radius: 24rpx; font-size: 24rpx; line-height: 48rpx; } }}.hot { margin:0 auto; width: 710rpx; margin-top:50rpx; .hot-title { display: flex; justify-content: space-between; font-size: 28rpx; color:#313131; margin-bottom: 15rpx; } .hot-content { display: flex; flex-wrap: wrap; overflow: hidden; .hot-item { margin-top:15rpx; margin-left:10rpx; margin-right:10rpx; padding-left:20rpx; padding-right: 20rpx; height: 48rpx; background-color: #eeeeee; border-radius: 24rpx; font-size: 24rpx; line-height: 48rpx; } }}
搜索结果页面
<view class="search"> <view class="search-container"> <view class="search-left"> <image class="search-image" src="/images/index/search.png" /> <input class="search-input" placeholder="请输入你喜欢的商品" value="{{keywords}}" bindinput='watchSearch' /> </view> <view class="search-btn" data-keywords="{{keywords}}" bindtap="go_to_search_result">搜索</view> </view></view><block wx:if="{{noData == 1}}"> <view class="no-data"> <view class="img"> <image class="search-image" src="/images/search/nodata.png" /> </view> <view class="msg">什么也没搜到哦</view> </view></block><block wx:else> <view class="data-list"> <block wx:for="{{searchResult}}" wx:key="id"> <view class="data-item"> <view class="item-img"> <image src="{{item.title_img}}" /> </view> <view class="item-content"> <view class="item-content-title">{{item.title}}</view> <view class="item-content-property"> <view class="property-item">销量:{{item.sales_count}}</view> <!-- <view class="property-item">库存:1970</view> --> </view> <view class="item-content-price">¥{{item.price}}</view> <view class="item-content-add"> <image src="/images/common/buy_more.png" catch:tap="openTypeSelect" data-id="{{item.id}}" lazy-load="{{true}}"/> </view> </view> </view> </block> <block wx:if="{{noMore==1}}"> <view class="no-more">无更多结果</view> </block> </view></block><goodsType id="goodsType" />
搜索结果页逻辑
import { initInPage } from "../../../common/requestData";import Storage from "../../../common/auth/Storage";import tips from "../../../common/tips";const app = getApp();Page({ /** * 页面的初始数据 */ data: { index_data: [], keywords: '' }, openTypeSelect({ currentTarget: { dataset: { id } } }) { this.selectComponent("#goodsType").openTypeSelect(id); }, // 监听输入 watchSearch: function (event) { console.log(event.detail.value); let keywords = event.detail.value; // 设置值 this.setData({ "keywords": keywords }); }, go_to_search_result({ currentTarget: { dataset: { keywords } } }) { console.log(keywords); if (keywords == '') { return tips.showMsg("请输入要搜索的内容"); } const uid = app.globalData.uid || Storage.get().uid; console.log(uid); // 初始化 initInPage( this, "searchData", { 'uid': uid, 'keywords': keywords, page: 1, page_size: 5 }, { inDataName: "inData", outDataName: "searchResult" } ); }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { // 能获取到参数 console.log(options.keywords); // 设置值 this.setData({ "keywords": options.keywords }); }, /** * 展示 */ onShow: function (options) { // 获取不到参数 let keywords = this.data.keywords; const uid = app.globalData.uid || Storage.get().uid; console.log(uid); // 初始化 initInPage( this, "searchData", { 'uid': uid, 'keywords': keywords, page: 1, page_size: 5 }, { inDataName: "inData", outDataName: "searchResult" } ); }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 用户点击右上角分享 */ onShareAppMessage() { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { return initInPage(this, "searchData", this.inData, { inDataName: "inData", outDataName: "searchResult" }); },});
搜索结果页样式
.search { height: 124rpx; background-color: #F7F7F7; display: flex; justify-content: center; .search-container { margin-top: 30rpx; height: 64rpx; // border:1px solid red; margin-left:22rpx; margin-right:33rpx; width: 695rpx; display: flex; .search-left { display: flex; background-color: #FFFFFF; border-radius: 32rpx; .search-input { // border:1px solid blue; height: 64rpx; line-height: 64rpx; font-size: 28rpx; width: 500rpx; } .search-image { width:34rpx; height: 34rpx; margin-left: 30rpx; margin-top:15rpx; margin-right: 15rpx; } } .search-btn { font-size: 32rpx; line-height: 64rpx; font-weight: bold; color:#313131; text-align: center; margin-left:30rpx; } }}.data-list { margin-top:16rpx; overflow: hidden; .data-item { height: 240rpx; border-bottom: 1rpx solid #E2E2E2; padding:30rpx 20rpx; display: flex; .item-img { width: 180rpx; height: 180rpx; // border: 1rpx solid red; image { width: 180rpx; height: 180rpx; } } .item-content { margin-left:20rpx; width: 510rpx; height: 180rpx; // border:1rpx solid blue; position: relative; .item-content-title { font-size:26rpx; color:#313131; } .item-content-property { margin-top:20rpx; font-size: 24rpx; height:24rpx; /* 防止上下空隙 */ line-height:24rpx; color:#AAAAAA; display: flex; .property-item:nth-child(n+2) { margin-left:20rpx; } } .item-content-price { margin-top:46rpx; font-size:32rpx; font-weight: bold; color:#F6001F; height:32rpx; line-height:32rpx; } .item-content-add { position: absolute; right: 0rpx; bottom: 0rpx; line-height: 46rpx; font-size: 46rpx; height: 46rpx; color: #F6001F; image { width: 46rpx; height: 46rpx; } } } } .no-more { text-align: center; color:#E2E2E2; font-size: 32rpx; font-weight: bold; margin-top:30rpx; }}.no-data { // display: none; /* 暂时先隐藏 */ margin:0 auto; margin-top:163rpx; height: 420rpx; // border:1px solid red; .img { width: 350rpx; height: 313rpx; // border:1px solid blue; margin:0 auto; image { width: 350rpx; height: 313rpx; } } .msg { text-align: center; font-size: 32rpx; color:#BFBFBF; margin-top:69rpx; }}