cyy-vue-material 7.0.19 → 7.0.21

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 (38) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +34 -34
  3. package/src/App.vue +149 -149
  4. package/src/api/http.js +16 -16
  5. package/src/api/index.js +21 -21
  6. package/src/api/urlQuery.js +20 -20
  7. package/src/common/js/constant.js +5 -5
  8. package/src/common/js/index.js +1 -1
  9. package/src/components/vop-label.vue +29 -29
  10. package/src/index.dev.js +4 -4
  11. package/src/package/cyy-ArsenalActivity/components/u-cont-down.vue +316 -316
  12. package/src/package/cyy-ArsenalActivity/components/u-line-progress.vue +150 -150
  13. package/src/package/cyy-ArsenalActivity/cyy-ArsenalActivity.vue +820 -820
  14. package/src/package/cyy-ArsenalCarousel/cyy-ArsenalCarousel.vue +137 -137
  15. package/src/package/cyy-ArsenalClass/cyy-ArsenalClass.vue +564 -564
  16. package/src/package/cyy-ArsenalMyNavigation/cyy-ArsenalMyNavigation.vue +128 -125
  17. package/src/package/cyy-ArsenalMyTop/cyy-ArsenalMyTop.vue +211 -211
  18. package/src/package/cyy-ArsenalNavigation/cyy-ArsenalNavigation.vue +236 -236
  19. package/src/package/cyy-ArsenalPicture/cyy-ArsenalPicture.vue +228 -228
  20. package/src/package/cyy-ArsenalPromotion/cyy-ArsenalPromotion.vue +913 -899
  21. package/src/package/cyy-ArsenalRecommend/cyy-ArsenalRecommend.vue +56 -56
  22. package/src/package/cyy-ArsenalTop/cyy-ArsenalTop.vue +328 -328
  23. package/src/package/cyy-collocation/cyy-collocation.vue +639 -639
  24. package/src/package/cyy-goods/cyy-goods.vue +317 -317
  25. package/src/package/cyy-goodsOne/consult.vue +267 -267
  26. package/src/package/cyy-goodsOne/cyy-goodsOne.vue +217 -217
  27. package/src/package/cyy-image/cyy-image.vue +64 -64
  28. package/src/package/cyy-live/cyy-live.vue +196 -196
  29. package/src/package/cyy-new-product/cyy-new-product.vue +834 -834
  30. package/src/package/cyy-notice/cyy-notice.vue +137 -137
  31. package/src/package/cyy-search/cyy-search.vue +57 -57
  32. package/src/package/cyy-slider/cyy-slider.vue +117 -117
  33. package/src/package/cyy-title/cyy-title.vue +38 -38
  34. package/src/package/cyy-video/cyy-video.vue +49 -49
  35. package/src/package/index.js +21 -21
  36. package/src/utils/checkEnv.js +16 -16
  37. package/src/utils/fetchFactory.js +100 -100
  38. package/src/utils/index.js +2 -2
