search.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. <template>
  2. <view>
  3. <view style="height: 96rpx; background: #fff; padding-top: 20rpx; position: fixed; width: 750rpx; top: 0">
  4. <view class="search-header">
  5. <view class="input-box">
  6. <image src="https://mall.zhaijieshi.cc/file/wx-dy/icon-search-grey.png" class="img" mode="aspectFit"></image>
  7. <input
  8. name="input"
  9. class="keywrod"
  10. :focus="true"
  11. :value="keyword"
  12. confirm-type="search"
  13. @input="inputChange"
  14. @focus="inputFocus"
  15. @confirm="onKeywordConfirm"
  16. placeholder="保洁、保姆、钟点工、家电清洗"
  17. placeholder-style="font-size:26rpx;color:#BEC0C5;"
  18. />
  19. <view class="devide-line"></view>
  20. <view class="search-text" @tap="onKeywordConfirmBtn">搜索</view>
  21. </view>
  22. </view>
  23. </view>
  24. <view class="no-search" v-if="!searchStatus">
  25. <view class="search-keywords search-history" v-if="!keyword && historyKeyword.length">
  26. <view class="h">
  27. <text class="title">最近搜索</text>
  28. </view>
  29. <view class="b history">
  30. <view class="item" @tap="onKeywordTap" :data-keyword="item.keyword" hover-class="navigator-hover" v-for="(item, index) in historyKeyword" :key="index">
  31. {{ item.keyword }}
  32. </view>
  33. </view>
  34. </view>
  35. <view class="search-keywords search-hot" v-if="!keyword && hotKeyword.length">
  36. <view class="h">
  37. <text class="title">大家都在搜</text>
  38. </view>
  39. <view class="b">
  40. <view
  41. :class="'item ' + (item.is_hot === 1 ? 'active' : '') + ' line'"
  42. hover-class="navigator-hover"
  43. @tap="onKeywordTap"
  44. :data-keyword="item.keyword"
  45. v-for="(item, index) in hotKeyword"
  46. :key="index"
  47. >
  48. <text>{{ item.keyword }}</text>
  49. <image src="https://mall.zhaijieshi.cc/file/wx-dy/icon-fire.png" class="hot" mode="aspectFit" v-if="index == 0"></image>
  50. </view>
  51. </view>
  52. </view>
  53. </view>
  54. <view class="search-result" v-if="searchStatus && goodsList.length">
  55. <view class="cate-item">
  56. <view class="b">
  57. <navigator
  58. :class="'item ' + ((iindex + 1) % 2 == 0 ? 'item-b' : '')"
  59. :url="'/pages/goods/goods?id=' + iitem.id"
  60. v-for="(iitem, iindex) in goodsList"
  61. :key="iindex"
  62. >
  63. <image class="img" :src="iitem.picUrl" background-size="cover"></image>
  64. <text class="name">{{ iitem.name }}</text>
  65. <view class="price">
  66. <view class="retailPrice">¥{{ iitem.retailPrice }}</view>
  67. </view>
  68. </navigator>
  69. </view>
  70. </view>
  71. </view>
  72. <view class="search-result-empty" v-if="!goodsList.length && searchStatus">
  73. <text class="text">暂无数据~</text>
  74. </view>
  75. </view>
  76. </template>
  77. <script>
  78. var util = require('../../../utils/util.js');
  79. var api = require('../../../config/api.js');
  80. var app = getApp();
  81. export default {
  82. data() {
  83. return {
  84. keyword: '',
  85. searchStatus: false,
  86. goodsList: [],
  87. helpKeyword: [],
  88. historyKeyword: [],
  89. categoryFilter: false,
  90. currentSort: 'name',
  91. currentSortType: 'default',
  92. currentSortOrder: 'desc',
  93. filterCategory: [],
  94. defaultKeyword: {},
  95. hotKeyword: [],
  96. page: 1,
  97. limit: 20,
  98. categoryId: 0,
  99. addressInfo: {},
  100. iindex: 0,
  101. iitem: {
  102. id: '',
  103. picUrl: '',
  104. name: '',
  105. retailPrice: ''
  106. }
  107. };
  108. },
  109. onLoad: function () {
  110. var addressInfo = uni.getStorageSync('addressInfo');
  111. if (addressInfo) {
  112. this.setData({
  113. addressInfo: addressInfo
  114. });
  115. }
  116. this.getSearchKeyword();
  117. },
  118. methods: {
  119. //事件处理函数
  120. closeSearch: function () {
  121. uni.navigateBack();
  122. },
  123. clearKeyword: function () {
  124. this.setData({
  125. keyword: '',
  126. searchStatus: false
  127. });
  128. },
  129. getSearchKeyword() {
  130. let that = this;
  131. util.request(api.SearchIndex).then(function (res) {
  132. if (res.errno === 0) {
  133. that.setData({
  134. historyKeyword: res.data.historyKeywordList,
  135. defaultKeyword: res.data.defaultKeyword,
  136. hotKeyword: res.data.hotKeywordList
  137. });
  138. }
  139. });
  140. },
  141. inputChange: function (e) {
  142. console.log(e);
  143. this.setData({
  144. keyword: e.detail.value,
  145. searchStatus: false
  146. });
  147. if (e.detail.value) {
  148. }
  149. },
  150. getHelpKeyword: function () {
  151. let that = this;
  152. let userInfo = uni.getStorageSync('userInfo');
  153. util.request(api.SearchHelper, {
  154. keyword: that.keyword,
  155. userId: userInfo.id
  156. }).then(function (res) {
  157. if (res.errno === 0) {
  158. that.setData({
  159. helpKeyword: res.data
  160. });
  161. }
  162. });
  163. },
  164. inputFocus: function () {
  165. this.setData({
  166. searchStatus: false,
  167. goodsList: []
  168. });
  169. if (this.keyword) {
  170. }
  171. },
  172. clearHistory: function () {
  173. this.setData({
  174. historyKeyword: []
  175. });
  176. util.request(api.SearchClearHistory, {}, 'POST').then(function (res) {
  177. console.log('清除成功');
  178. });
  179. },
  180. getGoodsList: function () {
  181. let that = this;
  182. util.request(api.GoodsList, {
  183. keyword: that.keyword,
  184. page: that.page,
  185. limit: that.limit,
  186. sort: that.currentSort,
  187. order: that.currentSortOrder,
  188. categoryId: that.categoryId,
  189. city: that.addressInfo.city,
  190. shopId: that.addressInfo.shopId
  191. }).then(function (res) {
  192. if (res.errno === 0) {
  193. that.setData({
  194. searchStatus: true,
  195. categoryFilter: false,
  196. goodsList: res.data.list,
  197. filterCategory: res.data.filterCategoryList
  198. });
  199. }
  200. //重新获取关键词
  201. that.getSearchKeyword();
  202. });
  203. },
  204. onKeywordTap: function (event) {
  205. this.getSearchResult(event.target.dataset.keyword);
  206. },
  207. getSearchResult(keyword) {
  208. this.setData({
  209. keyword: keyword,
  210. page: 1,
  211. categoryId: 0,
  212. goodsList: []
  213. });
  214. if (keyword === '') {
  215. } else {
  216. this.getGoodsList();
  217. }
  218. },
  219. openSortFilter: function (event) {
  220. let currentId = event.currentTarget.id;
  221. switch (currentId) {
  222. case 'categoryFilter':
  223. this.setData({
  224. categoryFilter: !this.categoryFilter,
  225. currentSortType: 'category',
  226. currentSort: 'add_time',
  227. currentSortOrder: 'desc'
  228. });
  229. break;
  230. case 'priceSort':
  231. let tmpSortOrder = 'asc';
  232. if (this.currentSortOrder == 'asc') {
  233. tmpSortOrder = 'desc';
  234. }
  235. this.setData({
  236. currentSortType: 'price',
  237. currentSort: 'retail_price',
  238. currentSortOrder: tmpSortOrder,
  239. categoryFilter: false
  240. });
  241. this.getGoodsList();
  242. break;
  243. default:
  244. //综合排序
  245. this.setData({
  246. currentSortType: 'default',
  247. currentSort: 'name',
  248. currentSortOrder: 'desc',
  249. categoryFilter: false,
  250. categoryId: 0
  251. });
  252. this.getGoodsList();
  253. }
  254. },
  255. selectCategory: function (event) {
  256. let currentIndex = event.target.dataset.categoryIndex;
  257. let filterCategory = this.filterCategory;
  258. let currentCategory = null;
  259. for (let key in filterCategory) {
  260. if (key == currentIndex) {
  261. filterCategory[key].selected = true;
  262. currentCategory = filterCategory[key];
  263. } else {
  264. filterCategory[key].selected = false;
  265. }
  266. }
  267. this.setData({
  268. filterCategory: filterCategory,
  269. categoryFilter: false,
  270. categoryId: currentCategory.id,
  271. page: 1,
  272. goodsList: []
  273. });
  274. this.getGoodsList();
  275. },
  276. onKeywordConfirm(event) {
  277. this.getSearchResult(event.detail.value);
  278. this.getHelpKeyword();
  279. },
  280. onKeywordConfirmBtn() {
  281. this.setData({
  282. page: 1,
  283. categoryId: 0,
  284. goodsList: []
  285. });
  286. this.getGoodsList();
  287. this.getHelpKeyword();
  288. }
  289. }
  290. };
  291. </script>
  292. <style>
  293. page {
  294. min-height: 100%;
  295. background: #fff;
  296. }
  297. .container {
  298. min-height: 100%;
  299. }
  300. .search-header {
  301. width: 690rpx;
  302. height: 76rpx;
  303. background: #f5f6fa;
  304. margin: 0 30rpx;
  305. font-size: 28rpx;
  306. color: #333;
  307. padding: 0 40rpx;
  308. border-radius: 76rpx;
  309. }
  310. .search-header .img {
  311. width: 34rpx;
  312. height: 34rpx;
  313. }
  314. .devide-line {
  315. width: 1rpx;
  316. height: 38rpx;
  317. background: #dcdcdc;
  318. }
  319. .search-text {
  320. color: #00c0ff;
  321. font-size: 26rpx;
  322. margin-left: 30rpx;
  323. }
  324. .search-header .van-icon-search {
  325. line-height: 59rpx;
  326. }
  327. .search-header .input-box {
  328. height: 76rpx;
  329. display: flex;
  330. align-items: center;
  331. }
  332. .search-header .icon {
  333. position: absolute;
  334. top: 14rpx;
  335. left: 20rpx;
  336. width: 31rpx;
  337. height: 31rpx;
  338. }
  339. .search-header .del {
  340. position: absolute;
  341. top: 3rpx;
  342. right: 10rpx;
  343. width: 53rpx;
  344. height: 53rpx;
  345. z-index: 10;
  346. }
  347. .search-header .keywrod {
  348. flex: 1;
  349. height: 76rpx;
  350. line-height: 76rpx;
  351. padding: 0 20rpx;
  352. }
  353. .search-header .right {
  354. margin-top: 24rpx;
  355. margin-left: 31rpx;
  356. margin-right: 6rpx;
  357. width: 58rpx;
  358. height: 43rpx;
  359. line-height: 43rpx;
  360. float: right;
  361. }
  362. .no-search {
  363. height: auto;
  364. overflow: hidden;
  365. margin-top: 96rpx;
  366. padding-left: 70rpx;
  367. background: #fff;
  368. }
  369. .search-keywords {
  370. background: #fff;
  371. width: 750rpx;
  372. height: auto;
  373. }
  374. .search-keywords .h {
  375. height: 93rpx;
  376. line-height: 93rpx;
  377. width: 100%;
  378. color: #999;
  379. font-size: 28rpx;
  380. }
  381. .search-keywords .title {
  382. font-size: 24rpx;
  383. color: #666;
  384. }
  385. .search-keywords .icon {
  386. margin-top: 19rpx;
  387. float: right;
  388. display: block;
  389. margin-left: 511rpx;
  390. height: 55rpx;
  391. width: 55rpx;
  392. }
  393. .search-keywords .b {
  394. width: 750rpx;
  395. height: auto;
  396. overflow: hidden;
  397. }
  398. .search-keywords .b .item {
  399. width: 750rpx;
  400. height: 84rpx;
  401. line-height: 84rpx;
  402. font-size: 28rpx;
  403. color: #666;
  404. }
  405. .search-keywords .item.active {
  406. color: #b4282d;
  407. border: 1px solid #b4282d;
  408. }
  409. .shelper-list {
  410. width: 750rpx;
  411. height: auto;
  412. overflow: hidden;
  413. background: #fff;
  414. padding: 0 31.25rpx;
  415. }
  416. .shelper-list .item {
  417. height: 93rpx;
  418. width: 687.5rpx;
  419. line-height: 93rpx;
  420. font-size: 24rpx;
  421. color: #333;
  422. border-bottom: 1px solid #f4f4f4;
  423. }
  424. .sort {
  425. position: fixed;
  426. top: 91rpx;
  427. background: #fff;
  428. width: 100%;
  429. height: 78rpx;
  430. }
  431. .sort-box {
  432. background: #fff;
  433. width: 100%;
  434. height: 78rpx;
  435. overflow: hidden;
  436. padding: 0 30rpx;
  437. display: flex;
  438. border-bottom: 1px solid #d9d9d9;
  439. }
  440. .sort-box .item {
  441. height: 78rpx;
  442. line-height: 78rpx;
  443. text-align: center;
  444. flex: 1;
  445. color: #333;
  446. font-size: 30rpx;
  447. }
  448. .sort-box .item .txt {
  449. color: #333;
  450. }
  451. .sort-box .item.active .txt {
  452. color: #b4282d;
  453. }
  454. .sort-box .item .van-icon {
  455. margin-left: 6rpx;
  456. }
  457. .sort-box-category {
  458. background: #fff;
  459. width: 100%;
  460. height: auto;
  461. overflow: hidden;
  462. padding: 40rpx 40rpx 0 0;
  463. border-bottom: 1px solid #d9d9d9;
  464. }
  465. .sort-box-category .item {
  466. height: 54rpx;
  467. line-height: 54rpx;
  468. text-align: center;
  469. float: left;
  470. padding: 0 16rpx;
  471. margin: 0 0 40rpx 40rpx;
  472. border: 1px solid #666;
  473. color: #333;
  474. font-size: 24rpx;
  475. }
  476. .sort-box-category .item.active {
  477. color: #b4282d;
  478. border: 1px solid #b4282d;
  479. }
  480. .cate-item {
  481. margin-top: 112rpx;
  482. height: auto;
  483. overflow: hidden;
  484. }
  485. .cate-item .h {
  486. height: 145rpx;
  487. width: 750rpx;
  488. display: flex;
  489. flex-direction: column;
  490. align-items: center;
  491. justify-content: center;
  492. }
  493. .cate-item .h .name {
  494. display: block;
  495. height: 35rpx;
  496. margin-bottom: 18rpx;
  497. font-size: 30rpx;
  498. color: #333;
  499. }
  500. .cate-item .h .desc {
  501. display: block;
  502. height: 24rpx;
  503. font-size: 24rpx;
  504. color: #999;
  505. }
  506. .cate-item .b {
  507. width: 750rpx;
  508. padding: 0 6.25rpx;
  509. height: auto;
  510. overflow: hidden;
  511. }
  512. .cate-item .list-filter {
  513. height: 80rpx;
  514. width: 100%;
  515. background: #fff;
  516. margin-bottom: 6.25rpx;
  517. }
  518. .cate-item .b .item {
  519. float: left;
  520. background: #fff;
  521. width: 365rpx;
  522. margin-bottom: 6.25rpx;
  523. padding-bottom: 33.333rpx;
  524. height: auto;
  525. overflow: hidden;
  526. text-align: center;
  527. }
  528. .cate-item .b .item-b {
  529. margin-left: 6.25rpx;
  530. }
  531. .cate-item .item .img {
  532. width: 302rpx;
  533. height: 302rpx;
  534. border-radius: 10rpx;
  535. }
  536. .cate-item .item .name {
  537. display: block;
  538. width: 360rpx;
  539. height: 68rpx;
  540. line-height: 34rpx;
  541. margin: 11.5rpx 0 0rpx 0;
  542. text-align: left;
  543. overflow: hidden;
  544. padding: 0 20rpx;
  545. font-size: 28rpx;
  546. color: #333;
  547. text-overflow: ellipsis;
  548. display: -webkit-box;
  549. -webkit-box-orient: vertical;
  550. -webkit-line-clamp: 2;
  551. }
  552. .cate-item .item .price {
  553. height: 40rpx;
  554. line-height: 40rpx;
  555. text-align: center;
  556. font-size: 30rpx;
  557. color: #b4282d;
  558. }
  559. .search-result-empty {
  560. width: 100%;
  561. height: 100%;
  562. padding-top: 600rpx;
  563. }
  564. .search-result-empty .text {
  565. display: block;
  566. width: 100%;
  567. height: 40rpx;
  568. font-size: 28rpx;
  569. text-align: center;
  570. color: #999;
  571. }
  572. .cate-item .item .price {
  573. height: 40rpx;
  574. justify-content: center;
  575. display: flex;
  576. margin-top: 10rpx;
  577. align-items: flex-end;
  578. }
  579. .counterPrice {
  580. text-decoration: line-through;
  581. font-size: 24rpx;
  582. margin: 0 0 0 20rpx;
  583. }
  584. .retailPrice {
  585. font-size: 30rpx;
  586. height: 30rpx;
  587. line-height: 30rpx;
  588. }
  589. .memberPrice {
  590. font-size: 22rpx;
  591. color: #dd483e;
  592. margin: 0 10rpx 0 20rpx;
  593. }
  594. .member-price-tag {
  595. width: 88rpx;
  596. height: 26rpx;
  597. line-height: 26rpx;
  598. background: url('https://mall.zhaijieshi.cc/file/jzmall/weixin/member/member-price-bg.png') no-repeat center center;
  599. background-size: 100% 100%;
  600. color: #5e3a11;
  601. font-size: 16rpx;
  602. padding: 0 8rpx 0 0;
  603. text-align: right;
  604. margin: 0 0 6rpx 0;
  605. }
  606. .search-keywords .b.history {
  607. }
  608. .search-keywords .b.history .item {
  609. display: inline-block;
  610. height: 68rpx;
  611. line-height: 68rpx;
  612. padding: 0 15rpx;
  613. font-size: 26rpx;
  614. color: #666;
  615. margin-right: 30rpx;
  616. }
  617. .search-keywords .line {
  618. height: 84rpx;
  619. display: flex;
  620. align-items: center;
  621. }
  622. .search-keywords .line .hot {
  623. width: 24rpx;
  624. height: 24rpx;
  625. margin-left: 12rpx;
  626. }
  627. .search-keywords .b.history {
  628. display: flex;
  629. flex-wrap: wrap;
  630. }
  631. .search-keywords .b.history .item {
  632. width: auto;
  633. padding: 0;
  634. margin-right: 40rpx;
  635. }
  636. </style>