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

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