@@ -1,834 +1,834 @@
1
- //新品专区
2
- <template>
3
- <div>
4
- <div v-if="!listArr.length && !isLc"></div>
5
- <div
6
- v-else
7
- :style="{
8
- margin: `${props.marginTop}px 0 ${props.marginBottom}px 0`,
9
- backgroundColor: `${props.backgroundColor}`,
10
- borderRadius: `${props.borderRadius}px`,
11
- }"
12
- >
13
- <div v-if="props.title || props.subTitle" class="new-product-header">
14
- <div class="header-title">{{ props.title }}</div>
15
- <div class="header-subtitle" @click="goMoreGoods()">{{ props.subTitle }}</div>
16
- </div>
17
-
18
- <template v-if="listArr.length">
19
- <template v-if="props.arrange === 3">
20
- <!--低代码端的左右滑动-->
21
- <div v-if="isLc" ref="lcSwiper" class="new-product-swiper lc-swiper" @scroll="handleLcScroll">
22
- <div class="lc-swiper-track">
23
- <div
24
- v-for="page in groupedList"
25
- :key="page.pageKey"
26
- class="new-product-page"
27
- style="gap:10px"
28
- >
29
- <div
30
- v-for="item in page.items"
31
- :key="item.renderKey"
32
- :class="['cube-item', { 'is-placeholder': item.isPlaceholder }]"
33
- @click="!item.isPlaceholder && goGoodsDetail(item)"
34
- :style="{ borderRadius: `${props.borderRadius}px`,marginBottom:`${props.marginBottom}px`,marginTop:`${props.marginTop}px`}"
35
- >
36
- <template v-if="!item.isPlaceholder">
37
- <div class="imgWrapper">
38
- <div
39
- v-if="isLc === false && (item.goodsSupplynum <= 0 || item.goodsProperty5 === '1')"
40
- class="imgMarked"
41
- >
42
- <div class="maskState">
43
- {{ getMaskState(item.goodsProperty5) }}
44
- </div>
45
- </div>
46
- <img
47
- class="goodsImg"
48
- :src="getGoodsImg(item)"
49
- alt=""
50
- :style="{ borderRadius: `${props.borderRadius}px` }"
51
- />
52
- </div>
53
-
54
- <div class="goodsDescription">
55
- <div class="goodsName">{{ item.goodsName }}</div>
56
- <section class="footerContent">
57
- <div class="goodsPrice">
58
- ¥{{ item.pricesetNprice }}
59
- <div class="scribing" v-if="props.markedPrice === 1">¥{{ item.pricesetMakeprice }}</div>
60
- </div>
61
- <div class="goodsBuy" @click.stop="goGoodsDetail(item)">立即购买</div>
62
- </section>
63
- </div>
64
- </template>
65
- </div>
66
- </div>
67
- </div>
68
- </div>
69
-
70
- <!--小程序的左右滑动-->
71
- <swiper
72
- v-else
73
- class="new-product-swiper mp-swiper"
74
- :current="currentPage"
75
- :autoplay="autoPlayResult"
76
- :interval="props.autoplayInterval || 1500"
77
- :circular="groupedList.length > 1"
78
- :indicator-dots="false"
79
- @change="handleSwiperChange"
80
- >
81
- <swiper-item v-for="page in groupedList" :key="page.pageKey">
82
- <div class="new-product-page" style="gap:10px">
83
- <div
84
- v-for="item in page.items"
85
- :key="item.renderKey"
86
- :class="['cube-item', { 'is-placeholder': item.isPlaceholder }]"
87
- @click="!item.isPlaceholder && goGoodsDetail(item)"
88
- :style="{ borderRadius: `${props.borderRadius}px`,marginBottom:`${props.marginBottom}px`,marginTop:`${props.marginTop}px`}"
89
- >
90
- <template v-if="!item.isPlaceholder">
91
- <div class="imgWrapper">
92
- <div
93
- v-if="isLc === false && (item.goodsSupplynum <= 0 || item.goodsProperty5 === '1')"
94
- class="imgMarked"
95
- >
96
- <div class="maskState">
97
- {{ getMaskState(item.goodsProperty5) }}
98
- </div>
99
- </div>
100
- <img
101
- class="goodsImg"
102
- :src="getGoodsImg(item)"
103
- alt=""
104
- :style="{ borderRadius: `${props.borderRadius}px` }"
105
- />
106
- </div>
107
-
108
- <div class="goodsDescription">
109
- <div class="goodsName">{{ item.goodsName }}</div>
110
- <section class="footerContent">
111
- <div class="goodsPrice">
112
- ¥{{ item.pricesetNprice }}
113
- <div class="scribing" v-if="props.markedPrice === 1">¥{{ item.pricesetMakeprice }}</div>
114
- </div>
115
- <div class="goodsBuy" @click.stop="goGoodsDetail(item)">立即购买</div>
116
- </section>
117
- </div>
118
- </template>
119
- </div>
120
- </div>
121
- </swiper-item>
122
- </swiper>
123
-
124
- <div v-if="groupedList.length > 1" class="swiper-dots">
125
- <div
126
- v-for="(page, index) in groupedList"
127
- :key="page.pageKey"
128
- :class="['swiper-dot', { active: currentPage === index }]"
129
- @click="goToPage(index)"
130
- ></div>
131
- </div>
132
- </template>
133
-
134
- <div
135
- v-else
136
- :class="['cube-container', `arrange-${props.arrange}`]"
137
- >
138
- <div
139
- v-for="item in normalizedList"
140
- :key="item.renderKey"
141
- class="cube-item"
142
- @click="goGoodsDetail(item)"
143
- :style="{ borderRadius: `${props.borderRadius}px`,marginBottom:`${props.marginBottom}px`,marginTop:`${props.marginTop}px` }"
144
- >
145
- <div class="imgWrapper">
146
- <div
147
- v-if="isLc === false && (item.goodsSupplynum <= 0 || item.goodsProperty5 === '1')"
148
- class="imgMarked"
149
- >
150
- <div class="maskState">
151
- {{ getMaskState(item.goodsProperty5) }}
152
- </div>
153
- </div>
154
- <img
155
- class="goodsImg"
156
- :src="getGoodsImg(item)"
157
- alt=""
158
- :style="{ borderRadius: `${props.borderRadius}px` }"
159
- />
160
- </div>
161
-
162
- <div class="goodsDescription">
163
- <div v-if="isLc === true && props.arrange === 2" class="specialGoodsName">{{ item.goodsName }}</div>
164
- <div v-else class="goodsName">{{ item.goodsName }}</div>
165
- <section class="footerContent">
166
- <div class="goodsPrice">
167
- ¥{{ item.pricesetNprice }}
168
- <div class="scribing" v-if="props.markedPrice === 1">¥{{ item.pricesetMakeprice }}</div>
169
- </div>
170
- <div class="goodsBuy" @click.stop="goGoodsDetail(item)">立即购买</div>
171
- </section>
172
- </div>
173
- </div>
174
- </div>
175
- </template>
176
- </div>
177
- </div>
178
- </template>
179
-
180
- <script>
181
- import { querySkuFromJm, find } from "../../api/index.js";
182
- import { isLc, getUrl } from "../../utils/index.js";
183
- import { get, orderBy } from "lodash-es";
184
-
185
- export default {
186
- name: "cyy-new-product",
187
- props: {
188
- props: {
189
- goods: Array,
190
- SelectGoods: Object,
191
- arrange: Number,
192
- borderRadius: Number,
193
- margin: Number,
194
- markedPrice: Number,
195
- marginTop: Number,
196
- marginBottom: Number,
197
- creatDate: String,
198
- priceRange: String,
199
- goodsType: String,
200
- title: String,
201
- subTitle: String,
202
- backgroundColor: String,
203
- channelCode: String,
204
- autoPlay: Number,
205
- autoplayInterval: Number,
206
- channelCode:Number
207
- },
208
- },
209
- data() {
210
- return {
211
- listArr: [],
212
- currentPage: 0,
213
- noDataStyle: {
214
- width: "100%",
215
- height: "180px",
216
- lineHeight: "180px",
217
- fontSize: "30px",
218
- backgroundColor: "#ccc",
219
- color: "#aaa",
220
- textAlign: "center",
221
- },
222
- domainNameUrl: "",
223
- isLc: isLc,
224
- };
225
- },
226
- computed: {
227
- wrapperStyle() {
228
- return {
229
- margin: `${this.props.marginTop}px 0 ${this.props.marginBottom}px 0`,
230
- backgroundColor: this.props.backgroundColor,
231
- borderRadius: `${this.props.borderRadius}px`,
232
- };
233
- },
234
- filterKey() {
235
- return (this.props.creatDate || "") + "|" + (this.props.priceRange || "") + "|" + (this.props.goodsType || "");
236
- },
237
- normalizedList() {
238
- return this.listArr.map((item, index) => ({
239
- ...item,
240
- renderKey: this.getGoodsUniqueKey(item) || `goods-${index}`,
241
- isPlaceholder: false,
242
- }));
243
- },
244
- groupedList() {
245
- if (this.props.arrange !== 3) {
246
- return [];
247
- }
248
- const result = [];
249
- const pageSize = 3;
250
- for (let i = 0; i < this.normalizedList.length; i += pageSize) {
251
- const pageIndex = Math.floor(i / pageSize);
252
- const items = this.normalizedList.slice(i, i + pageSize);
253
- while (items.length < pageSize) {
254
- items.push({
255
- renderKey: `placeholder-${pageIndex}-${items.length}`,
256
- isPlaceholder: true,
257
- });
258
- }
259
- result.push({
260
- pageKey: `page-${pageIndex}`,
261
- items,
262
- });
263
- }
264
- return result;
265
- },
266
- autoPlayResult() {
267
- return !this.isLc && this.props.arrange === 3 && this.props.autoPlay === 0 && this.groupedList.length > 1;
268
- },
269
- },
270
- mounted() {
271
- this.init();
272
- },
273
- watch: {
274
- filterKey() {
275
- this.init();
276
- },
277
- listArr() {
278
- this.resetCurrentPage();
279
- },
280
- "props.arrange"() {
281
- this.resetCurrentPage();
282
- },
283
- },
284
- methods: {
285
- resetCurrentPage() {
286
- this.currentPage = 0;
287
- this.$nextTick(() => {
288
- const el = this.$refs.lcSwiper;
289
- if (el && typeof el.scrollTo === "function") {
290
- el.scrollTo({
291
- left: 0,
292
- behavior: "auto",
293
- });
294
- }
295
- });
296
- },
297
- handleLcScroll(e) {
298
- const el = e.target;
299
- const width = el.clientWidth || 1;
300
- this.currentPage = Math.round(el.scrollLeft / width);
301
- },
302
- handleSwiperChange(e) {
303
- this.currentPage = e.detail.current || 0;
304
- },
305
- goToPage(index) {
306
- if (index < 0 || index >= this.groupedList.length) {
307
- return;
308
- }
309
- if (this.isLc) {
310
- const el = this.$refs.lcSwiper;
311
- if (!el) {
312
- return;
313
- }
314
- const width = el.clientWidth || 0;
315
- el.scrollTo({
316
- left: width * index,
317
- behavior: "smooth",
318
- });
319
- }
320
- this.currentPage = index;
321
- },
322
- getGoodsUniqueKey(item) {
323
- return item?.goodsCode || item?.skuCode || item?.goodsNo || "";
324
- },
325
- deduplicateGoodsList(list = []) {
326
- const result = [];
327
- const seen = new Set();
328
- list.forEach((item) => {
329
- if (!item) {
330
- return;
331
- }
332
- const key = this.getGoodsUniqueKey(item);
333
- if (!key || seen.has(key)) {
334
- return;
335
- }
336
- seen.add(key);
337
- result.push(item);
338
- });
339
- return result;
340
- },
341
- getGoodsImg(item) {
342
- if (!item.dataPic) {
343
- return "";
344
- }
345
- return item.dataPic.indexOf("http") === -1 ? this.domainNameUrl + item.dataPic : item.dataPic;
346
- },
347
- goMoreGoods() {
348
- if (isLc) {
349
- return;
350
- }
351
- const goodsCodes = this.listArr.map((item) => item.goodsCode).join(",");
352
- this.$routers.push("/pages/goodsList/main", {
353
- goodsCode: goodsCodes,
354
- page: "1",
355
- rows: "200",
356
- order:"asc",
357
- sortField:"pricesetNprice"
358
- });
359
- },
360
- formatDate(date) {
361
- const y = date.getFullYear();
362
- const m = String(date.getMonth() + 1).padStart(2, "0");
363
- const d = String(date.getDate()).padStart(2, "0");
364
- return `${y}-${m}-${d}`;
365
- },
366
- parseCreatDate(creatDate) {
367
- if (!creatDate) return {};
368
- try {
369
- const cfg = JSON.parse(creatDate);
370
- if (cfg.type === "days") {
371
- const now = new Date();
372
- const start = new Date(now.getTime() - Number(cfg.value) * 24 * 60 * 60 * 1000);
373
- return {
374
- gmtCreateQstart: this.formatDate(start),
375
- gmtCreateQend: this.formatDate(now),
376
- };
377
- }
378
- if (cfg.type === "range") {
379
- //如果没用设置截止时间,就将今天的时间=截止时间
380
- if(!cfg.start){
381
- return{};
382
- }
383
- const today=this.formatDate(new Date());
384
- return {
385
- gmtCreateQstart: cfg.start,
386
- gmtCreateQend: cfg.end || today,
387
- };
388
- }
389
- } catch (e) {
390
- console.error("时间解析错误", e);
391
- return {};
392
- }
393
- return {};
394
- },
395
- parsePriceRange(priceRange) {
396
- if (!priceRange) return {};
397
- try {
398
- const range = JSON.parse(priceRange);
399
- return {
400
- pricesetNpriceQmin: range.min || "",
401
- pricesetNpriceQmax: range.max || "",
402
- // pricesetNpriceQmin: range.min !== "" && range.min != null ? range.min : "",
403
- // pricesetNpriceQmax: range.max !== "" && range.max != null ? range.max : "",
404
- };
405
- } catch (e) {
406
- console.error("价格解析错误", e);
407
- return {};
408
- }
409
- },
410
- async init() {
411
- this.domainNameUrl = getUrl(this);
412
- const { creatDate, priceRange, goodsType, channelCode } = this.props;
413
- if (!creatDate || !goodsType) {
414
- this.listArr = [];
415
- return;
416
- }
417
-
418
- const dateParams = this.parseCreatDate(creatDate);
419
- const priceParams = this.parsePriceRange(priceRange);
420
- const baseParams = {
421
- rows: "200",
422
- page: "1",
423
- ...dateParams,
424
- ...priceParams,
425
- goodsDataState:"2",
426
- isNewArrival: 1,
427
- channelCode,
428
- };
429
-
430
- if (goodsType) {
431
- baseParams.goodsType = goodsType;
432
- }
433
- if (channelCode) {
434
- baseParams.channelCode = channelCode;
435
- }
436
-
437
- let res;
438
- if (isLc) {
439
- const urlParams = new URLSearchParams(window.location.hash.split("?")[1] || window.location.search);
440
- const hashChannelCode = urlParams.get("channelCode") || "";
441
- if (hashChannelCode) {
442
- baseParams.channelCode = hashChannelCode;
443
- }
444
- const queryStr = new URLSearchParams(baseParams).toString();
445
- const headers = {
446
- "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
447
- "saas-token": localStorage.getItem("saas-token"),
448
- };
449
- res = await fetch(process.env.REACT_APP_BASE_URL + querySkuFromJm + "&" + queryStr, {
450
- method: "GET",
451
- headers,
452
- credentials: "include",
453
- })
454
- .then((r) => r.json())
455
- .catch((e) => {
456
- console.log("接口请求错误", e);
457
- return {};
458
- });
459
- } else {
460
- const firstRes = await this.http.get(querySkuFromJm, baseParams);
461
- const firstList = this.deduplicateGoodsList(get(firstRes, "list", []));
462
- if (!firstList.length) {
463
- this.listArr = [];
464
- return;
465
- }
466
- const goodsCodeList = firstList.map((item) => item.goodsCode).filter(Boolean);
467
- const goodsCode = goodsCodeList.join(",");
468
- if (!goodsCode) {
469
- this.listArr = [];
470
- return;
471
- }
472
- res = await this.http.get(find + "?rows=200&page=1",
473
- { goodsCode,
474
- dataState: "2",
475
- order:"asc",
476
- sortField:"pricesetNprice"
477
- });
478
- const findList = this.deduplicateGoodsList(get(res, "list", []));
479
- const sortedArrays = [];
480
- goodsCodeList.forEach((code) => {
481
- const matchedItem = findList.find((item) => item.goodsCode === code);
482
- if (matchedItem) {
483
- sortedArrays.push(matchedItem);
484
- }
485
- });
486
- res = { list: sortedArrays };
487
- }
488
- this.listArr = this.deduplicateGoodsList(get(res, "list", []));
489
- },
490
- goGoodsDetail(item) {
491
- if (isLc) {
492
- return;
493
- }
494
- const { skuCode } = item;
495
- this.$routers.push("detail", {
496
- skuNo: skuCode,
497
- });
498
- },
499
- getMaskState(state) {
500
- if (state === "1") {
501
- return "预售中";
502
- }
503
- return "补货中";
504
- },
505
- },
506
- };
507
- </script>
508
-
509
- <style lang="less" scoped>
510
- .new-product-header {
511
- display: flex;
512
- justify-content: space-between;
513
- align-items: center;
514
- padding: 12px 16px;
515
-
516
- .header-title {
517
- font-size: 18px;
518
- font-weight: 600;
519
- color: #333;
520
- }
521
-
522
- .header-subtitle {
523
- font-size: 14px;
524
- color: #999;
525
- }
526
- }
527
-
528
- .new-product-swiper {
529
- width: 100%;
530
- }
531
-
532
- .mp-swiper {
533
- height: 220px;
534
- }
535
-
536
- .lc-swiper {
537
- overflow-x: auto;
538
- overflow-y: hidden;
539
- scroll-snap-type: x mandatory;
540
- -webkit-overflow-scrolling: touch;
541
- scrollbar-width: none;
542
- }
543
-
544
- .lc-swiper::-webkit-scrollbar {
545
- display: none;
546
- }
547
-
548
- .lc-swiper-track {
549
- display: flex;
550
- }
551
-
552
- .new-product-page {
553
- width: 100%;
554
- min-width: 100%;
555
- box-sizing: border-box;
556
- display: grid;
557
- gap:10px;
558
- grid-template-columns: repeat(3, minmax(0, 1fr));
559
- align-items: start;
560
- margin: 0 5px;
561
-
562
- .cube-item {
563
- background: #fff;
564
- padding-bottom: 10px;
565
- min-width: 0;
566
- &.is-placeholder {
567
- background: transparent;
568
- pointer-events: none;
569
- }
570
- }
571
-
572
- .goodsImg {
573
- width: 100%;
574
- height: 100px;
575
- aspect-ratio: 1;
576
- display: block;
577
- }
578
-
579
- .goodsDescription {
580
- position: relative;
581
-
582
- .goodsName {
583
- font-size: 13px;
584
- height: 36px;
585
- }
586
-
587
- .footerContent {
588
- flex-direction: column;
589
- align-items: stretch;
590
-
591
- .goodsPrice {
592
- font-size: 13px;
593
- text-align: left;
594
- margin-bottom: 4px;
595
-
596
- .scribing {
597
- font-size: 11px;
598
- }
599
- }
600
-
601
- .goodsBuy {
602
- align-self: center;
603
- width: 5em;
604
- font-size: 12px;
605
- line-height: 22px;
606
- border-radius: 15px;
607
- background-color: red;
608
- color: white;
609
- text-align: center;
610
- }
611
- }
612
- }
613
- }
614
-
615
- .swiper-dots {
616
- display: flex;
617
- justify-content: center;
618
- align-items: center;
619
- padding: 8px 0 4px;
620
- }
621
-
622
- .swiper-dot {
623
- width: 8px;
624
- height: 8px;
625
- border-radius: 50%;
626
- background: #d9d9d9;
627
- margin: 0 4px;
628
- }
629
-
630
- .swiper-dot.active {
631
- background: #333;
632
- }
633
-
634
- .cube-container {
635
- display: grid;
636
-
637
- &.arrange-1 {
638
- grid-template-columns: repeat(1, 1fr);
639
-
640
- .cube-item {
641
- background: #fff;
642
-
643
- .goodsImg {
644
- width: 100%;
645
- height: 100%;
646
- aspect-ratio: 1;
647
- margin-left: auto;
648
- margin-right: auto;
649
- }
650
-
651
- .goodsDescription {
652
- .goodsName {
653
- font-size: 20px;
654
- }
655
-
656
- .footerContent {
657
- .goodsPrice {
658
- font-size: 18px;
659
-
660
- .scribing {
661
- font-size: 14px;
662
- }
663
- }
664
- }
665
- }
666
- }
667
- }
668
-
669
- &.arrange-2 {
670
- grid-template-columns: repeat(2, 1fr);
671
-
672
- .cube-item {
673
- background: #fff;
674
- margin: 0 5px;
675
-
676
- .goodsImg {
677
- width: 100%;
678
- height: 100%;
679
- aspect-ratio: 1;
680
- }
681
-
682
- .goodsDescription {
683
- position: relative;
684
-
685
- .goodsName {
686
- font-size: 16px;
687
- height: 42px;
688
- width: 41vw;
689
- }
690
-
691
- .specialGoodsName {
692
- font-size: 12px;
693
- height: 42px;
694
- }
695
-
696
- .footerContent {
697
- .goodsPrice {
698
- font-size: 14px;
699
-
700
- .scribing {
701
- font-size: 12px;
702
- }
703
- }
704
- }
705
- }
706
- }
707
- }
708
-
709
- &.arrange-5 {
710
- box-sizing: border-box;
711
- display: grid;
712
- grid-template-columns: repeat(3, minmax(0, 1fr));
713
-
714
- .cube-item {
715
- background: #fff;
716
- padding-bottom: 10px;
717
- margin: 0 5px;
718
- width: 107px;
719
- height: 189px;
720
-
721
-
722
- .goodsImg {
723
- width: 100%;
724
- height: 100px;
725
- aspect-ratio: 1;
726
- }
727
-
728
- .goodsDescription {
729
- position: relative;
730
-
731
- .goodsName {
732
- font-size: 13px;
733
- height: 36px;
734
- }
735
-
736
- .footerContent {
737
- flex-direction: column;
738
- align-items: stretch;
739
-
740
- .goodsPrice {
741
- font-size: 13px;
742
- text-align: left;
743
- margin-bottom: 4px;
744
-
745
- .scribing {
746
- font-size: 11px;
747
- }
748
- }
749
-
750
- .goodsBuy {
751
- align-self: center;
752
- width: 5em;
753
- font-size: 12px;
754
- line-height: 22px;
755
- border-radius: 15px;
756
- background-color: red;
757
- color: white;
758
- text-align: center;
759
- }
760
- }
761
- }
762
- }
763
- }
764
- }
765
-
766
- .cube-item {
767
- .imgWrapper {
768
- position: relative;
769
- text-align: center;
770
- }
771
-
772
- .imgMarked {
773
- position: absolute;
774
- top: 0;
775
- left: 0;
776
- width: 100%;
777
- height: 100%;
778
- background-color: rgba(0, 0, 0, 0.5);
779
- display: flex;
780
- justify-content: center;
781
- align-items: center;
782
- z-index: 100;
783
-
784
- .maskState {
785
- font-size: 23px;
786
- color: white;
787
- }
788
- }
789
-
790
- .goodsDescription {
791
- display: flex;
792
- flex-direction: column;
793
- justify-content: space-between;
794
-
795
- .goodsName,
796
- .specialGoodsName {
797
- display: -webkit-box;
798
- -webkit-line-clamp: 2;
799
- -webkit-box-orient: vertical;
800
- overflow: hidden;
801
- text-overflow: ellipsis;
802
- }
803
-
804
- .footerContent {
805
- display: flex;
806
- justify-content: space-between;
807
- align-items: flex-start;
808
-
809
- .goodsPrice {
810
- color: #f53a50;
811
- font-weight: 600;
812
-
813
- .scribing {
814
- display: inline-block;
815
- color: #ccc;
816
- text-decoration: line-through;
817
- font-weight: normal;
818
- }
819
- }
820
- }
821
-
822
- .goodsBuy {
823
- text-align: center;
824
- border-radius: 5px;
825
- background-color: red;
826
- color: white;
827
- align-self: flex-end;
828
- font-size: 12px;
829
- line-height: 22px;
830
- width: 5em;
831
- }
832
- }
833
- }
834
- </style>
1
+ //新品专区
2
+ <template>
3
+ <div>
4
+ <div v-if="!listArr.length && !isLc"></div>
5
+ <div
6
+ v-else
7
+ :style="{
8
+ margin: `${props.marginTop}px 0 ${props.marginBottom}px 0`,
9
+ backgroundColor: `${props.backgroundColor}`,
10
+ borderRadius: `${props.borderRadius}px`,
11
+ }"
12
+ >
13
+ <div v-if="props.title || props.subTitle" class="new-product-header">
14
+ <div class="header-title">{{ props.title }}</div>
15
+ <div class="header-subtitle" @click="goMoreGoods()">{{ props.subTitle }}</div>
16
+ </div>
17
+
18
+ <template v-if="listArr.length">
19
+ <template v-if="props.arrange === 3">
20
+ <!--低代码端的左右滑动-->
21
+ <div v-if="isLc" ref="lcSwiper" class="new-product-swiper lc-swiper" @scroll="handleLcScroll">
22
+ <div class="lc-swiper-track">
23
+ <div
24
+ v-for="page in groupedList"
25
+ :key="page.pageKey"
26
+ class="new-product-page"
27
+ style="gap:10px"
28
+ >
29
+ <div
30
+ v-for="item in page.items"
31
+ :key="item.renderKey"
32
+ :class="['cube-item', { 'is-placeholder': item.isPlaceholder }]"
33
+ @click="!item.isPlaceholder && goGoodsDetail(item)"
34
+ :style="{ borderRadius: `${props.borderRadius}px`,marginBottom:`${props.marginBottom}px`,marginTop:`${props.marginTop}px`}"
35
+ >
36
+ <template v-if="!item.isPlaceholder">
37
+ <div class="imgWrapper">
38
+ <div
39
+ v-if="isLc === false && (item.goodsSupplynum <= 0 || item.goodsProperty5 === '1')"
40
+ class="imgMarked"
41
+ >
42
+ <div class="maskState">
43
+ {{ getMaskState(item.goodsProperty5) }}
44
+ </div>
45
+ </div>
46
+ <img
47
+ class="goodsImg"
48
+ :src="getGoodsImg(item)"
49
+ alt=""
50
+ :style="{ borderRadius: `${props.borderRadius}px` }"
51
+ />
52
+ </div>
53
+
54
+ <div class="goodsDescription">
55
+ <div class="goodsName">{{ item.goodsName }}</div>
56
+ <section class="footerContent">
57
+ <div class="goodsPrice">
58
+ ¥{{ item.pricesetNprice }}
59
+ <div class="scribing" v-if="props.markedPrice === 1">¥{{ item.pricesetMakeprice }}</div>
60
+ </div>
61
+ <div class="goodsBuy" @click.stop="goGoodsDetail(item)">立即购买</div>
62
+ </section>
63
+ </div>
64
+ </template>
65
+ </div>
66
+ </div>
67
+ </div>
68
+ </div>
69
+
70
+ <!--小程序的左右滑动-->
71
+ <swiper
72
+ v-else
73
+ class="new-product-swiper mp-swiper"
74
+ :current="currentPage"
75
+ :autoplay="autoPlayResult"
76
+ :interval="props.autoplayInterval || 1500"
77
+ :circular="groupedList.length > 1"
78
+ :indicator-dots="false"
79
+ @change="handleSwiperChange"
80
+ >
81
+ <swiper-item v-for="page in groupedList" :key="page.pageKey">
82
+ <div class="new-product-page" style="gap:10px">
83
+ <div
84
+ v-for="item in page.items"
85
+ :key="item.renderKey"
86
+ :class="['cube-item', { 'is-placeholder': item.isPlaceholder }]"
87
+ @click="!item.isPlaceholder && goGoodsDetail(item)"
88
+ :style="{ borderRadius: `${props.borderRadius}px`,marginBottom:`${props.marginBottom}px`,marginTop:`${props.marginTop}px`}"
89
+ >
90
+ <template v-if="!item.isPlaceholder">
91
+ <div class="imgWrapper">
92
+ <div
93
+ v-if="isLc === false && (item.goodsSupplynum <= 0 || item.goodsProperty5 === '1')"
94
+ class="imgMarked"
95
+ >
96
+ <div class="maskState">
97
+ {{ getMaskState(item.goodsProperty5) }}
98
+ </div>
99
+ </div>
100
+ <img
101
+ class="goodsImg"
102
+ :src="getGoodsImg(item)"
103
+ alt=""
104
+ :style="{ borderRadius: `${props.borderRadius}px` }"
105
+ />
106
+ </div>
107
+
108
+ <div class="goodsDescription">
109
+ <div class="goodsName">{{ item.goodsName }}</div>
110
+ <section class="footerContent">
111
+ <div class="goodsPrice">
112
+ ¥{{ item.pricesetNprice }}
113
+ <div class="scribing" v-if="props.markedPrice === 1">¥{{ item.pricesetMakeprice }}</div>
114
+ </div>
115
+ <div class="goodsBuy" @click.stop="goGoodsDetail(item)">立即购买</div>
116
+ </section>
117
+ </div>
118
+ </template>
119
+ </div>
120
+ </div>
121
+ </swiper-item>
122
+ </swiper>
123
+
124
+ <div v-if="groupedList.length > 1" class="swiper-dots">
125
+ <div
126
+ v-for="(page, index) in groupedList"
127
+ :key="page.pageKey"
128
+ :class="['swiper-dot', { active: currentPage === index }]"
129
+ @click="goToPage(index)"
130
+ ></div>
131
+ </div>
132
+ </template>
133
+
134
+ <div
135
+ v-else
136
+ :class="['cube-container', `arrange-${props.arrange}`]"
137
+ >
138
+ <div
139
+ v-for="item in normalizedList"
140
+ :key="item.renderKey"
141
+ class="cube-item"
142
+ @click="goGoodsDetail(item)"
143
+ :style="{ borderRadius: `${props.borderRadius}px`,marginBottom:`${props.marginBottom}px`,marginTop:`${props.marginTop}px` }"
144
+ >
145
+ <div class="imgWrapper">
146
+ <div
147
+ v-if="isLc === false && (item.goodsSupplynum <= 0 || item.goodsProperty5 === '1')"
148
+ class="imgMarked"
149
+ >
150
+ <div class="maskState">
151
+ {{ getMaskState(item.goodsProperty5) }}
152
+ </div>
153
+ </div>
154
+ <img
155
+ class="goodsImg"
156
+ :src="getGoodsImg(item)"
157
+ alt=""
158
+ :style="{ borderRadius: `${props.borderRadius}px` }"
159
+ />
160
+ </div>
161
+
162
+ <div class="goodsDescription">
163
+ <div v-if="isLc === true && props.arrange === 2" class="specialGoodsName">{{ item.goodsName }}</div>
164
+ <div v-else class="goodsName">{{ item.goodsName }}</div>
165
+ <section class="footerContent">
166
+ <div class="goodsPrice">
167
+ ¥{{ item.pricesetNprice }}
168
+ <div class="scribing" v-if="props.markedPrice === 1">¥{{ item.pricesetMakeprice }}</div>
169
+ </div>
170
+ <div class="goodsBuy" @click.stop="goGoodsDetail(item)">立即购买</div>
171
+ </section>
172
+ </div>
173
+ </div>
174
+ </div>
175
+ </template>
176
+ </div>
177
+ </div>
178
+ </template>
179
+
180
+ <script>
181
+ import { querySkuFromJm, find } from "../../api/index.js";
182
+ import { isLc, getUrl } from "../../utils/index.js";
183
+ import { get, orderBy } from "lodash-es";
184
+
185
+ export default {
186
+ name: "cyy-new-product",
187
+ props: {
188
+ props: {
189
+ goods: Array,
190
+ SelectGoods: Object,
191
+ arrange: Number,
192
+ borderRadius: Number,
193
+ margin: Number,
194
+ markedPrice: Number,
195
+ marginTop: Number,
196
+ marginBottom: Number,
197
+ creatDate: String,
198
+ priceRange: String,
199
+ goodsType: String,
200
+ title: String,
201
+ subTitle: String,
202
+ backgroundColor: String,
203
+ channelCode: String,
204
+ autoPlay: Number,
205
+ autoplayInterval: Number,
206
+ channelCode:Number
207
+ },
208
+ },
209
+ data() {
210
+ return {
211
+ listArr: [],
212
+ currentPage: 0,
213
+ noDataStyle: {
214
+ width: "100%",
215
+ height: "180px",
216
+ lineHeight: "180px",
217
+ fontSize: "30px",
218
+ backgroundColor: "#ccc",
219
+ color: "#aaa",
220
+ textAlign: "center",
221
+ },
222
+ domainNameUrl: "",
223
+ isLc: isLc,
224
+ };
225
+ },
226
+ computed: {
227
+ wrapperStyle() {
228
+ return {
229
+ margin: `${this.props.marginTop}px 0 ${this.props.marginBottom}px 0`,
230
+ backgroundColor: this.props.backgroundColor,
231
+ borderRadius: `${this.props.borderRadius}px`,
232
+ };
233
+ },
234
+ filterKey() {
235
+ return (this.props.creatDate || "") + "|" + (this.props.priceRange || "") + "|" + (this.props.goodsType || "");
236
+ },
237
+ normalizedList() {
238
+ return this.listArr.map((item, index) => ({
239
+ ...item,
240
+ renderKey: this.getGoodsUniqueKey(item) || `goods-${index}`,
241
+ isPlaceholder: false,
242
+ }));
243
+ },
244
+ groupedList() {
245
+ if (this.props.arrange !== 3) {
246
+ return [];
247
+ }
248
+ const result = [];
249
+ const pageSize = 3;
250
+ for (let i = 0; i < this.normalizedList.length; i += pageSize) {
251
+ const pageIndex = Math.floor(i / pageSize);
252
+ const items = this.normalizedList.slice(i, i + pageSize);
253
+ while (items.length < pageSize) {
254
+ items.push({
255
+ renderKey: `placeholder-${pageIndex}-${items.length}`,
256
+ isPlaceholder: true,
257
+ });
258
+ }
259
+ result.push({
260
+ pageKey: `page-${pageIndex}`,
261
+ items,
262
+ });
263
+ }
264
+ return result;
265
+ },
266
+ autoPlayResult() {
267
+ return !this.isLc && this.props.arrange === 3 && this.props.autoPlay === 0 && this.groupedList.length > 1;
268
+ },
269
+ },
270
+ mounted() {
271
+ this.init();
272
+ },
273
+ watch: {
274
+ filterKey() {
275
+ this.init();
276
+ },
277
+ listArr() {
278
+ this.resetCurrentPage();
279
+ },
280
+ "props.arrange"() {
281
+ this.resetCurrentPage();
282
+ },
283
+ },
284
+ methods: {
285
+ resetCurrentPage() {
286
+ this.currentPage = 0;
287
+ this.$nextTick(() => {
288
+ const el = this.$refs.lcSwiper;
289
+ if (el && typeof el.scrollTo === "function") {
290
+ el.scrollTo({
291
+ left: 0,
292
+ behavior: "auto",
293
+ });
294
+ }
295
+ });
296
+ },
297
+ handleLcScroll(e) {
298
+ const el = e.target;
299
+ const width = el.clientWidth || 1;
300
+ this.currentPage = Math.round(el.scrollLeft / width);
301
+ },
302
+ handleSwiperChange(e) {
303
+ this.currentPage = e.detail.current || 0;
304
+ },
305
+ goToPage(index) {
306
+ if (index < 0 || index >= this.groupedList.length) {
307
+ return;
308
+ }
309
+ if (this.isLc) {
310
+ const el = this.$refs.lcSwiper;
311
+ if (!el) {
312
+ return;
313
+ }
314
+ const width = el.clientWidth || 0;
315
+ el.scrollTo({
316
+ left: width * index,
317
+ behavior: "smooth",
318
+ });
319
+ }
320
+ this.currentPage = index;
321
+ },
322
+ getGoodsUniqueKey(item) {
323
+ return item?.goodsCode || item?.skuCode || item?.goodsNo || "";
324
+ },
325
+ deduplicateGoodsList(list = []) {
326
+ const result = [];
327
+ const seen = new Set();
328
+ list.forEach((item) => {
329
+ if (!item) {
330
+ return;
331
+ }
332
+ const key = this.getGoodsUniqueKey(item);
333
+ if (!key || seen.has(key)) {
334
+ return;
335
+ }
336
+ seen.add(key);
337
+ result.push(item);
338
+ });
339
+ return result;
340
+ },
341
+ getGoodsImg(item) {
342
+ if (!item.dataPic) {
343
+ return "";
344
+ }
345
+ return item.dataPic.indexOf("http") === -1 ? this.domainNameUrl + item.dataPic : item.dataPic;
346
+ },
347
+ goMoreGoods() {
348
+ if (isLc) {
349
+ return;
350
+ }
351
+ const goodsCodes = this.listArr.map((item) => item.goodsCode).join(",");
352
+ this.$routers.push("/pages/goodsList/main", {
353
+ goodsCode: goodsCodes,
354
+ page: "1",
355
+ rows: "200",
356
+ order:"asc",
357
+ sortField:"pricesetNprice"
358
+ });
359
+ },
360
+ formatDate(date) {
361
+ const y = date.getFullYear();
362
+ const m = String(date.getMonth() + 1).padStart(2, "0");
363
+ const d = String(date.getDate()).padStart(2, "0");
364
+ return `${y}-${m}-${d}`;
365
+ },
366
+ parseCreatDate(creatDate) {
367
+ if (!creatDate) return {};
368
+ try {
369
+ const cfg = JSON.parse(creatDate);
370
+ if (cfg.type === "days") {
371
+ const now = new Date();
372
+ const start = new Date(now.getTime() - Number(cfg.value) * 24 * 60 * 60 * 1000);
373
+ return {
374
+ gmtCreateQstart: this.formatDate(start),
375
+ gmtCreateQend: this.formatDate(now),
376
+ };
377
+ }
378
+ if (cfg.type === "range") {
379
+ //如果没用设置截止时间,就将今天的时间=截止时间
380
+ if(!cfg.start){
381
+ return{};
382
+ }
383
+ const today=this.formatDate(new Date());
384
+ return {
385
+ gmtCreateQstart: cfg.start,
386
+ gmtCreateQend: cfg.end || today,
387
+ };
388
+ }
389
+ } catch (e) {
390
+ console.error("时间解析错误", e);
391
+ return {};
392
+ }
393
+ return {};
394
+ },
395
+ parsePriceRange(priceRange) {
396
+ if (!priceRange) return {};
397
+ try {
398
+ const range = JSON.parse(priceRange);
399
+ return {
400
+ pricesetNpriceQmin: range.min || "",
401
+ pricesetNpriceQmax: range.max || "",
402
+ // pricesetNpriceQmin: range.min !== "" && range.min != null ? range.min : "",
403
+ // pricesetNpriceQmax: range.max !== "" && range.max != null ? range.max : "",
404
+ };
405
+ } catch (e) {
406
+ console.error("价格解析错误", e);
407
+ return {};
408
+ }
409
+ },
410
+ async init() {
411
+ this.domainNameUrl = getUrl(this);
412
+ const { creatDate, priceRange, goodsType, channelCode } = this.props;
413
+ if (!creatDate || !goodsType) {
414
+ this.listArr = [];
415
+ return;
416
+ }
417
+
418
+ const dateParams = this.parseCreatDate(creatDate);
419
+ const priceParams = this.parsePriceRange(priceRange);
420
+ const baseParams = {
421
+ rows: "200",
422
+ page: "1",
423
+ ...dateParams,
424
+ ...priceParams,
425
+ goodsDataState:"2",
426
+ isNewArrival: 1,
427
+ channelCode,
428
+ };
429
+
430
+ if (goodsType) {
431
+ baseParams.goodsType = goodsType;
432
+ }
433
+ if (channelCode) {
434
+ baseParams.channelCode = channelCode;
435
+ }
436
+
437
+ let res;
438
+ if (isLc) {
439
+ const urlParams = new URLSearchParams(window.location.hash.split("?")[1] || window.location.search);
440
+ const hashChannelCode = urlParams.get("channelCode") || "";
441
+ if (hashChannelCode) {
442
+ baseParams.channelCode = hashChannelCode;
443
+ }
444
+ const queryStr = new URLSearchParams(baseParams).toString();
445
+ const headers = {
446
+ "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
447
+ "saas-token": localStorage.getItem("saas-token"),
448
+ };
449
+ res = await fetch(process.env.REACT_APP_BASE_URL + querySkuFromJm + "&" + queryStr, {
450
+ method: "GET",
451
+ headers,
452
+ credentials: "include",
453
+ })
454
+ .then((r) => r.json())
455
+ .catch((e) => {
456
+ console.log("接口请求错误", e);
457
+ return {};
458
+ });
459
+ } else {
460
+ const firstRes = await this.http.get(querySkuFromJm, baseParams);
461
+ const firstList = this.deduplicateGoodsList(get(firstRes, "list", []));
462
+ if (!firstList.length) {
463
+ this.listArr = [];
464
+ return;
465
+ }
466
+ const goodsCodeList = firstList.map((item) => item.goodsCode).filter(Boolean);
467
+ const goodsCode = goodsCodeList.join(",");
468
+ if (!goodsCode) {
469
+ this.listArr = [];
470
+ return;
471
+ }
472
+ res = await this.http.get(find + "?rows=200&page=1",
473
+ { goodsCode,
474
+ dataState: "2",
475
+ order:"asc",
476
+ sortField:"pricesetNprice"
477
+ });
478
+ const findList = this.deduplicateGoodsList(get(res, "list", []));
479
+ const sortedArrays = [];
480
+ goodsCodeList.forEach((code) => {
481
+ const matchedItem = findList.find((item) => item.goodsCode === code);
482
+ if (matchedItem) {
483
+ sortedArrays.push(matchedItem);
484
+ }
485
+ });
486
+ res = { list: sortedArrays };
487
+ }
488
+ this.listArr = this.deduplicateGoodsList(get(res, "list", []));
489
+ },
490
+ goGoodsDetail(item) {
491
+ if (isLc) {
492
+ return;
493
+ }
494
+ const { skuCode } = item;
495
+ this.$routers.push("detail", {
496
+ skuNo: skuCode,
497
+ });
498
+ },
499
+ getMaskState(state) {
500
+ if (state === "1") {
501
+ return "预售中";
502
+ }
503
+ return "补货中";
504
+ },
505
+ },
506
+ };
507
+ </script>
508
+
509
+ <style lang="less" scoped>
510
+ .new-product-header {
511
+ display: flex;
512
+ justify-content: space-between;
513
+ align-items: center;
514
+ padding: 12px 16px;
515
+
516
+ .header-title {
517
+ font-size: 18px;
518
+ font-weight: 600;
519
+ color: #333;
520
+ }
521
+
522
+ .header-subtitle {
523
+ font-size: 14px;
524
+ color: #999;
525
+ }
526
+ }
527
+
528
+ .new-product-swiper {
529
+ width: 100%;
530
+ }
531
+
532
+ .mp-swiper {
533
+ height: 220px;
534
+ }
535
+
536
+ .lc-swiper {
537
+ overflow-x: auto;
538
+ overflow-y: hidden;
539
+ scroll-snap-type: x mandatory;
540
+ -webkit-overflow-scrolling: touch;
541
+ scrollbar-width: none;
542
+ }
543
+
544
+ .lc-swiper::-webkit-scrollbar {
545
+ display: none;
546
+ }
547
+
548
+ .lc-swiper-track {
549
+ display: flex;
550
+ }
551
+
552
+ .new-product-page {
553
+ width: 100%;
554
+ min-width: 100%;
555
+ box-sizing: border-box;
556
+ display: grid;
557
+ gap:10px;
558
+ grid-template-columns: repeat(3, minmax(0, 1fr));
559
+ align-items: start;
560
+ margin: 0 5px;
561
+
562
+ .cube-item {
563
+ background: #fff;
564
+ padding-bottom: 10px;
565
+ min-width: 0;
566
+ &.is-placeholder {
567
+ background: transparent;
568
+ pointer-events: none;
569
+ }
570
+ }
571
+
572
+ .goodsImg {
573
+ width: 100%;
574
+ height: 100px;
575
+ aspect-ratio: 1;
576
+ display: block;
577
+ }
578
+
579
+ .goodsDescription {
580
+ position: relative;
581
+
582
+ .goodsName {
583
+ font-size: 13px;
584
+ height: 36px;
585
+ }
586
+
587
+ .footerContent {
588
+ flex-direction: column;
589
+ align-items: stretch;
590
+
591
+ .goodsPrice {
592
+ font-size: 13px;
593
+ text-align: left;
594
+ margin-bottom: 4px;
595
+
596
+ .scribing {
597
+ font-size: 11px;
598
+ }
599
+ }
600
+
601
+ .goodsBuy {
602
+ align-self: center;
603
+ width: 5em;
604
+ font-size: 12px;
605
+ line-height: 22px;
606
+ border-radius: 15px;
607
+ background-color: red;
608
+ color: white;
609
+ text-align: center;
610
+ }
611
+ }
612
+ }
613
+ }
614
+
615
+ .swiper-dots {
616
+ display: flex;
617
+ justify-content: center;
618
+ align-items: center;
619
+ padding: 8px 0 4px;
620
+ }
621
+
622
+ .swiper-dot {
623
+ width: 8px;
624
+ height: 8px;
625
+ border-radius: 50%;
626
+ background: #d9d9d9;
627
+ margin: 0 4px;
628
+ }
629
+
630
+ .swiper-dot.active {
631
+ background: #333;
632
+ }
633
+
634
+ .cube-container {
635
+ display: grid;
636
+
637
+ &.arrange-1 {
638
+ grid-template-columns: repeat(1, 1fr);
639
+
640
+ .cube-item {
641
+ background: #fff;
642
+
643
+ .goodsImg {
644
+ width: 100%;
645
+ height: 100%;
646
+ aspect-ratio: 1;
647
+ margin-left: auto;
648
+ margin-right: auto;
649
+ }
650
+
651
+ .goodsDescription {
652
+ .goodsName {
653
+ font-size: 20px;
654
+ }
655
+
656
+ .footerContent {
657
+ .goodsPrice {
658
+ font-size: 18px;
659
+
660
+ .scribing {
661
+ font-size: 14px;
662
+ }
663
+ }
664
+ }
665
+ }
666
+ }
667
+ }
668
+
669
+ &.arrange-2 {
670
+ grid-template-columns: repeat(2, 1fr);
671
+
672
+ .cube-item {
673
+ background: #fff;
674
+ margin: 0 5px;
675
+
676
+ .goodsImg {
677
+ width: 100%;
678
+ height: 100%;
679
+ aspect-ratio: 1;
680
+ }
681
+
682
+ .goodsDescription {
683
+ position: relative;
684
+
685
+ .goodsName {
686
+ font-size: 16px;
687
+ height: 42px;
688
+ width: 41vw;
689
+ }
690
+
691
+ .specialGoodsName {
692
+ font-size: 12px;
693
+ height: 42px;
694
+ }
695
+
696
+ .footerContent {
697
+ .goodsPrice {
698
+ font-size: 14px;
699
+
700
+ .scribing {
701
+ font-size: 12px;
702
+ }
703
+ }
704
+ }
705
+ }
706
+ }
707
+ }
708
+
709
+ &.arrange-5 {
710
+ box-sizing: border-box;
711
+ display: grid;
712
+ grid-template-columns: repeat(3, minmax(0, 1fr));
713
+
714
+ .cube-item {
715
+ background: #fff;
716
+ padding-bottom: 10px;
717
+ margin: 0 5px;
718
+ width: 107px;
719
+ height: 189px;
720
+
721
+
722
+ .goodsImg {
723
+ width: 100%;
724
+ height: 100px;
725
+ aspect-ratio: 1;
726
+ }
727
+
728
+ .goodsDescription {
729
+ position: relative;
730
+
731
+ .goodsName {
732
+ font-size: 13px;
733
+ height: 36px;
734
+ }
735
+
736
+ .footerContent {
737
+ flex-direction: column;
738
+ align-items: stretch;
739
+
740
+ .goodsPrice {
741
+ font-size: 13px;
742
+ text-align: left;
743
+ margin-bottom: 4px;
744
+
745
+ .scribing {
746
+ font-size: 11px;
747
+ }
748
+ }
749
+
750
+ .goodsBuy {
751
+ align-self: center;
752
+ width: 5em;
753
+ font-size: 12px;
754
+ line-height: 22px;
755
+ border-radius: 15px;
756
+ background-color: red;
757
+ color: white;
758
+ text-align: center;
759
+ }
760
+ }
761
+ }
762
+ }
763
+ }
764
+ }
765
+
766
+ .cube-item {
767
+ .imgWrapper {
768
+ position: relative;
769
+ text-align: center;
770
+ }
771
+
772
+ .imgMarked {
773
+ position: absolute;
774
+ top: 0;
775
+ left: 0;
776
+ width: 100%;
777
+ height: 100%;
778
+ background-color: rgba(0, 0, 0, 0.5);
779
+ display: flex;
780
+ justify-content: center;
781
+ align-items: center;
782
+ z-index: 100;
783
+
784
+ .maskState {
785
+ font-size: 23px;
786
+ color: white;
787
+ }
788
+ }
789
+
790
+ .goodsDescription {
791
+ display: flex;
792
+ flex-direction: column;
793
+ justify-content: space-between;
794
+
795
+ .goodsName,
796
+ .specialGoodsName {
797
+ display: -webkit-box;
798
+ -webkit-line-clamp: 2;
799
+ -webkit-box-orient: vertical;
800
+ overflow: hidden;
801
+ text-overflow: ellipsis;
802
+ }
803
+
804
+ .footerContent {
805
+ display: flex;
806
+ justify-content: space-between;
807
+ align-items: flex-start;
808
+
809
+ .goodsPrice {
810
+ color: #f53a50;
811
+ font-weight: 600;
812
+
813
+ .scribing {
814
+ display: inline-block;
815
+ color: #ccc;
816
+ text-decoration: line-through;
817
+ font-weight: normal;
818
+ }
819
+ }
820
+ }
821
+
822
+ .goodsBuy {
823
+ text-align: center;
824
+ border-radius: 5px;
825
+ background-color: red;
826
+ color: white;
827
+ align-self: flex-end;
828
+ font-size: 12px;
829
+ line-height: 22px;
830
+ width: 5em;
831
+ }
832
+ }
833
+ }
834
+ </style>