dev #24

Merged
liyongle merged 4 commits from dev into test 3 years ago
  1. 10
      CHANGELOG.md
  2. 4
      package-lock.json
  3. 2
      package.json
  4. 27
      public/static/offline/JSON/getActivityListByMall.json
  5. 56
      public/static/offline/JSON/getAllActivityList.json
  6. 20
      public/static/offline/JSON/getMemberBenefits.json
  7. 60
      public/static/offline/JSON/getShopActivityList.json
  8. BIN
      src/assets/images/activity/next-b.png
  9. BIN
      src/assets/images/activity/next-w.png
  10. BIN
      src/assets/images/activity/next.png
  11. BIN
      src/assets/images/activity/prev-b.png
  12. BIN
      src/assets/images/activity/prev-w.png
  13. BIN
      src/assets/images/activity/prev.png
  14. 275
      src/components/ActivityDetail/MainActivityDetail.vue
  15. 4
      src/http/api/activity/index.ts
  16. 2
      src/types/activity.d.ts
  17. 274
      src/views/Activity/Activity.vue
  18. 150
      src/views/Activity/ActivityItem.vue
  19. 77
      src/views/Activity/ActivityItem2.vue

10
CHANGELOG.md

@ -2,6 +2,16 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [1.0.9-B.0](https://git.1000my.com/project-chengduSKP/cd_SKP_H_base_daoshi_vue_ts/compare/v1.0.8...v1.0.9-B.0) (2023-10-11)
### Bug Fixes
* 🧩 活动精选模块开发 ([4870c97](https://git.1000my.com/project-chengduSKP/cd_SKP_H_base_daoshi_vue_ts/commit/4870c979f7e139498bfe362b24163c6657f7444f))
* 🧩 优化 ([55736db](https://git.1000my.com/project-chengduSKP/cd_SKP_H_base_daoshi_vue_ts/commit/55736db9b43bab4d1138e2f92a44e7a7baa0a370))
### [1.0.8](https://git.1000my.com/project-chengduSKP/cd_SKP_H_base_daoshi_vue_ts/compare/v1.0.8-B.0...v1.0.8) (2023-09-01)
### [1.0.8-B.0](https://git.1000my.com/project-chengduSKP/cd_SKP_H_base_daoshi_vue_ts/compare/v1.0.7...v1.0.8-B.0) (2023-09-01)
### [1.0.7](https://git.1000my.com/project-chengduSKP/cd_SKP_H_base_daoshi_vue_ts/compare/v1.0.7-B.0...v1.0.7) (2023-09-01)

4
package-lock.json

@ -1,12 +1,12 @@
{
"name": "vue_cli_ts",
"version": "1.0.8-B.0",
"version": "1.0.9-B.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "vue_cli_ts",
"version": "1.0.8-B.0",
"version": "1.0.9-B.0",
"dependencies": {
"@better-scroll/core": "^2.5.0",
"@better-scroll/observe-image": "^2.5.0",

2
package.json

@ -1,6 +1,6 @@
{
"name": "vue_cli_ts",
"version": "1.0.8-B.0",
"version": "1.0.9-B.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",

27
public/static/offline/JSON/getActivityListByMall.json

@ -1 +1,26 @@
{"code":200,"msg":"操作成功","data":[{"id":264,"title":"主KV","content":{"activityAddress":"","activityAddressEn":"","activityContent":"SKP是全球最具标志性的高端时尚百货之一,首家SKP于2007年在北京诞生。目前,成都SKP是继北京、西安之后的全国第三家SKP旗舰项目,设计融合了成都本土文化和城市特色,将公园城市理念、TOD站城一体化开发理念、以及时尚高端零售理念综合进行统一规划设计。成都SKP是亚洲最大的下沉式建筑,作为成都交子公园商圈引入的首个高端百货业态,成都SKP项目总建筑面积约32.4万平米,品牌共约1300余个,涵盖多个首店品牌。同时,通过SKP最前卫的专业买手团队从世界各地甄选最新、最好、最尖端的品牌和单品,将SKP SELECT作为SKP旗下的多品牌概念店,建立成为一站式的购物体验目的地。","activityContentEn":"","activityName":"主KV","activityNameEn":"","startDate":"2023-07-21","endDate":"2023-08-22","point":"","fileUrl":["/iotFile/project-ey_fpaur6s6fkgvszywana/20230721/VxD2notoXjw8qTxQMerDh.png"],"limitStartDate":"2023-07-21 14:43:31","limitEndDate":"2023-08-22 00:00:00"}}]}
{
"code": 200,
"msg": "操作成功",
"data": [
{
"id": 264,
"title": "主KV",
"content": {
"activityAddress": "",
"activityAddressEn": "",
"activityContent": "SKP是全球最具标志性的高端时尚百货之一,首家SKP于2007年在北京诞生。目前,成都SKP是继北京、西安之后的全国第三家SKP旗舰项目,设计融合了成都本土文化和城市特色,将公园城市理念、TOD站城一体化开发理念、以及时尚高端零售理念综合进行统一规划设计。成都SKP是亚洲最大的下沉式建筑,作为成都交子公园商圈引入的首个高端百货业态,成都SKP项目总建筑面积约32.4万平米,品牌共约1300余个,涵盖多个首店品牌。同时,通过SKP最前卫的专业买手团队从世界各地甄选最新、最好、最尖端的品牌和单品,将SKP SELECT作为SKP旗下的多品牌概念店,建立成为一站式的购物体验目的地。",
"activityContentEn": "",
"activityName": "主KV",
"activityNameEn": "",
"startDate": "2023-07-21",
"endDate": "2023-08-22",
"point": "",
"fileUrl": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230721/VxD2notoXjw8qTxQMerDh.png"
],
"limitStartDate": "2023-07-21 14:43:31",
"limitEndDate": "2023-08-22 00:00:00"
}
}
]
}

56
public/static/offline/JSON/getAllActivityList.json

@ -0,0 +1,56 @@
{
"code": 200,
"msg": "操作成功",
"data": [
{
"id": 617,
"entryCode": "UIBbbmSxX1bvI_icEzNNu",
"title": "欢度中秋国庆",
"content": {
"activityName": "欢度中秋国庆",
"activityNameEn": "happy",
"type": "档期活动",
"coverUrl": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230721/VxD2notoXjw8qTxQMerDh.png"
],
"fileUrl_h": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230721/VxD2notoXjw8qTxQMerDh.png",
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230719/JUhRWWwrWE_WkoZgp_TOm.png"
],
"fileUrl_v": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230721/VxD2notoXjw8qTxQMerDh.png"
]
}
},
{
"id": 618,
"entryCode": "liuUoTMkKVyk_ON7TV3jw",
"title": "品牌活动",
"content": {
"activityName": "品牌活动",
"activityNameEn": "brand988",
"type": "品牌活动",
"coverUrl": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230721/VxD2notoXjw8qTxQMerDh.png"
],
"fileUrl_h": [],
"fileUrl_v": []
}
},
{
"id": 618,
"entryCode": "liuUoTMkKVyk_ON7TV3jw",
"title": "品牌活动",
"content": {
"activityName": "品牌活动",
"activityNameEn": "brand988",
"type": "品牌活动",
"coverUrl": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230721/VxD2notoXjw8qTxQMerDh.png"
],
"fileUrl_h": [],
"fileUrl_v": []
}
}
]
}

20
public/static/offline/JSON/getMemberBenefits.json

@ -1 +1,19 @@
{"code":200,"msg":"操作成功","data":[{"id":196,"title":"成都SKP会员权益","content":{"name":"成都SKP会员权益","nameEn":"","content":"(一)参加会员促销活动,享受会员积分【每消费1元人民币 (仅限现金、支票及银行卡刷卡消费,不含电子礼金等消费) 获得1个积分】,换礼等权益;\n(二)SKP普通会籍在一个定级期内达到定级积分标准后,可获得相应的尊贵会籍资格。尊贵会籍除享有普通会籍权益外,还可享有特殊权益如下:\n金卡定级积分标准:100000 ,享特殊权益(奖励积分0.2倍)\n黑卡定级积分标准:500000, 享特殊权益(奖励积分1倍)\n尊贵会籍自生效日起至下一个定级期的8月31日止。\n(三)SKP在法律法规允许的范围内,对本细则拥有最终解释权;详情可咨询SKP店内服务台或会员服务中心。咨询电话:028-68385888。","contentEn":"","file_code":["/iotFile/project-ey_fpaur6s6fkgvszywana/20230719/JUhRWWwrWE_WkoZgp_TOm.png"]}}]}
{
"code": 200,
"msg": "操作成功",
"data": [
{
"id": 196,
"title": "成都SKP会员权益",
"content": {
"name": "成都SKP会员权益",
"nameEn": "",
"content": "(一)参加会员促销活动,享受会员积分【每消费1元人民币 (仅限现金、支票及银行卡刷卡消费,不含电子礼金等消费) 获得1个积分】,换礼等权益;\n(二)SKP普通会籍在一个定级期内达到定级积分标准后,可获得相应的尊贵会籍资格。尊贵会籍除享有普通会籍权益外,还可享有特殊权益如下:\n金卡定级积分标准:100000 ,享特殊权益(奖励积分0.2倍)\n黑卡定级积分标准:500000, 享特殊权益(奖励积分1倍)\n尊贵会籍自生效日起至下一个定级期的8月31日止。\n(三)SKP在法律法规允许的范围内,对本细则拥有最终解释权;详情可咨询SKP店内服务台或会员服务中心。咨询电话:028-68385888。",
"contentEn": "",
"file_code": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230719/JUhRWWwrWE_WkoZgp_TOm.png"
]
}
}
]
}

60
public/static/offline/JSON/getShopActivityList.json

@ -0,0 +1,60 @@
{
"code": 200,
"msg": "操作成功",
"data": [
{
"id": 620,
"entryCode": "7PtFGpCK-XIyq_qKRJPR5",
"title": "品牌活动",
"content": {
"fileUrl": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230719/JUhRWWwrWE_WkoZgp_TOm.png"
],
"title": "COLOMBO V-SPACE限时店 ",
"titleEn": "COLOMBO V-SPACE",
"time": "即日起-国庆节",
"place": "成都SKP 1F",
"placeEn": "成都SKP 1F",
"typeId": [
"liuUoTMkKVyk_ON7TV3jw"
]
}
},
{
"id": 620,
"entryCode": "7PtFGpCK-XIyq_qKRJPR51",
"title": "品牌活动",
"content": {
"fileUrl": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230719/JUhRWWwrWE_WkoZgp_TOm.png"
],
"title": "COLOMBO V-SPACE限时店 ",
"titleEn": "COLOMBO V-SPACE",
"time": "即日起-国庆节",
"place": "成都SKP 1F",
"placeEn": "成都SKP 1F",
"typeId": [
"liuUoTMkKVyk_ON7TV3jw"
]
}
},
{
"id": 620,
"entryCode": "7PtFGpCK-XIyq_qKRJPR518",
"title": "品牌活动",
"content": {
"fileUrl": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230719/JUhRWWwrWE_WkoZgp_TOm.png"
],
"title": "COLOMBO V-SPACE限时店 ",
"titleEn": "COLOMBO V-SPACE",
"time": "即日起-国庆节",
"place": "成都SKP 1F",
"placeEn": "成都SKP 1F",
"typeId": [
"liuUoTMkKVyk_ON7TV3jw"
]
}
}
]
}

