jufubao-mall 2.0.21 → 2.0.23-beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/package.json +1 -1
  2. package/src/components/CusProduct/CusProduct.vue +1 -1
  3. package/src/components/JfbMallBrandWall/Attr.js +10 -449
  4. package/src/components/JfbMallBrandWall/JfbMallBrandWall.vue +783 -308
  5. package/src/components/JfbMallBrandWall/cusAttr/advanced.js +61 -0
  6. package/src/components/JfbMallBrandWall/cusAttr/brand.js +341 -0
  7. package/src/components/JfbMallBrandWall/cusAttr/content.js +251 -0
  8. package/src/components/JfbMallBrandWall/cusAttr/style.js +252 -0
  9. package/src/components/JfbMallBrandWall/cusAttr/tab.js +471 -0
  10. package/src/components/JfbMallHomeProductList/JfbMallHomeProductList.vue +3 -1
  11. package/src/components/JfbMallHomeProductList/cusAttr/content.js +1 -2
  12. package/src/components/JfbMallNetworkMedia/Api.js +58 -0
  13. package/src/components/JfbMallNetworkMedia/Attr.js +20 -0
  14. package/src/components/JfbMallNetworkMedia/JfbMallNetworkMedia.vue +84 -0
  15. package/src/components/JfbMallNetworkMedia/JfbMallNetworkMediaLess.less +80 -0
  16. package/src/components/JfbMallNetworkMedia/JfbMallNetworkMediaMixin.js +30 -0
  17. package/src/components/JfbMallNetworkMedia/Mock.js +13 -0
  18. package/src/components/JfbMallNetworkMedia/cusAttr/advanced.js +60 -0
  19. package/src/components/JfbMallNetworkMedia/cusAttr/content.js +125 -0
  20. package/src/components/JfbMallNetworkMedia/cusAttr/filter.js +333 -0
  21. package/src/components/JfbMallNetworkMedia/cusAttr/font.js +114 -0
  22. package/src/components/JfbMallNetworkMedia/cusAttr/icon.js +298 -0
  23. package/src/components/{JfbMallProductList → JfbMallNetworkMedia/cusAttr}/style.js +15 -50
  24. package/src/components/JfbMallProductInfo/JfbMallProductInfo.vue +27 -23
  25. package/src/components/JfbMallProductInfo/cusAttr/content.js +1 -1
  26. package/src/components/JfbMallProductInfoV2/Api.js +1 -1
  27. package/src/components/JfbMallProductInfoV2/Attr.js +134 -41
  28. package/src/components/JfbMallProductInfoV2/JfbMallProductInfoV2.vue +136 -127
  29. package/src/components/JfbMallProductInfoV2/Mock.js +38 -10
  30. package/src/components/JfbMallProductList/Api.js +7 -7
  31. package/src/components/JfbMallProductList/Attr.js +7 -762
  32. package/src/components/JfbMallProductList/ComFilterQuery.vue +950 -0
  33. package/src/components/JfbMallProductList/JfbMallProductList.vue +807 -792
  34. package/src/components/JfbMallProductList/Mock.js +168 -255
  35. package/src/components/JfbMallProductList/XdCateV1.vue +335 -122
  36. package/src/components/JfbMallProductList/XdCateV2.vue +144 -76
  37. package/src/components/JfbMallProductList/XdQueryCommon.vue +189 -0
  38. package/src/components/JfbMallProductList/XdQueryFilter.vue +94 -76
  39. package/src/components/JfbMallProductList/XdQuerySort.vue +100 -109
  40. package/src/components/JfbMallProductList/cateMixins.js +103 -0
  41. package/src/components/JfbMallProductList/{advanced.js → cusAttr/advanced.js} +12 -4
  42. package/src/components/JfbMallProductList/cusAttr/content.js +465 -0
  43. package/src/components/JfbMallProductList/cusAttr/filter.js +333 -0
  44. package/src/components/JfbMallProductList/cusAttr/font.js +114 -0
  45. package/src/components/JfbMallProductList/cusAttr/icon.js +298 -0
  46. package/src/components/JfbMallProductList/cusAttr/style.js +91 -0
  47. package/src/components/JfbMallRecommendProduct/Attr.js +8 -366
  48. package/src/components/JfbMallRecommendProduct/JfbMallRecommendProduct.vue +218 -187
  49. package/src/components/JfbMallRecommendProduct/Mock.js +236 -693
  50. package/src/components/JfbMallRecommendProduct/cusAttr/advanced.js +79 -0
  51. package/src/components/JfbMallRecommendProduct/cusAttr/content.js +202 -0
  52. package/src/components/JfbMallRecommendProduct/cusAttr/style.js +594 -0
  53. package/src/components/JfbMallResourceShopList/Mock.js +4 -6
  54. package/src/components/JfbMallTestNormal/JfbMallTestNormal.vue +23 -2
  55. package/src/components/JfbMallTestNormal/data.js +152 -0
  56. package/src/mixins/componentsMixins.js +1 -0
  57. package/src/mixins/productCompMixins.js +29 -19
  58. package/src/components/JfbMallProductList/PosterAttr.js +0 -327
  59. package/src/components/JfbMallProductList/ProductAttr.js +0 -164
  60. package/src/components/JfbMallProductList/XdQueryBrand.vue +0 -150
