金诚优选前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

436 lines
11 KiB

  1. <template>
  2. <view>
  3. <lf-nav :title="title" :showIcon="true" @changeHeight="e => nav_height = e"></lf-nav>
  4. <view class="head">
  5. <u-search placeholder="搜你想要的" :show-action="false" :disabled="true" @click="searchClick"></u-search>
  6. </view>
  7. <view class="filter-box">
  8. <!-- tabs -->
  9. <view class="filter-item"
  10. v-for="(item, index) in filter_tabs"
  11. :key="index" @click="switchTab(index)">
  12. <text style="white-space: nowrap" v-if="index == 0">{{ item.list[item.select_index].name }}</text>
  13. <text style="white-space: nowrap" v-else>{{ item.name }}</text>
  14. </view>
  15. <!-- 普通列表文字选择 -->
  16. <view class="filter-modal" v-if="show_filter && tab_current == 0" @click="show_filter = false">
  17. <view class="filter-content">
  18. <view v-for="(item, index) in filter_tabs[0].list"
  19. :key="index"
  20. :class="{'active-c': filter_tabs[0].select_index == index}"
  21. @click="clickSort(index)">{{ item.name }}
  22. </view>
  23. </view>
  24. </view>
  25. <!-- 多条件搜索 -->
  26. <view class="filter-modal" v-else-if="show_filter && tab_current == 2" @click="show_filter = false">
  27. <view class="filter-many" @click.stop>
  28. <view class="filter-main">
  29. <view>
  30. <view class="filter-title lf-row-between">
  31. <view>{{ filter_tabs[2].list[0].name }}</view>
  32. <view class="lf-flex">
  33. <input class="filter-input" type="number" v-model="filter_tabs[2].list[0].min_price" placeholder="最低价" />
  34. <view class="filter-division">-</view>
  35. <input class="filter-input" type="number" v-model="filter_tabs[2].list[0].max_price" placeholder="最高价"/>
  36. </view>
  37. </view>
  38. <view class="filter-title" style="margin-top: 80rpx;">
  39. <text>{{ filter_tabs[2].list[1].name }}</text>
  40. <text class="lf-font-24 lf-color-777">(可多选)</text>
  41. </view>
  42. <view class="lf-flex-wrap">
  43. <view class="filter-capsule"
  44. :class="{'active-bg': autoSelectBrand(index)}"
  45. @click="clickBrand(index)"
  46. v-for="(item, index) in filter_tabs[2].list[1].brand"
  47. :key="index">{{ item.name }}
  48. </view>
  49. </view>
  50. </view>
  51. </view>
  52. <view class="filter-foot">
  53. <button class="filter-btn" @click="reset">重置条件</button>
  54. <button class="filter-btn solid-btn" @click="submit">确定</button>
  55. </view>
  56. </view>
  57. </view>
  58. </view>
  59. <view style="height: 104rpx;"></view>
  60. <scroll-view :style="{height: autoHeight}" :scroll-y="true" @scrolltolower="scrolltolower">
  61. <view class="scroll-content">
  62. <lf-waterfall :list="list"></lf-waterfall>
  63. </view>
  64. </scroll-view>
  65. </view>
  66. </template>
  67. <script>
  68. import lfWaterfall from '@/components/lf-waterfall-shopdetails/lf-waterfall.vue';
  69. export default {
  70. components: {
  71. lfWaterfall
  72. },
  73. data(){
  74. return {
  75. show_filter: true,
  76. tab_current: null,
  77. scrollH: 0,
  78. nav_height: 0,
  79. list: [],
  80. title: '',
  81. c_id: 0,
  82. filter_tabs: [{
  83. name: '综合排序',
  84. select_index: 0,
  85. list: [{
  86. name: '综合排序',
  87. orderBy: ''
  88. },{
  89. name: '销量最高',
  90. orderBy: 'sale_count'
  91. },{
  92. name: '价格最香',
  93. orderBy: 'sell_price'
  94. },{
  95. name: '最新排序',
  96. orderBy: 'updated_at'
  97. }]
  98. },{
  99. name: ''
  100. },{
  101. name: '筛选',
  102. list: [{
  103. name: '价格区间',
  104. min_price: '',
  105. max_price: ''
  106. },{
  107. name: '品牌',
  108. brand: [],
  109. selected: []
  110. }]
  111. }],
  112. filter_tabs_source: []
  113. }
  114. },
  115. computed: {
  116. autoHeight(){
  117. return `calc(${this.scrollH}px - ${this.nav_height}px - 124rpx - 104rpx)`;
  118. },
  119. autoSelectBrand(){
  120. return function(index){
  121. let item = this.filter_tabs[2].list[1];
  122. let flag = false;
  123. item.selected.map(i => {
  124. if(index == i){
  125. flag = true;
  126. }
  127. })
  128. return flag;
  129. }
  130. }
  131. },
  132. onLoad(options){
  133. let info = uni.getSystemInfoSync();
  134. this.scrollH = info.screenHeight;
  135. this.c_id = options.id;
  136. this.getGoodsList();
  137. },
  138. methods: {
  139. // 首次获取商品列表
  140. getGoodsList(){
  141. this.$http.get({
  142. api: 'api/store/list',
  143. data: {
  144. c_id: this.c_id
  145. }
  146. }).then(res => {
  147. console.log("getgoodslist", res);
  148. this.getBrandList();
  149. let data_list = res.data.data || [];
  150. let list = data_list.map(item => {
  151. return {
  152. id: item.id,
  153. original_price: item.market_price,
  154. picture: item.img,
  155. pictures: [item.img],
  156. price: item.min_price,
  157. product_id: item.brand_id,
  158. sale: item.sale_count,
  159. title: item.name
  160. }
  161. })
  162. if(data_list[0] && data_list[0].tags){
  163. this.title = data_list[0].tags[0];
  164. this.filter_tabs[1].name = data_list[0].tags[0];
  165. }
  166. this.list = list;
  167. })
  168. },
  169. // 获取品牌列表,只会在第一次进入页面时获取
  170. getBrandList(){
  171. this.$http.get({
  172. api: 'api/brand'
  173. }).then(res => {
  174. console.log("brand", res);
  175. let list = res.data.data.list;
  176. let brand = list.map(item => {
  177. return {name: item.name, id: item.id};
  178. })
  179. this.filter_tabs[2].list[1].brand = brand;
  180. this.filter_tabs_source = JSON.parse(JSON.stringify(this.filter_tabs));
  181. })
  182. },
  183. // 筛选后的接口请求获取商品列表
  184. getFilterGoods(){
  185. let sortItem = this.filter_tabs[0];
  186. let moreItem = this.filter_tabs[2];
  187. let par = {
  188. c_id: this.c_id
  189. }
  190. // 排序
  191. par.orderBy = sortItem.list[sortItem.select_index].orderBy;
  192. // 品牌
  193. if(moreItem.list[1].selected.length){
  194. let brand_id = [];
  195. moreItem.list[1].selected.map(s_item => {
  196. brand_id.push( moreItem.list[1].brand[s_item].id );
  197. })
  198. par.brand_id = brand_id;
  199. }
  200. // 价格
  201. if(moreItem.list[0].min_price && moreItem.list[0].max_price){
  202. par.price = moreItem.list[0].min_price +'-'+ moreItem.list[0].max_price;
  203. }
  204. // TODO 传入分页等信息
  205. this.$http.get({
  206. api: 'api/store/list',
  207. data: par
  208. }).then(res => {
  209. console.log("res", res);
  210. })
  211. },
  212. // 点击选择筛选
  213. clickSort(index){
  214. this.filter_tabs[0].select_index = index;
  215. this.getFilterGoods();
  216. },
  217. // 点击选中筛选某个品牌
  218. clickBrand(index){
  219. let item = this.filter_tabs[2].list[1];
  220. let num = item.selected.indexOf(index);
  221. if(num != -1){
  222. item.selected.splice(num, 1);
  223. }else{
  224. item.selected.push(index);
  225. }
  226. },
  227. // 提交筛选
  228. submit(){
  229. console.log("所以筛选条件", this.filter_tabs)
  230. this.show_filter = false;
  231. this.getFilterGoods();
  232. },
  233. // 重置所有筛选
  234. reset(){
  235. if(this.filter_tabs_source && Object.keys(this.filter_tabs_source).length){
  236. this.filter_tabs = JSON.parse(JSON.stringify(this.filter_tabs_source));
  237. this.show_filter = false;
  238. this.getFilterGoods();
  239. }else{
  240. this.$msg('重置失败', {icon: 'error'});
  241. }
  242. },
  243. // 搜索框被点击
  244. searchClick(){
  245. this.$url('/pages/shop/search');
  246. },
  247. // 切换tabs
  248. switchTab(current){
  249. if(this.tab_current != current){
  250. this.show_filter = true;
  251. }else{
  252. this.show_filter = !this.show_filter;
  253. }
  254. this.tab_current = current;
  255. },
  256. // scroll page滚动到底部
  257. scrolltolower(){
  258. this.$msg('页面触底啦~')
  259. }
  260. }
  261. }
  262. </script>
  263. <style lang="scss" scoped="scoped">
  264. .head{
  265. padding: 30rpx 32rpx;
  266. }
  267. .filter-box{
  268. width: 750rpx;
  269. height: 102rpx;
  270. border-bottom: 1rpx solid #e5e5e5;
  271. position: fixed;
  272. background-color: #FFFFFF;
  273. z-index: 9;
  274. display: flex;
  275. // justify-content: space-between;
  276. justify-content: space-around;
  277. align-items: center;
  278. padding: 0 32rpx;
  279. box-sizing: border-box;
  280. .filter-item{
  281. width: 114rpx;
  282. height: 62rpx;
  283. display: flex;
  284. flex-wrap: nowrap;
  285. justify-content: center;
  286. align-items: center;
  287. font-size: 28rpx;
  288. color: #222222;
  289. .tab-active{
  290. display: inline-block;
  291. transform: rotate(180deg);
  292. color: #15716E !important;
  293. }
  294. }
  295. .filter-modal{
  296. position: absolute;
  297. z-index: 7;
  298. background-color: rgba(0,0,0,0.5);
  299. top: 103rpx;
  300. right: 0;
  301. bottom: 0;
  302. left: 0;
  303. width: 100vw;
  304. height: calc(100vh - 103rpx);
  305. .filter-content{
  306. position: absolute;
  307. width: 100%;
  308. height: max-content;
  309. max-height: 806rpx;
  310. background-color: #FFFFFF;
  311. left: 0;
  312. z-index: 14;
  313. overflow-y: scroll;
  314. padding: 0 0 32rpx 32rpx;
  315. display: flex;
  316. flex-direction: column;
  317. justify-content: space-evenly;
  318. view{
  319. height: 60rpx;
  320. // border-bottom: 1rpx solid #e5e5e5;
  321. padding: 20rpx 0;
  322. line-height: 60rpx;
  323. }
  324. }
  325. .filter-many{
  326. position: absolute;
  327. width: 100%;
  328. min-height: max-content;
  329. max-height: 630rpx;
  330. background-color: #FFFFFF;
  331. left: 0;
  332. z-index: 14;
  333. .filter-main{
  334. min-height: max-content;
  335. max-height: 500rpx;
  336. overflow-y: scroll;
  337. box-sizing: border-box;
  338. padding: 32rpx;
  339. .filter-title{
  340. font-size: 28rpx;
  341. color: #222222;
  342. font-weight: bold;
  343. margin-bottom: 20rpx;
  344. .filter-input{
  345. width: 160rpx;
  346. height: 50rpx;
  347. background-color: #FFFFFF;
  348. border: 1rpx solid #e5e5e5;
  349. text-align: center;
  350. font-size: 24rpx;
  351. font-weight: initial;
  352. border-radius: 40rpx;
  353. }
  354. .filter-division{
  355. padding: 0 20rpx;
  356. font-weight: initial;
  357. }
  358. }
  359. .filter-capsule{
  360. width: 163rpx;
  361. height: 62rpx;
  362. border-radius: 31rpx;
  363. border: 1rpx solid #999999;
  364. font-size: 20rpx;
  365. color: #999999;
  366. text-align: center;
  367. line-height: 62rpx;
  368. margin-right: 12rpx;
  369. &:nth-child(4n){
  370. margin-right: 0rpx;
  371. }
  372. &:nth-child(n+5){
  373. margin-top: 12rpx;
  374. }
  375. }
  376. .filter-active{
  377. border-color: #15716E;
  378. color: #15716E;
  379. }
  380. .input-search{
  381. width: 686rpx;
  382. height: 62rpx;
  383. background-color: #FFFFFF;
  384. border-radius: 10rpx;
  385. border: 1rpx solid #DDDDDD;
  386. box-sizing: border-box;
  387. padding: 0 15rpx;
  388. font-size: 28rpx;
  389. margin-bottom: 50rpx;
  390. }
  391. }
  392. .filter-main>view:nth-child(n+3){
  393. margin-top: 40rpx;
  394. }
  395. .filter-foot{
  396. height: 130rpx;
  397. border-top: 1rpx solid #e5e5e5;
  398. padding: 32rpx;
  399. display: flex;
  400. justify-content: space-between;
  401. align-items: center;
  402. .filter-btn{
  403. width: 332rpx;
  404. height: 90rpx;
  405. border-radius: 10rpx;
  406. border: 1rpx solid #555555;
  407. background-color: #FFFFFF;
  408. line-height: 88rpx;
  409. font-size: 32rpx;
  410. color: #555555;
  411. margin: 0;
  412. }
  413. .solid-btn{
  414. background-color: #15716E;
  415. color: #FFFFFF;
  416. border: none;
  417. }
  418. }
  419. }
  420. }
  421. }
  422. .active-c{
  423. color: #15716E;
  424. }
  425. .active-bg{
  426. background: #15716E;
  427. color: #fff !important;
  428. border: none;
  429. }
  430. .scroll-content{
  431. padding: 30rpx 32rpx;
  432. }
  433. </style>