Browse Source

feat(moment): 圈子详情

EvilDragon 6 months ago
parent
commit
f71e331ec6

+ 1 - 1
pages.config.ts

@@ -30,7 +30,7 @@ export default defineUniPages({
       {
         // iconPath: 'static/tabbar/home.png',
         // selectedIconPath: 'static/tabbar/homeHL.png',
-        pagePath: 'pages/index/index',
+        pagePath: 'pages/home/index',
         // text: '首页',
       },
       {

+ 5 - 0
src/assets/svgs/thumbs-up.svg

@@ -0,0 +1,5 @@
+<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="Frame">
+<path id="Rectangle 1361 (Stroke)" fill-rule="evenodd" clip-rule="evenodd" d="M7.42562 3.17905C7.57957 1.71013 9.23209 0.656129 10.6019 1.47798C10.7337 1.55709 10.8976 1.6749 11.0236 1.85676C11.2162 2.13485 11.5 2.68511 11.5 3.49997V5.50011C11.5 5.77616 11.7238 5.99997 12 5.99997H14.6126C15.6364 5.99997 16.3594 7.00302 16.0356 7.97431L13.7023 14.9743C13.4981 15.5868 12.9249 16 12.2792 16H6.5C5.67157 16 5 15.3284 5 14.5V9.49997C5 9.22383 5.22386 8.99997 5.5 8.99997C5.77614 8.99997 6 9.22383 6 9.49997V14.5C6 14.7761 6.22386 15 6.5 15H12.2792C12.4945 15 12.6855 14.8623 12.7536 14.6581L15.0869 7.65808C15.1948 7.33432 14.9539 6.99997 14.6126 6.99997H12C11.1717 6.99997 10.5 6.32863 10.5 5.50011V3.49997C10.5 2.92919 10.3038 2.57381 10.2016 2.42626C10.1905 2.41024 10.1619 2.38022 10.0874 2.33548C9.4464 1.9509 8.51064 2.42009 8.42017 3.28328C8.34714 3.9801 8.21299 4.73364 7.93961 5.23817C7.41288 6.21029 6.74468 6.67492 6.39904 6.86271C6.20019 6.97075 5.99384 6.99997 5.82167 6.99997H3C2.72386 6.99997 2.5 7.22383 2.5 7.49997V14.5C2.5 14.7761 2.72386 15 3 15H3.5C3.77614 15 4 15.2238 4 15.5C4 15.7761 3.77614 16 3.5 16H3C2.17157 16 1.5 15.3284 1.5 14.5V7.49997C1.5 6.67154 2.17157 5.99997 3 5.99997H5.82167C5.88541 5.99997 5.91319 5.98861 5.92163 5.98403C6.13346 5.86894 6.6437 5.53079 7.06039 4.76177C7.23082 4.44722 7.35308 3.87111 7.42562 3.17905Z" fill="black" fill-opacity="0.45"/>
+</g>
+</svg>

+ 6 - 1
src/components/moment-item.vue

@@ -27,6 +27,11 @@ const props = defineProps({
   },
 })
 const imgClass = ref('')
+const toDetail = () => {
+  uni.navigateTo({
+    url: '/pages/home/moment/index',
+  })
+}
 
 onMounted(async () => {
   console.log('加载')
@@ -44,7 +49,7 @@ onMounted(async () => {
 })
 </script>
 <template>
-  <Card>
+  <Card @click="toDetail" @tap="toDetail">
     <view class="flex items-center">
       <view class="overflow-hidden rounded-full mr-2">
         <wd-img

+ 56 - 1
src/core/libs/requests.ts

@@ -1,5 +1,7 @@
 import { http, httpGet } from '@/utils/http'
 import { Schedule } from '../models/schedule'
+import { Moment } from '../models/moment'
+import dayjs from 'dayjs'
 
 export const getUserInfo = () =>
   httpGetMock<any>({
@@ -29,6 +31,59 @@ export const getSchedule = () =>
       },
     ],
   })
-
+export const getMoment = () =>
+  httpGetMock<Moment>({
+    author: {
+      avatar: 'https://via.placeholder.com/35x35',
+      nickname: '苏小萌',
+      level: '0',
+    },
+    content: '用心做好设计,为客户创造美好家居环境',
+    images: [
+      'https://via.placeholder.com/165x220',
+      'https://via.placeholder.com/220x220',
+      'https://via.placeholder.com/165x220',
+    ],
+    tags: ['意大利游学设计班'],
+    shares: 0,
+    comments: 0,
+    likes: 0,
+    createdAt: dayjs('2024-07-15').toDate(),
+    commentList: [
+      {
+        id: 1,
+        author: {
+          avatar: 'https://via.placeholder.com/28x28',
+          nickname: '李一鸣设计师',
+          level: '',
+        },
+        content: '哇~你真的好厉害,棒棒棒',
+        createdAt: dayjs('2024-07-15').toDate(),
+        childrens: [
+          {
+            id: 3,
+            parentId: 1,
+            author: {
+              avatar: 'https://via.placeholder.com/28x28',
+              nickname: '李一鸣设计师',
+              level: '',
+            },
+            content: '这个是去参加了意大利游学活动',
+            createdAt: undefined,
+          },
+        ],
+      },
+      {
+        id: 2,
+        author: {
+          avatar: 'https://via.placeholder.com/28x28',
+          nickname: '王莉莎',
+          level: '',
+        },
+        content: '这个活动怎么参加呢?',
+        createdAt: undefined,
+      },
+    ],
+  })
 export const httpGetMock = <T>(data: T) =>
   new Promise<IResData<T>>((resolve) => resolve({ code: 1, msg: '', data } as IResData<T>))

+ 2 - 1
src/core/libs/svgs.ts

@@ -7,4 +7,5 @@ import award from '@/assets/svgs/award.svg'
 import camera from '@/assets/svgs/camera.svg'
 import scheduleCardBg from '@/assets/svgs/schedule-card-bg.svg'
 import map from '@/assets/svgs/map.svg'
-export { polygon16, frame, peoples, right, wechat, award, camera, scheduleCardBg, map }
+import thumbsUp from '@/assets/svgs/thumbs-up.svg'
+export { polygon16, frame, peoples, right, wechat, award, camera, scheduleCardBg, map, thumbsUp }

+ 0 - 0
src/core/models/comment.ts


+ 41 - 0
src/core/models/moment.ts

@@ -0,0 +1,41 @@
+export interface Moment {
+  // {
+  //     author: {
+  //       avatar: 'https://via.placeholder.com/35x35',
+  //       nickname: '苏小萌',
+  //       level: '0',
+  //     },
+  //     content: '用心做好设计,为客户创造美好家居环境',
+  //     images: ['https://via.placeholder.com/165x220'],
+  //     tags: ['意大利游学设计班'],
+  //     shares: 0,
+  //     comments: 0,
+  //     likes: 0,
+  //     createdAt: dayjs('2024-07-15').toDate(),
+  //   },
+  author: {
+    avatar: string
+    nickname: string
+    level: string
+  }
+  content: string
+  images: string[]
+  tags: string[]
+  shares: number
+  comments: number
+  likes: number
+  createdAt: Date
+  commentList?: Comment[]
+}
+export interface Comment {
+  id: number
+  author: {
+    avatar: string
+    nickname: string
+    level: string
+  }
+  content: string
+  createdAt: Date
+  parentId?: number
+  childrens?: Comment[]
+}

+ 1 - 1
src/layouts/default.vue

@@ -1,6 +1,6 @@
 <template>
   <wd-config-provider class="flex-grow flex flex-col" style="flex-grow: 1" :themeVars="themeVars">
-    <view class="bg-[#f6f6f6] pb-20 flex-grow">
+    <view class="bg-[#f6f6f6] pb-20 flex-grow flex">
       <slot />
     </view>
     <wd-toast />

+ 9 - 1
src/pages.json

@@ -25,7 +25,7 @@
     "height": "0px",
     "list": [
       {
-        "pagePath": "pages/index/index"
+        "pagePath": "pages/home/index"
       },
       {
         "pagePath": "pages/about/about"
@@ -95,6 +95,14 @@
       }
     },
     {
+      "path": "pages/home/moment/index",
+      "type": "page",
+      "style": {
+        "navigationBarTitleText": "详情",
+        "navigationBarBackgroundColor": "#fff"
+      }
+    },
+    {
       "path": "pages/home/offline-activity/index",
       "type": "page",
       "style": {

+ 52 - 0
src/pages/home/components/comment-item.vue

@@ -0,0 +1,52 @@
+<script setup lang="ts">
+import { thumbsUp } from '@/core/libs/svgs'
+import { Comment } from '@/core/models/moment'
+import { dayjs } from 'wot-design-uni'
+
+defineProps({
+  options: {
+    type: Object as PropType<Comment>,
+    default: () => ({}),
+  },
+  isChild: {
+    type: Boolean,
+    default: false,
+  },
+})
+</script>
+<template>
+  <view class="grid grid-cols-[28px_1fr_28px] gap-2.5" :class="isChild ? 'ml-9' : ''">
+    <wd-img
+      custom-class="rounded-full overflow-hidden col-start-1 row-start-1"
+      width="28"
+      height="28"
+      :src="options.author.avatar"
+    />
+    <view class="col-start-2 row-start-1">
+      <div class="text-black/40 text-xs font-normal font-['PingFang SC'] leading-[10.18px]">
+        {{ options.author.nickname }}
+      </div>
+      <div class="my-3 text-black/90 text-sm font-normal font-['PingFang SC'] leading-[10.18px]">
+        {{ options.content }}
+      </div>
+      <view class="flex items-center mt--2">
+        <div class="text-black/30 text-[10px] font-normal font-['PingFang SC'] leading-[10.18px]">
+          {{ dayjs(options.createdAt).format('YYYY/MM/DD') }}
+        </div>
+        <view class="ml-3">
+          <wd-button custom-class="text-2.5!" type="text">回复</wd-button>
+        </view>
+      </view>
+    </view>
+    <view class="col-start-3 row-start-1 flex flex-col items-center">
+      <div class="w-[18px] h-[18px] relative">
+        <wd-img :src="thumbsUp" width="18" height="18"></wd-img>
+      </div>
+      <div
+        class="mt-1.5 text-black/40 text-[10px] font-normal font-['PingFang SC'] leading-[10.18px]"
+      >
+        20
+      </div>
+    </view>
+  </view>
+</template>

+ 147 - 0
src/pages/home/moment/index.vue

@@ -0,0 +1,147 @@
+<route lang="yaml">
+style:
+  navigationBarTitleText: '详情'
+  navigationBarBackgroundColor: '#fff'
+</route>
+<script setup lang="ts">
+import SectionHeading from '@/components/section-heading.vue'
+import Tag from '@/components/tag.vue'
+import { getMoment } from '@/core/libs/requests'
+import { thumbsUp } from '@/core/libs/svgs'
+import dayjs from 'dayjs'
+import CommentItem from '../components/comment-item.vue'
+import AvatarGroupCasual from '@/components/avatar-group-casual/avatar-group-casual.vue'
+
+const { data, run } = useRequest(getMoment)
+const current = ref(0)
+const swiperSizes = ref()
+const swiperStyle = ref()
+const handleChange = ({ detail: { current } }) => {
+  swiperStyle.value = {
+    height: swiperSizes.value[current].height + 'px',
+  }
+}
+const setSwiperStyle = async () => {
+  const { screenWidth } = await uni.getSystemInfo()
+  swiperSizes.value = (
+    await Promise.all(data.value.images.map((src) => uni.getImageInfo({ src })))
+  ).map(({ width, height }) => ({ width: screenWidth, height: height / (width / screenWidth) }))
+  swiperStyle.value = {
+    height: swiperSizes.value[0].height + 'px',
+  }
+}
+onMounted(async () => {
+  await run()
+  await setSwiperStyle()
+})
+</script>
+<template>
+  <view class="bg-white flex-grow">
+    <!-- <div class="my-4 text-black/90 text-lg font-normal font-['PingFang SC'] leading-[10.18px]">
+      {{ data?.content }}
+    </div> -->
+    <template v-if="swiperSizes">
+      <swiper :style="swiperStyle" @change="handleChange">
+        <template v-for="it of data?.images" :key="it">
+          <swiper-item>
+            <wd-img width="100%" :src="it" mode="widthFix"></wd-img>
+          </swiper-item>
+        </template>
+      </swiper>
+    </template>
+    <!-- <wd-swiper
+      v-model="current"
+      custom-class="my-1"
+      autoplay="false"
+      :list="data?.images"
+      :indicator="{ type: 'fraction' }"
+      indicatorPosition="top-right"
+      imageMode="widthFix"
+    ></wd-swiper> -->
+    <view class="m-3.5">
+      <div class="text-black/90 text-base font-normal font-['PingFang SC'] leading-[10.18px]">
+        用心做好设计,为客户创造美好家居环境
+      </div>
+      <view class="my-5.5">
+        <!-- <TiltedButton>按钮</TiltedButton> -->
+        <template v-for="it of data?.tags" :key="it">
+          <Tag>{{ it }}</Tag>
+        </template>
+      </view>
+      <div class="text-black/30 text-xs font-normal font-['PingFang SC'] leading-[10.18px]">
+        2024-5-31 10:06
+      </div>
+      <view class="flex items-center my-4">
+        <view class="flex items-center">
+          <avatar-group-casual
+            :show-number="3"
+            :urls="[
+              'https://via.placeholder.com/20x20',
+              'https://via.placeholder.com/20x20',
+              'https://via.placeholder.com/20x20',
+            ]"
+          ></avatar-group-casual>
+          <div
+            class="ml-1 text-black/60 text-sm font-normal font-['PingFang SC'] leading-[10.18px]"
+          >
+            40人赞过
+          </div>
+        </view>
+        <view class="flex-1"></view>
+        <view><wd-icon class="text-black/65" name="arrow-right" size="22px"></wd-icon></view>
+      </view>
+      <!-- <SectionHeading :title="`评论 ${data.comments}`"></SectionHeading> -->
+      <view class="flex items-center my-8">
+        <div class="text-black/90 text-base font-normal font-['PingFang SC'] leading-[10.18px]">
+          {{ `评论 ${data?.comments}` }}
+        </div>
+        <view class="flex-1"></view>
+        <div class="text-black/90 text-xs font-normal font-['PingFang SC'] leading-[10.18px]">
+          按热度
+        </div>
+        <div class="mx-2 text-black/40 text-xs font-normal font-['PingFang SC'] leading-[10.18px]">
+          |
+        </div>
+        <div class="text-black/40 text-xs font-normal font-['PingFang SC'] leading-[10.18px]">
+          按时间
+        </div>
+      </view>
+
+      <view>
+        <template v-for="it of data?.commentList" :key="it.id">
+          <CommentItem :options="it" :isChild="false"></CommentItem>
+          <template v-for="child of it.childrens" :key="child.id">
+            <CommentItem :options="child" :isChild="true"></CommentItem>
+          </template>
+        </template>
+      </view>
+    </view>
+    <div
+      class="fixed bottom-0 left-0 right-0 border-t border-t-solid border-[#ececec] h-[54px] bg-white flex items-center px-3.5"
+    >
+      <div class="w-[168px] bg-[#f6f6f6] rounded-[60px] px-3.5 py-2 flex items-center">
+        <wd-input custom-class="bg-transparent!" no-border></wd-input>
+      </div>
+      <view class="flex justify-around flex-1">
+        <view
+          class="flex flex-col items-center text-[rgba(0,0,0,0.85)] text-3.5 font-400 line-height-5.5"
+        >
+          <wd-img width="15" height="15" src="/static/svgs/share.svg"></wd-img>
+          <view class="">{{ data.shares }}</view>
+        </view>
+        <view
+          class="flex flex-col items-center text-[rgba(0,0,0,0.85)] text-3.5 font-400 line-height-5.5"
+        >
+          <wd-img width="15" height="15" src="/static/svgs/comment.svg"></wd-img>
+          <view class="">{{ data.shares }}</view>
+        </view>
+        <view
+          class="flex flex-col items-center text-[rgba(0,0,0,0.85)] text-3.5 font-400 line-height-5.5"
+        >
+          <wd-img width="15" height="15" :src="thumbsUp"></wd-img>
+          <view>{{ data.shares }}</view>
+        </view>
+      </view>
+    </div>
+  </view>
+</template>

+ 2 - 1
src/types/uni-pages.d.ts

@@ -11,6 +11,7 @@ interface NavigateToOptions {
        "/pages/mine/index" |
        "/pages/publish/index" |
        "/pages/home/mall/index" |
+       "/pages/home/moment/index" |
        "/pages/home/offline-activity/index" |
        "/pages/home/schedule/index" |
        "/pages/home/spread/index" |
@@ -19,7 +20,7 @@ interface NavigateToOptions {
 interface RedirectToOptions extends NavigateToOptions {}
 
 interface SwitchTabOptions {
-  url: "/pages/index/index" | "/pages/about/about"
+  url: "/pages/home/index" | "/pages/about/about"
 }
 
 type ReLaunchOptions = NavigateToOptions | SwitchTabOptions;