@@ -0,0 +1,950 @@
1
+ <template>
2
+ <view class="jfb-filter" v-if="showQuery === 'Y'" :style="[cssStyle]">
3
+
4
+ <view class="jfb-filter-placeholder" :style="[placeholderStyleComp]"></view>
5
+ <view class="jfb-filter-menu" :style="[cusMenuStyle,menuStyleTopComp]">
6
+ <template v-if="sortList.length > 0">
7
+ <view
8
+ class="jfb-filter-menu-item"
9
+ v-for="sortValue in sortList"
10
+ :key="sortValue.value"
11
+ @click="handleNenu(sortValue.value)"
12
+ >
13
+ <view
14
+ class="jfb-filter-menu-name"
15
+ :class="{ fontWeight: sortValue.value === sortAct}"
16
+ :style="[menuTextColorComp]"
17
+ >{{sortValue|fCusName}}</view>
18
+ <view class="jfb-filter-menu-icon">
19
+ <view v-if="sortValue.value === 'common'">
20
+ <xd-font-icon icon="iconxia_down" width="50" :color="menuTextColorComp.color" :size="20"/>
21
+ </view>
22
+ <template v-if="sortValue.value === 'price'">
23
+ <view v-if="!['price_desc','price_asc'].includes(sort)">
24
+ <xd-font-icon icon="iconshang_up" width="50" :color="menuTextColorComp.color" height="20" :size="20"/>
25
+ <xd-font-icon icon="iconxia_down" width="50" :color="menuTextColorComp.color" height="20" :size="20"/>
26
+ </view>
27
+ <view v-if="sort === 'price_desc'">
28
+ <xd-font-icon icon="iconxia_down" width="50" :color="menuTextColorComp.color" :size="20"/>
29
+ </view>
30
+ <view v-if="sort === 'price_asc'">
31
+ <xd-font-icon icon="iconshang_up" width="50" :color="menuTextColorComp.color" :size="20"/>
32
+ </view>
33
+ </template>
34
+ </view>
35
+ </view>
36
+ </template>
37
+ <template v-if="otherNenuItems.length > 0">
38
+ <view
39
+ class="jfb-filter-menu-item"
40
+ v-for="otherNenu in otherNenuItems"
41
+ :key="otherNenu.value"
42
+ @click="handleNenu(otherNenu.value)"
43
+ >
44
+ <view
45
+ class="jfb-filter-menu-name"
46
+ :class="{ fontWeight: otherNenu.value !=='filter' && selectedNenuLabels[otherNenu.value].length > 0}"
47
+ :style="[menuTextColorComp]"
48
+ >{{otherNenu|fCusOtherName}}</view>
49
+ <view class="jfb-filter-menu-icon">
50
+ <view>
51
+ <xd-font-icon icon="iconxia_down" width="50" :color="menuTextColorComp.color" :size="20"/>
52
+ </view>
53
+ </view>
54
+ </view>
55
+ </template>
56
+ </view>
57
+ <view class="jfb-filter-pop" :style="[queryTopComp]">
58
+ <view
59
+ class="xd-query-sort"
60
+ v-if="menuAct === 'common' && showQueryModal"
61
+ :style="[boxStyleComp]">
62
+ <view
63
+ class="xd-query-sort-item"
64
+ v-for="item in allSortItems"
65
+ :key="item.value"
66
+ :style="[(sort === item.value? labelActColor:labelColor)]"
67
+ @click="handleCommonSort(item)"
68
+ >{{item.label}}</view>
69
+ </view>
70
+ <view
71
+ class="xd-query-filter"
72
+ v-if="!['common','price', 'hot'].includes(menuAct) && showQueryModal"
73
+ >
74
+ <view class="filter_wrap" :style="[otherMenuComp]">
75
+ <view
76
+ class="filter_item"
77
+ v-for="tab in filterTabs"
78
+ :key="tab.value"
79
+ :style="[otherMenuContComp]"
80
+ >
81
+ <view class="filter_title" v-if="isFitler">
82
+ <view>{{tab.title}}</view>
83
+ <view v-if="tab.options.length > collapseNum" class="_ext" @click="switchOtherOpen(tab)">
84
+ <text>{{tab.open ? '收起' : '展开'}}</text>
85
+ <xd-font-icon v-if="tab.open" icon="iconshang_up" :size="20"></xd-font-icon>
86
+ <xd-font-icon v-else icon="iconxia_down" :size="20"></xd-font-icon>
87
+ </view>
88
+ </view>
89
+ <view class="filter_tab">
90
+ <template v-for="(item,i) in tab.options">
91
+ <view
92
+ class="_tag"
93
+ :style="[otherMenuItemComp,(isOtherActive(tab, item.value)?labelActColor:labelColor)]"
94
+ v-if="(!tab.open && i < collapseNum) || tab.open || !isFitler"
95
+ :key="item.value"
96
+ :class="{
97
+ active: isOtherActive(tab, item.value),
98
+ noMarginRigth: i%column === (column-1),
99
+ noMarginTop: i/column < 1
100
+ }"
101
+ @click="setOhterChooseTag(tab, item)"
102
+ >{{item.label}}</view>
103
+ </template>
104
+ </view>
105
+ </view>
106
+ </view>
107
+ <view class="bottom_btn" v-if="isShowBtn">
108
+ <xd-button class="xd-button" type="info" width="248rpx" size="normal" @click="onOtherReset">重置</xd-button>
109
+ <xd-button class="xd-button" type="primary" width="248rpx" size="normal" @click="onOtherConfirm">确定</xd-button>
110
+ </view>
111
+ </view>
112
+ </view>
113
+ <view
114
+ v-if="showQueryModal"
115
+ class="jfb-filter-mask"
116
+ :style="[queryMaskComp]"
117
+ @click="closeQueryModal"
118
+ @touchmove.stop.prevent="moveHandle"
119
+ ></view>
120
+ </view>
121
+ </template>
122
+
123
+ <script>
124
+ import XdFontIcon from "@/components/XdFontIcon/XdFontIcon.vue";
125
+ import XdButton from "@/components/XdButton/XdButton"
126
+ import {mapActions} from "vuex";
127
+ import Color from "color";
128
+
129
+ let $vm = null;
130
+ export default {
131
+ name: 'ComFilterQuery',
132
+ components:{
133
+ XdFontIcon,
134
+ XdButton
135
+ },
136
+ props:{
137
+ showQuery:{
138
+ type: String,
139
+ default: 'N',
140
+ },
141
+ layoutInfo:{
142
+ type: Object,
143
+ default(){
144
+ return {}
145
+ }
146
+ },
147
+ topHeight: {
148
+ type: Number,
149
+ default: 0,
150
+ },
151
+ cusMenuStyle:{
152
+ type: Object,
153
+ default(){
154
+ return {}
155
+ }
156
+ },
157
+ cusPopStyle:{
158
+ type: Object,
159
+ default(){
160
+ return {}
161
+ }
162
+ },
163
+ menuHeight:{
164
+ type: Number,
165
+ default: 48,
166
+ },
167
+ menuItems: {
168
+ type: Array,
169
+ default(){
170
+ return []
171
+ }
172
+ },
173
+
174
+ //排序默认值
175
+ defSort:{
176
+ type: String,
177
+ default: '',
178
+ },
179
+ defRemote:{
180
+ type: Object,
181
+ default(){
182
+ return {}
183
+ },
184
+ },
185
+ remoteList:{
186
+ type:Array,
187
+ default(){
188
+ return {}
189
+ }
190
+ },
191
+ //是否在筛选项过滤配置项
192
+ filterFields:{
193
+ type: Array,
194
+ default(){
195
+ return []
196
+ },
197
+ },
198
+
199
+ column:{
200
+ type: Number,
201
+ default: 3
202
+ },
203
+
204
+ //几个开始折叠
205
+ collapseNum: {
206
+ type: Number,
207
+ default: 3
208
+ },
209
+ },
210
+ filters:{
211
+ fCusName(item){
212
+ if($vm.sort) {
213
+ if($vm.sortAct === item.value) {
214
+ let act = $vm.allSortItemsOrg.filter(it=>$vm.sort===it.value);
215
+ if(act.length === 1) return act[0].menuName;
216
+ return item.label
217
+ }
218
+ return item.label
219
+ }
220
+ return item.label
221
+ },
222
+ fCusOtherName(item){
223
+ if(item.value === 'filter') return item.label;
224
+ else {
225
+ let names = $vm.selectedNenuLabels[item.value];
226
+ if(names.length > 0) {
227
+ let namesStr = ''
228
+ if(typeof names === 'string') namesStr = names
229
+ else namesStr = names.join(',');
230
+ let maxStr = 9;
231
+ if($vm.menuItems.length === 3) maxStr = 7;
232
+ if($vm.menuItems.length === 4) maxStr = 4;
233
+ if(namesStr.length > maxStr) return namesStr.substring(0,maxStr) + '...'
234
+ return namesStr
235
+ }
236
+ return item.label;
237
+ }
238
+ }
239
+ },
240
+ computed:{
241
+ queryMaskComp(){
242
+ return {
243
+ top: this.topHeight + this.layoutInfo.top + 'rpx'
244
+ }
245
+ },
246
+ placeholderStyleComp(){
247
+ let {paddingTb, borderTopWidth} = this.cusMenuStyle;
248
+ return {
249
+ height: this.menuHeight + paddingTb + borderTopWidth + 'rpx'
250
+ }
251
+ },
252
+ menuStyleTopComp(){
253
+ return {
254
+ zIndex: this.showQueryModal ? 1002 : 1,
255
+ position:this.$configProject.isPreview?'absolute':'fixed',
256
+ top: this.$configProject.isPreview ? 0 : (parseInt(this.queryMaskComp.top) - 2) + 'rpx',
257
+ }
258
+ },
259
+ queryTopComp(){
260
+ let {paddingTb} = this.cusMenuStyle;
261
+ let height = 48;//默认90高,填充0
262
+ return {
263
+ top: this.topHeight + this.layoutInfo.top + (height + paddingTb - 2) + 'rpx'
264
+ }
265
+ },
266
+ menuTextColorComp(){
267
+ return {
268
+ color: this.cusMenuStyle.color || '#999'
269
+ }
270
+ },
271
+
272
+ //other menu======
273
+ otherMenuComp(){
274
+ let height = 48; //菜单高度
275
+ let maxHeight = this.$root.layoutInfo['bodyMinHeightRpx'] - (300 + height + this.topHeight) ;
276
+ if(this.$configProject.isPreview) maxHeight = 600;
277
+ return {
278
+ backgroundColor: this.cusPopStyle['filterListColor'] || '#f8f8f8',
279
+ maxHeight: maxHeight + 'rpx',
280
+ borderTop: this.cusPopStyle.filterTopBorder || '2rpx solid #f8f8f8',
281
+
282
+ }
283
+ },
284
+ otherMenuContComp(){
285
+ return {
286
+ backgroundColor: '#fff',
287
+ marginBottom: (this.cusPopStyle['filterRowSpacing'] || 16) + 'rpx',
288
+ padding: (this.cusPopStyle['filterPadding'] || '32rpx 48rpx'),
289
+ }
290
+ },
291
+
292
+ otherMenuItemComp(){
293
+ let outWidth = uni.getSystemInfoSync().safeArea.width;
294
+ let columnSpacing = this.cusPopStyle['filterRowSpacing'] || 16
295
+ let columnSpacingAllWidth = columnSpacing * this.$rpxNum * (this.column-1)
296
+ let marginRL = this.cusPopStyle['filterPaddingRL'] * this.$rpxNum;
297
+ return {
298
+ width: (outWidth - (columnSpacingAllWidth + marginRL))/this.column + 'px',
299
+ marginRight: columnSpacing + 'rpx',
300
+ marginTop: columnSpacing + 'rpx',
301
+ borderRadius:(this.cusPopStyle['filterListRadius']||0) + 'rpx',
302
+ };
303
+ },
304
+ //other menu======
305
+
306
+ boxStyleComp(){
307
+ return {
308
+ backgroundColor: this.cusPopStyle.filterListColor||'#fff',
309
+ }
310
+ },
311
+ labelColor(){
312
+ let font = this.cusPopStyle.filterFontStyle;
313
+ let params = {
314
+ color: font.color,
315
+ fontSize: font.fontSize,
316
+ }
317
+ if(this.menuAct !== 'common') {
318
+ params = {
319
+ ...params,
320
+ borderColor: Color(font.color).alpha(0.01).toString(),
321
+ backgroundColor: Color(font.color).alpha(0.05).toString(),
322
+ }
323
+ }
324
+ return params
325
+ },
326
+ labelActColor(){
327
+ let font = this.cusPopStyle.filterActFontStyle;
328
+ let params = {
329
+ color: font.color,
330
+ fontSize: font.fontSize,
331
+ }
332
+ if(this.menuAct !== 'common') {
333
+ params = {
334
+ ...params,
335
+ borderColor: Color(font.color).alpha(0.2).toString(),
336
+ backgroundColor: Color(font.color).alpha(0.1).toString(),
337
+ }
338
+ }
339
+ return params
340
+ },
341
+ cssStyle(){
342
+ let filterListColor = this.cusPopStyle['filterListColor'] || '#f8f8f8';
343
+ if(Color(filterListColor).isDark()) filterListColor = Color(filterListColor).lighten(0.8).toString();
344
+ else if(Color(filterListColor).isLight()) filterListColor = Color(filterListColor).darken(0.03).toString();
345
+
346
+ let menuListColor = this.cusPopStyle['backgroundColor'] || '#fff';
347
+ if(Color(menuListColor).isDark()) menuListColor = Color(menuListColor).lighten(0.8).toString();
348
+ else if(Color(menuListColor).isLight()) menuListColor = Color(menuListColor).darken(0.03).toString();
349
+
350
+ return {
351
+ '--com-pop-border': filterListColor,
352
+ '--com-menu-border': menuListColor
353
+ }
354
+ }
355
+ },
356
+ watch:{
357
+ menuItems(){
358
+ this.initMune();
359
+ },
360
+
361
+ showQueryModal(val){
362
+ if(val) this.setHasPopStatus({popId: this.bodyID, action: 'add'});
363
+ else this.setHasPopStatus({popId: this.bodyID, action: 'del'});
364
+ },
365
+ remoteList(){
366
+ this.initFilterData()
367
+ },
368
+
369
+ },
370
+ data(){
371
+ return {
372
+ allSortItemsOrg:[],
373
+ showQueryModal: false,
374
+ allSortItems:[],//综合列表
375
+ sortList:[], //排序数组显示菜单
376
+ sort: '', //排序键值
377
+ sortAct: '',
378
+ menuAct: '', //当前操作菜单
379
+ bodyID:null,
380
+
381
+ //其他按钮
382
+ otherNenuItems:[], //其他远程菜单列表
383
+ selectedNenuItems:{}, //存放选中选项卡对象
384
+ selectedNenuIds:{}, //存放选中选项卡ID对象
385
+ selectedNenuLabels:{}, //存放选中选项卡名称对象
386
+ isFitler: true, //是筛选OR快捷方式
387
+ isShowBtn: false, //是单选还是多选
388
+ filterTabs: [],//当前下拉菜单数据
389
+ filterTabsOrg:[], //下拉菜单原始数据
390
+ }
391
+ },
392
+ created() {
393
+ $vm = this;
394
+ this.bodyID = `body_${this.$xdUniHelper.randomChar(10)}`;
395
+ this.initMune();
396
+ this.initFilterData();
397
+ },
398
+ methods:{
399
+ ...mapActions(['setHasPopStatus']),
400
+
401
+ //==menu====
402
+ hideSelectMenu(){
403
+ this.showQueryModal = false;
404
+ },
405
+ clearFitlerMenu(){
406
+ //设置默认值
407
+ if(this.defSort){
408
+ this.sort = this.defSort;
409
+ let sortAct = 'common';
410
+ if(this.menuItems.includes('hot') && this.sort === 'sale_num_desc') sortAct = 'hot';
411
+ if(this.menuItems.includes('price') && ['price_desc','price_asc'].includes(this.sort)) sortAct = 'price';
412
+ this.sortAct = sortAct;
413
+ }
414
+
415
+ let menuItems = ['filter'];
416
+ this.initCurrentFilter('filter', true).map(item=>{
417
+ if(item['filter_keys'] === false) menuItems.push(item.value)
418
+ })
419
+ menuItems.map(key=>{
420
+ this.$set(this.selectedNenuIds,key, []);
421
+ this.$set(this.selectedNenuItems, key, []);
422
+ this.$set(this.selectedNenuLabels, key, []);
423
+ });
424
+
425
+ let otherParams = {};
426
+ Object.keys(this.defRemote).map(key=>{
427
+ otherParams[key] = typeof this.defRemote[key] === 'string'?this.defRemote[key]: this.defRemote[key].join(',')
428
+ })
429
+
430
+ this.$emit('on-change', {
431
+ sort: this.defSort,
432
+ filter:{
433
+ items: [],
434
+ labels: [],
435
+ ids: this.defRemote
436
+ },
437
+ params:{
438
+ sort: this.defSort,
439
+ ...otherParams,
440
+ }
441
+ })
442
+ },
443
+ initMune() {
444
+ let sortList = [];
445
+ let allSortItems = [
446
+ {label: "综合", value: "default", menuName: '综合', key: 'common'},
447
+ {label: "销量", value: "sale_num_desc", menuName: '销量', key: 'hot'},
448
+ {label: "价格由高到低", value: "price_desc", menuName: '价格降', key: 'price'},
449
+ {label: "价格由低到高", value: "price_asc", menuName: '价格升', key: 'price'},
450
+ ]
451
+ this.allSortItemsOrg = this.$xdUniHelper.cloneDeep(allSortItems);
452
+
453
+ //综合处理
454
+ if(this.menuItems.includes('common')) sortList.push({label:'综合', value:'common'});
455
+
456
+ //价格处理
457
+ if(this.menuItems.includes('price')) {
458
+ sortList.push({label:'价格', value:'price'});
459
+ allSortItems = allSortItems.filter(item=> item.key !== 'price');
460
+ }
461
+
462
+ //销量处理
463
+ if(this.menuItems.includes('hot')) {
464
+ sortList.push({label:'销量', value:'hot'});
465
+ allSortItems = allSortItems.filter(item=> item.key !== 'hot');
466
+ }
467
+ this.sortList = sortList;
468
+ this.allSortItems = allSortItems;
469
+
470
+ //设置排序默认值
471
+ if(this.defSort){
472
+ this.sort = this.defSort;
473
+ let sortAct = 'common';
474
+ if(this.menuItems.includes('hot') && this.sort === 'sale_num_desc') sortAct = 'hot';
475
+ if(this.menuItems.includes('price') && ['price_desc','price_asc'].includes(this.sort)) sortAct = 'price';
476
+ this.sortAct = sortAct;
477
+ }
478
+
479
+ //其他菜单处理
480
+ let otherNenuItems = this.menuItems.filter(item=>{
481
+ return !(typeof item === 'string' && ['common', 'price', 'hot'].includes(item));
482
+ });
483
+
484
+ this.initSelected(otherNenuItems.map(item=>item.value));
485
+ this.otherNenuItems = otherNenuItems;
486
+ },
487
+ initSelected(nenuItems){
488
+ nenuItems.map(key=>{
489
+ this.$set(this.selectedNenuIds, key, []);
490
+ this.$set(this.selectedNenuItems,key, []);
491
+ this.$set(this.selectedNenuLabels, key, []);
492
+ });
493
+ },
494
+ handleCommonSort(item){
495
+ this.sort = item.value;
496
+ this.closeQueryModal();
497
+ this.update();
498
+ },
499
+ moveHandle(){
500
+ return false
501
+ },
502
+ closeQueryModal(){
503
+ this.showQueryModal = false;
504
+ },
505
+ //==menu====
506
+
507
+ handleNenu(value){
508
+ //排序菜单操作
509
+ if(['common','price','hot'].includes(value)) {
510
+ if(value=== 'hot') {
511
+ this.sort = 'sale_num_desc';
512
+ this.showQueryModal = false;
513
+ this.update();
514
+ }
515
+ if(value === 'price') {
516
+ if(!['price_desc','price_asc'].includes(this.sort)) {
517
+ this.sort = 'price_desc';
518
+ }
519
+ else {
520
+ switch(this.sort) {
521
+ case 'price_desc':
522
+ this.sort = 'price_asc';
523
+ break;
524
+ default:
525
+ this.sort = 'price_desc';
526
+ }
527
+ }
528
+ this.showQueryModal = false;
529
+ this.update();
530
+ }
531
+ if(value === 'common') {
532
+ if(value === this.menuAct) this.showQueryModal = !this.showQueryModal;
533
+ else this.showQueryModal = true;
534
+ }
535
+ this.sortAct = value;
536
+ this.menuAct = value;
537
+ }
538
+
539
+ //其他菜单操作
540
+ else {
541
+ this.initCurrentFilter(value);
542
+
543
+ //点击是当前菜单直接关闭操作
544
+ if(value === this.menuAct) this.showQueryModal = !this.showQueryModal;
545
+ else this.showQueryModal = true;
546
+
547
+ this.menuAct = value;
548
+ }
549
+ },
550
+
551
+ //==其他菜单下拉操作====
552
+ initCurrentFilter(value,isData=false){
553
+ if(this.filterTabsOrg.length === 0) this.filterTabs= [];
554
+ let filterTabs = this.$xdUniHelper.cloneDeep(this.filterTabsOrg);
555
+
556
+ //过滤条件
557
+ if(value === 'filter') {
558
+ if(this.filterFields.length > 0) {
559
+ filterTabs = filterTabs.filter(item=>{
560
+ return !(this.filterFields.includes(item.title) || this.filterFields.includes(item.value))
561
+ })
562
+ }
563
+ let filterTabsNew = this.$xdUniHelper.cloneDeep(filterTabs).map(item =>{
564
+ //私有属性
565
+ if(item.value === undefined || item.value === 'attr'){
566
+ item.value = `attr-${this.$xdUniHelper.randomChar(15)}`;
567
+ item.filter_keys = true;
568
+ }
569
+ else item.filter_keys = false;
570
+ return item
571
+ });
572
+ if(isData) return filterTabsNew;
573
+ else {
574
+ this.filterTabs = this.$xdUniHelper.cloneDeep(filterTabsNew).map(item =>{
575
+ //私有属性
576
+ if(item.value === undefined || item.value === 'attr'){
577
+ item.value = `attr-${this.$xdUniHelper.randomChar(15)}`;
578
+ item.filter_keys = true;
579
+ }
580
+ else item.filter_keys = false;
581
+ return item
582
+ });
583
+ this.isFitler = true
584
+ this.isShowBtn = true
585
+ }
586
+
587
+ }
588
+ //快捷方式
589
+ else {
590
+ this.filterTabs = filterTabs.filter(item=>item.value === value);
591
+ this.isFitler = false;
592
+ if(this.filterTabs.length === 1) this.isShowBtn = this.filterTabs[0]['multiple'];
593
+ else this.isShowBtn = false;
594
+ }
595
+ },
596
+ initFilterData(){
597
+ if(this.remoteList.length === 0) this.filterTabsOrg = [];
598
+ else {
599
+ this.filterTabsOrg = this.$xdUniHelper.cloneDeep(this.remoteList).map(item=>{
600
+ let isOwnAttr = !(item.value.indexOf('attr') === 0);
601
+ //当前菜单不在快捷方式里面时候进行数据初始化
602
+ if(isOwnAttr) {
603
+ let ids = [], items=[], labels = [];
604
+ //有默认值
605
+ if(this.defRemote[item.value] && this.defRemote[item.value].length > 0) {
606
+ this.defRemote[item.value].map(id=>{
607
+ let cur = (item.options||[]).find(item=> id === item.value);
608
+ if(cur) {
609
+ ids.push(cur.value);
610
+ labels.push(cur.label);
611
+ items.push(cur);
612
+ }
613
+ })
614
+ }
615
+ this.$set(this.selectedNenuIds, item.value, ids);
616
+ this.$set(this.selectedNenuItems, item.value, items);
617
+ this.$set(this.selectedNenuLabels, item.value,labels);
618
+ }
619
+ return item;
620
+ });
621
+ }
622
+ },
623
+ onOtherReset(){
624
+ if(this.menuAct === 'filter') {
625
+ let nenuItems = ['filter'];
626
+ this.filterTabs.map(item=>{
627
+ if(item['filter_keys'] === false) nenuItems.push(item.value)
628
+ });
629
+ this.initSelected(nenuItems);
630
+ }
631
+ else {
632
+ this.$set(this.selectedNenuIds, this.menuAct, []);
633
+ this.$set(this.selectedNenuItems, this.menuAct, []);
634
+ this.$set(this.selectedNenuLabels, this.menuAct, []);
635
+ }
636
+ },
637
+ onOtherConfirm(){
638
+ this.update();
639
+ this.closeQueryModal();
640
+ },
641
+ switchOtherOpen(tab){
642
+ this.filterTabs = this.filterTabs.map(item => {
643
+ if(JSON.stringify(tab.value) === JSON.stringify(item.value)) item['open'] = !item['open'];
644
+ return item;
645
+ })
646
+ },
647
+ isOtherActive(tab, value){
648
+ let isOwnAttr = !(tab.value.indexOf('attr-') === 0);
649
+ let saveKey = isOwnAttr ? tab.value : 'filter';
650
+ if(!this.selectedNenuIds[saveKey]) return false
651
+ return this.selectedNenuIds[saveKey].includes(value);
652
+ },
653
+ setSelectMenuOneData(saveKey, ids, items, labels){
654
+ this.$set(this.selectedNenuIds, saveKey, ids);
655
+ this.$set(this.selectedNenuItems, saveKey, items);
656
+ this.$set(this.selectedNenuLabels, saveKey, labels);
657
+ },
658
+ setSelectMenuMoreData(saveKey, item){
659
+ let ids = this.$xdUniHelper.cloneDeep(this.selectedNenuIds[saveKey] || []),
660
+ items = this.$xdUniHelper.cloneDeep(this.selectedNenuItems[saveKey] || []),
661
+ labels = this.$xdUniHelper.cloneDeep(this.selectedNenuLabels[saveKey] || []);
662
+ ids.push(item.value);
663
+ items.push(item);
664
+ labels.push(item.label);
665
+ this.$set(this.selectedNenuIds, saveKey, ids);
666
+ this.$set(this.selectedNenuItems, saveKey, items);
667
+ this.$set(this.selectedNenuLabels, saveKey, labels);
668
+ },
669
+ setUnselectMenu(saveKey,index){
670
+ this.selectedNenuIds[saveKey].splice(index,1);
671
+ this.selectedNenuLabels[saveKey].splice(index,1);
672
+ this.selectedNenuItems[saveKey].splice(index,1);
673
+ },
674
+ setOhterChooseTag(tab, item){
675
+ let isOwnAttr = !(tab.value.indexOf('attr-') === 0);
676
+ let saveKey = isOwnAttr ? tab.value : 'filter';
677
+
678
+ //单选(排除筛选中的单选选项)
679
+ if(isOwnAttr && !tab.multiple) {
680
+ //点击筛选中的单选
681
+ if(this.menuAct === 'filter') {
682
+ //取消选中
683
+ if(item.value === this.selectedNenuIds[tab.value]) {
684
+ this.$set(this.selectedNenuIds, saveKey, '');
685
+ this.$set(this.selectedNenuItems, saveKey, '');
686
+ this.$set(this.selectedNenuLabels, saveKey, '');
687
+ }
688
+ //新增操作
689
+ else {
690
+ this.setSelectMenuOneData(saveKey, item.value, item , item.label);
691
+ }
692
+ return;
693
+ }
694
+ this.setSelectMenuOneData(saveKey, item.value, item , item.label);
695
+ //单选直接触发返回数据
696
+ if(this.isShowBtn === false) this.onOtherConfirm();
697
+ }
698
+
699
+ //多选or筛选菜单中的单选属性
700
+ else {
701
+ let index = this.selectedNenuIds[saveKey].indexOf(item.value);
702
+
703
+ //filter中的单选操作
704
+ if(!tab.multiple) {
705
+ if(index === -1) {
706
+ tab.options.map(it=>{
707
+ let idx = this.selectedNenuIds[saveKey].indexOf(it.value);
708
+ if(idx !== -1) {
709
+ this.setUnselectMenu(saveKey,idx)
710
+ }
711
+ });
712
+ this.setSelectMenuMoreData(saveKey,item);
713
+ }
714
+ else {
715
+ this.setUnselectMenu(saveKey,index)
716
+ }
717
+ return
718
+ }
719
+
720
+ //新增
721
+ if(index === -1) {
722
+ this.setSelectMenuMoreData(saveKey,item)
723
+ }
724
+
725
+ //取消操作
726
+ else {
727
+ this.setUnselectMenu(saveKey,index)
728
+ }
729
+ }
730
+
731
+ },
732
+ //==其他菜单下拉操作====
733
+
734
+ update(){
735
+ let params = {};
736
+ if(this.sort) params['sort'] = this.sort;
737
+ Object.keys(this.selectedNenuIds).map(key=>{
738
+ if(key === 'filter') {
739
+ if( this.selectedNenuIds[key].length > 0) params['filter_keys'] = this.selectedNenuIds[key].join(',');
740
+ }
741
+ else {
742
+ if( this.selectedNenuIds[key].length > 0){
743
+ //单选
744
+ if(typeof this.selectedNenuIds[key] === 'string') params[key] = this.selectedNenuIds[key];
745
+ //多选
746
+ else params[key] = this.selectedNenuIds[key].join(',');
747
+ }
748
+ }
749
+ })
750
+ this.$emit('on-change', {
751
+ sort: this.sort,
752
+ filter:{
753
+ items: this.$xdUniHelper.cloneDeep(this.selectedNenuItems),
754
+ labels: this.$xdUniHelper.cloneDeep(this.selectedNenuLabels),
755
+ ids: this.$xdUniHelper.cloneDeep(this.selectedNenuIds)
756
+ },
757
+ params
758
+ })
759
+ },
760
+
761
+ }
762
+ }
763
+ </script>
764
+
765
+ <style scoped lang="less">
766
+ .jfb-filter {
767
+ position: relative;
768
+ &-placeholder {
769
+ font-size: 20rpx;
770
+ }
771
+ &-menu {
772
+ position: fixed;
773
+ top: 0;
774
+ left: 0;
775
+ right: 0;
776
+ z-index: 100;
777
+ border-top: 1px solid var(--com-menu-border);
778
+ display: flex;
779
+ justify-content: space-around;
780
+ height: 49rpx;
781
+
782
+
783
+ &-item {
784
+ display: flex;
785
+ font-size: unit(28, rpx);
786
+ line-height: unit(48, rpx);
787
+ justify-content: center;
788
+ align-items: center;
789
+ color: #333;
790
+ flex: 1;
791
+
792
+
793
+ //.query_item{
794
+ // display: flex;
795
+ // font-size: unit(28, rpx);
796
+ // line-height: unit(48, rpx);
797
+ // justify-content: center;
798
+ // align-items: center;
799
+ // color: #333;
800
+ // font-weight: 400;
801
+ // flex: 1;
802
+ //
803
+ // & > view {
804
+ // display: flex;
805
+ // justify-content:center;
806
+ // align-items: center;
807
+ // width: unit(40, rpx);
808
+ // height: unit(92, rpx);
809
+ // flex-shrink: 0;
810
+ // }
811
+ // &__sort{
812
+ // flex-direction: column;
813
+ // justify-items: center;
814
+ // align-content: center;
815
+ // line-height: 16rpx;
816
+ // }
817
+ // & > text {
818
+ // flex-shrink: 0;
819
+ // }
820
+ //}
821
+ }
822
+
823
+ &-name {
824
+
825
+ &.fontWeight {
826
+ font-weight: bold;
827
+ }
828
+ }
829
+
830
+ &-icon {
831
+
832
+ & > view {
833
+ height: 100%;
834
+ display: flex;
835
+ align-content: center;
836
+ align-items: center;
837
+ flex-direction: column;
838
+ }
839
+ }
840
+ }
841
+
842
+ &-pop {
843
+ position: fixed;
844
+ z-index: 110;
845
+ left: 0;
846
+ right: 0;
847
+ .xd-query-sort{
848
+ &-item {
849
+ height: 80rpx;
850
+ border-bottom: 1rpx solid var(--com-pop-border);
851
+ line-height: 80rpx;
852
+ padding-left: 80rpx;
853
+ color: #999;
854
+ font-size: 24rpx;
855
+ }
856
+ }
857
+
858
+ .xd-query-filter {
859
+ background-color: #fff;
860
+
861
+ .filter_wrap{
862
+ overflow: auto;
863
+
864
+ .filter_item{
865
+ &:last-child {
866
+ margin-bottom: 0!important;
867
+ }
868
+ }
869
+ .filter_title{
870
+ color: #333333;
871
+ font-size: 28rpx;
872
+ margin-bottom: 1.2rem;
873
+ font-weight: bold;
874
+ display: flex;
875
+ justify-content: space-between;
876
+
877
+ ._ext{
878
+ display: flex;
879
+ align-items: center;
880
+ font-size: 24rpx;
881
+ color: #BBBBBB;
882
+ font-weight: normal;
883
+
884
+ & > text {
885
+ padding-right: unit(10, rpx);
886
+ }
887
+ }
888
+ }
889
+
890
+ .filter_tab{
891
+ display: flex;
892
+ flex-wrap: wrap;
893
+ justify-content: flex-start;
894
+ align-items: center;
895
+
896
+ & > ._tag {
897
+ text-align: center;
898
+ line-height: 62rpx;
899
+ border-radius: 4rpx;
900
+ font-size: 24rpx;
901
+ color: #666;
902
+ text-overflow: ellipsis;
903
+ overflow: hidden;
904
+ white-space: nowrap;
905
+ box-sizing: border-box;
906
+ background-color: #f8f8f8;
907
+ border-width: 2rpx;
908
+ border-style: solid;
909
+ padding: 0 10rpx;
910
+
911
+ &.noMarginRigth{
912
+ margin-right: 0!important;
913
+ }
914
+ &.noMarginTop {
915
+ margin-top: 0!important;
916
+ }
917
+ }
918
+
919
+
920
+ }
921
+
922
+ }
923
+
924
+ .bottom_btn{
925
+ display: flex;
926
+ justify-content: center;
927
+ padding: 16rpx 32rpx;
928
+ border-top: 2rpx solid #f8f8f8;
929
+
930
+ .xd-button{
931
+ margin: 0 32rpx;
932
+ }
933
+ }
934
+ }
935
+
936
+
937
+ }
938
+
939
+ &-mask {
940
+ position: fixed;
941
+ width: 100%;
942
+ height: 100%;
943
+ left: 0;
944
+ right: 0;
945
+ bottom: 0;
946
+ background: rgba(0, 0, 0, .4);
947
+ z-index: 102;
948
+ }
949
+ }
950
+ </style>