BIN
src/assets/images/activity/next-b.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

BIN
src/assets/images/activity/next-w.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 B

BIN
src/assets/images/activity/next.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
src/assets/images/activity/prev-b.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 B

BIN
src/assets/images/activity/prev-w.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 B

BIN
src/assets/images/activity/prev.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

275
src/components/ActivityDetail/MainActivityDetail.vue

@ -0,0 +1,275 @@
<template>
<transition appear enter-active-class="animate__animated animate__fadeIn" leave-active-class="animate__animated animate__fadeOut">
<masker @click="close">
<div v-show="actInfo.type === '档期活动'">
<swiper
:ref="mySwiper1"
class="carousel"
:autoplay="true"
:observer="true"
:modules="modules"
:loop="actInfo.fileUrl_h.length > 1"
:effect="'fade'"
:pagination="true"
@swiper="setControlledSwiper"
>
<swiper-slide v-for="item of actInfo.fileUrl_h" :key="item">
<img :src="item" class="banner" />
</swiper-slide>
<div v-if="actInfo.fileUrl_h.length > 1" class="swiper-prev" @click="pre">
<img src="@/assets/images/activity/prev-w.png" alt="" />
</div>
<div v-if="actInfo.fileUrl_h.length > 1" class="swiper-next" @click="next">
<img src="@/assets/images/activity/next-w.png" alt="" />
</div>
</swiper>
<img v-if="!actInfo.fileUrl_h.length" src="../../assets/images/empty_big.svg" class="banner" alt="" />
</div>
<div v-show="actInfo.type !== '档期活动'" class="shop-container">
<swiper
:ref="mySwiper2"
class="carousel1"
:slides-per-view="2"
:autoplay="{ autoplay: actInfo.list.length > 1, disableOnInteraction: false }"
:observer="true"
:space-between="40"
:pagination="true"
:modules="modules1"
@swiper="setControlledSwiper2"
>
<swiper-slide v-for="item of actInfo.list" :key="item.entryCode" class="slide">
<img :src="item.content.fileUrl[0]" class="banner" />
<div class="title">
<Marquees class="name" :speed="40" :delay="0.8" :content="switchLanguage(item, 'title')">{{
switchLanguage(item.content, 'title')
}}</Marquees>
</div>
<div class="label">{{ $t('activity.time') + item.content.time }}</div>
<div class="label">{{ $t('activity.address') + switchLanguage(item.content, 'place') }}</div>
</swiper-slide>
<div v-if="actInfo.list.length > 1" class="swiper-prev-w" @click="pre2">
<img src="@/assets/images/activity/prev-b.png" alt="" />
</div>
<div v-if="actInfo.list.length > 1" class="swiper-next-w" @click="next2">
<img src="@/assets/images/activity/next-b.png" alt="" />
</div>
</swiper>
</div>
<!-- 关闭 -->
<div class="exit" :class="actInfo.type !== '档期活动' && 'w'" @click="close">
<img src="@/assets/images/shopDetail/close.svg" alt="" />
</div>
</masker>
</transition>
</template>
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Autoplay, Pagination, EffectFade } from 'swiper'
import 'swiper/css'
import 'swiper/css/pagination'
import 'swiper/css/effect-fade'
import { useSwitchLanguage } from '@/composables/useSwitchLanguage'
import { Swiper, SwiperSlide } from 'swiper/vue'
import masker from '@/base/Masker/Masker.vue'
import Marquees from '@/base/Marquees/Marquees.vue'
const modules1 = [Autoplay, Pagination]
const modules = [Autoplay, Pagination, EffectFade]
interface AItem {
actInfo: any
}
defineProps<AItem>()
const emit = defineEmits(['close'])
function close() {
emit('close')
}
const { switchLanguage } = useSwitchLanguage()
//
const mySwiper1 = shallowRef()
const mySwiper2 = shallowRef()
// swiper
function setControlledSwiper(swiper: any) {
mySwiper1.value = swiper
}
// swiper
function setControlledSwiper2(swiper: any) {
mySwiper2.value = swiper
}
//
function pre() {
mySwiper1.value.slidePrev()
}
//
function next() {
mySwiper1.value.slideNext()
}
//
function pre2() {
mySwiper2.value.slidePrev()
}
//
function next2() {
mySwiper2.value.slideNext()
}
</script>
<style lang="scss" scoped>
.carousel {
height: 940px;
margin-top: 90px;
text-align: center;
.banner {
width: 1600px;
height: 900px;
border-radius: 16px;
}
:deep(.swiper-pagination-bullet) {
width: 4px;
height: 4px;
margin-right: 6px;
background: #e2dcd5;
border-radius: 2px;
}
:deep(.swiper-pagination-bullet-active) {
width: 40px;
background: #e00068;
}
.swiper-prev {
position: absolute;
top: 430px;
left: 60px;
z-index: 1;
img {
width: 20px;
height: 40px;
}
}
.swiper-next {
position: absolute;
top: 430px;
right: 60px;
z-index: 1;
img {
width: 20px;
height: 40px;
}
}
}
.shop-container {
position: relative;
z-index: 1;
width: 1760px;
height: 772px;
padding-top: 52px;
padding-left: 48px;
margin-top: 154px;
margin-left: 80px;
background: #f5f5f5;
border-radius: 16px;
:deep(.swiper-pagination-bullet) {
width: 4px;
height: 4px;
margin-right: 6px;
background: rgb(0 0 0 / 20%);
border-radius: 2px;
}
:deep(.swiper-pagination-horizontal) {
bottom: 17px;
}
:deep(.swiper-pagination-bullet-active) {
width: 40px;
background: #e00068;
}
.carousel1 {
height: 700px;
.slide {
width: 800px !important;
height: 640px;
background: #fff;
border-radius: 24px;
.banner {
width: 800px;
height: 450px;
border-radius: 16px;
}
.title {
height: 32px;
margin: 32px 0 40px 40px;
font-size: 24px;
font-family: 'font_bold';
color: rgb(0 0 0 / 70%);
font-style: normal;
font-weight: 700;
line-height: 32px;
}
.label {
@include no-wrap;
width: 730px;
margin-bottom: 8px;
margin-left: 40px;
font-size: 14px;
font-family: 'font_bold';
color: #8e9090;
font-style: normal;
font-weight: 700;
line-height: 22px;
}
}
.swiper-prev-w {
position: absolute;
top: 670px;
left: 0;
z-index: 11;
img {
width: 10px;
height: 18px;
}
}
.swiper-next-w {
position: absolute;
top: 670px;
right: 48px;
z-index: 11;
img {
width: 10px;
height: 18px;
}
}
}
}
.exit {
position: absolute;
top: 50px;
right: 128px;
z-index: 1;
width: 100px;
height: 100px;
padding: 26px;
font-size: 20px;
font-family: 'font_bold';
text-align: center;
color: rgb(0 0 0 / 80%);
background: rgb(255 255 255 / 60%);
border: 2px solid #fff;
border-radius: 50px;
backdrop-filter: blur(20px);
box-shadow: 0 20px 30px 0 rgb(0 0 0 / 10%);
line-height: 72px;
img {
width: 48px;
}
}
.w {
top: 114px;
right: 48px;
}
</style>

