index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. <template>
  2. <view>
  3. <view class='searchGood'>
  4. <view class='search acea-row row-between-wrapper'>
  5. <view class='input acea-row row-between-wrapper'>
  6. <text class='iconfont icon-sousuo2'></text>
  7. <input type='text' :value='searchValue' :focus="focus" placeholder='点击搜索商品、店铺名称' placeholder-class='placeholder'
  8. @input="setValue"></input>
  9. </view>
  10. <view class='bnt' @tap='searchBut'>搜索</view>
  11. </view>
  12. <view class='title'>历史记录 <text class="iconfont icon-shanchu" @click="remove"></text></view>
  13. <view class='list acea-row' :style="{'height':historyBox?'auto':'150rpx'}" v-if="historyList.length > 0">
  14. <block v-for="(item,index) in historyList" :key="index">
  15. <view class='item line1' @tap='setHotSearchValue(item,0)'>{{item}}</view>
  16. </block>
  17. </view>
  18. <view>
  19. <view class="more-btn" v-if="historyList.length>9 && !historyBox" @click="historyBox = true">
  20. 展开全部<text class="iconfont icon-xiangxia"></text>
  21. </view>
  22. <view class="more-btn" v-if="historyList.length>9 && historyBox" @click="historyBox = false">
  23. 收起<text class="iconfont icon-xiangshang"></text>
  24. </view>
  25. </view>
  26. <view v-if="historyList.length == 0" style="text-align: center; color: #999;">暂无搜索历史~</view>
  27. <view class='title'>热门搜索</view>
  28. <view class='list acea-row' :style="{'height': hotSearchBox?'auto':'150rpx'}">
  29. <block v-for="(item,index) in hotSearchList" :key="index">
  30. <view class='item line1' @tap='setHotSearchValue(item,1)'>{{item.keyword}}</view>
  31. </block>
  32. </view>
  33. <view>
  34. <view class="more-btn" v-if="hotSearchList.length>8 && !hotSearchBox" @click="hotSearchBox = true">
  35. 展开全部<text class="iconfont icon-xiangxia"></text>
  36. </view>
  37. <view class="more-btn" v-if="hotSearchList.length>8 && hotSearchBox" @click="hotSearchBox = false">
  38. 收起<text class="iconfont icon-xiangshang"></text>
  39. </view>
  40. </view>
  41. <!--今日热搜模块-->
  42. <view class="search-hot">
  43. <scroll-view v-if="isShow" scroll-x="true" style="white-space: nowrap; display: flex;" scroll-with-animation show-scrollbar="true">
  44. <view v-if="daySearchList.length>0" class="scroll-count">
  45. <view class="scroll-item" :style="{'background-image':`url(${domain}/static/images/search-title-bg.png)`}">
  46. <view class="search-title">
  47. <image :src="`${domain}/static/images/search-title-icon.png`" class="title-icon"></image>
  48. <text>今日热搜</text>
  49. </view>
  50. <view class="search-list">
  51. <navigator v-for="(item,index) in daySearchList" :url="`/pages/goods_details/index?id=${item.product_id}`" hover-class="none" class="search-item">
  52. <block v-if="index<3">
  53. <view class="picture">
  54. <image :src="item.image" class="image"></image>
  55. <text class="list-num num-pic" :style="{'background-image':`url(${domain}/static/images/search-list${index+1}.png)`}">{{index+1}}</text>
  56. </view>
  57. <view class="list-info">
  58. <view class="title line1">{{item.store_name}}</view>
  59. <view class="info line1">{{item.store_info}}</view>
  60. </view>
  61. </block>
  62. <block v-else>
  63. <view class="list-more">
  64. <view class="list-num" :style="{'background-image':`url(${domain}/static/images/search-list.png)`}">{{index+1}}</view>
  65. <view class="title line1 titleml">{{item.store_name}}</view>
  66. </view>
  67. </block>
  68. </navigator>
  69. </view>
  70. </view>
  71. </view>
  72. <!--热销排行-->
  73. <view v-for="(item,index) in hotRankList" class="scroll-count">
  74. <view class="scroll-item" :style="{'background-image':`url(${domain}/static/images/search-title-bg.png)`}">
  75. <view class="search-title">
  76. <image :src="`${domain}/static/images/search-title-icon.png`" class="title-icon"></image>
  77. <text>{{item.cate_name}}</text>
  78. </view>
  79. <view class="search-list">
  80. <navigator v-for="(itm,idx) in item.list" :url="`/pages/goods_details/index?id=${itm.product_id}`" hover-class="none" class="search-item">
  81. <block v-if="idx<3">
  82. <view class="picture">
  83. <image :src="itm.image" class="image"></image>
  84. <text class="list-num num-pic" :style="{'background-image':`url(${domain}/static/images/search-list${idx+1}.png)`}">{{idx+1}}</text>
  85. </view>
  86. <view class="list-info">
  87. <view class="title line1">{{itm.store_name}}</view>
  88. <view class="info line1">{{itm.store_info}}</view>
  89. </view>
  90. </block>
  91. <block v-else>
  92. <view class="list-more">
  93. <view class="list-num" :style="{'background-image':`url(${domain}/static/images/search-list.png)`}">{{idx+1}}</view>
  94. <view class="title line1 titleml">{{itm.store_name}}</view>
  95. </view>
  96. </block>
  97. </navigator>
  98. </view>
  99. </view>
  100. </view>
  101. </scroll-view>
  102. <view class="search-hot-switch">
  103. <view v-if="isShow" class="switch" @click="isShow=!isShow">
  104. <text class="iconfont icon-xianshizhuangtai"></text>
  105. <text>隐藏热搜榜</text>
  106. </view>
  107. <view v-else class="switch" @click="isShow=!isShow">
  108. <text class="iconfont icon-yincangzhuangtai"></text>
  109. <text>开启热搜榜</text>
  110. </view>
  111. </view>
  112. </view>
  113. </view>
  114. <!-- #ifndef H5 -->
  115. <passwordPopup></passwordPopup>
  116. <!-- #endif -->
  117. </view>
  118. </template>
  119. <script>
  120. // +----------------------------------------------------------------------
  121. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  122. // +----------------------------------------------------------------------
  123. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  124. // +----------------------------------------------------------------------
  125. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  126. // +----------------------------------------------------------------------
  127. // | Author: CRMEB Team <admin@crmeb.com>
  128. // +----------------------------------------------------------------------
  129. import { getSearchKeyword,copyPasswordSearch,getTodayHotSearch,getHotRanking } from '@/api/store.js';
  130. import shareScence from '@/libs/spread';
  131. import { silenceBindingSpread } from '@/utils';
  132. import { goShopDetail } from '@/libs/order.js';
  133. import { initiateAssistApi } from '@/api/activity.js';
  134. import { mapGetters } from 'vuex';
  135. import { HTTP_REQUEST_URL } from '@/config/app';
  136. // #ifndef H5
  137. import passwordPopup from '@/components/passwordPopup';
  138. // #endif
  139. import { toLogin } from '@/libs/login.js';
  140. export default {
  141. computed: mapGetters(['isLogin', 'uid']),
  142. components: {
  143. // #ifndef H5
  144. passwordPopup,
  145. // #endif
  146. },
  147. data() {
  148. return {
  149. domain: HTTP_REQUEST_URL,
  150. hostProduct: [],
  151. searchValue: '',
  152. focus: true,
  153. bastList: [],
  154. hotSearchList: [],
  155. daySearchList: [],
  156. hotRankList: [],
  157. first: 0,
  158. limit: 8,
  159. page: 1,
  160. loading: false,
  161. loadend: false,
  162. loadTitle: '加载更多',
  163. hotPage: 1,
  164. isScroll: true,
  165. // 搜索历史
  166. historyList: [],
  167. // 临时搜索列表
  168. tempStorage: [],
  169. historyBox: false,
  170. hotSearchBox: false,
  171. mainWidth: 960,
  172. isShow: true,
  173. };
  174. },
  175. onLoad(options) {
  176. this.searchValue = options.searchVal || ''
  177. },
  178. onShow: function() {
  179. try {
  180. this.historyList = []
  181. this.tempStorage = []
  182. let arr = uni.getStorageSync('historyList')
  183. if (arr.length > 0) {
  184. this.historyList = arr
  185. } else {
  186. this.historyList = []
  187. }
  188. this.tempStorage = this.historyList
  189. } catch (e) {}
  190. this.getRoutineHotSearch();
  191. this.getHotSearchList();
  192. this.getHotRankingList();
  193. },
  194. methods: {
  195. // 清空历史记录
  196. remove() {
  197. let self = this
  198. uni.showModal({
  199. title: '提示',
  200. content: '确认删除全部历史搜索记录?',
  201. success: function(res) {
  202. if (res.confirm) {
  203. self.tempStorage = []
  204. try {
  205. uni.setStorageSync('historyList', self.tempStorage)
  206. self.historyList = []
  207. } catch (e) {}
  208. } else if (res.cancel) {
  209. console.log('用户点击取消');
  210. }
  211. }
  212. });
  213. },
  214. getRoutineHotSearch: function() {
  215. let that = this;
  216. getSearchKeyword().then(res => {
  217. that.$set(that, 'hotSearchList', res.data);
  218. });
  219. },
  220. /*今日热搜*/
  221. getHotSearchList(){
  222. getTodayHotSearch().then(res => {
  223. this.$set(this, 'daySearchList', res.data);
  224. });
  225. },
  226. /*热销排行*/
  227. getHotRankingList(){
  228. getHotRanking().then(res => {
  229. this.$set(this, 'hotRankList', res.data);
  230. });
  231. },
  232. setHotSearchValue: function(event, key) {
  233. this.focus = false
  234. if (key) {
  235. this.$set(this, 'searchValue', event.keyword);
  236. } else {
  237. this.$set(this, 'searchValue', event);
  238. }
  239. this.$nextTick(() => {
  240. this.focus = true
  241. })
  242. this.searchBut()
  243. },
  244. setValue: function(event) {
  245. this.$set(this, 'searchValue', event.detail.value);
  246. },
  247. searchBut: function() {
  248. if(/^(\/@[1-9]{1}).*\*\//.test(this.searchValue)){
  249. uni.showLoading({
  250. title: '加载中',
  251. mask: true
  252. });
  253. copyPasswordSearch({key: this.searchValue}).then(res => {
  254. uni.hideLoading();
  255. let item = res.data
  256. shareScence(res.data.user.uid, this.isLogin);
  257. //#ifdef H5
  258. this.isLogin && silenceBindingSpread();
  259. //#endif
  260. goShopDetail(item, this.uid).then(res => {
  261. if (this.isLogin) {
  262. initiateAssistApi(item.activity_id)
  263. .then(res => {
  264. let id = res.data.product_assist_set_id;
  265. uni.hideLoading();
  266. uni.navigateTo({
  267. url: '/pages/activity/assist_detail/index?id=' + id
  268. });
  269. })
  270. .catch(err => {
  271. uni.showToast({
  272. title: err,
  273. icon: 'none'
  274. });
  275. });
  276. } else {
  277. toLogin()
  278. }
  279. })
  280. }).catch(err => {
  281. uni.showToast({
  282. title: err,
  283. icon: 'none'
  284. });
  285. this.searchValue = ""
  286. });
  287. }else{
  288. let status = false
  289. this.tempStorage.forEach((el, index) => {
  290. if (el == this.searchValue) {
  291. status = true
  292. }
  293. })
  294. if (!status && this.searchValue) {
  295. this.tempStorage.unshift(this.searchValue)
  296. }
  297. try {
  298. uni.setStorageSync('historyList', this.tempStorage);
  299. } catch (e) {}
  300. uni.navigateTo({
  301. url: '/pages/columnGoods/goods_search_con/index?searchValue=' + this.searchValue
  302. })
  303. }
  304. }
  305. }
  306. }
  307. </script>
  308. <style>
  309. page {
  310. background-color: #fff;
  311. }
  312. </style>
  313. <style lang="scss">
  314. .searchGood .search {
  315. padding-left: 30rpx;
  316. }
  317. .searchGood .search {
  318. margin-top: 20rpx;
  319. }
  320. .searchGood .search .input {
  321. width: 598rpx;
  322. background-color: #f7f7f7;
  323. border-radius: 33rpx;
  324. padding: 0 35rpx;
  325. box-sizing: border-box;
  326. height: 66rpx;
  327. }
  328. .searchGood .search .input input {
  329. width: 472rpx;
  330. font-size: 28rpx;
  331. }
  332. .searchGood .search .input .placeholder {
  333. color: #bbb;
  334. }
  335. .searchGood .search .input .iconfont {
  336. color: #000;
  337. font-size: 35rpx;
  338. }
  339. .searchGood .search .bnt {
  340. width: 120rpx;
  341. text-align: center;
  342. height: 66rpx;
  343. line-height: 66rpx;
  344. font-size: 30rpx;
  345. color: #282828;
  346. }
  347. .searchGood .title {
  348. position: relative;
  349. font-size: 28rpx;
  350. color: #282828;
  351. margin: 50rpx 30rpx 25rpx 30rpx;
  352. .icon-shanchu {
  353. position: absolute;
  354. right: 0;
  355. top: 50%;
  356. transform: translateY(-50%);
  357. color: #999;
  358. }
  359. }
  360. .searchGood .list {
  361. padding: 0 10rpx;
  362. overflow: hidden;
  363. }
  364. .searchGood .list .item {
  365. font-size: 26rpx;
  366. color: #666;
  367. padding: 0 21rpx;
  368. height: 60rpx;
  369. background: rgba(242, 242, 242, 1);
  370. border-radius: 22rpx;
  371. line-height: 60rpx;
  372. margin: 0 0 20rpx 20rpx;
  373. max-width: 150rpx;
  374. }
  375. .searchGood .line {
  376. border-bottom: 1rpx solid #eee;
  377. margin: 20rpx 30rpx 0 30rpx;
  378. }
  379. .more-btn {
  380. display: flex;
  381. align-items: center;
  382. justify-content: center;
  383. margin: 0 0 20rpx 20rpx;
  384. height: 60rpx;
  385. font-size: 24rpx;
  386. color: #999;
  387. .iconfont {
  388. font-size: 22rpx;
  389. margin-left: 10rpx;
  390. }
  391. }
  392. .search-hot{
  393. padding: 0 30rpx 30rpx;
  394. padding-bottom: calc(30rpx+ constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
  395. padding-bottom: calc(30rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
  396. scroll-view{
  397. width:100%;
  398. }
  399. /deep/.uni-scroll-view-content{
  400. display: flex;
  401. }
  402. }
  403. .scroll-item{
  404. border: 1px solid #FFECEC;
  405. border-radius: 16rpx;
  406. background-repeat: no-repeat;
  407. background-size: 100% auto;
  408. height: 980rpx;
  409. }
  410. .scroll-count{
  411. display: inline-block;
  412. width: 450rpx;
  413. margin-right: 30rpx;
  414. vertical-align:top;
  415. &:last-child{
  416. margin-right: 0;
  417. }
  418. .search-title{
  419. padding: 20rpx 20rpx 32rpx;
  420. color: #E93323;
  421. font-size: 28rpx;
  422. font-weight: bold;
  423. display: flex;
  424. align-items: center;
  425. .title-icon{
  426. width: 30rpx;
  427. height: 30rpx;
  428. margin-right: 10rpx;
  429. }
  430. }
  431. .search-list{
  432. padding: 0 20rpx 40rpx;
  433. position: relative;
  434. top: -15rpx;
  435. }
  436. .search-item{
  437. display: flex;
  438. align-items: center;
  439. margin-bottom: 20rpx;
  440. &:nth-child(n+3){
  441. margin-bottom: 0;
  442. }
  443. .list-more{
  444. display: flex;
  445. align-items: center;
  446. margin-top: 40rpx;
  447. }
  448. .picture{
  449. width: 106rpx;
  450. height: 106rpx;
  451. border-radius: 10rpx;
  452. position: relative;
  453. .image{
  454. width: 100%;
  455. height: 100%;
  456. border-radius: 10rpx;
  457. }
  458. }
  459. .list-info{
  460. max-width: 260rpx;
  461. margin-left: 20rpx;
  462. }
  463. .title{
  464. margin: 0;
  465. color: #282828;
  466. font-size: 26rpx;
  467. &.titleml{
  468. margin-left: 15rpx;
  469. max-width: 360rpx;
  470. }
  471. }
  472. .info{
  473. font-size: 22rpx;
  474. color: #999999;
  475. }
  476. }
  477. .list-num{
  478. width: 28rpx;
  479. height: 31rpx;
  480. display: flex;
  481. align-items: center;
  482. justify-content: center;
  483. font-size: 20rpx;
  484. color: #ffffff;
  485. background-size: 100% 100%;
  486. &.num-pic{
  487. position: absolute;
  488. top: 0;
  489. left: 0;
  490. }
  491. }
  492. }
  493. .search-hot-switch{
  494. margin-top: 20rpx;
  495. .switch{
  496. border: 1px solid #CCCCCC;
  497. border-radius: 22rpx;
  498. display: flex;
  499. align-items: center;
  500. justify-content: center;
  501. width: 174rpx;
  502. height: 43rpx;
  503. color: #666666;
  504. font-size: 20rpx;
  505. .iconfont{
  506. font-size: 24rpx;
  507. margin-right: 10rpx;
  508. position: relative;
  509. }
  510. }
  511. }
  512. </style>