Browse Source

feat(home): 对接评论功能并优化UI

EvilDragon 5 months ago
parent
commit
2cc9a562f3

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

@@ -204,6 +204,43 @@ export const createCircle = (data: Partial<Circle>) =>
   httpPost<any>('/app-api/member/circle/create', data)
 export const getCircle = (id: string) =>
   httpGet<Partial<CircleRes>>('/app-api/member/circle/get', { id })
+export const createCircleReview = (
+  data: Partial<{
+    circleId: string
+    userId: string | number
+    userName: string
+    reviewContent: string
+    replayReviewId: string
+  }>,
+) => httpPost<any>('/app-api/member/circle-review/create', data)
+export const getCircleReviews = (query: { circleId: string }) =>
+  httpGet<{
+    list: Partial<{
+      id: number
+      circleId: number
+      userId: number
+      userName: string
+      reviewContent: string
+      upvoteCount: any
+      replayReviewId: any
+      reviewTime: number
+      createTime: number
+      replayToUserName: any
+      replayToUserId: any
+      replayFirstId: any
+      upvote: boolean
+      ownDel: boolean
+    }>[]
+  }>('/app-api/member/circle-review/getCircleReviewByCircleId', query)
+export const createCircleReviewUpvote = (
+  data:
+    | {
+        circleId: number
+        userId: number
+        userName: string
+      }
+    | Partial<{ reviewId: number }>,
+) => httpPost('/app-api/member/circle-review-upvote/create', data)
 export const refreshToken = (refreshToken: string) =>
   httpPost<any>('/app-api/member/auth/refresh-token', {}, { refreshToken })
 export const httpGetMock = <T>(data: T) =>

+ 13 - 9
packages/app/src/core/models/moment.ts

@@ -29,13 +29,17 @@ export interface Moment {
 }
 export interface Comment {
   id: number
-  author: {
-    avatar: string
-    nickname: string
-    level: string
-  }
-  content: string
-  createdAt: Date
-  parentId?: number
-  childrens?: Comment[]
+  circleId: number
+  userId: number
+  userName: string
+  reviewContent: string
+  upvoteCount: any
+  replayReviewId: any
+  reviewTime: number
+  createTime: number
+  replayToUserName: any
+  replayToUserId: any
+  replayFirstId: any
+  upvote: boolean
+  ownDel: boolean
 }

+ 7 - 7
packages/app/src/pages/home/components/comment-item.vue

@@ -1,6 +1,6 @@
 <script setup lang="ts">
-import { thumbsUp } from '@/core/libs/svgs'
-import { Comment } from '@/core/models/moment'
+import { thumbsUp } from '../../../core/libs/svgs'
+import { Comment } from '../../../core/models/moment'
 import { dayjs } from 'wot-design-uni'
 
 defineProps({
@@ -20,18 +20,18 @@ defineProps({
       custom-class="rounded-full overflow-hidden col-start-1 row-start-1"
       width="28"
       height="28"
-      :src="options.author.avatar"
+      :src="''"
     />
     <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 }}
+        {{ options.userName }}
       </div>
       <div class="my-3 text-black/90 text-sm font-normal font-['PingFang SC'] leading-[10.18px]">
-        {{ options.content }}
+        {{ options.reviewContent }}
       </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') }}
+          {{ dayjs(options.reviewTime).format('YYYY/MM/DD') }}
         </div>
         <view class="ml-3">
           <wd-button custom-class="text-2.5!" type="text">回复</wd-button>
@@ -45,7 +45,7 @@ defineProps({
       <div
         class="mt-1.5 text-black/40 text-[10px] font-normal font-['PingFang SC'] leading-[10.18px]"
       >
-        20
+        {{ options.upvoteCount || 0 }}
       </div>
     </view>
   </view>

+ 47 - 8
packages/app/src/pages/home/moment/index.vue

@@ -6,17 +6,35 @@ style:
 <script setup lang="ts">
 import SectionHeading from '@/components/section-heading.vue'
 import Tag from '@/components/tag.vue'
-import { getCircle, getMoment } from '../../../core/libs/requests'
+import {
+  createCircleReview,
+  getCircle,
+  getCircleReviews,
+  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'
+import { useUserStore } from '../../../store'
+import { storeToRefs } from 'pinia'
 
+const userStore = useUserStore()
+const { userInfo } = storeToRefs(userStore)
 const id = ref()
 const { data, run } = useRequest(() => getCircle(id.value), { initialData: {} })
+const { data: reviews, run: runGetReviews } = useRequest(
+  () => getCircleReviews({ circleId: id.value }),
+  {
+    initialData: {
+      list: [],
+    },
+  },
+)
 const current = ref(0)
 const swiperSizes = ref()
 const swiperStyle = ref()
+const reviewContent = ref('')
 const handleChange = ({ detail: { current } }) => {
   swiperStyle.value = {
     height: swiperSizes.value[current].height + 'px',
@@ -31,10 +49,25 @@ const setSwiperStyle = async () => {
     height: swiperSizes.value[0].height + 'px',
   }
 }
+const handleSend = async () => {
+  const { code, msg } = await createCircleReview({
+    circleId: id.value,
+    userId: userInfo.value.userId,
+    userName: userInfo.value.nickname,
+    reviewContent: reviewContent.value,
+  })
+  if (code !== 0) {
+    uni.showToast({ title: msg, icon: 'none' })
+  } else {
+    reviewContent.value = ''
+    uni.showToast({ title: '评论成功', icon: 'none' })
+  }
+}
 onMounted(async () => {})
 onLoad(async (query: { id: string }) => {
   id.value = query.id
   await run()
+  await runGetReviews()
   await setSwiperStyle()
 })
 </script>
@@ -102,7 +135,7 @@ onLoad(async (query: { id: string }) => {
           <!-- <span v-if="data?.comments">{{ data?.comments }}</span> -->
         </div>
         <view class="flex-1"></view>
-        <!-- <view v-if="data?.comments" class="flex">
+        <view v-if="reviews?.list" class="flex">
           <div class="text-black/90 text-xs font-normal font-['PingFang SC'] leading-[10.18px]">
             按热度
           </div>
@@ -114,12 +147,12 @@ onLoad(async (query: { id: string }) => {
           <div class="text-black/40 text-xs font-normal font-['PingFang SC'] leading-[10.18px]">
             按时间
           </div>
-        </view> -->
+        </view>
       </view>
 
-      <!-- <view>
-        <template v-if="data?.commentList.length">
-          <template v-for="it of data?.commentList" :key="it.id">
+      <view>
+        <template v-if="reviews?.list.length">
+          <template v-for="it of reviews?.list" :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>
@@ -138,13 +171,19 @@ onLoad(async (query: { id: string }) => {
             </div>
           </view>
         </template>
-      </view> -->
+      </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>
+        <wd-input
+          custom-class="bg-transparent!"
+          no-border
+          confirm-type="send"
+          v-model="reviewContent"
+          @confirm="handleSend"
+        ></wd-input>
       </div>
       <view class="flex justify-around flex-1">
         <view