jufubao-mall 2.0.35-beta9 → 2.0.35-beta91

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.
@@ -0,0 +1,591 @@
1
+
2
+ <template>
3
+ <view :style="[{'--main-color': mainColor,'--sub-main-color': subMainColor},activeComp]">
4
+ <view class="shopping-ske" v-if="dataShopList ===null">null</view>
5
+ <view
6
+ class="shopping"
7
+ v-else-if="dataShopList.length > 0"
8
+ :style="[cusStyle['box']||{}]"
9
+ >
10
+ <view
11
+ class="shopping-list"
12
+ v-for="(item) in dataShopList"
13
+ :key="item[compMK.id]"
14
+ :id="`shop_item_${item[compMK.id]}`"
15
+ :class="{active: [
16
+ item[compMK.id].toString(),
17
+ item[compMK.shop_id].toString()
18
+ ].includes(selectId)}"
19
+ :style="[cusStyle['item']||{}]"
20
+ @click="handleClick(item, 'DL')"
21
+ >
22
+ <!--图片区域-->
23
+ <view class="shopping-img" v-if="image" :style="[cusStyle['image']||{}]">
24
+ <image v-if="!item.errorStatus" :src="item[compMK.image]" :alt="item[compMK.name]" mode="aspectFit" @error="handleError(item)"></image>
25
+ <image v-if="item.errorStatus" :src="errorImage" :alt="item[compMK.name]"></image>
26
+ </view>
27
+ <!--图片区域-->
28
+ <!--信息区域-->
29
+ <view class="shopping-cont" :class="{noImage: !image}">
30
+ <view class="shopping-cont-nameInfo">
31
+ <view class="shopping-name">
32
+ <view class="name" :style="[cusStyle['name']||{}]" v-html="item[compMK.name]"></view>
33
+ <view
34
+ class="distance"
35
+ v-if="distance && distanceStyle === 'title' && item[compMK.distance]"
36
+ :style="[cusStyle['distance']||{}]"
37
+ >{{item[compMK.distance]}}</view>
38
+ <view class="priceAndDiscount" v-if="distanceStyle === 'button'">
39
+ <view class="price" v-if="price && item[compMK.price]">
40
+ <text>{{item[compMK.price]|filterPrice}}</text>
41
+ <text>起</text>
42
+ </view>
43
+ <view class="discount" v-if="discount && item[compMK.discount]">
44
+ <text>{{item[compMK.discount]|filterDiscount}}</text>
45
+ <text>折</text>
46
+ </view>
47
+ </view>
48
+ </view>
49
+ <view class="shopping-info">
50
+ <view
51
+ class="shopping-address"
52
+ :class="{one: tagPos === 'info'}"
53
+ v-if="address"
54
+ v-html="item[compMK.address]"
55
+ ></view>
56
+ <view class="tags-info" v-if="tagPos === 'info'">
57
+ <view class="tags-info-tag">
58
+ <xd-font-icon icon="iconduihuan" color="#43CF7C" size="28" style="margin-right: 8rpx;"></xd-font-icon>
59
+ <text>支持到店使用</text>
60
+ </view>
61
+ </view>
62
+ </view>
63
+ </view>
64
+ <view class="shopping-btn">
65
+ <!--v3-->
66
+ <view class="distance" v-if="distance && distanceStyle === 'button' && item[compMK.distance]" >
67
+ <xd-font-icon :style="[cusStyle['distance']||{}]" icon="icondizhi" size="26"></xd-font-icon>
68
+ <text :style="[cusStyle['distance']||{}]" style="margin-left: 10rpx" >{{item[compMK.distance]}}</text>
69
+ </view>
70
+ <!--v3-->
71
+ <!--v2-->
72
+ <view v-if="tagPos === 'info'">
73
+ <view class="priceAndDiscount">
74
+ <view class="price" v-if="price && item[compMK.price]">
75
+ <text>{{item[compMK.price]|filterPrice}}</text>
76
+ <text>起</text>
77
+ </view>
78
+ <view class="discount" v-if="discount && item[compMK.discount]">
79
+ <text>{{item[compMK.discount]|filterDiscount}}</text>
80
+ <text>折</text>
81
+ </view>
82
+ </view>
83
+ </view>
84
+ <!--v2-->
85
+ <!--v1-->
86
+ <template v-if="tagPos === 'btn'">
87
+ <view v-if="!isShowBtn" class="tags">
88
+ <view v-for="it in item[compMK.mode]" :key="it" :style="[compTagsStyle]">{{item[compMK.modeName]|filterMode(it)}}</view>
89
+ </view>
90
+ <view class="priceAndDiscount">
91
+ <view class="price" v-if="price && item[compMK.price]">
92
+ <text>{{item[compMK.price]|filterPrice}}</text>
93
+ <text>起</text>
94
+ </view>
95
+ <view class="discount" v-if="discount && item[compMK.discount]">
96
+ <text>{{item[compMK.discount]|filterDiscount}}</text>
97
+ <text>折</text>
98
+ </view>
99
+ </view>
100
+ </template>
101
+ <!--v1-->
102
+ <!--按钮-->
103
+ <view class="buttons" v-if="isShowBtn && isBtn">
104
+ <!-- CV:店员核销(小蜜蜂);WB:用户扫水牌;CR:收银机;POS:POS机;JHD:聚好兑; QP:快捷支付;MC电影去购买-->
105
+ <template v-for="it in item[compMK.mode]">
106
+ <view
107
+ v-if="compEntry[mapCodeKeys[it]] === true"
108
+ class="change_btn"
109
+ @click.stop="handleClick(item, it)"
110
+ >{{ compNames[mapCodeKeys[it]]}}</view>
111
+ </template>
112
+ </view>
113
+ <!--按钮-->
114
+ </view>
115
+ </view>
116
+ <!--信息区域-->
117
+ </view>
118
+ </view>
119
+ <view class="shopping-empty" v-else-if="dataShopList.length === 0"></view>
120
+ </view>
121
+
122
+ </template>
123
+
124
+ <script>
125
+ import XdFontIcon from "@/components/XdFontIcon/XdFontIcon.vue";
126
+ import Color from "color";
127
+ let $vm = null;
128
+
129
+ export default {
130
+ name:'CusShops',
131
+ components:{
132
+ XdFontIcon
133
+ },
134
+ props:{
135
+ list: {
136
+ type: Array|null,
137
+ default(){
138
+ return []
139
+ }
140
+ },
141
+ cusStyle:{
142
+ type: Object,
143
+ // image,item,box,name,distance
144
+ default(){
145
+ return {}
146
+ }
147
+ },
148
+ layout:{
149
+ type: String,
150
+ required: true
151
+ },
152
+ content:{
153
+ type: Array|null,
154
+ default(){
155
+ return ['image', 'address', 'distance', 'discount','price']
156
+ }
157
+ },
158
+ isShowBtn:{
159
+ type:Boolean,
160
+ default: false,
161
+ },
162
+ mainColor:{
163
+ type: String,
164
+ required: true
165
+ },
166
+ subMainColor:{
167
+ type: String,
168
+ required: true
169
+ },
170
+ names:{
171
+ type: Object,
172
+ //jhd,scan,takeGoods,buyTicket,code,hdSelf
173
+ default(){
174
+ return {}
175
+ }
176
+ },
177
+ mapKeys:{
178
+ type:Object,
179
+ default(){
180
+ return {}
181
+ }
182
+ },
183
+ entry:{
184
+ type:Object,
185
+ default(){
186
+ return {}
187
+ }
188
+ },
189
+ selectId:{
190
+ type:String,
191
+ default:''
192
+ }
193
+ },
194
+ data(){
195
+ return {
196
+ distanceStyle:'title',//title:标题后面 button: 操作按钮左侧
197
+ tagPos: 'info', //info=>信息下方 btn: 操作按钮左侧
198
+ errorImage:'https://img0.jufubao.cn/common/empty/shop.png?v1=1',
199
+
200
+ //内容区状态
201
+ image: false,
202
+ address:true,
203
+ distance: false,
204
+ price: false,
205
+ discount: false,
206
+
207
+ //数据键值map关系
208
+ defMapKeys:{
209
+ id: 'resource_shop_id',
210
+ brand_id: 'brand_id',//品牌ID
211
+ shop_id:'shop_id',//整理前的门店ID
212
+ name: 'resource_shop_name', //店铺名字
213
+ distance: 'distance', //距离
214
+ address:'address', //店铺地址
215
+ image:'shop_icon', //店铺图片
216
+ discount : 'discount_ratio', //折扣
217
+ price:'price', //价格
218
+ mode:'consume_mode',//标签类型[]
219
+ modeName:'consume_mode_name',//服务类型名称{CODE:NAME}
220
+ defType:'default_consume_type',
221
+ },
222
+ modeName:{
223
+ CODE:'电子码',
224
+ SELL:'支持核销',
225
+ SEAT:'在线选座',
226
+ TRAVEL:'在线订票',
227
+ HDSELF:'到店自取'
228
+ },
229
+
230
+ mapCodeKeys:{
231
+ CODE:'code',
232
+ SELL: 'cashier',
233
+ SEAT:'buyTicket',
234
+ TRAVEL:'travel',
235
+ HDSELF:'hdSelf'
236
+ },
237
+
238
+ //自定义名称
239
+ defName:{
240
+ cashier:'去买单',
241
+ buyTicket: "去购票", //在选选座
242
+ code:'电子码', //电子码名字
243
+ hdSelf:'到店自取', //到店自取名字
244
+ travel: '去购票 ', //旅游订票
245
+ },
246
+
247
+ defEntry:{
248
+ cashier:false, //支持核销
249
+ buyTicket: false, //去购票名称
250
+ code:false, //电子码名字
251
+ hdSelf:false, //电子码名字
252
+ travel: false, //旅游订票
253
+ },
254
+
255
+ //按钮功能
256
+ buttons:[],
257
+
258
+ dataShopList:null,
259
+ }
260
+ },
261
+ computed:{
262
+ activeComp(){
263
+ let border = `rgba(${Color(this.mainColor).alpha(0.6).array().join(',')})`;
264
+ let bgColor= `rgba(${Color(this.mainColor).alpha(.05).array().join(',')})`;
265
+ return {
266
+ '--xd-bgColor': bgColor,
267
+ '--xd-border': `1px solid ${border}`
268
+ }
269
+ },
270
+
271
+ compTagsStyle(){
272
+ let textColor = `rgba(${Color(this.mainColor).alpha(0.1).array().join(',')})`;
273
+ return {
274
+ backgroundColor: textColor,
275
+ color: this.mainColor,
276
+ }
277
+ },
278
+
279
+ compNames(){
280
+ return Object.assign({}, this.defName,this.$xdUniHelper.cloneDeep(this.names) )
281
+ },
282
+ compMK(){
283
+ return Object.assign({},this.defMapKeys,this.$xdUniHelper.cloneDeep(this.mapKeys))
284
+ },
285
+ compEntry(){
286
+ return Object.assign({},this.defEntry,this.$xdUniHelper.cloneDeep(this.entry))
287
+ },
288
+ isBtn(){
289
+ let flag = false;
290
+ Object.keys(this.compEntry).map(key=>{
291
+ if(this.compEntry[key] === true) flag = true;
292
+ });
293
+ return flag
294
+ }
295
+ },
296
+ filters:{
297
+ filterPrice(val){
298
+ if(typeof val === 'string') val = Number(val)
299
+ return $vm.$xdUniHelper.divisionFloatNumber(val,100);
300
+ },
301
+ filterDiscount(val){
302
+ if(typeof val === 'string') val = Number(val)
303
+ return $vm.$xdUniHelper.divisionFloatNumber(val,1000);
304
+ },
305
+ filterMode(value, code){
306
+ if(!value) return $vm.modeName[code];
307
+ return value[code];
308
+ }
309
+ },
310
+ watch:{
311
+ layout(val){
312
+ this.layoutParse(val)
313
+ },
314
+ content(val){
315
+ this.contentParse(val)
316
+ },
317
+ list(){
318
+ this.initData();
319
+ },
320
+ },
321
+ created() {
322
+ $vm = this;
323
+ this.layoutParse(this.layout);
324
+ this.contentParse(this.content);
325
+ this.initData();
326
+ },
327
+ methods:{
328
+ initData(){
329
+ if(this.list === null) this.dataShopList = null;
330
+ else if(this.$xdUniHelper.checkVarType(this.list) === 'array'){
331
+ this.dataShopList = this.$xdUniHelper.cloneDeep(this.list).map(item=>{
332
+ item[this.compMK['mode']] = item[this.compMK['mode']].filter(it=>{
333
+ return this.mapCodeKeys[it];
334
+ });
335
+ item['is_detail_to_btn'] = this.isShowBtn && item[this.compMK['mode']].length === 1;
336
+ if(item['errorStatus'] === undefined) item['errorStatus'] = false;
337
+ return item
338
+ });
339
+ }
340
+ else this.dataShopList = [];
341
+ },
342
+ handleError(item){
343
+ item.errorStatus = true;
344
+ },
345
+ layoutParse(value){
346
+ let distanceStyle = 'title';
347
+ let tagPos = '';
348
+
349
+ //布局1
350
+ if(['v1'].includes(value)) {
351
+ tagPos = 'btn'
352
+ }
353
+
354
+ //布局2
355
+ if(['v2'].includes(value)) {
356
+ tagPos = 'info'
357
+ }
358
+
359
+ //电影模式
360
+ if(['v3'].includes(value)) {
361
+ distanceStyle = 'button';
362
+ }
363
+ this.tagPos = tagPos;
364
+ this.distanceStyle = distanceStyle;
365
+ },
366
+ contentParse(value){
367
+ this.image = value.includes('image')
368
+ this.address = value.includes('address')
369
+ this.distance = value.includes('distance')
370
+ //价格和折扣只有在v1,v2线上
371
+ this.price = value.includes('price')
372
+ this.discount = value.includes('discount')
373
+ },
374
+
375
+ /**
376
+ * @description 事件操作
377
+ * @param item {Object} 数据对象
378
+ * @param type {string} 类型
379
+ */
380
+ handleClick(item, type) {
381
+ //当只有一个服务器点击详情直接进入服务
382
+ if(item.is_detail_to_btn === true) type = item[this.compMK['mode']][0]
383
+ this.$emit('on-event', {item,type});
384
+ }
385
+ }
386
+ }
387
+
388
+ </script>
389
+ <style scoped lang="less">
390
+ .shopping {
391
+ &-list {
392
+ background-color: #fff;
393
+ display: flex;
394
+ justify-content: space-between;
395
+ align-items: flex-start;
396
+
397
+ &:first-child {
398
+ margin-top: 0;
399
+ }
400
+
401
+ &.active {
402
+ background-color: var(--xd-bgColor)!important;
403
+ border: var(--xd-border)!important;
404
+ }
405
+ }
406
+ &-img {
407
+ width: 200rpx;
408
+ height: 200rpx;
409
+ margin-right: 16rpx;
410
+ flex-shrink: 0;
411
+ overflow: hidden;
412
+
413
+ & > image {
414
+ width: 200rpx;
415
+ height: 200rpx;
416
+ }
417
+ }
418
+
419
+ &-cont {
420
+ flex: 1;
421
+ display: flex;
422
+ flex-wrap: wrap;
423
+ align-content: space-between;
424
+ min-height: 200rpx;
425
+ justify-items: flex-end;
426
+
427
+
428
+ // #ifdef MP-WEIXIN
429
+ &-nameInfo {
430
+ width: 100%;
431
+ }
432
+
433
+ & > .shopping-btn {
434
+ width: 100%;
435
+ }
436
+ // #endif
437
+
438
+
439
+ &.noImage {
440
+ min-height: 0;
441
+ align-content: normal;
442
+ display: block;
443
+
444
+ & .shopping-btn {
445
+ margin-top: 16rpx;
446
+ }
447
+ }
448
+
449
+ & > * {
450
+ width: 100%;
451
+ flex-shrink: 0;
452
+ }
453
+ }
454
+
455
+ &-name {
456
+ display: flex;
457
+ justify-content: flex-start;
458
+ align-items: center;
459
+ & .name {
460
+ font-size: 32rpx;
461
+ font-weight: 400;
462
+ line-height: 1.5;
463
+ .uni-cut(1,48);
464
+ flex: 1;
465
+ color: #333;
466
+ word-wrap: break-word;
467
+ word-break: break-all;
468
+ }
469
+
470
+ & .distance {
471
+ margin-left: 20rpx;
472
+ font-size: 24rpx;
473
+ color: #999;
474
+ }
475
+ }
476
+
477
+ &-info {
478
+ & .tags-info {
479
+ margin-top: 16rpx;
480
+ display: flex;
481
+ flex-flow: wrap;
482
+ justify-content: flex-start;
483
+ &-tag {
484
+ display: flex;
485
+ justify-content: flex-start;
486
+ align-items: center;
487
+ font-size: 24rpx;
488
+ color: #999;
489
+ flex-shrink: 0;
490
+ margin-top: 10rpx;
491
+
492
+ width: 45%;
493
+ margin-right: 10%;
494
+ &:nth-child(2n) {
495
+ margin-right: 0;
496
+ }
497
+
498
+ &:nth-child(1), &:nth-child(2) {
499
+ margin-top: 0;
500
+ }
501
+ }
502
+ }
503
+ }
504
+
505
+ &-address {
506
+ margin-top: 16rpx;
507
+ font-size: 24rpx;
508
+ color: #999;
509
+ line-height: 1.5em;
510
+ word-wrap: break-word;
511
+ word-break: break-all;
512
+ .uni-max-cut(2,72);
513
+
514
+ &.one {
515
+ .uni-max-cut(1,36);
516
+ }
517
+ }
518
+
519
+ &-btn {
520
+ display: flex;
521
+ justify-content: space-between;
522
+ align-items: center;
523
+ margin-top: 16rpx;
524
+
525
+ & .distance {
526
+ display: flex;
527
+ justify-items: flex-start;
528
+ flex-shrink: 0;
529
+ font-size: 24rpx;
530
+ color: #999;
531
+ }
532
+
533
+ & .tags {
534
+ display: flex;
535
+ justify-content: flex-start;
536
+ align-items: center;
537
+ & > view {
538
+ font-size: 24rpx;
539
+ height: 42rpx;
540
+ line-height: 42rpx;
541
+ border-radius: 12rpx;
542
+ padding: 0 16rpx;
543
+ margin-right: 16rpx;
544
+ &:last-child {
545
+ margin-right: 0;
546
+ }
547
+ }
548
+
549
+ }
550
+
551
+ & .buttons {
552
+ display: flex;
553
+ justify-content: flex-end;
554
+ align-items: center;
555
+ & .change_btn{
556
+ padding: 0 16rpx;
557
+ height: 48rpx;
558
+ line-height: 48rpx;
559
+ border-radius: 24rpx;
560
+ background-color: var(--main-color);
561
+ font-size: 24rpx;
562
+ flex-shrink: 0;
563
+ color: #fff;
564
+ & + .change_btn{
565
+ margin-left: 10rpx;
566
+ }
567
+
568
+ &.code {
569
+ background-color: var(--sub-main-color);
570
+ }
571
+ }
572
+ }
573
+ }
574
+
575
+ & .priceAndDiscount{
576
+ & > .price, & > .discount {
577
+ font-size: 24rpx;
578
+ & > text {
579
+ &:first-child {
580
+ color: rgb(255, 44, 24)
581
+ }
582
+ &:last-child {
583
+ color: #999;
584
+ margin-left: 4rpx;
585
+ }
586
+ }
587
+
588
+ }
589
+ }
590
+ }
591
+ </style>