金诚优选前端代码
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.

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