index.vue 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. <route lang="json">
  2. {
  3. "style": {
  4. "navigationBarTitleText": "设计游学",
  5. "navigationBarBackgroundColor": "#fff"
  6. }
  7. }
  8. </route>
  9. <script lang="ts" setup>
  10. import Card from '@/components/card.vue'
  11. import MomentItem from '@/components/moment-item.vue'
  12. import SectionHeading from '@/components/section-heading.vue'
  13. import ClassItem from '../components/class-item.vue'
  14. import { storeToRefs } from 'pinia'
  15. import { useUserStore } from '@/store'
  16. import {
  17. getAppMemberLevelConfigs,
  18. getBanners,
  19. getCircles,
  20. getContents,
  21. getStudyTours,
  22. } from '../../../core/libs/requests'
  23. import { handleUpvoteClick } from '@/core/libs/actions'
  24. import { NetImages } from '../../../core/libs/net-images'
  25. import { BannerMode } from '../../../core/libs/models'
  26. import { useRouter } from '../../../core/utils/router'
  27. import PageHelper from '@/components/page-helper.vue'
  28. import RegisterCard from './components/register-card.vue'
  29. import { ComponentExposed } from 'vue-component-type-helpers'
  30. const pageHelperRef = ref<ComponentExposed<typeof PageHelper>>()
  31. const currentBanner = ref(0)
  32. const handleSwiperChange = ({ detail: { current } }) => {
  33. currentBanner.value = current
  34. }
  35. const userStore = useUserStore()
  36. const { userInfo } = storeToRefs(userStore)
  37. const shareOptions = ref()
  38. const router = useRouter()
  39. const { data: studyTours, run: setStudyTours } = useRequest(() =>
  40. getStudyTours({ headRecommend: 1 }),
  41. )
  42. const { data: classmates, run: setClassmates } = useRequest(
  43. () => getContents({ contentCategory: '101', pageSize: '2' }),
  44. { initialData: { list: [] } },
  45. )
  46. const { data: banners, run: setBanners } = useRequest(
  47. () => getBanners({ mode: BannerMode.StudyTour }),
  48. { initialData: [] },
  49. )
  50. const { data: levels, run: setLevels } = useRequest(() => getAppMemberLevelConfigs(), {
  51. initialData: [],
  52. })
  53. const handleLike = async (options) => {
  54. await handleUpvoteClick({
  55. ...options,
  56. userId: userInfo.value.userId,
  57. userName: userInfo.value.nickname,
  58. })
  59. await pageHelperRef.value?.refresh()
  60. }
  61. const levelsByMemberLevel = computed(() =>
  62. levels.value.reduce((acc, item) => {
  63. acc[item.memberLevel] = item
  64. return acc
  65. }, {}),
  66. )
  67. onMounted(async () => {
  68. await Promise.all([setLevels(), setStudyTours(), setClassmates(), setBanners()])
  69. })
  70. onShow(async () => {
  71. await pageHelperRef.value?.reload()
  72. })
  73. </script>
  74. <template>
  75. <view class="flex-grow flex flex-col gap-6 p-3.5">
  76. <div class="">
  77. <!-- <TimeLine></TimeLine> -->
  78. <template v-if="banners.length">
  79. <div class="aspect-[1.73/1]">
  80. <wd-img
  81. width="100%"
  82. height="100%"
  83. custom-class="aspect-[1.73/1]"
  84. :src="banners[0].bannerImgUrl"
  85. @click="
  86. router.push(
  87. `/pages-sub/home/study-tour/list?designStudyAbroadYear=${banners[0].designStudyAbroadYear}&designDesc=${banners[0].designDesc}`,
  88. )
  89. "
  90. ></wd-img>
  91. </div>
  92. </template>
  93. </div>
  94. <div class="relative">
  95. <template v-if="studyTours?.list.length">
  96. <swiper class="aspect-[0.75/1] rounded-[20px] overflow-hidden" @change="handleSwiperChange">
  97. <template v-for="(it, i) in studyTours?.list" :key="i">
  98. <swiper-item>
  99. <RegisterCard :options="{ ...it, levelsByMemberLevel }"></RegisterCard>
  100. </swiper-item>
  101. </template>
  102. </swiper>
  103. </template>
  104. <div class="absolute flex gap-1 dots">
  105. <template v-for="(it, i) in studyTours?.list" :key="i">
  106. <div
  107. class="w-1 h-1 rounded-full"
  108. :class="`${currentBanner === i ? 'bg-white bg-active' : 'bg-white/40'}`"
  109. ></div>
  110. </template>
  111. </div>
  112. </div>
  113. <!-- </template>
  114. </PageHelper> -->
  115. <!-- <card custom-class="p-0!">
  116. <view class="relative">
  117. <wd-img
  118. custom-class="vertical-bottom"
  119. width="100%"
  120. height="275"
  121. src="https://via.placeholder.com/347x464"
  122. ></wd-img>
  123. <div
  124. class="w-[63px] h-[29px] bg-black/60 rounded-[20px] backdrop-blur-[15px] absolute top-5 right-3.5 flex items-center justify-center"
  125. >
  126. <div class="text-white text-sm font-normal font-['PingFang_SC'] leading-relaxed">
  127. 报名中
  128. </div>
  129. </div>
  130. <view class="absolute left-3.5 bottom-2.5 flex items-center">
  131. <avatar-group-casual
  132. :show-number="3"
  133. :urls="[
  134. 'https://via.placeholder.com/20x20',
  135. 'https://via.placeholder.com/20x20',
  136. 'https://via.placeholder.com/20x20',
  137. ]"
  138. ></avatar-group-casual>
  139. <div
  140. class="ml-1 text-white/60 text-sm font-normal font-['PingFang_SC'] leading-[10.18px]"
  141. >
  142. 40人已报名
  143. </div>
  144. </view>
  145. </view>
  146. <div class="bg-[#27130d]/50 rounded-bl-2xl rounded-br-2xl backdrop-blur-[20px] p-3.5">
  147. <div class="w-[293px] text-white text-xl font-normal font-['PingFang_SC'] leading-relaxed">
  148. 日本研学·东京艺术大学设计游学
  149. </div>
  150. <view class="flex items-center">
  151. <div class="text-white/60 text-sm font-normal font-['PingFang_SC'] leading-[34px]">
  152. 游学时间:
  153. </div>
  154. <div class="text-white/60 text-base font-normal font-['PingFang_SC'] leading-[34px]">
  155. 07.15 08.10
  156. </div>
  157. </view>
  158. <div
  159. class="text-justify text-white/60 text-sm font-normal font-['PingFang_SC'] leading-relaxed"
  160. >
  161. 等级限制:黄金会员以上
  162. </div>
  163. <view class="flex items-center justify-between">
  164. <view class="flex items-end">
  165. <div class="text-white text-3xl font-bold font-['D-DIN_Exp'] leading-normal">16000</div>
  166. <div class="ml-1 text-white/60 text-sm font-normal font-['PingFang_SC'] leading-[34px]">
  167. 积分
  168. </div>
  169. </view>
  170. <tilted-button custom-class="" size="large" color="white">立即报名</tilted-button>
  171. </view>
  172. </div>
  173. </card> -->
  174. <card custom-class="">
  175. <div class="my-7.5 text-black text-xl font-normal font-['PingFang_SC'] leading-[10.18px]">
  176. 筑巢荟-设计游学
  177. </div>
  178. <div
  179. class="text-justify text-black/40 text-base font-normal font-['PingFang_SC'] leading-relaxed"
  180. >
  181. 我们为您精心打造了一个独特且极具价值的游学项目。这个项目的核心旨在全方位提升您作为设计师的能力。
  182. 在这里,您将拥有无比优质的游学资源。我们与全球知名的设计学府、顶尖设计工作室以及具有代表性的经典建筑和室内空间建立了紧密合作。您将有机会深入这些卓越的场所,亲身体验最前沿的设计理念和实践。
  183. 参与专业的研讨会和工作坊,与同行们分享见解、碰撞思维火花,进一步深化对设计的理解。
  184. </div>
  185. </card>
  186. <section-heading
  187. custom-class=""
  188. title="同学荟"
  189. path="/pages-sub/home/classmates/index"
  190. ></section-heading>
  191. <template v-for="(it, i) in classmates.list" :key="i">
  192. <ClassItem :options="it"></ClassItem>
  193. </template>
  194. <wd-status-tip
  195. v-if="!classmates.list?.length"
  196. :image="NetImages.NotContent"
  197. tip="暂无内容"
  198. ></wd-status-tip>
  199. <section-heading custom-class="" title="设计圈"></section-heading>
  200. <PageHelper
  201. ref="pageHelperRef"
  202. :request="getCircles"
  203. :query="{ tagName: '设计游学' }"
  204. class="flex-grow flex flex-col"
  205. >
  206. <template #default="{ source }">
  207. <div class="flex-grow flex flex-col gap-6">
  208. <template v-for="(it, i) in source.list" :key="i">
  209. <MomentItem :options="it" @like="handleLike"></MomentItem>
  210. </template>
  211. </div>
  212. </template>
  213. </PageHelper>
  214. </view>
  215. </template>
  216. <style scoped>
  217. .dots {
  218. bottom: 20rpx;
  219. left: 50%;
  220. transform: translateX(-50%);
  221. }
  222. .bg-active {
  223. width: 40rpx;
  224. }
  225. :deep(.level-circle) {
  226. top: -10rpx;
  227. left: -5rpx;
  228. }
  229. </style>