search.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. <template>
  2. <view>
  3. <!-- 排序 -->
  4. <view class="nav-sort bg-white oh pr">
  5. <view class="nav-sort-content">
  6. <block v-for="(item, index) in search_nav_sort_list" :key="index">
  7. <view class="item tc fl" :data-index="index" @tap="nav_sort_event">
  8. <text class="cr-base va-m">{{item.name}}</text>
  9. <image v-if="(item.icon || null) != null" class="icon va-m" :src="common_static_url + 'sort-' + item.icon + '-icon.png'" mode="aspectFill"></image>
  10. </view>
  11. </block>
  12. </view>
  13. <image class="screening-submit pa cp" :src="common_static_url+'search-submit-icon.png'" mode="aspectFill" @tap="popup_form_event_show"></image>
  14. <image class="show-type-submit pa cp" :src="common_static_url+'show-'+(data_show_type_value == 0 ? 'grid' : 'list')+'-icon.png'" mode="aspectFill" @tap="data_show_type_event"></image>
  15. </view>
  16. <!-- 列表 -->
  17. <scroll-view :scroll-y="true" class="scroll-box scroll-box-ece-nav" @scrolltolower="scroll_lower" lower-threshold="60">
  18. <view v-if="data_list.length > 0" class="padding-horizontal-main padding-top-main oh">
  19. <component-goods-list :propData="{style_type: data_show_type_value, goods_list: data_list}" :propCurrencySymbol="currency_symbol"></component-goods-list>
  20. </view>
  21. <view v-else>
  22. <!-- 提示信息 -->
  23. <component-no-data :propStatus="data_list_loding_status"></component-no-data>
  24. </view>
  25. <!-- 结尾 -->
  26. <component-bottom-line :propStatus="data_bottom_line_status"></component-bottom-line>
  27. </scroll-view>
  28. <!-- 筛选条件 popup -->
  29. <component-popup :propShow="is_show_popup_form" propPosition="left" @onclose="popup_form_event_close">
  30. <form @submit="form_submit_event" class="popup-form oh">
  31. <view class="search-map padding-main bg-base">
  32. <view class="padding-main border-radius-main bg-white">
  33. <view class="map-item map-base br-b">
  34. <text>筛选出</text>
  35. <text class="cr-main"> {{data_total}} </text>
  36. <text>条数据</text>
  37. <text class="fr cr-red" @tap="map_remove_event">清除</text>
  38. </view>
  39. <!-- 搜索关键字 -->
  40. <input type="text" confirm-type="done" placeholder="其实搜索很简单^_^ !" name="wd" :value="(post_data.wd || '')" class="map-keywords wh-auto round bg-base margin-top-lg" placeholder-class="cr-grey">
  41. </view>
  42. <!-- 分类 -->
  43. <view v-if="(search_map_list.category_list || null) != null && search_map_list.category_list.length > 0" class="map-item padding-horizontal-main padding-top-main border-radius-main bg-white spacing-mt">
  44. <view class="map-nav pr br-b">
  45. <text>分类</text>
  46. <text class="arrow-bottom pa cr-grey" v-if="search_map_list.category_list.length > 3" @tap="more_event" data-value="category_list">更多</text>
  47. </view>
  48. <view class="map-content map-text-item map-category-container oh margin-top-lg" :style="'height:' + map_fields_list.category_list.height + ';'">
  49. <block v-for="(item, index) in search_map_list.category_list" :key="index">
  50. <view :class="'item fl cr-base radius ' + (item.active == 1 ? 'cr-main br-main' : '')" @tap="map_item_event" :data-index="index" data-field="category_list">{{item.name}}</view>
  51. </block>
  52. </view>
  53. </view>
  54. <view class="search-submit padding-main pa">
  55. <button form-type="submit" class="bg-main cr-white text-size wh-auto round" :disabled="popup_form_loading_status" hover-class="none">确认</button>
  56. </view>
  57. </view>
  58. </form>
  59. </component-popup>
  60. </view>
  61. </template>
  62. <script>
  63. const app = getApp();
  64. import componentPopup from "../../../../components/popup/popup";
  65. import componentNoData from "../../../../components/no-data/no-data";
  66. import componentBottomLine from "../../../../components/bottom-line/bottom-line";
  67. import componentGoodsList from "../../../../components/goods-list/goods-list";
  68. var common_static_url = app.globalData.get_static_url('common');
  69. export default {
  70. data() {
  71. return {
  72. common_static_url: common_static_url,
  73. data_list_loding_status: 1,
  74. data_bottom_line_status: false,
  75. currency_symbol: app.globalData.data.currency_symbol,
  76. data_list: [],
  77. data_total: 0,
  78. data_page_total: 0,
  79. data_page: 1,
  80. params: null,
  81. post_data: {},
  82. shop: null,
  83. is_show_popup_form: false,
  84. popup_form_loading_status: false,
  85. // 排序导航
  86. search_nav_sort_index: 0,
  87. search_nav_sort_list: [
  88. { name: "综合", field: "default", sort: "asc", "icon": null },
  89. { name: "销量", field: "sales_count", sort: "asc", "icon": "default" },
  90. { name: "热度", field: "access_count", sort: "asc", "icon": "default" },
  91. { name: "价格", field: "min_price", sort: "asc", "icon": "default" },
  92. { name: "最新", field: "id", sort: "asc", "icon": "default" }
  93. ],
  94. // 数据展示样式(0图文、1九方格)
  95. data_show_type_value: 1,
  96. // 搜素条件
  97. search_map_list: {
  98. category_list: []
  99. },
  100. map_fields_list: {
  101. category_list: {height: "82rpx", default: "82rpx", form_key: "category_ids"}
  102. },
  103. // 自定义分享信息
  104. share_info: {}
  105. };
  106. },
  107. components: {
  108. componentPopup,
  109. componentNoData,
  110. componentBottomLine,
  111. componentGoodsList
  112. },
  113. props: {},
  114. onLoad(params) {
  115. this.setData({
  116. params: params,
  117. post_data: {
  118. wd: params.keywords || '',
  119. shop_id: params.shop_id || 0,
  120. category_ids: ((params.category_id || 0) == 0) ? '' : JSON.stringify({"0":params.category_id})
  121. }
  122. });
  123. // 数据加载
  124. this.get_data();
  125. },
  126. onShow() {
  127. // 初始化配置
  128. this.init_config();
  129. },
  130. // 下拉刷新
  131. onPullDownRefresh() {
  132. this.setData({
  133. data_page: 1
  134. });
  135. this.get_data_list(1);
  136. },
  137. methods: {
  138. // 初始化配置
  139. init_config(status) {
  140. if ((status || false) == true) {
  141. this.setData({
  142. currency_symbol: app.globalData.get_config('currency_symbol')
  143. });
  144. } else {
  145. app.globalData.is_config(this, 'init_config');
  146. }
  147. },
  148. // 搜索
  149. search_event() {
  150. this.setData({
  151. data_list: [],
  152. data_page: 1
  153. });
  154. this.get_data_list(1);
  155. },
  156. // 初始化
  157. get_data() {
  158. uni.showLoading({
  159. title: '加载中...',
  160. mask: true
  161. });
  162. var post_data = this.request_map_handle();
  163. uni.request({
  164. url: app.globalData.get_request_url("index", "search", "shop"),
  165. method: 'POST',
  166. data: post_data,
  167. dataType: 'json',
  168. success: res => {
  169. uni.hideLoading();
  170. uni.stopPullDownRefresh();
  171. if (res.data.code == 0) {
  172. var data = res.data.data;
  173. // 分类选中处理
  174. var category = data.shop_goods_category || [];
  175. if((this.params.category_id || 0) != 0 && category.length > 0) {
  176. for(var i in category) {
  177. category[i]['active'] = (category[i]['id'] == this.params.category_id) ? 1 : 0;
  178. }
  179. }
  180. this.setData({
  181. shop: data.shop || null,
  182. search_map_info: data.search_map_info || [],
  183. search_map_list: {
  184. category_list: category
  185. }
  186. });
  187. if((this.shop || null) != null) {
  188. // 基础自定义分享
  189. var shop_id = this.shop.id;
  190. var category_id = this.params.category_id || 0;
  191. var keywords = this.params.keywords || '';
  192. this.setData({
  193. share_info: {
  194. title: this.shop.seo_title || this.shop.name,
  195. desc: this.shop.seo_desc || this.shop.describe,
  196. path: '/pages/plugins/shop/search/search',
  197. query: 'shop_id='+shop_id+'&category_id='+category_id+'&keywords='+keywords,
  198. img: this.shop.logo
  199. }
  200. });
  201. // 获取列表数据
  202. this.get_data_list(1);
  203. } else {
  204. this.setData({
  205. data_list_loding_status: 0,
  206. data_bottom_line_status: false
  207. });
  208. }
  209. } else {
  210. this.setData({
  211. data_list_loding_status: 0
  212. });
  213. app.globalData.showToast(res.data.msg);
  214. }
  215. // 分享菜单处理
  216. app.globalData.page_share_handle(this.share_info);
  217. },
  218. fail: () => {
  219. uni.hideLoading();
  220. uni.stopPullDownRefresh();
  221. this.setData({
  222. data_list_loding_status: 2
  223. });
  224. app.globalData.showToast('服务器请求出错');
  225. }
  226. });
  227. },
  228. // 获取数据列表
  229. get_data_list(is_mandatory) {
  230. // 分页是否还有数据
  231. if ((is_mandatory || 0) == 0) {
  232. if (this.data_bottom_line_status == true) {
  233. uni.stopPullDownRefresh();
  234. return false;
  235. }
  236. }
  237. // 获取数据
  238. uni.showLoading({
  239. title: '加载中...',
  240. mask: true
  241. });
  242. var post_data = this.request_map_handle();
  243. uni.request({
  244. url: app.globalData.get_request_url("datalist", "search", "shop"),
  245. method: 'POST',
  246. data: post_data,
  247. dataType: 'json',
  248. success: res => {
  249. uni.hideLoading();
  250. uni.stopPullDownRefresh();
  251. if (res.data.code == 0) {
  252. var data = res.data.data;
  253. if (data.data.length > 0) {
  254. if (this.data_page <= 1) {
  255. var temp_data_list = data.data;
  256. } else {
  257. var temp_data_list = this.data_list || [];
  258. var temp_data = data.data;
  259. for (var i in temp_data) {
  260. temp_data_list.push(temp_data[i]);
  261. }
  262. }
  263. this.setData({
  264. data_list: temp_data_list,
  265. data_total: data.total,
  266. data_page_total: data.page_total,
  267. data_list_loding_status: 3,
  268. data_page: this.data_page + 1
  269. });
  270. // 是否还有数据
  271. this.setData({
  272. data_bottom_line_status: (this.data_page > 1 && this.data_page > this.data_page_total)
  273. });
  274. } else {
  275. this.setData({
  276. data_list_loding_status: 0,
  277. data_total: 0
  278. });
  279. if (this.data_page <= 1) {
  280. this.setData({
  281. data_list: [],
  282. data_bottom_line_status: false
  283. });
  284. }
  285. }
  286. } else {
  287. this.setData({
  288. data_list_loding_status: 0
  289. });
  290. app.globalData.showToast(res.data.msg);
  291. }
  292. },
  293. fail: () => {
  294. uni.hideLoading();
  295. uni.stopPullDownRefresh();
  296. this.setData({
  297. data_list_loding_status: 2
  298. });
  299. app.globalData.showToast('服务器请求出错');
  300. }
  301. });
  302. },
  303. // 搜索条件处理
  304. request_map_handle() {
  305. var params = this.params;
  306. var post_data = this.post_data;
  307. post_data['page'] = this.data_page;
  308. // 店铺id
  309. post_data['shop_id'] = params['shop_id'] || 0;
  310. // 搜索条件
  311. var temp_field = this.map_fields_list;
  312. var temp_list = this.search_map_list;
  313. for (var i in temp_field) {
  314. if (temp_list[i] != null != null && temp_list[i].length > 0) {
  315. var temp = {};
  316. var index = 0;
  317. for (var k in temp_list[i]) {
  318. if ((temp_list[i][k]['active'] || 0) == 1) {
  319. temp[index] = temp_list[i][k]['id'];
  320. index++;
  321. }
  322. }
  323. post_data[temp_field[i]['form_key']] = app.globalData.get_length(temp) > 0 ? JSON.stringify(temp) : '';
  324. }
  325. }
  326. // 排序
  327. var temp_index = this.search_nav_sort_index;
  328. var temp_search_nav_sort = this.search_nav_sort_list;
  329. post_data['order_by_type'] = temp_search_nav_sort[temp_index]['sort'] == 'desc' ? 'asc' : 'desc';
  330. post_data['order_by_field'] = temp_search_nav_sort[temp_index]['field'];
  331. return post_data;
  332. },
  333. // 滚动加载
  334. scroll_lower(e) {
  335. this.get_data_list();
  336. },
  337. // 搜索条件
  338. form_submit_event(e) {
  339. this.setData({
  340. post_data: e.detail.value,
  341. data_page: 1
  342. });
  343. this.popup_form_event_close();
  344. this.get_data_list(1);
  345. },
  346. // 筛选条件关闭
  347. popup_form_event_close(e) {
  348. this.setData({
  349. is_show_popup_form: false
  350. });
  351. },
  352. // 筛选条件开启
  353. popup_form_event_show(e) {
  354. this.setData({
  355. is_show_popup_form: true
  356. });
  357. },
  358. // 排序事件
  359. nav_sort_event(e) {
  360. var index = e.currentTarget.dataset.index || 0;
  361. var temp_search_nav_sort = this.search_nav_sort_list;
  362. var temp_sort = temp_search_nav_sort[index]['sort'] == 'desc' ? 'asc' : 'desc';
  363. for (var i in temp_search_nav_sort) {
  364. if (i != index) {
  365. if (temp_search_nav_sort[i]['icon'] != null) {
  366. temp_search_nav_sort[i]['icon'] = 'default';
  367. }
  368. temp_search_nav_sort[i]['sort'] = 'desc';
  369. }
  370. }
  371. temp_search_nav_sort[index]['sort'] = temp_sort;
  372. if (temp_search_nav_sort[index]['icon'] != null) {
  373. temp_search_nav_sort[index]['icon'] = temp_sort;
  374. }
  375. this.setData({
  376. search_nav_sort_index: index,
  377. search_nav_sort_list: temp_search_nav_sort,
  378. data_page: 1
  379. });
  380. this.get_data_list(1);
  381. },
  382. // 条件-更多数据展示事件
  383. more_event(e) {
  384. var value = e.currentTarget.dataset.value || null;
  385. var temp_more = this.map_fields_list;
  386. if (value != null && (temp_more[value] || null) != null) {
  387. temp_more[value]['height'] = temp_more[value]['height'] == 'auto' ? temp_more[value]['default'] : 'auto';
  388. this.setData({
  389. map_fields_list: temp_more
  390. });
  391. }
  392. },
  393. // 条件-选择事件
  394. map_item_event(e) {
  395. var index = e.currentTarget.dataset.index;
  396. var field = e.currentTarget.dataset.field;
  397. var temp_list = this.search_map_list;
  398. if ((temp_list[field] || null) != null && (temp_list[field][index] || null) != null) {
  399. temp_list[field][index]['active'] = (temp_list[field][index]['active'] || 0) == 0 ? 1 : 0;
  400. this.setData({
  401. search_map_list: temp_list
  402. });
  403. }
  404. },
  405. // 条件-清空
  406. map_remove_event(e) {
  407. var temp_list = this.search_map_list;
  408. var temp_post = this.post_data;
  409. // 关键字
  410. temp_post['wd'] = '';
  411. // 分类
  412. for (var i in temp_list) {
  413. if((temp_list[i] || null) != null && temp_list[i].length > 0) {
  414. for(var k in temp_list[i]) {
  415. temp_list[i][k]['active'] = 0;
  416. }
  417. }
  418. }
  419. // 排序导航
  420. var temp_search_nav_sort = this.search_nav_sort_list;
  421. for (var i in temp_search_nav_sort) {
  422. temp_search_nav_sort[i]['sort'] = 'asc';
  423. temp_search_nav_sort[i]['icon'] = (temp_search_nav_sort[i]['field'] == 'default') ? null : 'default';
  424. }
  425. // 关闭弹窗、分页恢复1页、重新获取数据
  426. this.setData({
  427. search_map_list: temp_list,
  428. post_data: temp_post,
  429. is_show_popup_form: false,
  430. search_nav_sort_list: temp_search_nav_sort,
  431. search_nav_sort_index: 0,
  432. data_page: 1
  433. });
  434. this.get_data_list(1);
  435. },
  436. // 数据展示类型
  437. data_show_type_event(e) {
  438. this.setData({data_show_type_value: this.data_show_type_value == 0 ? 1 : 0});
  439. }
  440. }
  441. };
  442. </script>
  443. <style>
  444. @import './search.css';
  445. </style>