Browse Source

feat(app): 优化设计师主页功能

- 添加删除动态功能
- 优化个人资料展示
- 调整页面布局和样式
- 移除视频标签
- 优化圈子数据加载和展示
EvilDragon 4 months ago
parent
commit
8108152fd9

+ 28 - 24
packages/app/src/components/moment-item.vue

@@ -7,10 +7,11 @@ import { stringify } from 'qs'
 import { isImageOrVideo } from '../core/utils/common'
 import { useRouter } from '../core/utils/router'
 import { likeActived, likeBlack } from '@designer-hub/assets/src/icons'
+import { NetImages } from '../core/libs/net-images'
 
-const props = defineProps({
-  options: {
-    type: Object as PropType<{
+const props = withDefaults(
+  defineProps<{
+    options: {
       id: number
       headUrl?: string
       stylistId?: number
@@ -32,26 +33,12 @@ const props = defineProps({
       upvoteCount?: number
       ownUpvote: boolean
       reviewCount: number
-    }>,
-    default: () => ({
-      author: {
-        nickname: '张三',
-        avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
-      },
-      createTime: new Date(),
-      images: [
-        'https://via.placeholder.com/104x104',
-        'https://via.placeholder.com/104x104',
-        'https://via.placeholder.com/104x104',
-      ],
-      content: '',
-      tags: [],
-      shares: 0,
-      comments: 0,
-      likes: 0,
-    }),
-  },
-})
+    }
+    isOwn?: boolean
+  }>(),
+  {},
+)
+const emits = defineEmits<{ delete: [id: number] }>()
 const router = useRouter()
 const imgClass = ref('')
 const isVideo = ref(false)
@@ -60,6 +47,15 @@ const toDetail = () => {
     url: `/pages/home/moment/index?${stringify({ id: props.options.id })}`,
   })
 }
