index.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <route lang="json5">
  2. {
  3. style: {
  4. navigationBarTitleText: '线下活动',
  5. navigationBarBackgroundColor: '#fff',
  6. },
  7. }
  8. </route>
  9. <script setup lang="ts">
  10. import SectionHeading from '@/components/section-heading.vue'
  11. import Card from '@/components/card.vue'
  12. import OfflineActivityItem from '../components/offline-activity-item.vue'
  13. import {
  14. getAllCategories,
  15. getContents,
  16. getActivities,
  17. getAppMemberLevelConfigs,
  18. } from '../../../core/libs/requests'
  19. import { strip, leaderboardText } from '@designer-hub/assets/src/assets/svgs'
  20. import { NetImages } from '../../../core/libs/net-images'
  21. import RegisterCard from '../components/register-card.vue'
  22. import PageHelper from '@/components/page-helper.vue'
  23. const { data: categories, run: setCategories } = useRequest(() => getAllCategories(), {
  24. initialData: [],
  25. })
  26. const currentBanner = ref(0)
  27. const tab = ref<number>(0)
  28. const contentCategory = ref()
  29. const { data, run: setData } = useRequest(
  30. () =>
  31. getContents({
  32. // contentType: '2',
  33. contentCategory: contentCategory.value,
  34. }),
  35. {
  36. initialData: { list: [] },
  37. },
  38. )
  39. const { data: activities, run: setActivities } = useRequest(
  40. () => getActivities({ headRecommend: 1 }),
  41. {
  42. initialData: { list: [] },
  43. },
  44. )
  45. const { data: levels, run: setLevels } = useRequest(() => getAppMemberLevelConfigs(), {
  46. initialData: [],
  47. })
  48. const handleSwiperChange = ({ detail: { current } }) => {
  49. currentBanner.value = current
  50. }
  51. const levelsByMemberLevel = computed(() =>
  52. levels.value.reduce((acc, item) => {
  53. acc[item.memberLevel] = item
  54. return acc
  55. }, {}),
  56. )
  57. const setContentCategory = (index) => {
  58. contentCategory.value = categories.value.find(({ id }) => id === 2)?.children[index].id.toString()
  59. }
  60. const handleTabChange = ({ index }) => {
  61. setContentCategory(index)
  62. setData()
  63. }
  64. onMounted(async () => {
  65. await setCategories()
  66. setContentCategory(tab.value)
  67. await Promise.all([setActivities(), setData(), setLevels()])
  68. })
  69. </script>
  70. <template>
  71. <view class="flex-grow px-3.5 flex flex-col gap-6 py-7">
  72. <section-heading
  73. custom-class=""
  74. title="线下活动"
  75. path="/pages-sub/home/offline-activity/list/index"
  76. end-text="查看全部"
  77. ></section-heading>
  78. <view class="relative">
  79. <template v-if="activities.list?.length">
  80. <swiper class="aspect-[0.75/1] rounded-[20px] overflow-hidden" @change="handleSwiperChange">
  81. <template v-for="(it, i) in activities.list" :key="i">
  82. <swiper-item>
  83. <RegisterCard :options="{ ...it, levelsByMemberLevel }"></RegisterCard>
  84. </swiper-item>
  85. </template>
  86. </swiper>
  87. <div class="absolute flex gap-1 dots">
  88. <template v-for="(it, i) in activities.list" :key="i">
  89. <div
  90. class="w-1 h-1 rounded-full"
  91. :class="`${currentBanner === i ? 'bg-white bg-active' : 'bg-white/40'}`"
  92. ></div>
  93. </template>
  94. </div>
  95. </template>
  96. </view>
  97. <card custom-class="">
  98. <div class="my-7.5 text-black text-xl font-normal font-['PingFang_SC'] leading-[10.18px]">
  99. 筑巢荟-活动营
  100. </div>
  101. <div
  102. class="text-justify text-black/40 text-base font-normal font-['PingFang_SC'] leading-relaxed"
  103. >
  104. 以师为核心策划线下活动体系,通过深入的交流、创新的体验、贴心的关爱,打造丰富多彩的活动。这一体系旨在创建一个充满互动的平台,促进设计师之间的思想碰撞与灵感交流,同时会为设计师打造专业的线下课程,通过专业的培训和讲座不断成长,提升自身技能和职业素养。
  105. </div>
  106. </card>
  107. <wd-tabs
  108. v-model="tab"
  109. custom-class="bg-transparent!"
  110. slidable="always"
  111. @change="handleTabChange"
  112. >
  113. <block v-for="(it, item) in categories.find(({ id }) => id === 2)?.children" :key="item">
  114. <wd-tab :title="it.name"></wd-tab>
  115. </block>
  116. </wd-tabs>
  117. <Card custom-class="py-2 rounded-lg" v-if="tab === 0">
  118. <div class="flex items-center">
  119. <wd-img width="22" height="22" :src="strip"></wd-img>
  120. <wd-img width="80" :src="leaderboardText" mode="widthFix"></wd-img>
  121. <div class="flex-1">
  122. <section-heading
  123. title="筑巢荟骑行俱乐部"
  124. size="sm"
  125. path="/pages-sub/home/offline-activity/cycling-rankings/index"
  126. ></section-heading>
  127. </div>
  128. </div>
  129. </Card>
  130. <template v-for="(it, index) in data.list" :key="index">
  131. <offline-activity-item class="" :options="it"></offline-activity-item>
  132. </template>
  133. <wd-status-tip
  134. v-if="!data.list?.length"
  135. :image="NetImages.NotContent"
  136. tip="暂无内容"
  137. ></wd-status-tip>
  138. </view>
  139. </template>
  140. <style scoped lang="scss">
  141. .dots{
  142. bottom: 20rpx;
  143. left: 50%;
  144. transform: translateX(-50%);
  145. }
  146. .bg-active{
  147. width:40rpx;
  148. }
  149. :deep(.wd-tabs.is-slide .wd-tabs__nav-item){
  150. padding:0 12px !important;
  151. }
  152. </style>