4
src/http/api/activity/index.ts

@ -6,8 +6,8 @@ type TypeAct = {
content: object
}
//获取商场活动
export const getMallActivity = () => request<TypeAct[]>({ url: `${PREFIX.STATIC_URL}/JSON/getActivityListByMall.json` })
export const getMallActivity = () => request<TypeAct[]>({ url: `${PREFIX.STATIC_URL}/JSON/getAllActivityList.json` })
//获取店铺活动
export const getShopActivity = () => request({ url: `/JSON/getActivityList2.json` })
export const getShopActivity = () => request({ url: `${PREFIX.STATIC_URL}/JSON/getShopActivityList.json` })
//获取会员活动
export const getMemberActivity = () => request({ url: `/JSON/getActivityList3.json` })

2
src/types/activity.d.ts

@ -19,4 +19,6 @@ declare interface Activity {
shopCode: string //关联店铺code
logo_code?: string //一些地方用到这个字段
facilityCode?: string //服务里需要这个字段
fileUrl_h?: string // 横版详情图
fileUrl_v?: string // 竖版详情图
}

274
src/views/Activity/Activity.vue

@ -1,197 +1,149 @@
<template>
<div class="activity-container">
<!-- 切换按钮
<switchTab
class="btn-group"
:width="314.5"
:height="82"
:wrapper-width="637"
:wrapper-height="90"
:list="list"
@click="handleSwitch"
></switchTab> -->
<div class="big-title">
<li>{{ switchLanguage({ name: '商场活动' }, 'name') }}</li>
<li>MALL ACTIVITIES</li>
</div>
<!-- 活动列表 -->
<transition
enter-active-class="animate__faster animate__animated animate__fadeInRight"
leave-active-class="animate__animated animate__fadeOutDown"
>
<ScrollView
v-if="actList.length"
ref="actScroll"
:list="actList"
:refresh-delay="200"
:scroll-x="true"
:scrollbar="true"
class="act-scroll"
>
<ul class="act-list">
<ActivityItem v-for="(item, index) in actList" :key="index" :act-info="item" @click="clickItem"></ActivityItem>
</ul>
</ScrollView>
<!-- <swiper
v-if="showList"
class="act-scroll"
direction="horizontal"
:autoplay="
actList.length >= 3
? {
disableOnInteraction: false,
delay: 1000
}
: false
"
:pagination="{
type: 'progressbar'
}"
:free-mode="{
enabled: true
}"
:enabled="actList.length >= 3"
:loop="actList.length >= 3"
:speed="1000"
<transition appear enter-active-class="animate__faster animate__animated animate__fadeIn">
<div v-if="actList.length === 1" class="act-list">
<ActivityItem2 style="margin-right: 0" :act-info="actList[0]" @handle="clickItem"></ActivityItem2>
</div>
<div v-else-if="actList.length === 2" class="act-list">
<ActivityItem2 :act-info="actList[0]" @handle="clickItem"></ActivityItem2>
<ActivityItem2 style="margin-right: 0" :act-info="actList[1]" @handle="clickItem"></ActivityItem2>
</div>
<swiper
v-else-if="actList.length > 2"
:modules="modules"
:looped-slides="3"
:loop-additional-slides="3"
:slides-per-view="1"
:space-between="32"
:slides-per-view="1.92"
:observer="true"
:centered-slides="true"
:loop="true"
:pagination="false"
:autoplay="{ delay: 5000, disableOnInteraction: false }"
class="myswiper"
@swiper="setControlledSwiper"
>
<swiper-slide v-for="(item, index) in actList" :key="index">
<ActivityItem :act-info="item" @click-img="clickImage"></ActivityItem>
<ActivityItem :act-info="item" @handle="clickItem"></ActivityItem>
</swiper-slide>
</swiper> -->
<div class="swiper-prev" @click="pre">
<img src="@/assets/images/activity/prev.png" alt="" />
</div>
<div class="swiper-next" @click="next">
<img src="@/assets/images/activity/next.png" alt="" />
</div>
</swiper>
</transition>
<img v-if="showEmpty" class="tra" src="@/assets/images/empty_big_tra.svg" alt="" />
<activityDetail v-if="showDetail" :act-info="currentItem" @close="showDetail = false"></activityDetail>
</div>
<MainActivityDetail v-if="showDetail" :act-info="currentItem" @close="showDetail = false"></MainActivityDetail>
</template>
<script setup lang="ts">
import { Autoplay, FreeMode, Pagination } from 'swiper'
import { ref, shallowRef, watch } from 'vue'
import { getMallActivity, getShopActivity } from '@/http/api/activity'
import MainActivityDetail from '@/components/ActivityDetail/MainActivityDetail.vue'
import ActivityItem from './ActivityItem.vue'
import ActivityItem2 from './ActivityItem2.vue'
import { Autoplay, Pagination } from 'swiper'
import { Swiper, SwiperSlide } from 'swiper/vue'
import 'swiper/css'
import 'swiper/css/free-mode'
import { useStatisticsModel } from '@/composables/useStatistics'
import activityDetail from '@/components/ActivityDetail/ActivityDetail.vue'
import ScrollView from '@/base/ScrollView/ScrollView.vue'
import ActivityItem from './ActivityItem.vue'
import { getMallActivity, getShopActivity } from '@/http/api/activity'
import { ref } from 'vue'
// import switchTab from '@/components/SwitchTab/SwitchTab.vue'
import { useSwitchLanguage } from '@/composables/useSwitchLanguage'
const { switchLanguage } = useSwitchLanguage()
const modules = [Autoplay, FreeMode, Pagination]
/**
const list = [
{
name: '商场活动',
nameEn: 'Community activities',
icon: require('@/assets/images/activity/icon_mall.svg'),
iconSel: require('@/assets/images/activity/icon_mallSel.svg'),
const modules = [Autoplay, Pagination]
fun: () => getData('mall')
},
{
name: '商家活动',
nameEn: 'Brand promotion',
icon: require('../../assets/images/activity/icon_shop.svg'),
iconSel: require('../../assets/images/activity/icon_shopSel.svg'),
fun: () => getData('shop')
}
]
*/
const actList = ref<Activity[]>([])
const switchIdx = ref(0)
const showList = ref(false)
const currentItem = ref<Activity>()
const showDetail = ref(false)
function clickItem(item: Activity) {
useStatisticsModel({ recordType: 2, moduleName: item.activityName, activityCode: item.id })
function clickItem(item: Activity, code: string) {
mySwiper.value.autoplay.stop()
item.list = shopAcList.value.filter(info => info.content.typeId[0] === code)
currentItem.value = item
showDetail.value = true
}
/**
*
* @param index 点击分类
*/
function handleSwitch(index: number) {
if (switchIdx.value === index) {
return
}
switchIdx.value = index
showList.value = false
// list[index].fun()
}
//
const showEmpty = ref(false)
function getData(type: 'mall' | 'shop') {
const fun = type === 'mall' ? getMallActivity() : getShopActivity()
fun.then(res => {
// actList.value = res.data ?? []
for (let t = 0; t < res.data.length; t++) {
actList.value.push({ id: res.data[t].id, ...res.data[t].content })
}
if (!res.data.length) {
showEmpty.value = true
}
showList.value = true
})
const actList = ref([])
const shopAcList = ref([])
getMallActivity().then(({ data }) => {
actList.value = data ?? []
if (!data.length) {
showEmpty.value = true
}
})
getShopActivity().then(({ data }) => {
shopAcList.value = data ?? []
})
//
const mySwiper = shallowRef()
// swiper
function setControlledSwiper(swiper: any) {
mySwiper.value = swiper
}
getData('mall')
//
function pre() {
mySwiper.value.slidePrev()
}
//
function next() {
mySwiper.value.slideNext()
}
//
watch(
() => showDetail.value,
() => {
if (!showDetail.value) {
mySwiper.value.autoplay.start()
}
}
)
</script>
<style lang="scss" scoped>
:deep(.bscroll-horizontal-scrollbar) {
z-index: 3 !important;
width: 500px !important;
background: rgb(0 0 0 / 10%);
border-radius: 6px;
opacity: 1 !important;
.bscroll-indicator {
background: #e00068 !important;
border: none !important;
border-radius: 6px !important;
.activity-container {
padding-top: 212px;
text-align: center;
:deep(.swiper-slide) {
transform: scale(0.86) !important;
backface-visibility: hidden;
transition: all 0.3s;
}
:deep(.swiper-slide-active) {
transform: scale(1) !important;
backface-visibility: hidden;
}
.act-list {
display: flex;
justify-content: center;
margin-top: 40px;
}
}
.activity-container {
overflow: hidden;
padding-top: 172px;
padding-left: 60px;
--animate-duration: 0.5s;
.myswiper {
height: 656px;
text-align: center;
}
.big-title {
font-size: 24px;
font-family: 'font_bold';
color: #534f46;
li:nth-child(2) {
margin-top: 5px;
font-size: 14px;
}
.swiper-prev {
position: absolute;
top: 248px;
left: 40px;
z-index: 1;
img {
width: 64px;
height: 64px;
}
.act-scroll {
position: relative;
width: 1864px;
height: 610px;
margin-top: 40px;
margin-left: 0;
:deep(.swiper-slide) {
width: 880px !important;
height: 575px;
}
.act-list {
// display: flex;
width: fit-content;
white-space: nowrap;
}
}
.swiper-next {
position: absolute;
top: 248px;
right: 40px;
z-index: 1;
img {
width: 64px;
height: 64px;
}
}

150
src/views/Activity/ActivityItem.vue

@ -1,105 +1,42 @@
<template>
<div v-if="showThis" :key="actInfo.id" class="act-item">
<div :key="actInfo.id" class="act-item" @click="clickActItem">
<!-- 图片 -->
<div class="img-container" @click="clickActItem">
<img :src="getBackGround()" alt="" />
<img v-if="actInfo.fileUrl.length === 0" src="@/assets/images/empty_big.svg" alt="" />
<div class="img-container">
<img :src="actInfo.content.coverUrl[0] ? actInfo.content.coverUrl[0] : '@/assets/images/empty_big.svg'" alt="" />
</div>
<!-- 标题 -->
<div class="marquee-wrapper">
<Marquees class="name" :speed="40" :delay="0.8" :content="switchLanguage(actInfo, 'activityName')">{{
switchLanguage(actInfo, 'activityName')
<Marquees class="name" :speed="40" :delay="0.8" :content="switchLanguage(actInfo.content, 'activityName')">{{
switchLanguage(actInfo.content, 'activityName')
}}</Marquees>
</div>
<!-- 介紹无 -->
<scroll-view
v-if="false"
ref="introScrollRef"
class="intro-scroll"
:style="{ height: actInfo.point !== -1 || actInfo.shopCode ? '499px' : null }"
:list="[switchLanguage(actInfo, 'activityContent')]"
:scrollbar="true"
:observe-image="true"
:refresh-delay="500"
>
<p class="intro" v-text="switchLanguage(actInfo, 'activityContent')"></p>
</scroll-view>
<!-- 导航无 -->
<div
v-if="false"
class="attr-container"
:style="{
justifyContent: actInfo.startDate === '' && actInfo.activityAddress === '' ? 'flex-end' : ''
}"
>
<p class="time-tip">
<span v-if="actInfo.startDate" class="act-time">{{ $t('activity.time') + actInfo.startDate + '' + actInfo.endDate }}</span>
<span v-if="actInfo.activityAddress" class="act-time">{{
$t('activity.address') + switchLanguage(actInfo, 'activityAddress')
}}</span>
</p>
<!-- go -->
<div v-if="actInfo.point !== -1 || actInfo.shopCode" class="go" @click="handleGo">
<span>{{ $t('activity.actGo') }}</span>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useStatisticsModel } from '@/composables/useStatistics'
import Marquees from '@/base/Marquees/Marquees.vue'
import scrollView from '@/base/ScrollView/ScrollView.vue'
import { useActivityNav } from '@/composables/useActivityNav'
import { useSwitchLanguage } from '@/composables/useSwitchLanguage'
interface AItem {
actInfo: Activity
actInfo: any
}
const props = defineProps<AItem>()
const emits = defineEmits(['click', 'clickImg'])
const { nav } = useActivityNav()
const emits = defineEmits(['handle'])
const { switchLanguage } = useSwitchLanguage()
const showThis = ref(false)
function clickActItem() {
useStatisticsModel({ recordType: 2, moduleName: props.actInfo.activityName, activityCode: props.actInfo.activityId })
emits('click', props.actInfo)
}
function handleGo() {
nav(props.actInfo)
useStatisticsModel({ recordType: 2, moduleName: props.actInfo.activityName, activityCode: props.actInfo.activityId })
// emits('clickGo', props.actInfo)
}
function getBackGround() {
if (props.actInfo.fileUrl.length) {
return props.actInfo.fileUrl[0]
}
return require('@/assets/images/empty_big.svg')
useStatisticsModel({ recordType: 2, moduleName: props.actInfo.content.activityName, activityCode: props.actInfo.entryCode })
emits('handle', props.actInfo.content, props.actInfo.entryCode)
}
onMounted(() => {
showThis.value = true
})
</script>
<style lang="scss" scoped>
:deep(.bscroll-vertical-scrollbar) {
z-index: 3 !important;
background: rgb(0 0 0 / 3%);
border-radius: 6px;
opacity: 1 !important;
.bscroll-indicator {
background: rgb(0 0 0 / 6%) !important;
border: none !important;
border-radius: 6px !important;
}
}
.act-item {
position: relative;
display: inline-flex;
overflow: hidden;
width: 880px;
height: 575px;
width: 1024px;
height: 656px;
padding-bottom: 0;
margin-right: 32px;
background-color: #fff;
@ -110,12 +47,12 @@ onMounted(() => {
.img-container {
position: relative;
width: inherit;
height: 495px;
height: 576px;
background: #ebebeb00;
img {
width: 880px;
height: 495px;
width: 1024px;
height: 576px;
border-radius: 16px;
}
}
@ -136,64 +73,5 @@ onMounted(() => {
color: rgb(0 0 0 / 70%);
}
}
.intro-scroll {
position: relative;
overflow: hidden;
width: 544px;
height: 100%;
padding: 0;
padding-right: 20px;
margin-top: 5px;
margin-left: 48px;
border-radius: 0;
.intro {
font-size: 14px;
font-family: 'font_medium';
text-align: justify;
white-space: pre-wrap;
color: rgb(0 0 0 / 60%);
line-height: 200%;
:deep(img) {
width: 100%;
}
}
}
.attr-container {
display: flex;
justify-content: space-between;
align-items: flex-end;
height: 44px;
padding: 0 48px;
margin-top: 16px;
.time-tip {
display: flex;
flex-direction: column;
justify-content: flex-end;
width: 415px;
height: 48px;
margin-bottom: 0;
font-size: 14px;
font-family: 'font_regular';
color: #d0b186;
.act-time {
&:nth-child(2) {
@include no-wrap();
margin-top: 5px;
}
}
}
.go {
width: 115px;
height: 38px;
font-size: 20px;
font-family: 'font_bold';
text-align: center;
color: #fff;
background: linear-gradient(180deg, #c7a77b 0%, #d6bb97 100%);
border-radius: 90px;
line-height: 38px;
}
}
}
</style>

77
src/views/Activity/ActivityItem2.vue

@ -0,0 +1,77 @@
<template>
<div :key="actInfo.id" class="act-item" @click="clickActItem">
<!-- 图片 -->
<div class="img-container">
<img :src="actInfo.content.coverUrl[0] ? actInfo.content.coverUrl[0] : '@/assets/images/empty_big.svg'" alt="" />
</div>
<!-- 标题 -->
<div class="marquee-wrapper">
<Marquees class="name" :speed="40" :delay="0.8" :content="switchLanguage(actInfo.content, 'activityName')">{{
switchLanguage(actInfo.content, 'activityName')
}}</Marquees>
</div>
</div>
</template>
<script setup lang="ts">
import { useStatisticsModel } from '@/composables/useStatistics'
import Marquees from '@/base/Marquees/Marquees.vue'
import { useSwitchLanguage } from '@/composables/useSwitchLanguage'
interface AItem {
actInfo: any
}
const props = defineProps<AItem>()
const emits = defineEmits(['handle'])
const { switchLanguage } = useSwitchLanguage()
function clickActItem() {
useStatisticsModel({ recordType: 2, moduleName: props.actInfo.content.activityName, activityCode: props.actInfo.entryCode })
emits('handle', props.actInfo.content, props.actInfo.entryCode)
}
</script>
<style lang="scss" scoped>
.act-item {
position: relative;
display: inline-flex;
overflow: hidden;
width: 880px;
height: 575px;
padding-bottom: 0;
margin-right: 32px;
background-color: #fff;
border-radius: 16px;
flex-direction: column;
--animate-duration: 0.5s;
.img-container {
position: relative;
width: inherit;
height: 495px;
background: #ebebeb00;
img {
width: 880px;
height: 495px;
border-radius: 16px;
}
}
.marquee-wrapper {
flex-shrink: 0;
overflow: hidden;
width: 800px;
height: 32px;
margin-top: 24px;
margin-left: 40px;
white-space: nowrap;
.name {
display: inline-block;
font-weight: 700;
font-size: 24px;
line-height: inherit;
font-family: 'font_bold';
color: rgb(0 0 0 / 70%);
}
}
}
</style>
Loading…
Cancel
Save