+const handleDelete = async () => {
+  console.log(1111)
+  emits('delete', props.options.id)
+  // try {
+  //   alert({ title: '警告', msg: '确定删除吗?' })
+  // } catch (e) {
+  //   console.log(e)
+  // }
+}
 onMounted(async () => {
   // console.log('加载')
   if (
@@ -95,7 +91,7 @@ onMounted(async () => {
           custom-class="vertical-bottom"
           :width="35"
           :height="35"
-          :src="props.options.headUrl"
+          :src="props.options.headUrl || NetImages.DefaultAvatar"
           mode="scaleToFill"
         />
       </view>
@@ -162,6 +158,14 @@ onMounted(async () => {
         </template>
         <view class="ml-1">{{ props.options.upvoteCount }}</view>
       </view>
+      <div v-if="isOwn">
+        <wd-button type="text" size="small" @click.stop="handleDelete">
+          <span class="text-black/30 text-xs font-normal font-['PingFang_SC']">
+            删除
+            <wd-icon name="close" size="12"></wd-icon>
+          </span>
+        </wd-button>
+      </div>
     </view>
   </Card>
 </template>

+ 8 - 8
packages/app/src/components/page-helper.vue

@@ -40,15 +40,12 @@ const queryList = (no, size) => {
 watch(
   () => props.query,
   async (e) => {
-    await setData()
+    // console.log(e)
+    paging.value?.reload()
   },
 )
 // const
-onMounted(async () => {
-  if (props.automatic) {
-    await setData()
-  }
-})
+onMounted(async () => {})
 
 onPageScroll((e) => {
   paging.value?.updatePageScrollTop(e.scrollTop)
@@ -58,7 +55,8 @@ onReachBottom(() => {
 })
 const refresh = async () => {
   console.log('Page Helper Refresh')
-  await setData()
+  // await setData()
+  paging.value?.refresh()
 }
 defineExpose({
   refresh,
@@ -76,8 +74,10 @@ defineExpose({
       :use-page-scroll="true"
       @query="queryList"
     >
+      <template #top>
+        <slot name="top"></slot>
+      </template>
       <template #empty>
-        <!-- <div v-if="!data?.list?.length" class="flex-grow flex items-center justify-center"></div> -->
         <wd-status-tip :image="NetImages.NotContent" tip="暂无内容"></wd-status-tip>
       </template>
       <slot :source="{ list: dataList } as T" :data="dataList as unknown as Ref<S>[]"></slot>

+ 1 - 1
packages/app/src/core/libs/net-images.ts

@@ -3,7 +3,7 @@ export enum NetImages {
   'avatar' = 'https://cdn.jsdelivr.net/gh/yangyang-yangyang/yangyang-yangyang.github.io@master/images/avatar.png',
   'NotContent' = 'https://image.zhuchaohui.com/zhucaohui/3819d411440c23cc9e4f4bd3a520325386d7f038ed6dfa7c2ba076bd5110d2d2.png',
   'DesigerHomepageDefaultBg' = 'https://image.zhuchaohui.com/zhucaohui/58dcb982d2957c5578478abbf000936efe9d11c96c5af4d457177cf5d90a9d39.png',
-  ConsultDefaultBg = 'https://image.zhuchaohui.com/zhucaohui/f1942e62d1b1adc23f37de705570e22d098da319e10c8a448dc49e594d4bee3a.png',
+  ConsultDefaultBg = 'https://image.zhuchaohui.com/zhucaohui/7e98b5995902cd9484a6baecfc1219420cbcc30d8ae11e058af0c140a3c11137.png',
   StudyTourItemBg = 'https://image.zhuchaohui.com/zhucaohui/254b7ea7fdecaba8e318a7f50e292d036cafe49904fc7fc160a5477ce921e261.png',
   DefaultAvatar = 'https://image.zhuchaohui.com/zhucaohui/0b57771c2fbe60157e592a5b0e51a2b2b6c5263300663ad33efd55b235a2402a.png',
 }

+ 5 - 1
packages/app/src/core/libs/requests.ts

@@ -1,4 +1,4 @@
-import { http, httpGet, httpPost, httpPut } from '../../utils/http'
+import { http, httpDelete, httpGet, httpPost, httpPut } from '../../utils/http'
 import { Schedule } from '../models/schedule'
 import {
   Category,
@@ -186,6 +186,10 @@ 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 deleteCircle = (id: string) => httpDelete('/app-api/member/circle/delete', { id })
 export const shareCircle = (id: string) => httpGet('/app-api/member/circle/share', { id })
 export const getCircleUpvotes = (id) =>
   httpGet<{

+ 54 - 49
packages/app/src/pages/mine/homepage/index.vue

@@ -7,7 +7,12 @@
 </route>
 <script setup lang="ts">
 import MomentItem from '@/components/moment-item.vue'
-import { getCircles, getDesignerInfo, getUserInfoById } from '../../../core/libs/requests'
+import {
+  deleteCircle,
+  getCircles,
+  getDesignerInfo,
+  getUserInfoById,
+} from '../../../core/libs/requests'
 import { useUserStore } from '../../../store'
 import { storeToRefs } from 'pinia'
 import { NetImages } from '../../../core/libs/net-images'
@@ -15,16 +20,21 @@ import PageHelper from '@/components/page-helper.vue'
 import BottomAppBar from '@/components/bottom-app-bar.vue'
 import { useRouter } from '../../../core/utils/router'
 import NavbarEvo from '@/components/navbar-evo.vue'
+import { useMessage } from 'wot-design-uni'
+import { requestToast } from '../../../core/utils/common'
+import { ComponentExposed } from 'vue-component-type-helpers'
 
+const { alert, confirm } = useMessage()
 const router = useRouter()
 const userStore = useUserStore()
 const { userInfo } = storeToRefs(userStore)
+const pageHelperRef = ref<ComponentExposed<typeof PageHelper>>()
 const id = ref()
 const tab = ref('2')
 const tabs = ref([
   { label: '案例', value: '2' },
   { label: '动态', value: '1' },
-  { label: '视频', value: '0' },
+  // { label: '视频', value: '0' },
 ])
 const { data: memberInfo, run: setMemberInfo } = useRequest(() => getUserInfoById(id.value), {
   initialData: {},
@@ -38,30 +48,22 @@ const skills = computed(() => [
   { label: '客户', value: designerInfo.value.serviceCustomerCount },
   { label: '设计费', value: `${designerInfo.value.designFee}元/㎡` },
 ])
-onMounted(async () => {})
-function getVideoListByAccessToken(accessToken, openid) {
-  const VIDEO_API = 'https://api.weixin.qq.com/wxa/business/getuservideo'
-
-  uni.request({
-    url: VIDEO_API,
-    method: 'POST',
-    header: {
-      'Content-Type': 'application/json',
-    },
-    data: {
-      access_token: accessToken,
-      openid,
-      // 可以添加其他参数,如offset, limit
-    },
-    success: function (res) {
-      // 获取视频号列表成功
-      console.log('视频号列表:', res.data)
-    },
-    fail: function (error) {
-      console.log('获取视频号列表失败', error)
+const query = computed(() => ({
+  circleType: tab.value,
+  stylistId: id.value,
+}))
+const handleMomentDelete = async (id) => {
+  confirm({
+    title: '警告',
+    msg: '确定要删除吗?',
+    beforeConfirm: async ({ resolve }) => {
+      await requestToast(() => deleteCircle(id))
+      await pageHelperRef.value?.refresh()
+      resolve(true)
     },
   })
 }
+onMounted(async () => {})
 onLoad(async (query: { id: string }) => {
   if (query.id) {
     id.value = query.id
@@ -70,10 +72,6 @@ onLoad(async (query: { id: string }) => {
     id.value = userInfo.value.userId
   }
   await setDesignerInfo()
-  // uni.request({
-  //   url: '',
-  // })
-  // getVideoListByAccessToken(userInfo.value.accessToken, userInfo.value.openid)
 })
 onShareAppMessage(() => ({ title: `${userInfo.value.nickname}` }))
 defineExpose({
@@ -141,29 +139,36 @@ defineExpose({
         </template>
       </div>
       <div class="text-black/80 text-sm font-normal font-['PingFang_SC'] leading-normal">
-        “设计没有风格,设计是对生活的一种诠释,不是所谓的造型与装饰!”
+        {{ designerInfo?.personalIdentity }}
+      </div>
+      <div>
+        <wd-tabs v-model="tab" custom-class="bg-transparent!">
+          <template v-for="({ label, value }, index) in tabs" :key="index">
+            <wd-tab :title="label" :name="value"></wd-tab>
+          </template>
+        </wd-tabs>
+        <PageHelper
+          ref="pageHelperRef"
+          class="flex-grow flex flex-col bg-[#f6f6f6] mx--3.5"
+          custom-class=""
+          :request="getCircles"
+          :query="query"
+        >
+          <template #default="{ source }">
+            <div class="p-3.5 flex flex-col bg-[#f6f6f6] gap-3.5">
+              <template v-for="it of source.list" :key="it.id">
+                <view class="">
+                  <MomentItem
+                    :options="it"
+                    :is-own="userInfo.userId === it.stylistId"
+                    @delete="handleMomentDelete"
+                  ></MomentItem>
+                </view>
+              </template>
+            </div>
+          </template>
+        </PageHelper>
       </div>
-      <wd-tabs v-model="tab" custom-class="bg-transparent!">
-        <template v-for="({ label, value }, index) in tabs" :key="index">
-          <wd-tab :title="label" :name="value"></wd-tab>
-        </template>
-      </wd-tabs>
-      <PageHelper
-        class="flex-grow flex flex-col bg-[#f6f6f6] mx--3.5"
-        custom-class=""
-        :request="getCircles"
-        :query="{ circleType: tab, stylistId: id }"
-      >
-        <template #default="{ source }">
-          <div class="p-3.5 flex flex-col bg-[#f6f6f6] gap-3.5">
-            <template v-for="it of source.list" :key="it.id">
-              <view class="">
-                <MomentItem :options="it"></MomentItem>
-              </view>
-            </template>
-          </div>
-        </template>
-      </PageHelper>
     </div>
     <BottomAppBar fixed placeholder>
       <div class="flex gap-7.5">

+ 2 - 0
packages/app/src/utils/http.ts

@@ -129,6 +129,8 @@ export const httpPut = <T>(url: string, data?: Record<string, any>) =>
     data,
     method: 'PUT',
   })
+export const httpDelete = <T>(url: string, query?: Record<string, any>) =>
+  http<T>({ url, query, method: 'DELETE' })
 
 http.get = httpGet
 http.post = httpPost