Browse Source

Merge remote-tracking branch 'origin/main' into main

赵添更 2 months ago
parent
commit
abaaa1530f

+ 7 - 2
packages/app/src/App.vue

@@ -4,8 +4,13 @@ import { useAnalysis } from '@/composables/analysis'
 
 useAnalysis(true, true)
 
-onLaunch(() => {
-  console.log('App Launch')
+onLaunch((options: any) => {
+  console.log('App Launch', options)
+  if (options.query?.isShared === 'true' && options.path === 'pages-sub/mine/homepage/index') {
+    uni.reLaunch({
+      url: `/pages-sub/mine/homepage/index?id=${options.query.id}&isShared=true`,
+    })
+  }
 })
 onShow(() => {
   console.log('App Show')

+ 5 - 4
packages/app/src/components/moment-item.vue

@@ -11,8 +11,6 @@ import { NetImages } from '../core/libs/net-images'
 import { currRoute } from '../utils'
 import { usePermissions } from '../composables/permissions'
 import { useMemberLevelsStore } from '../store/member-levles'
-import { useDictStore } from '../store'
-import { DictType } from '../core/libs/models'
 import { CircleRes } from '../core/libs/requests'
 
 const props = withDefaults(
@@ -194,7 +192,10 @@ onMounted(async () => {
         </template>
         <template v-else>{{ options.circleDesc }}</template>
       </view>
-      <view v-if="props.options.tagName !== ''" class="my-5.5 flex flex-wrap gap-3.5">
+      <view
+        v-if="props.options.tagName && props.options.tagName?.split(',').length > 0"
+        class="my-5.5 flex flex-wrap gap-3.5"
+      >
         <template v-if="props.options.tagName !== ''">
           <template v-for="it of props.options.tagName?.split(',')" :key="it">
             <Tag>{{ it }}</Tag>
@@ -202,7 +203,7 @@ onMounted(async () => {
         </template>
       </view>
 
-      <view v-if="!isShared" class="flex justify-between">
+      <view v-if="!isShared" class="flex justify-between items-center">
         <div>
           <template v-if="features.shareMoment">
             <button

+ 0 - 1
packages/app/src/composables/activity.ts

@@ -1,4 +1,3 @@
-import { get } from 'radash'
 import { Activity, StudyTour } from '../core/libs/models'
 import { getActivityStatusButtonText } from '../core/utils/common'
 import dayjs from 'dayjs'

+ 6 - 24
packages/app/src/composables/share.ts

@@ -3,33 +3,14 @@ import { messages } from '@/core/libs/messages'
 
 export const useShare = () => {
   const shareAppMessage = async ({ from, target }) => {
-    // const res: Page.CustomShareContent = {}
-    // if (from === 'button') {
-    //   console.log(target)
-    //
-    //   if (target.dataset.type === 'homepage') {
-    //     res.title = `${userInfo.value.nickname}: “${designerInfo.value.designDesc}”`
-    //     res.imageUrl = designerInfo.value?.sharePageUrl
-    //     res.path = `/pages-sub/mine/homepage/index?id=${id.value}&isShared=true`
-    //   } else {
-    //     await shareCircle(target.dataset.options.id)
-    //     res.path = `/pages-sub/home/moment/index?id=${target.dataset.options.id}&isShared=true`
-    //     res.imageUrl = target.dataset.options.bannerUrls[0]
-    //     res.title = `${target.dataset.options.stylistName}: ${target.dataset.options.circleDesc}`
-    //   }
-    // }
-    // if (from === 'menu') {
-    //   res.title = `${userInfo.value.nickname}: “${designerInfo.value.designDesc}”`
-    //   res.imageUrl = designerInfo.value?.sharePageUrl
-    //   res.path = `/pages-sub/mine/homepage/index?id=${id.value}&isShared=true`
-    // }
-    // return res
-
-    // console.log('from', from)
-    console.log('target', target)
+    console.log('target::::::::', from, target)
     const res: Page.CustomShareContent = {}
     if (from === 'button') {
       if (target.dataset.type === 'homepage') {
+        if (target.dataset.level && target.dataset.level < 2) {
+          uni.showToast({ title: '普通会员无法分享', icon: 'none' })
+          throw new Error('禁止分享')
+        }
         await shareDesignerHome({
           stylistId: target.dataset.options.homepageId,
           bizId: target.dataset.options.userId,
@@ -53,6 +34,7 @@ export const useShare = () => {
     if (from === 'menu') {
       res.title = messages.home.shareTitle
     }
+    console.log('res:::::::分享数据:', res)
     return res
   }
   return { shareAppMessage }

+ 0 - 1
packages/app/src/core/libs/levels.ts

@@ -1,4 +1,3 @@
-import { group, mapEntries } from 'radash'
 import memberSilver from '@designer-hub/assets/src/libs/assets/memberSilver'
 import memberGold from '@designer-hub/assets/src/libs/assets/memberGold'
 import memberPlatinum from '@designer-hub/assets/src/libs/assets/memberPlatinum'

+ 1 - 0
packages/app/src/core/libs/models.ts

@@ -53,6 +53,7 @@ export interface MaterialDealer {
    * 累计到店次数
    */
   cumulativeStoreNum?: number
+  bannerUrl?: string
 }
 export interface ShopList {
   id: number

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

@@ -205,7 +205,7 @@ export const getCircle = (id: string) =>
  * 删除个人圈子
  */
 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 shareCircle = (id: string | number) => httpGet('/app-api/member/circle/share', { id })
 /**
  * /app-api/member/designer/shareHomeHistory 分享设计师主页
  */

+ 26 - 21
packages/app/src/layouts/tabbar.vue

@@ -1,9 +1,7 @@
 <script setup lang="ts">
 import TabbarEvo from '@/components/tabbar-evo.vue'
 import { iconCamera, iconWallet } from '../core/libs/pngs'
-import {
-  readCount
-} from '../core/libs/requests'
+import { readCount } from '../core/libs/requests'
 import {
   home,
   homeActive,
@@ -18,7 +16,7 @@ import {
 import { currRoute } from '../utils'
 import { defaultThemeVars } from '../core/themes/default'
 import { useRouter } from '../core/utils/router'
-import HonorDialog from "@/pages/home/components/honor-dialog/honor-dialog.vue";
+import HonorDialog from '@/pages/home/components/honor-dialog/honor-dialog.vue'
 
 const router = useRouter()
 const publishState = ref(false)
@@ -47,7 +45,7 @@ const items = [
     title: '消息',
     iconPath: message,
     selectedIconPath: messageActive,
-	notice:messageCount,
+    notice: messageCount,
     path: '/pages/messages/index',
   },
   {
@@ -60,36 +58,43 @@ const items = [
 const handleTabbarItemClick = (path: string) => {
   if (path === '/pages-sub/publish/index') {
     publishState.value = true
+    uni.$emit('clickTabbar', publishState.value)
     return
   }
   getMessageNotice()
   router.push(path, true)
   // uni.switchTab({ url: path })
 }
-const getMessageNotice = async () =>{
-	let value = await readCount();
-	if(value?.data?.length > 0){
-		let count = 0
-		for(let i in value.data){
-			count += value.data[i].quantity
-		}
-		if(count > 0){
-			messageCount.value = true
-		}else{
-			messageCount.value = false
-		}
-	}
+const getMessageNotice = async () => {
+  let value = await readCount()
+  if (value?.data?.length > 0) {
+    let count = 0
+    for (let i in value.data) {
+      count += value.data[i].quantity
+    }
+    if (count > 0) {
+      messageCount.value = true
+    } else {
+      messageCount.value = false
+    }
+  }
+}
+const handlePublishState = () => {
+  publishState.value = false
+  uni.$emit('clickTabbar', publishState.value)
 }
-onShow(async ()=>{
-	await getMessageNotice()
+onShow(async () => {
+  await getMessageNotice()
 })
 const toPublishMoment = () => {
   router.push('/pages-sub/publish/moment/index?circleType=1')
   publishState.value = false
+  uni.$emit('clickTabbar', publishState.value)
 }
 const toPublishCase = () => {
   router.push('/pages-sub/publish/moment/index?circleType=2')
   publishState.value = false
+  uni.$emit('clickTabbar', publishState.value)
 }
 </script>
 
@@ -135,7 +140,7 @@ const toPublishCase = () => {
             custom-class="mt-15"
             type="icon"
             icon="close"
-            @click="publishState = false"
+            @click="handlePublishState"
           ></wd-button>
         </div>
       </div>

+ 4 - 23
packages/app/src/pages-sub/home/activity/detail/index.vue

@@ -129,7 +129,9 @@ const infos = computed(() => [
     icon: user,
     title: `${activityTypes.value[type.value]}名额`,
     content: [
-      places.value === '不限制' ? `不限制` : `${places.value}人/剩余${data.value.surplus}人`,
+      places.value === '不限制'
+        ? `不限制`
+        : `${places.value}人/剩余${status.value === 'closed' || status.value === 'overdue' ? 0 : data.value.surplus}人`,
     ],
     visable: true,
   },
@@ -150,7 +152,6 @@ const schedules = computed(() =>
 
 const activity = useActivity(data)
 const { status, statusText, difference, refresh } = activity
-
 const handleConfirm = async () => {
   const { data, code, msg } = await (isActivity.value ? activitySignup : studyTourSignup)({
     id: id.value,
@@ -213,6 +214,7 @@ onLoad(async (query: { id: string; type: 'activity' | 'studyTour' }) => {
     })
     .exec()
   await Promise.all([setSignups(), setLevels(), setPhotos()])
+  console.log('报名状态::::', status.value)
 })
 
 onShareAppMessage(() => ({ title: data.value.name, imageUrl: data.value.thumbnailUrl }))
@@ -227,31 +229,16 @@ onShareTimeline(() => ({ title: data.value.name, imageUrl: data.value.thumbnailU
   >
     <NavbarEvo transparent dark></NavbarEvo>
     <div class="aspect-[1.26/1] relative mx--3.5 relative">
-      <!-- <wd-img width="100%" height="100%" :src="data.bannerUrl?.at(0)"></wd-img> -->
       <canvas
         class="w-full h-full absolute top--1000"
         canvas-id="firstCanvas"
         id="firstCanvas"
       ></canvas>
-      <!--      <ImageEvo :src="data?.bannerUrl" mode="aspectFill"></ImageEvo>-->
       <div
         class="w-full h-full bg-[length:100%_auto]"
         :style="{ backgroundImage: `url(${data?.bannerUrl})` }"
       ></div>
-      <!-- <wd-img width="100%" height="100%" :src="data?.backgroundUrl"></wd-img> -->
       <div class="absolute left-3.5 bottom-3" @click="isActivity && (listShow = true)">
-        <!--        <div-->
-        <!--          v-if="isStudyTour"-->
-        <!--          class="bg-white/20 rounded-[20px] backdrop-blur-[6px] px-3.5 py-1 flex gap-2.5"-->
-        <!--        >-->
-        <!--          <wd-img width="20" height="20" :src="bell"></wd-img>-->
-        <!--          <div class="text-[#c1c1c1] text-base font-normal font-['PingFang_SC'] leading-normal">-->
-        <!--            白金会员王凯峰已报名-->
-        <!--          </div>-->
-        <!--          <div class="w-6 bg-black aspect-square rounded-full flex items-center justify-center">-->
-        <!--            <wd-img width="18" height="18" :src="rightFill"></wd-img>-->
-        <!--          </div>-->
-        <!--        </div>-->
         <div class="flex items-center gap-1.25">
           <AvatarGroupCasual
             :urls="
@@ -288,7 +275,6 @@ onShareTimeline(() => ({ title: data.value.name, imageUrl: data.value.thumbnailU
     <div
       class="px-4 py-6 bg-[#010102]/30 backdrop-blur-[20px] rounded-2xl my-8 flex flex-col gap-3"
     >
-      <!-- {{ levelsById }} -->
       <template v-for="(it, i) in infos" :key="i">
         <div v-if="it.visable" class="flex items-center gap-1.5">
           <wd-img width="16" height="16" :src="it.icon"></wd-img>
@@ -328,12 +314,10 @@ onShareTimeline(() => ({ title: data.value.name, imageUrl: data.value.thumbnailU
         v-if="tab === 0"
         class="text-justify text-[#c1c1c1] text-base font-normal font-['PingFang_SC'] leading-relaxed"
       >
-        <!-- <u-parse :content="data['activityDesc'] || data['studyDesc']"></u-parse> -->
         <mpHtml :content="data['activityDesc'] || data['studyDesc']"></mpHtml>
       </div>
 
       <div v-if="tab === 1 && 'studyTravelList' in data" class="flex flex-col gap-6">
-        <!-- {{ mapEntries(schedules, (key, value) => [key, value]) }} -->
         <template v-for="([key, items], i) in Object.entries(schedules)" :key="key">
           <div class="flex flex-col gap-6">
             <div class="text-white text-base font-normal font-['PingFang_SC'] leading-normal">
@@ -475,9 +459,6 @@ onShareTimeline(() => ({ title: data.value.name, imageUrl: data.value.thumbnailU
                 {{ data.needPointsCount || 0 }}
               </div>
               <div class="text-black/40 text-sm font-normal font-['PingFang_SC']">积分</div>
-              <!--              <div class="ml-1 text-black/40 text-xs font-normal font-['PingFang_SC']">-->
-              <!--                剩余:{{ remainedCount || 0 }}-->
-              <!--              </div>-->
               <div class="flex-1"></div>
             </div>
           </div>

+ 14 - 20
packages/app/src/pages-sub/home/moment/index.vue

@@ -58,6 +58,9 @@ const focus = ref(false)
 const hot = ref(true)
 const active = ref('hot')
 const { data, run } = useRequest(() => getCircle(id.value), { initialData: {} })
+const toPreview = () => {
+  uni.previewImage({ current: current.value, urls: data.value.bannerUrls, loop: true })
+}
 const { data: reviews, run: runGetReviews } = useRequest(
   () => getCircleReviews({ circleId: id.value, hot: hot.value }),
   {
@@ -164,9 +167,6 @@ const handleUpvote = async (index?: number) => {
   await runGetReviews()
 }
 const toDesignerHomepage = () => {
-  console.log(
-    `/pages-sub/mine/homepage/index?id=${data.value?.stylistId}${isShared.value ? '&isShared=true' : ''}`,
-  )
   if (['1', '2'].includes(String(data.value?.circleType)) && data.value?.levelId >= 2) {
     router.push(
       `/pages-sub/mine/homepage/index?id=${data.value?.stylistId}${isShared.value ? '&isShared=true' : ''}`,
@@ -195,18 +195,21 @@ onLoad(async (query?: { id: string; isShared?: boolean; circleType?: string }) =
     })
   }
 })
-// onShareAppMessage(async () => {
-//   await shareCircle(id.value)
-//   return { title: data.value?.circleDesc }
-// })
-onShareAppMessage(({ from, target }) => {
+onShow(async () => {
+  await run()
+})
+onShareAppMessage(async ({ from, target }) => {
   if (from === 'button') {
-    return shareAppMessage({ from, target })
+    return await shareAppMessage({ from, target })
   } else if (from === 'menu') {
+    await shareCircle(data.value?.id)
     return {
       title: `${data.value?.stylistName}: ${data.value?.circleType === '2' ? '设计案例-' + data.value?.caseName : data.value?.circleDesc}`,
       path: `/pages-sub/home/moment/index?id=${data.value?.id}&isShared=true&circleType=${data.value?.circleType}`,
       imageUrl: data.value?.bannerUrls[0],
+      success: async () => {
+        await run()
+      },
     }
   }
 })
@@ -243,13 +246,13 @@ const handleClick = async (value: boolean) => {
             :indicator-dots="true"
           >
             <template v-for="it of data?.bannerUrls" :key="it">
-              <swiper-item>
+              <swiper-item @click="toPreview">
                 <wd-img
                   width="100%"
                   height="100%"
                   :src="it"
                   mode="aspectFill"
-                  :enable-preview="true"
+                  :enable-preview="false"
                 ></wd-img>
               </swiper-item>
             </template>
@@ -262,15 +265,6 @@ const handleClick = async (value: boolean) => {
           <swiper @change="handleChange">
             <template v-for="it of data?.bannerUrls" :key="it">
               <swiper-item>
-                <!--                <video-->
-                <!--                  ref="momentVideo"-->
-                <!--                  width="100%"-->
-                <!--                  class="w-full aspect-[1.64/1]"-->
-                <!--                  :controls="'contimg'"-->
-                <!--                  :loop="true"-->
-                <!--                  :enable-progress-gesture="false"-->
-                <!--                  :src="it"-->
-                <!--                ></video>-->
                 <MomentVideo
                   ref="momentVideoRef"
                   :src="it"

+ 27 - 66
packages/app/src/pages-sub/home/study-tour/index.vue

@@ -27,15 +27,23 @@ import { useRouter } from '../../../core/utils/router'
 import PageHelper from '@/components/page-helper.vue'
 import RegisterCard from './components/register-card.vue'
 import { ComponentExposed } from 'vue-component-type-helpers'
-const pageHelperRef = ref<ComponentExposed<typeof PageHelper>>()
+import { useShare } from '@/composables/share'
+import { getByDictType } from '@/core/libs/requests'
+import { DictType } from '@/core/libs/models'
+import PageHelperEvo from '@/components/page-helper-evo.vue'
+const pageHelperRef = ref<ComponentExposed<typeof PageHelperEvo>>()
 const currentBanner = ref(0)
+const dictMemberDesignStyle = ref<any[]>()
+const dictCircleSpaceType = ref<any[]>()
 const handleSwiperChange = ({ detail: { current } }) => {
   currentBanner.value = current
 }
 const userStore = useUserStore()
 const { userInfo } = storeToRefs(userStore)
 const shareOptions = ref()
+const shareActionState = ref(false)
 const router = useRouter()
+const { shareAppMessage } = useShare()
 const { data: studyTours, run: setStudyTours } = useRequest(() =>
   getStudyTours({ headRecommend: 1 }),
 )
@@ -58,18 +66,27 @@ const handleLike = async (options) => {
   })
   await pageHelperRef.value?.refresh()
 }
+const handleShare = (options: any) => {
+  shareOptions.value = options
+  shareActionState.value = true
+}
 const levelsByMemberLevel = computed(() =>
   levels.value.reduce((acc, item) => {
     acc[item.memberLevel] = item
     return acc
   }, {}),
 )
-onMounted(async () => {
+onLoad(async () => {
   await Promise.all([setLevels(), setStudyTours(), setClassmates(), setBanners()])
+  let value1 = await getByDictType(DictType.circleSpaceType)
+  dictCircleSpaceType.value = value1.data
+  let value2 = await getByDictType(DictType.memberDesignStyle)
+  dictMemberDesignStyle.value = value2.data
 })
 onShow(async () => {
   await pageHelperRef.value?.reload()
 })
+onShareAppMessage(shareAppMessage)
 </script>
 <template>
   <view class="flex-grow flex flex-col gap-6 p-3.5">
@@ -111,67 +128,6 @@ onShow(async () => {
         </template>
       </div>
     </div>
-    <!-- </template>
-    </PageHelper> -->
-    <!-- <card custom-class="p-0!">
-      <view class="relative">
-        <wd-img
-          custom-class="vertical-bottom"
-          width="100%"
-          height="275"
-          src="https://via.placeholder.com/347x464"
-        ></wd-img>
-        <div
-          class="w-[63px] h-[29px] bg-black/60 rounded-[20px] backdrop-blur-[15px] absolute top-5 right-3.5 flex items-center justify-center"
-        >
-          <div class="text-white text-sm font-normal font-['PingFang_SC'] leading-relaxed">
-            报名中
-          </div>
-        </div>
-        <view class="absolute left-3.5 bottom-2.5 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-white/60 text-sm font-normal font-['PingFang_SC'] leading-[10.18px]"
-          >
-            40人已报名
-          </div>
-        </view>
-      </view>
-      <div class="bg-[#27130d]/50 rounded-bl-2xl rounded-br-2xl backdrop-blur-[20px] p-3.5">
-        <div class="w-[293px] text-white text-xl font-normal font-['PingFang_SC'] leading-relaxed">
-          日本研学·东京艺术大学设计游学
-        </div>
-        <view class="flex items-center">
-          <div class="text-white/60 text-sm font-normal font-['PingFang_SC'] leading-[34px]">
-            游学时间:
-          </div>
-          <div class="text-white/60 text-base font-normal font-['PingFang_SC'] leading-[34px]">
-            07.15 08.10
-          </div>
-        </view>
-        <div
-          class="text-justify text-white/60 text-sm font-normal font-['PingFang_SC'] leading-relaxed"
-        >
-          等级限制:黄金会员以上
-        </div>
-        <view class="flex items-center justify-between">
-          <view class="flex items-end">
-            <div class="text-white text-3xl font-bold font-['D-DIN_Exp'] leading-normal">16000</div>
-            <div class="ml-1 text-white/60 text-sm font-normal font-['PingFang_SC'] leading-[34px]">
-              积分
-            </div>
-          </view>
-          <tilted-button custom-class="" size="large" color="white">立即报名</tilted-button>
-        </view>
-      </div>
-    </card> -->
     <card custom-class="">
       <div class="my-10px text-black text-xl fw-500 font-['PingFang_SC'] leading-[10.18px]">
         筑巢荟-设计游学
@@ -198,7 +154,7 @@ onShow(async () => {
       tip="暂无内容"
     ></wd-status-tip>
     <section-heading custom-class="" title="设计圈"></section-heading>
-    <PageHelper
+    <PageHelperEvo
       ref="pageHelperRef"
       :request="getCircles"
       :query="{ tagName: '设计游学' }"
@@ -207,11 +163,16 @@ onShow(async () => {
       <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" @like="handleLike"></MomentItem>
+            <MomentItem
+              :dict="{ spaceType: dictCircleSpaceType, designStyle: dictMemberDesignStyle }"
+              :options="it"
+              @like="handleLike"
+              @share="handleShare"
+            ></MomentItem>
           </template>
         </div>
       </template>
-    </PageHelper>
+    </PageHelperEvo>
   </view>
 </template>
 <style scoped>

+ 96 - 51
packages/app/src/pages-sub/mine/homepage/index.vue

@@ -52,6 +52,7 @@ const { userInfo } = storeToRefs(userStore)
 const pageHelperRef = ref<ComponentExposed<typeof PageHelper>>()
 const id = ref()
 const isShared = ref(false)
+const videoNumberShare = ref(false)
 const tab = ref('2')
 const tabs = ref([
   { label: '案例', value: '2' },
@@ -60,6 +61,7 @@ const tabs = ref([
 ])
 const viewDuration = ref(0)
 const viewStartAt = ref<Date>()
+const shareOptions = ref()
 const { data: memberInfo, run: setMemberInfo } = useRequest(() => getUserInfoById(id.value), {
   initialData: {},
 })
@@ -87,6 +89,32 @@ const skills = computed(() =>
     },
   ].filter(({ show }) => show),
 )
+const shareContent = computed(() => {
+  return {
+    title: designerInfo.value?.homePageName
+      ? designerInfo.value?.homePageName
+      : memberInfo.value.nickname,
+    imageUrl: designerInfo.value?.sharePageUrl ?? designerInfo.value?.homePageUrl,
+    path: `/pages-sub/mine/homepage/index?id=${id.value}&isShared=true`,
+  }
+})
+const shareMessage = () => {
+  const promise = new Promise((resolve, reject) => {
+    if (userInfo.value?.level?.level < 2) {
+      uni.showToast({ title: '普通会员无法分享', icon: 'none' })
+      reject()
+    } else {
+      const res: Page.CustomShareContent = {}
+      res.title = designerInfo.value?.homePageName
+        ? designerInfo.value?.homePageName
+        : memberInfo.value.nickname
+      res.imageUrl = designerInfo.value.sharePageUrl ?? designerInfo.value?.homePageUrl
+      res.path = `/pages-sub/mine/homepage/index?id=${id.value}&isShared=true`
+      resolve(res)
+    }
+  })
+  return { promise }
+}
 const query = computed(() => ({
   circleType: tab.value,
   stylistId: id.value,
@@ -110,9 +138,34 @@ const handleLike = async (options) => {
   })
   await pageHelperRef.value?.refresh()
 }
+const handleShare = (options: any) => {
+  console.log('options 分享', options)
+  shareOptions.value = options
+}
 const handle2Video = () => {
   try {
-    uni.openChannelsUserProfile({ finderUserName: designerInfo.value?.videoNumber })
+    uni.openChannelsUserProfile({
+      finderUserName: designerInfo.value?.videoNumber,
+      success: (res) => {
+        console.log('success', res)
+      },
+      fail: (error) => {
+        let { errMsg } = error
+        if (
+          errMsg === 'openChannelsUserProfile:fail cancel' ||
+          errMsg === 'openChannelsUserProfile:fail user cancel'
+        ) {
+          console.log('取消报错')
+        } else if (
+          errMsg === 'openChannelsUserProfile:fail rejected due to no permission currently'
+        ) {
+          uni.showToast({
+            title: '请前往小程序使用完整功能',
+            icon: 'none',
+          })
+        }
+      },
+    })
   } catch (e) {
     uni.showToast({
       title: '打开失败',
@@ -120,6 +173,9 @@ const handle2Video = () => {
     })
   }
 }
+const handle2VideoNumber = (share: boolean) => {
+  handle2Video()
+}
 const handleUnbundle = async () => {
   confirm({
     title: '警告',
@@ -148,6 +204,9 @@ onLoad(async (query: { id: string; isShared?: string }) => {
   }
   if (query.isShared) {
     isShared.value = true
+    videoNumberShare.value = true
+  } else {
+    videoNumberShare.value = false
   }
   if (!isOwn.value) {
     viewStartAt.value = new Date()
@@ -157,44 +216,43 @@ onLoad(async (query: { id: string; isShared?: string }) => {
   dictCircleSpaceType.value = value1.data
   let value2 = await getByDictType(DictType.memberDesignStyle)
   dictMemberDesignStyle.value = value2.data
+
+  // 若 等级 小于 2 则无法分享
+  if (userInfo.value?.level?.level < 2) {
+    uni.hideShareMenu({
+      hideShareItems: ['shareAppMessage', 'shareTimeline'],
+    })
+  }
 })
 onShow(async () => {
   await setDesignerInfo()
+  await pageHelperRef.value?.refresh()
 })
-onUnload(async () => {
-  if (!isOwn.value) {
-    viewDuration.value = dayjs().diff(viewStartAt.value, 'seconds')
-    const { data, code } = await createBrowseHistory({
-      stylistId: id.value,
-      bizType: 3,
-      // bizId: '1',
-      duration: viewDuration.value.toString(),
-    })
+onShareAppMessage(async (share) => {
+  if (share.from === 'button') {
+    return await shareAppMessage(share)
+  } else if (share.from === 'menu') {
+    return shareContent.value
   }
 })
-const shareMessage = () => {
-  const promise = new Promise((resolve, reject) => {
-    if (userInfo.value?.level?.level < 2) {
-      uni.showToast({ title: '普通会员无法分享', icon: 'none' })
-      reject()
-    } else {
-      const res: Page.CustomShareContent = {}
-      res.title = designerInfo.value?.homePageName
-        ? designerInfo.value?.homePageName
-        : memberInfo.value.nickname
-      res.imageUrl = designerInfo.value.sharePageUrl
-      res.path = `/pages-sub/mine/homepage/index?id=${id.value}&isShared=true`
-      resolve(res)
-    }
+onUnload(async () => {
+  viewDuration.value = dayjs().diff(viewStartAt.value, 'seconds')
+  const { data, code } = await createBrowseHistory({
+    stylistId: id.value,
+    bizType: 3,
+    // bizId: '1',
+    duration: viewDuration.value.toString(),
   })
-  return { promise }
-}
-onShareAppMessage(shareMessage)
-// onShareAppMessage(() => ({
-//   title: `${userInfo.value?.nickname}: “${designerInfo.value?.designDesc}”`,
-//   imageUrl:designerInfo.value.sharePageUrl,
-//   path:`/pages-sub/mine/homepage/index?id=${id}&isShared=true`
-// }))
+})
+onHide(async () => {
+  viewDuration.value = dayjs().diff(viewStartAt.value, 'seconds')
+  const { data, code } = await createBrowseHistory({
+    stylistId: id.value,
+    bizType: 3,
+    // bizId: '1',
+    duration: viewDuration.value.toString(),
+  })
+})
 onShareTimeline(() => ({
   title: designerInfo.value?.homePageName
     ? designerInfo.value?.homePageName
@@ -367,6 +425,7 @@ defineExpose({
           <div
             v-if="designerInfo?.videoNumber"
             class="text-[#e08e38] text-xs font-normal font-['PingFang_SC'] leading-normal"
+            @click.stop="handle2VideoNumber(videoNumberShare)"
           >
             去看看
           </div>
@@ -405,6 +464,7 @@ defineExpose({
                     :options="it"
                     :is-own="userInfo.userId === it.stylistId"
                     :is-shared="isShared"
+                    @share="handleShare"
                     @delete="handleMomentDelete"
                     @like="handleLike"
                   ></MomentItem>
@@ -427,31 +487,16 @@ defineExpose({
           </wd-button>
         </div>
         <div class="flex-1" v-if="isOwn && !isShared">
-          <!-- <button
-            v-if="features.shareMoment"
-            class="p-0 after:b-none"
-            block
-            :round="false"
-            :open-type="features.shareMoment ? 'share' : ''"
-            :data-type="'homepage'"
-            :data-share-content="{
-              title: `${userInfo.nickname}: “${designerInfo.designDesc}”`,
-              imageUrl: designerInfo.sharePageUrl,
-              path: `/pages-sub/mine/homepage/index?id=${id}&isShared=true`,
-            }"
-            :data-options="{
-              homepageId: id,
-              userId: userInfo.userId,
-            }"
-          >
-            <wd-button block :round="false">分享</wd-button>
-          </button> -->
           <button
             v-if="features.shareMoment"
             class="p-0 after:b-none"
             block
             :round="false"
+            data-type="homepage"
+            :data-share-content="shareContent"
             :open-type="features.shareMoment ? 'share' : ''"
+            :data-options="{ userId: userInfo.userId, homepageId: id }"
+            :data-level="userInfo.level.level"
             @click="clickByPermission('share', () => {})"
           >
             <wd-button block :round="false">分享</wd-button>

+ 24 - 10
packages/app/src/pages-sub/mine/honors/detail/index.vue

@@ -18,10 +18,19 @@ import { useUserStore } from '@/store'
 import { Canvas } from '@/core/utils/canvas'
 
 const show = ref<boolean>(false)
+const id = ref<string | number>('')
 const canvasHidden = ref<boolean>(false)
 const posterUrl = ref<string | any>()
 const userStore = useUserStore()
 const { userInfo } = storeToRefs(userStore)
+const badgePath = ref<any[]>([
+  { badgeType: '游学徽章', path: '/pages-sub/home/study-tour/index' },
+  { badgeType: '课程徽章', path: '/pages-sub/home/offline-activity/index' },
+  { badgeType: '传播徽章', path: '/pages-sub/mine/homepage/index' },
+  { badgeType: '积分徽章', path: '/pages-sub/home/mall/index' },
+  { badgeType: '打卡徽章', path: '/pages/mine/index' },
+  { badgeType: '活动徽章', path: '/pages-sub/home/offline-activity/index' },
+])
 const panels = ref([
   {
     iconUrl: NetImages.savePosterIcon,
@@ -29,7 +38,7 @@ const panels = ref([
     index: 0,
   },
 ])
-const { data: designer, run: setData } = useRequest(() => getDesignerInfo(userInfo.value.userId))
+const { data: designer, run: setData } = useRequest(() => getDesignerInfo(id.value))
 /**
  * 生成分享海拔
  * */
@@ -123,11 +132,7 @@ const subTitle = computed(() =>
     : `${dayjs(data.value.createTime).format('YYYY年MM月DD日')}获得`,
 )
 const setBadgesPath = (type: string) => {
-  if (type === '活动徽章') {
-    uni.redirectTo({
-      url: `/pages-sub/home/offline-activity/index`,
-    })
-  } else if (type === '游学徽章' || type === '典藏勋章') {
+  if (type === '游学徽章' || type === '典藏勋章') {
     if (banners.value?.length > 0) {
       uni.redirectTo({
         url: `/pages-sub/home/study-tour/list?designStudyAbroadYear=${banners.value[0].designStudyAbroadYear}&designDesc=${banners.value[0].designDesc}`,
@@ -139,9 +144,15 @@ const setBadgesPath = (type: string) => {
       })
     }
   } else {
-    uni.switchTab({
-      url: `/pages/home/index`,
-    })
+    if (type === '打卡徽章') {
+      uni.switchTab({
+        url: badgePath.value.find((it) => it.badgeType === type)?.path,
+      })
+    } else {
+      uni.redirectTo({
+        url: badgePath.value.find((it) => it.badgeType === type)?.path,
+      })
+    }
   }
 }
 const showActions = () => {
@@ -164,6 +175,7 @@ const { data: banners, run: setBanners } = useRequest(
 onLoad(async (query: { type: 'badge' | 'certificate'; data: string; id: number }) => {
   console.log(query, 'query2')
   if (query.type === 'badge') {
+    id.value = query?.id
     const badge = JSON.parse(query.data) as Badge
     data.value = {
       name: badge.badgeName,
@@ -180,7 +192,9 @@ onLoad(async (query: { type: 'badge' | 'certificate'; data: string; id: number }
     if (data.value.quantity > 0) {
       await setData()
       if (data.value.userId == userInfo.value.userId) {
-        posterUrl.value = await createPoster()
+        nextTick(async () => {
+          posterUrl.value = await createPoster()
+        })
       }
     }
   }

+ 3 - 1
packages/app/src/pages/home/index.vue

@@ -235,7 +235,9 @@ onShareAppMessage(shareAppMessage)
         <Card>
           <div class="flex items-center gap-2">
             <wd-img width="28" height="28" :src="logo"></wd-img>
-            <div class="text-black/90 text-base font-normal font-['PingFang_SC'] leading-[10.18px]">
+            <div
+              class="text-black/90 text-base font-normal font-['PihandleSharengFang_SC'] leading-[10.18px]"
+            >
               1分钟快速了解筑巢荟
             </div>
             <div class="flex-1"></div>

+ 40 - 14
packages/app/src/pages/material/detail/index.vue

@@ -60,6 +60,13 @@ const copy = (url) => {
     },
   })
 }
+const imageGroup = ref<any[]>([
+  { height: '171px' },
+  1,
+  { width: '107px' },
+  [{ width: '93px' }, { width: '32px', marginLeft: '41px' }],
+])
+const isLoaded = ref(false)
 const handleDownload = async () => {
   downloading.value = true
   const { filePath } = await uni.downloadFile({
@@ -95,19 +102,24 @@ const handleDownload = async () => {
   }
 }
 onLoad(async (query: { id: number }) => {
-  id.value = query.id
-  await setData()
-  option.value = {
-    remark: `最近浏览品牌: ${data.value?.materialsName}`,
+  console.log(query, '最近浏览品牌')
+  if (query.id) {
+    id.value = query.id
+    await setData()
+    option.value = {
+      remark: `最近浏览品牌: ${data.value?.materialsName}`,
+    }
+    await setMaterialHomePageData()
+    console.log(data.value)
+    await Promise.all([
+      setMaterialBrandLevels(),
+      setMaterialBrandTypes(),
+      setMaterialOperationTypes(),
+      setMaterialsManageBrands(),
+    ]).then(() => {
+      isLoaded.value = true
+    })
   }
-  await setMaterialHomePageData()
-  console.log(data.value)
-  await Promise.all([
-    setMaterialBrandLevels(),
-    setMaterialBrandTypes(),
-    setMaterialOperationTypes(),
-    setMaterialsManageBrands(),
-  ])
 })
 onShareAppMessage(() => ({
   title: data.value?.materialsName,
@@ -119,7 +131,7 @@ onShareTimeline(() => ({
 }))
 </script>
 <template>
-  <view class="flex-grow flex flex-col">
+  <view class="flex-grow flex flex-col" v-if="isLoaded">
     <div
       class="w-full aspect-[1.16/1] bg-[url(https://image.zhuchaohui.com/zhucaohui/9da274c73312f5ff828b60457bf4a469e631c001a4bf1c1f355338887b19f035.png)] bg-[length:100%]"
       :style="{ backgroundImage: `url(${materialHomePageData?.bannerUrl})` }"
@@ -253,7 +265,11 @@ onShareTimeline(() => ({
       <template v-if="materialHomePageData.productDOList?.length">
         <SectionHeading title="产品展示"></SectionHeading>
       </template>
-      <template v-for="(it, index) in materialHomePageData.productDOList" :key="index">
+      <template
+        v-if="materialHomePageData.productDOList?.length"
+        v-for="(it, index) in materialHomePageData.productDOList"
+        :key="index"
+      >
         <div class="aspect-[1.66/1] rounded-2xl overflow-hidden relative">
           <swiper class="h-[55.7vw]" @change="handleSwiperChange">
             <template v-for="(img, index) in it?.productImgUrl?.split(',')" :key="img">
@@ -318,6 +334,16 @@ onShareTimeline(() => ({
       </view>
     </wd-overlay>
   </view>
+  <!-- 骨架 屏 -->
+  <view v-else>
+    <wd-skeleton animation="gradient" theme="paragraph" :row-col="imageGroup" />
+    <wd-skeleton
+      animation="gradient"
+      theme="paragraph"
+      :custom-style="{ marginTop: '20px' }"
+      :row-col="imageGroup"
+    />
+  </view>
 </template>
 <style scoped>
 .dots {

+ 1 - 1
packages/app/src/pages/messages/components/message-card.vue

@@ -13,7 +13,7 @@ import { messages } from '../../../core/libs/messages'
 import { stringify } from 'qs'
 
 const props = withDefaults(
-  defineProps<{ options?: Message & { selectedCoupons?: Coupon[] } }>(),
+  defineProps<{ options?: Message & { selectedCoupons?: Coupon[]; couponType?: any } }>(),
   {},
 )
 const emits = defineEmits<{

+ 6 - 1
packages/app/src/pages/mine/index.vue

@@ -30,6 +30,7 @@ import { AnalysisEventType, useAnalysis } from '@/composables/analysis'
 
 const { option, report } = useAnalysis(false)
 const official = ref(false)
+const isPublish = ref<boolean>(false)
 const router = useRouter()
 const userStore = useUserStore()
 const { isLogined, userInfo } = storeToRefs(userStore)
@@ -224,6 +225,10 @@ const handleClickScan = async () => {
 const navBarProps = ref({ customClass: 'bg-transparent!' })
 onMounted(async () => {
   await setLevelConfigs()
+  // 监听 tabbar 点击事件
+  uni.$on('clickTabbar', (e) => {
+    isPublish.value = e
+  })
 })
 onShow(async () => {
   if (isLogined.value) {
@@ -250,7 +255,7 @@ onPageScroll(({ scrollTop }: { scrollTop: number }) => {
       :bordered="false"
       v-bind="navBarProps"
     >
-      <template #left>
+      <template v-if="!isPublish" #left>
         <wd-button
           v-if="isLogined"
           type="text"

+ 1 - 1
packages/merchant/src/components/data-form.vue

@@ -215,7 +215,7 @@ defineExpose({
             v-model="modelValue[prop]"
           >
             <template v-for="{ label, value } of props.columns" :key="value">
-              <wd-radio :value="value">{{ label }}</wd-radio>
+              <wd-radio custom-class="custom-line" :value="value">{{ label }}</wd-radio>
             </template>
           </wd-radio-group>
 

+ 6 - 5
packages/merchant/src/layouts/tabbar.vue

@@ -164,7 +164,7 @@ const handleChange = ({ fileList: files }) => {
   console.log(fileList.value)
 }
 const getCurrentLocation = () => {
-  console.log('点击地址')
+  uni.showToast({ icon: 'loading', title: '正在获取位置...' })
   uni.getLocation({
     type: 'gcj02',
     success: async (success: any) => {
@@ -173,7 +173,7 @@ const getCurrentLocation = () => {
       dataForm.value.address.address = name
       dataForm.value.address.latitude = latitude
       dataForm.value.address.longitude = longitude
-      console.log('提交信息:::', dataForm.value)
+      uni.hideToast()
     },
     fail: (err) => {
       console.log('获取地址失败', err)
@@ -191,15 +191,16 @@ const getCurrentLocation = () => {
                 dataForm.value.address.address = name
                 dataForm.value.address.latitude = latitude
                 dataForm.value.address.longitude = longitude
-                console.log('提交信息:::', dataForm.value)
+                uni.hideToast()
               },
               fail: function (err) {
                 console.log('获取位置失败:', err)
+                uni.hideToast()
               },
             })
           },
           fail: function () {
-            console.log('用户拒绝授权,不再提示')
+            uni.hideToast()
             // 用户拒绝授权,可以选择记录下来,不再提示
             uni.showToast({
               title: '您拒绝了位置授权',
@@ -253,7 +254,7 @@ onMounted(async () => {
       @click="handleTabbarItemClick"
     />
     <wd-action-sheet v-model="publishState" title="创建跟进" @close="publishState = false">
-      <view class="flex flex-col p-4 h-[calc(75vh)] overflow-y-auto">
+      <view class="flex flex-col p-4 h-[calc(65vh)]! overflow-y-auto">
         <div>
           <DataForm
             ref="dataFormRef"

+ 4 - 2
packages/merchant/src/pages/agent/designer/archives/index.vue

@@ -52,7 +52,6 @@ const tabs = [
 ]
 const id = ref()
 const { data: basicData, run: setBasicData } = useRequest(() => getDesignerBasicInfo(id.value))
-console.log('basicData::::', basicData)
 const { data: familyData, run: setData } = useRequest(() => getUserInfoById(id.value))
 const { data: editData, run: setEditData } = useRequest(() => getEditRecords())
 const query = computed(() => ({ userId: id.value }))
@@ -669,7 +668,7 @@ onShow(async () => {
     <wd-action-sheet v-model="actionSheetStatus">
       <div class="p-4">
         <DataForm :schema="schema" :direction="'horizontal'" v-model="formData"></DataForm>
-        <template v-if="submitType = 'award'">
+        <template v-if="submitType == 'award'">
           <div
             class="grid mb-4 items-start"
             :style="{ 'grid-template-columns': `${addUnit(64)} auto` }"
@@ -711,4 +710,7 @@ onShow(async () => {
     font-size: 28rpx;
   }
 }
+::v-deep .wd-radio__label {
+  line-height: 30px !important;
+}
 </style>

+ 5 - 4
packages/merchant/src/pages/agent/designer/index.vue

@@ -69,7 +69,7 @@ const wxGetAddress = (longitude: number, latitude: number) => {
   })
 }
 const getCurrentLocation = () => {
-  console.log('点击地址')
+  uni.showToast({ icon: 'loading', title: '正在获取位置...' })
   uni.getLocation({
     type: 'gcj02',
     success: async (success: any) => {
@@ -78,7 +78,7 @@ const getCurrentLocation = () => {
       followUpForm.value.address.address = name
       followUpForm.value.address.latitude = latitude
       followUpForm.value.address.longitude = longitude
-      console.log('提交信息:::', followUpForm.value)
+      uni.hideToast()
     },
     fail: (err) => {
       console.log('获取地址失败', err)
@@ -96,15 +96,16 @@ const getCurrentLocation = () => {
                 followUpForm.value.address.address = name
                 followUpForm.value.address.latitude = latitude
                 followUpForm.value.address.longitude = longitude
-                console.log('提交信息:::', followUpForm.value)
+                uni.hideToast()
               },
               fail: function (err) {
+                uni.hideToast()
                 console.log('获取位置失败:', err)
               },
             })
           },
           fail: function () {
-            console.log('用户拒绝授权,不再提示')
+            uni.hideToast()
             // 用户拒绝授权,可以选择记录下来,不再提示
             uni.showToast({
               title: '您拒绝了位置授权',