Browse Source

feat(home): 新增 banner 组件并优化首页布局

EvilDragon 4 months ago
parent
commit
8876575920

+ 4 - 0
packages/app/src/core/libs/requests.ts

@@ -363,6 +363,10 @@ export const getActivitySignups = (query: { activityId: string }) =>
  */
 export const getBanners = (query: { mode: BannerMode }) =>
   httpGet<Banner[]>('/app-api/member/banner/get-by-mode', query)
+/**
+ * 获取Banner
+ */
+export const getBanner = (id) => httpGet<Banner>('/app-api/member/banner/get-by-id', { id })
 export const refreshToken = (refreshToken: string) =>
   httpPost<any>('/app-api/member/auth/refresh-token', {}, { refreshToken })
 export const httpGetMock = <T>(data: T) =>

+ 8 - 0
packages/app/src/pages.json

@@ -143,6 +143,14 @@
       }
     },
     {
+      "path": "pages/home/content/index",
+      "type": "page",
+      "style": {
+        "navigationBarTitleText": "详情",
+        "navigationBarBackgroundColor": "#fff"
+      }
+    },
+    {
       "path": "pages/home/mall/index",
       "type": "page",
       "style": {

+ 44 - 0
packages/app/src/pages/home/components/banner.vue

@@ -0,0 +1,44 @@
+<script setup lang="ts">
+import { getBanners } from '../../../core/libs/requests'
+import { BannerMode } from '../../../core/models/moment'
+import { useRouter } from '../../../core/utils/router'
+
+const props = defineProps<{ mode: BannerMode }>()
+const router = useRouter()
+const { data: banners, run: setBanners } = useRequest(() => getBanners({ mode: props.mode }), {
+  initialData: [],
+})
+const current = ref<number>(0)
+const swiperList = computed(() => banners.value.map((it) => it.bannerImgUrl))
+const handleClick = ({ index }: { index: number }) => {
+  const banner = banners.value[index]
+  console.log(banner)
+  if (banner.bannerDetailsType === '2') {
+    router.push(banner.bannerLinkUrl)
+  }
+  if (banner.bannerDetailsType === '1') {
+    router.push(`/pages/home/content/index?type=banner&id=${banner.id}`)
+  }
+}
+function onChange(e) {
+  //   console.log(e)
+}
+onMounted(() => {
+  setBanners()
+})
+</script>
+<template>
+  <div>
+    <wd-swiper
+      custom-class="rounded-2xl overflow-hidden aspect-[2.71/1]"
+      width="100%"
+      height="100%"
+      :list="swiperList"
+      autoplay
+      v-model:current="current"
+      :indicator="{ type: 'dots-bar' } as any"
+      @click="handleClick"
+      @change="onChange"
+    ></wd-swiper>
+  </div>
+</template>

+ 51 - 0
packages/app/src/pages/home/content/index.vue

@@ -0,0 +1,51 @@
+<route lang="json">
+{
+  "style": {
+    "navigationBarTitleText": "详情",
+    "navigationBarBackgroundColor": "#fff"
+  }
+}
+</route>
+<script setup lang="ts">
+import { logo } from '../../../core/libs/svgs'
+import { getBanner, getContent } from '../../../core/libs/requests'
+import Article from '../components/article.vue'
+import { Content } from '../../../core/models/moment'
+
+const id = ref()
+const type = ref()
+const request = ref<() => Promise<IResData<Partial<Content>>>>()
+const { data, run } = useRequest(() => request.value(), { initialData: {} })
+onLoad(async (query: { id: string; type?: 'banner' }) => {
+  id.value = query.id
+  type.value = query.type
+  if (type.value === 'banner') {
+    request.value = () =>
+      getBanner(id.value).then((res) => ({
+        ...res,
+        data: {
+          title: res.data?.name,
+          contentDetail: res.data?.bannerDetailsContent,
+          createTime: res.data?.createTime.toString(),
+          viewsCount: res.data?.viewCount,
+        },
+      }))
+  } else {
+    request.value = () => getContent({ id: id.value })
+  }
+  await run()
+})
+</script>
+<template>
+  <div class="flex-grow bg-white">
+    <Article
+      :title="data?.title"
+      :author="{ name: '筑巢荟' }"
+      :content="data?.contentDetail"
+      :createAt="data?.createTime"
+      :viewNum="data?.viewsCount"
+    >
+      <template #avatar><wd-img width="28" height="28" :src="logo"></wd-img></template>
+    </Article>
+  </div>
+</template>

+ 4 - 2
packages/app/src/pages/home/mall/index.vue

@@ -15,6 +15,7 @@ import { useRouter } from '../../../core/utils/router'
 import { getBanners, getProductCategories, getProducts } from '../../../core/libs/requests'
 import PageHelper from '@/components/page-helper.vue'
 import { BannerMode } from '../../../core/models/moment'
+import Banner from '../components/banner.vue'
 
 const router = useRouter()
 
@@ -44,7 +45,7 @@ onMounted(async () => {
 
 <template>
   <view class="bg-white flex-grow flex flex-col px-3.5 py-5.5 gap-5.5">
-    <wd-swiper
+    <!-- <wd-swiper
       custom-class="rounded-2xl overflow-hidden aspect-[2.71/1]"
       width="100%"
       height="100%"
@@ -54,10 +55,11 @@ onMounted(async () => {
       :indicator="{ type: 'dots-bar' } as any"
       @click="handleClick"
       @change="onChange"
-    ></wd-swiper>
+    ></wd-swiper> -->
     <!-- <div class="bg-black rounded-2xl pt-11">
       <div class="bg-white rounded-2xl shadow p-3.5"></div>
     </div> -->
+    <Banner :mode="BannerMode.Mall"></Banner>
     <div class="w-full inline-flex gap-2">
       <!-- <div><wd-button type="primary" size="small">GELATO专区</wd-button></div> -->
       <template v-for="(it, i) in categories" :key="i">

+ 4 - 2
packages/app/src/pages/home/spread/design-awards/index.vue

@@ -13,6 +13,7 @@ import ElegantInfoCard from '../../components/elegant-info-card.vue'
 import { getBanners, getContents } from '../../../../core/libs/requests'
 import { NetImages } from '../../../../core/libs/net-images'
 import { BannerMode } from '../../../../core/models/moment'
+import Banner from '../../components/banner.vue'
 
 const { data, run: setData } = useRequest(
   () =>
@@ -45,7 +46,7 @@ onMounted(async () => {
 
 <template>
   <view class="bg-white flex-grow flex flex-col px-3.5 py-5.5 gap-5.5">
-    <wd-swiper
+    <!-- <wd-swiper
       custom-class="rounded-2xl overflow-hidden aspect-[2.71/1]"
       width="100%"
       height="100%"
@@ -55,7 +56,8 @@ onMounted(async () => {
       :indicator="{ type: 'dots-bar' } as any"
       @click="handleClick"
       @change="onChange"
-    ></wd-swiper>
+    ></wd-swiper> -->
+    <Banner :mode="BannerMode.DesignAwards"></Banner>
     <SectionHeading title="筑巢奖"></SectionHeading>
     <template v-for="(it, i) in data.list" :key="i">
       <ElegantInfoCard :options="it"></ElegantInfoCard>

+ 4 - 10
packages/app/src/pages/home/spread/index.vue

@@ -12,9 +12,9 @@ import { useRouter } from '../../../core/utils/router'
 import { getBanners, getContents } from '../../../core/libs/requests'
 import { NetImages } from '../../../core/libs/net-images'
 import { BannerMode } from '../../../core/models/moment'
+import Banner from '../components/banner.vue'
 
 const router = useRouter()
-const current = ref<number>(0)
 const { data, run: setData } = useRequest(
   () =>
     getContents({
@@ -29,7 +29,6 @@ const { data: banners, run: setBanners } = useRequest(
   { initialData: [] },
 )
 
-const swiperList = computed(() => banners.value.map((it) => it.bannerImgUrl))
 const menus = ref([
   {
     title: '微信代运营',
@@ -50,12 +49,6 @@ const menus = ref([
     path: '/pages/home/spread/case-shooting/index',
   },
 ])
-function handleClick(e) {
-  console.log(e)
-}
-function onChange(e) {
-  console.log(e)
-}
 onMounted(async () => {
   await setData()
   await setBanners()
@@ -64,7 +57,7 @@ onMounted(async () => {
 
 <template>
   <view class="px-3.5 py-5.5">
-    <wd-swiper
+    <!-- <wd-swiper
       custom-class="rounded-2xl overflow-hidden aspect-[2.71/1]"
       width="100%"
       height="100%"
@@ -74,7 +67,8 @@ onMounted(async () => {
       :indicator="{ type: 'dots-bar' } as any"
       @click="handleClick"
       @change="onChange"
-    ></wd-swiper>
+    ></wd-swiper> -->
+    <Banner :mode="BannerMode.Spread"></Banner>
 
     <view class="my-6 grid gap-2.5 grid-cols-2">
       <template v-for="it of menus" :key="it.title">

+ 11 - 13
packages/app/src/pages/home/study-tour/index.vue

@@ -16,6 +16,7 @@ import { getBanners, getCircles, getContents } from '../../../core/libs/requests
 import { NetImages } from '../../../core/libs/net-images'
 import { BannerMode } from '../../../core/models/moment'
 import { useRouter } from '../../../core/utils/router'
+import PageHelper from '@/components/page-helper.vue'
 
 const router = useRouter()
 const { data: studyTours, run: setStudyTours } = useRequest(() => getContents({ contentType: '1' }))
@@ -23,9 +24,6 @@ const { data: classmates, run: setClassmates } = useRequest(
   () => getContents({ contentType: '1', contentCategory: '101', pageSize: '2' }),
   { initialData: { list: [] } },
 )
-const { data: circles, run: setCircles } = useRequest(() => getCircles({ tagName: '' }), {
-  initialData: { list: [] },
-})
 const { data: banners, run: setBanners } = useRequest(
   () => getBanners({ mode: BannerMode.StudyTour }),
   { initialData: [] },
@@ -33,7 +31,6 @@ const { data: banners, run: setBanners } = useRequest(
 onMounted(async () => {
   await setStudyTours()
   await setClassmates()
-  // await setCircles()
   await setBanners()
 })
 </script>
@@ -135,14 +132,15 @@ onMounted(async () => {
       :image="NetImages.NotContent"
       tip="暂无内容"
     ></wd-status-tip>
-    <section-heading custom-class="my-6" title="设计圈"></section-heading>
-    <template v-for="(it, i) in circles.list" :key="i">
-      <moment-item :options="it"></moment-item>
-    </template>
-    <wd-status-tip
-      v-if="!circles.list?.length"
-      :image="NetImages.NotContent"
-      tip="暂无内容"
-    ></wd-status-tip>
+    <section-heading custom-class="" title="设计圈"></section-heading>
+    <PageHelper :request="getCircles" :query="{}" class="flex-grow flex flex-col">
+      <template #default="{ source }">
+        <div class="flex-grow flex flex-col gap-6">
+          <template v-for="(it, i) in source.list" :key="i">
+            <MomentItem :options="it"></MomentItem>
+          </template>
+        </div>
+      </template>
+    </PageHelper>
   </view>
 </template>

+ 4 - 2
packages/app/src/pages/material/index.vue

@@ -10,6 +10,7 @@ import { getAppMaterials, getBanners, getByDictType } from '../../core/libs/requ
 import { materialDealers, close, phone } from '../../core/libs/svgs'
 import { BannerMode, DictType, MaterialDealer, MaterialsList } from '../../core/models/moment'
 import router from '@designer-hub/assets/src/assets/svgs/router'
+import Banner from '../home/components/banner.vue'
 
 const { data: materialDealerData, run: setMaterialDealerData } = useRequest(
   () => getAppMaterials(),
@@ -95,7 +96,7 @@ onMounted(async () => {
         height="100%"
         src="https://image.zhuchaohui.com/zhucaohui/f866f4f72392e8f4627d8f5d6628739ad7f0907d3703139e7cdbcb999b803dfe.jpg"
       /> -->
-      <wd-swiper
+      <!-- <wd-swiper
         custom-class="rounded-2xl overflow-hidden aspect-[1.26/1]"
         width="100%"
         height="100%"
@@ -105,7 +106,8 @@ onMounted(async () => {
         :indicator="{ type: 'dots-bar' } as any"
         @click="handleClick"
         @change="onChange"
-      ></wd-swiper>
+      ></wd-swiper> -->
+      <Banner :mode="BannerMode.Material"></Banner>
     </view>
     <view class="bg-[#f6f6f6] relative bottom-4 rounded-t-2xl py-1">
       <div class="my-6 grid grid-cols-2 grid-gap-3.5 mx-3.5">

+ 1 - 0
packages/app/src/types/uni-pages.d.ts

@@ -13,6 +13,7 @@ interface NavigateToOptions {
        "/pages/home/about/index" |
        "/pages/home/classmates/index" |
        "/pages/home/classmates-detail/index" |
+       "/pages/home/content/index" |
        "/pages/home/mall/index" |
        "/pages/home/moment/index" |
        "/pages/home/offline-activity/index" |