Ver Fonte

Merge branch 'main' of http://39.106.91.179:3000/hunter/designer-hub into main

kevin.T há 2 meses atrás
pai
commit
8183e02cc0
29 ficheiros alterados com 305 adições e 101 exclusões
  1. 3 4
      packages/app/src/components/moment-item.vue
  2. 13 2
      packages/app/src/components/tabbar-evo.vue
  3. 3 1
      packages/app/src/composables/permissions.ts
  4. 9 4
      packages/app/src/composables/share.ts
  5. 1 1
      packages/app/src/core/libs/messages.ts
  6. 23 0
      packages/app/src/layouts/tabbar.vue
  7. 8 0
      packages/app/src/pages-sub/home/classmates-detail/index.vue
  8. 9 16
      packages/app/src/pages-sub/home/mall/detail/index.vue
  9. 24 2
      packages/app/src/pages-sub/home/moment/index.vue
  10. 27 3
      packages/app/src/pages-sub/home/offline-activity/index.vue
  11. 3 1
      packages/app/src/pages-sub/home/spread/product-detail/index.vue
  12. 1 1
      packages/app/src/pages-sub/home/spread/wx-agent-operation/index.vue
  13. 23 2
      packages/app/src/pages-sub/home/study-tour/index.vue
  14. 11 2
      packages/app/src/pages-sub/home/study-tour/list.vue
  15. 18 4
      packages/app/src/pages-sub/mine/authentication/index.vue
  16. 6 0
      packages/app/src/pages-sub/mine/coupons/index.vue
  17. 39 4
      packages/app/src/pages-sub/mine/homepage/index.vue
  18. 6 2
      packages/app/src/pages-sub/mine/honors/detail/index.vue
  19. 20 8
      packages/app/src/pages-sub/mine/honors/index.vue
  20. 11 2
      packages/app/src/pages-sub/mine/invite/index.vue
  21. 30 28
      packages/app/src/pages-sub/mine/levels/components/level-card.vue
  22. 2 1
      packages/app/src/pages-sub/mine/levels/index.vue
  23. 1 1
      packages/app/src/pages-sub/mine/levels/rules/index.vue
  24. 4 0
      packages/app/src/pages/home/index.vue
  25. 3 0
      packages/app/src/pages/material/detail/index.vue
  26. 2 0
      packages/app/src/pages/messages/components/message-card.vue
  27. 1 7
      packages/app/src/pages/messages/index.vue
  28. 3 4
      packages/app/src/pages/mine/index.vue
  29. 1 1
      packages/app/src/style/index.scss

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

@@ -58,7 +58,6 @@ const dictLabelChange = (dictArr:any, value:any) => {
 }
 
 onMounted(async () => {
-  console.log(features.value,"features")
   if (
     props.options.circleType === '1' &&
     props.options.bannerUrls?.length === 1 &&
@@ -105,8 +104,8 @@ onMounted(async () => {
           />
           <wd-img
             v-if="getMemberAvatarFrame(options?.levelId)"
-            custom-class="vertical-bottom absolute! top--1.25 left--1.25"
-            :width="40"
+            custom-class="absolute! level-circle"
+            :width="38"
             :height="40"
             :src="getMemberAvatarFrame(options?.levelId) || ''"
           ></wd-img>
@@ -262,4 +261,4 @@ onMounted(async () => {
       </view>
     </Card>
   </div>
-</template>
+</template>

+ 13 - 2
packages/app/src/components/tabbar-evo.vue

@@ -10,6 +10,7 @@ const props = defineProps({
         selectedIconPath: string
         path: string
         hiddenTitle?: boolean
+		notice?: boolean
       }[]
     >,
     default: () => [],
@@ -57,15 +58,18 @@ onMounted(async () => {
         class="m-3.5 h-[60px] bg-white/70 rounded-[60px] border border-white backdrop-blur-[25px] flex items-center justify-around"
       >
         <template
-          v-for="({ iconPath, selectedIconPath, title, hiddenTitle, path }, i) in items"
+          v-for="({ iconPath, selectedIconPath, title, hiddenTitle, path, notice }, i) in items"
           :key="i"
         >
-          <div class="w-full flex flex-col items-center justify-center" @click="handleClick(path)">
+          <div class="w-full flex flex-col items-center justify-center relative" @click="handleClick(path)">
             <wd-img
               :height="hiddenTitle ? 40 : 22"
               :width="hiddenTitle ? 40 : 22"
               :src="`/${currentPath}` === path ? selectedIconPath : iconPath"
             ></wd-img>
+			<div class="notice">
+				<wd-img v-if="notice" width="16" height="16" src="/static/svgs/red.svg"></wd-img>
+			</div>
             <span
               class="mt-1 text-center text-[10px] font-normal leading-none"
               :class="[`/${currentPath}` === path ? 'text-black' : 'text-[#8c8c8c]']"
@@ -79,3 +83,10 @@ onMounted(async () => {
     </div>
   </div>
 </template>
+<style scoped>
+	.notice{
+		position: absolute;
+		top: -10rpx;
+		right: 20rpx;
+	}
+</style>

+ 3 - 1
packages/app/src/composables/permissions.ts

@@ -7,7 +7,7 @@ export const usePermissions = () => {
   const userStore = useUserStore()
   const { isLogined, isDesigner, userInfo } = storeToRefs(userStore)
   const routes = [
-    { path: '/pages-sub/mine/homepage/index', meta: { canNotLogin: false, canNotDesigner: true } },
+    { path: '/pages-sub/mine/homepage/index', meta: { canNotLogin: true, canNotDesigner: true } },
     {
       path: '/pages/material/mini-class/index',
       meta: { canNotLogin: false, canNotDesigner: true, toLogin: true },
@@ -112,6 +112,7 @@ export const usePermissions = () => {
       { name: 'download', meta: { canNotLogin: false, canNotDesigner: false } },
     ]
     const feature = features.find((item) => item.name === name)
+	console.log("feature",feature)
     if (feature) {
       if (!feature.meta.canNotLogin && !isLogined.value) {
         uni.showToast({ title: messages.components.toast.pleaseLogin, icon: 'none' })
@@ -130,6 +131,7 @@ export const usePermissions = () => {
         return
       }
     }
+	console.log("111")
     callback()
   }
   return { isLogined, isDesigner, routes, features, clickByPermission }

+ 9 - 4
packages/app/src/composables/share.ts

@@ -24,11 +24,12 @@ export const useShare = () => {
     //   res.path = `/pages-sub/mine/homepage/index?id=${id.value}&isShared=true`
     // }
     // return res
-
-    console.log('from', from)
+	
+	
+    // console.log('from', from)
     console.log('target', target)
     const res: Page.CustomShareContent = {}
-    if (from === 'button') {
+    if (from === 'button') {		
       if (target.dataset.type === 'homepage') {
         await shareDesignerHome({
           stylistId: target.dataset.options.homepageId,
@@ -37,8 +38,12 @@ export const useShare = () => {
         res.title = target.dataset.shareContent.title
         res.imageUrl = target.dataset.shareContent.imageUrl
         res.path = target.dataset.shareContent.path
-      } else {
+      } else {	 
         if (['1', '2'].includes(target.dataset.options.circleType)) {
+			if(!target.dataset.options.levelId || target.dataset.options.levelId < 2){
+				uni.showToast({ title: '无法分享普通会员等级作者的圈子内容', icon: 'none' }).then()
+				throw new Error("禁止分享")
+			} 
           await shareCircle(target.dataset.options.id)
         }
         res.path = `/pages-sub/home/moment/index?id=${target.dataset.options.id}&isShared=true`

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

@@ -19,7 +19,7 @@ export const messages = {
     toast: {
       pleaseLogin: '请先登录',
       pleaseAuthentication: '请先完成认证',
-      levelNotEnough: '等级不足',
+      levelNotEnough: '普通会员无法分享',
     },
   },
 }

+ 23 - 0
packages/app/src/layouts/tabbar.vue

@@ -2,6 +2,9 @@
 import TabbarEvo from '@/components/tabbar-evo.vue'
 import { iconCamera, iconWallet } from '../core/libs/pngs'
 import {
+  readCount
+} from '../core/libs/requests'
+import {
   home,
   homeActive,
   material,
@@ -19,6 +22,7 @@ import HonorDialog from "@/pages/home/components/honor-dialog/honor-dialog.vue";
 
 const router = useRouter()
 const publishState = ref(false)
+const messageCount = ref(false)
 const items = [
   {
     title: '首页',
@@ -43,6 +47,7 @@ const items = [
     title: '消息',
     iconPath: message,
     selectedIconPath: messageActive,
+	notice:messageCount,
     path: '/pages/messages/index',
   },
   {
@@ -57,9 +62,27 @@ const handleTabbarItemClick = (path: string) => {
     publishState.value = true
     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
+		}
+	}
+}
+onShow(async ()=>{
+	await getMessageNotice()
+})
 const toPublishMoment = () => {
   router.push('/pages-sub/publish/moment/index?circleType=1')
   publishState.value = false

+ 8 - 0
packages/app/src/pages-sub/home/classmates-detail/index.vue

@@ -17,6 +17,14 @@ onLoad(async (query: { id: string }) => {
   id.value = query.id
   await run()
 })
+onShareAppMessage(() => ({
+  title: data.value?.title,
+  imageUrl:data.value?.bannerUrl
+}))
+onShareTimeline(() => ({
+  title: data.value?.title,
+  imageUrl:data.value?.bannerUrl
+}))
 </script>
 <template>
   <div class="flex-grow bg-white">

+ 9 - 16
packages/app/src/pages-sub/home/mall/detail/index.vue

@@ -78,8 +78,9 @@ const handleClick = (product) => {
     toast.show('库存不足')
     return null
   }
-  const levelIds = product.memberLevelIds.split(',')
-  if (!levelIds.includes(String(userInfo.value.level.level))) {
+  console.log(product)
+  const levelIds = product?.memberLevelIds.split(',')
+  if (levelIds.length>0 && !levelIds.includes(String(userInfo.value.level.level))) {
     toast.show('您当前会员等级不符合兑换条件')
     return null
   }
@@ -95,9 +96,11 @@ onLoad(async (query: { id: string }) => {
 })
 onShareAppMessage(() => ({
   title: data.value?.prodcutName,
+  imageUrl:data.value?.productCoverImgUrl,
 }))
 onShareTimeline(() => ({
   title: data.value?.prodcutName,
+  imageUrl:data.value?.productCoverImgUrl,
 }))
 </script>
 
@@ -185,25 +188,15 @@ onShareTimeline(() => ({
               block
               color="white"
               location="right"
-              @click="((show = true), (type = 'add2Cart'))"
+              @click="clickByPermission('mallExchange', () => {(show = true), (type = 'add2Cart')})"
             >
               <span class="text-black/80">加入购物车</span>
             </ButtonEvo>
           </div>
           <div class="flex-1">
-            <ButtonEvo
-              block
-              size="lg"
-              :disabled="
-                (data?.isRestrict === 1 && data?.productRepertory == 0) ||
-                !data?.memberLevelIds.split(',').includes(String(userInfo.level.level))
-                  ? 'isDisabled'
-                  : null
-              "
-              @click="handleClick(data)"
-            >
-              立即兑换
-            </ButtonEvo>
+			  <wd-button block :round="false" @click="clickByPermission('mallExchange', () => {handleClick(data)})">
+			    立即兑换
+			  </wd-button>   
           </div>
         </div>
       </BottomAppBar>

+ 24 - 2
packages/app/src/pages-sub/home/moment/index.vue

@@ -15,6 +15,7 @@ import {
   getCircleReviews,
   getCircleUpvotes,
   shareCircle,
+  getByDictType,
 } from '../../../core/libs/requests'
 import { handleShareClick, handleUpvoteClick } from '../../../core/libs/actions'
 import CommentItem from '../components/comment-item.vue'
@@ -148,6 +149,13 @@ const handleDelete = async (index?: number) => {
     await runGetReviews()
   }
 }
+const dictLabelChange = (dictArr:any, value:any) => {
+	for(let i in dictArr){
+		if(dictArr[i].value === value){
+			return dictArr[i].label
+		}
+	}
+}
 const handleUpvote = async (index?: number) => {
   if (index !== undefined) {
     await commentItemRef.value.at(index).refresh()
@@ -155,6 +163,7 @@ 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))) {
     router.push(
       `/pages-sub/mine/homepage/index?id=${data.value?.stylistId}${isShared.value ? '&isShared=true' : ''}`,
@@ -162,6 +171,8 @@ const toDesignerHomepage = () => {
   }
 }
 onMounted(async () => {})
+const dictMemberDesignStyle = ref<[]>()
+const dictCircleSpaceType = ref<[]>()
 onLoad(async (query?: { id: string; isShared?: boolean }) => {
   id.value = query?.id
   isShared.value = query?.isShared
@@ -169,6 +180,10 @@ onLoad(async (query?: { id: string; isShared?: boolean }) => {
   await setSwiperStyle()
   await runGetReviews()
   await setCircleUpvotes()
+  let value1  = await getByDictType(DictType.circleSpaceType);
+  dictCircleSpaceType.value = value1.data
+  let value2  = await getByDictType(DictType.memberDesignStyle);
+  dictMemberDesignStyle.value = value2.data
 })
 // onShareAppMessage(async () => {
 //   await shareCircle(id.value)
@@ -262,13 +277,20 @@ const handleClick = async (value:boolean) => {
                 设计案例:{{ data?.caseName }}
               </div>
               <div class="mt-4 flex items-center justify-between text-black/40 text-sm">
-                <div class="font-normal font-['PingFang_SC']">
+                <!-- <div class="font-normal font-['PingFang_SC']">
                   类别:{{ getOptionLabel(DictType.circleSpaceType, data?.spaceType) }}
                 </div>
                 |
                 <div class="text-black/40 text-sm font-normal font-['PingFang_SC']">
                   风格:{{ getOptionLabel(DictType.memberDesignStyle, data.designStyle) }}
-                </div>
+                </div> -->
+				<div class="font-normal font-['PingFang_SC']">
+				  类别:{{ dictLabelChange(dictCircleSpaceType, data?.spaceType) }}
+				</div>
+				|
+				<div class="text-black/40 text-sm font-normal font-['PingFang_SC']">
+				  风格:{{ dictLabelChange(dictMemberDesignStyle, data.designStyle) }}
+				</div>
                 |
                 <div class="text-black/40 text-sm font-normal font-['PingFang_SC']">
                   面积:{{ data.spaceExtent }}

+ 27 - 3
packages/app/src/pages-sub/home/offline-activity/index.vue

@@ -25,6 +25,7 @@ import PageHelper from '@/components/page-helper.vue'
 const { data: categories, run: setCategories } = useRequest(() => getAllCategories(), {
   initialData: [],
 })
+const currentBanner = ref(0)
 const tab = ref<number>(0)
 const contentCategory = ref()
 const { data, run: setData } = useRequest(
@@ -46,6 +47,9 @@ const { data: activities, run: setActivities } = useRequest(
 const { data: levels, run: setLevels } = useRequest(() => getAppMemberLevelConfigs(), {
   initialData: [],
 })
+const handleSwiperChange = ({ detail: { current } }) => {
+  currentBanner.value = current 
+}
 const levelsByMemberLevel = computed(() =>
   levels.value.reduce((acc, item) => {
     acc[item.memberLevel] = item
@@ -76,13 +80,21 @@ onMounted(async () => {
     ></section-heading>
     <view class="relative">
 		<template v-if="activities.list?.length">
-		  <swiper class="aspect-[0.75/1] rounded-[20px] overflow-hidden">
+		  <swiper class="aspect-[0.75/1] rounded-[20px] overflow-hidden" @change="handleSwiperChange">
 		    <template v-for="(it, i) in activities.list" :key="i">
 		      <swiper-item>
 		        <RegisterCard :options="{ ...it, levelsByMemberLevel }"></RegisterCard>
 		      </swiper-item>
 		    </template>
 		  </swiper>
+		  <div class="absolute flex gap-1 dots">
+		    <template v-for="(it, i) in activities.list" :key="i">
+		      <div
+		        class="w-1 h-1 rounded-full"
+		        :class="`${currentBanner === i ? 'bg-white bg-active' : 'bg-white/40'}`"
+		      ></div>
+		    </template>
+		  </div>
 		</template>
 	</view>
     <card custom-class="">
@@ -98,7 +110,7 @@ onMounted(async () => {
     <wd-tabs
       v-model="tab"
       custom-class="bg-transparent!"
-      :slidable-num="4"
+      slidable="always"
       @change="handleTabChange"
     >
       <block v-for="(it, item) in categories.find(({ id }) => id === 2)?.children" :key="item">
@@ -129,4 +141,16 @@ onMounted(async () => {
   </view>
 </template>
 
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+	.dots{
+		bottom: 20rpx;
+		left: 50%;
+		transform: translateX(-50%);
+	}
+	.bg-active{
+		width:40rpx;
+	}
+	:deep(.wd-tabs.is-slide .wd-tabs__nav-item){
+		padding:0 12px !important;
+	}
+</style>

+ 3 - 1
packages/app/src/pages-sub/home/spread/product-detail/index.vue

@@ -64,14 +64,16 @@ const handleConfirm = async () => {
 onLoad(async (query: { id: string; title: string; item: string }) => {
   id.value = query.id
   item.value = query.item
-  uni.setNavigationBarTitle({ title: query.title })
+  uni.setNavigationBarTitle({ title: decodeURIComponent(query.title) })
   await setData()
 })
 onShareAppMessage(() => ({
   title: data.value?.prodcutName,
+  imageUrl:data.value?.productCoverImgUrl
 }))
 onShareTimeline(() => ({
   title: data.value?.prodcutName,
+  imageUrl:data.value?.productCoverImgUrl
 }))
 </script>
 

+ 1 - 1
packages/app/src/pages-sub/home/spread/wx-agent-operation/index.vue

@@ -54,7 +54,7 @@ onShareTimeline(() => ({
                 {{ it.showFavourable ? it.favourablePoints : it.points }}
               </div>
               <div class="text-black/60 text-sm font-normal font-['PingFang_SC'] leading-[34px]">
-                {{ String(it.needPoints) == '1' ? '折' : '积分' }}
+                {{ it.needPoints == '1' ? '折' : '积分' }}
               </div>
               <div class="flex-1"></div>
               <div

+ 23 - 2
packages/app/src/pages-sub/home/study-tour/index.vue

@@ -23,7 +23,10 @@ import { BannerMode } from '../../../core/libs/models'
 import { useRouter } from '../../../core/utils/router'
 import PageHelper from '@/components/page-helper.vue'
 import RegisterCard from './components/register-card.vue'
-
+const currentBanner = ref(0)
+const handleSwiperChange = ({ detail: { current } }) => {
+  currentBanner.value = current 
+}
 const router = useRouter()
 const { data: studyTours, run: setStudyTours } = useRequest(() =>
   getStudyTours({ headRecommend: 1 }),
@@ -72,7 +75,7 @@ onMounted(async () => {
 
     <div class="relative">
 		<template v-if="studyTours?.list.length">
-		  <swiper class="aspect-[0.75/1] rounded-[20px] overflow-hidden">
+		  <swiper class="aspect-[0.75/1] rounded-[20px] overflow-hidden" @change="handleSwiperChange">
 		    <template v-for="(it, i) in studyTours?.list" :key="i">
 		      <swiper-item>
 		        <RegisterCard :options="{ ...it, levelsByMemberLevel }"></RegisterCard>
@@ -80,6 +83,14 @@ onMounted(async () => {
 		    </template>
 		  </swiper>
 		</template>
+		<div class="absolute flex gap-1 dots">
+		  <template v-for="(it, i) in studyTours?.list" :key="i">
+		    <div
+		      class="w-1 h-1 rounded-full"
+		      :class="`${currentBanner === i ? 'bg-white bg-active' : 'bg-white/40'}`"
+		    ></div>
+		  </template>
+		</div>
 	</div>
     <!-- </template>
     </PageHelper> -->
@@ -179,3 +190,13 @@ onMounted(async () => {
     </PageHelper>
   </view>
 </template>
+<style scoped>
+	.dots{
+		bottom: 20rpx;
+		left: 50%;
+		transform: translateX(-50%);
+	}
+	.bg-active{
+		width:40rpx;
+	}
+</style>

+ 11 - 2
packages/app/src/pages-sub/home/study-tour/list.vue

@@ -8,7 +8,8 @@
 </route>
 <script setup lang="ts">
 import SectionHeading from '@/components/section-heading.vue'
-import { getAppMemberLevelConfigs, getStudyTours } from '../../../core/libs/requests'
+import { BannerMode } from '../../../core/libs/models'
+import { getAppMemberLevelConfigs, getStudyTours, getBanners } from '../../../core/libs/requests'
 import StudyTourCard from './components/study-tour-card.vue'
 import PageHelper from '@/components/page-helper.vue'
 
@@ -27,22 +28,30 @@ const levelsByMemberLevel = computed(() =>
     return acc
   }, {}),
 )
+const { data: banners, run: setBanners } = useRequest(
+  () => getBanners({ mode: BannerMode.StudyTour }),
+  { initialData: [] },
+)
 onLoad(async (query?: Record<string | 'designStudyAbroadYear' | 'designDesc', string>) => {
   designStudyAbroadYear.value = query.designStudyAbroadYear
   title.value = `${designStudyAbroadYear.value}年游学计划`
   if (query.designDesc) {
-    designDesc.value = query.designDesc
+    designDesc.value = decodeURIComponent(query.designDesc)
   }
 })
 
 onMounted(async () => {
   await setLevels()
+  await setBanners();
+  console.log(banners)
 })
 onShareAppMessage(() => ({
   title: '游学计划',
+  imageUrl:banners.value?.length>0?banners.value[0].bannerImgUrl:""
 }))
 onShareTimeline(() => ({
   title: '游学计划',
+  imageUrl:banners.value?.length>0?banners.value[0].bannerImgUrl:""
 }))
 </script>
 <template>

+ 18 - 4
packages/app/src/pages-sub/mine/authentication/index.vue

@@ -111,7 +111,7 @@ const setReferrerExisting = (value: string) => {
 }
 const handleSubmit = async () => {
   console.log(formData.value)
-  if (formData.value.channelSource && formData.value.channelSource !== '4' && !userAuthInfo.value) {
+  if (formData.value.channelSource && formData.value.channelSource !== '4' && formData.value.channelSource !== '3' && !userAuthInfo.value) {
     if ((formData.value.referrer ?? '') === '') {
       await uni.showToast({ title: messages.mine.authentication.referrerErrorText, icon: 'none' })
       return
@@ -198,7 +198,6 @@ onLoad(async (query?: Record<string | 'scene', string>) => {
     }
   }
   await setUserAuthInfo()
-  console.log(userAuthInfo.value)
   if (userAuthInfo.value) {
     formData.value = {
       ...pick(userAuthInfo.value, [
@@ -219,12 +218,13 @@ onLoad(async (query?: Record<string | 'scene', string>) => {
   }
   const { data } = await getByDictType('member_channel_source')
   const { data: res } = await getByDictType(DictType.memberSpatialExpertiseType)
-  console.log(res)
+  // console.log(res)
   schema.value.channelSource.props.columns = data
   schema.value.spatialExpertiseType.props.columns = res
   formInited.value = true
+  console.log(userInfo.value)
   if (userInfo.value.userAuthStatus === 1) {
-    console.log(formData.value)
+    // console.log(formData.value)
     Object.entries(schema.value).forEach(([key]) => {
       schema.value[key].props.disabled = true
     })
@@ -241,6 +241,20 @@ onLoad(async (query?: Record<string | 'scene', string>) => {
       msg: userAuthInfo.value?.remark || '由于系统原因,您提交的认证暂时无法通过,请修改后重新提交',
     })
   }
+  if(userInfo.value.userAuthStatus === 0){
+	await uni.showToast({ title: "您当前已是筑巢荟会员", icon: 'none' })
+	setTimeout(()=>{
+		uni.switchTab({
+			url:"/pages/mine/index"
+		})
+	},2000)
+  }
+})
+onShow(()=>{
+	// console.log(!userInfo.value.nickname)
+	if(!userInfo.value.nickname){
+		router.push('/pages-sub/login/index')
+	}
 })
 defineExpose({})
 </script>

+ 6 - 0
packages/app/src/pages-sub/mine/coupons/index.vue

@@ -18,6 +18,12 @@ const tabs = ref([
   { label: '商品优惠券', value: '2' },
 ])
 const query = computed(() => ({ couponType: tab.value }))
+onLoad(async (query)=>{
+	if(query?.type){
+		tab.value = query?.type
+		console.log(tab.value)
+	}
+})
 // const {data, run: set} = useRequest(() => getCoupons({}))
 </script>
 <template>

+ 39 - 4
packages/app/src/pages-sub/mine/homepage/index.vue

@@ -164,8 +164,32 @@ onUnload(async () => {
     })
   }
 })
-onShareAppMessage(shareAppMessage)
-onShareTimeline(() => ({}))
+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:userInfo.value?.nickname}: “${designerInfo.value?.designDesc}”`;
+			  res.imageUrl = designerInfo.value.sharePageUrl;
+			  res.path = `/pages-sub/mine/homepage/index?id=${userInfo.value?.id}&isShared=true`
+			  resolve(res)
+		  }
+	})
+	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`
+// }))
+onShareTimeline(()=>({
+	title:`${designerInfo.value?.homePageName?designerInfo.value?.homePageName:userInfo.value?.nickname}: “${designerInfo.value?.designDesc}”`,
+	imageUrl:designerInfo.value.sharePageUrl,
+	query:`${id}&isShared=true`
+}))
 defineExpose({
   navBarFixed: false,
 })
@@ -186,6 +210,7 @@ defineExpose({
           <div class="flex min-h-27 px-3.5 gap-3.5">
             <div class="relative">
               <wd-img
+				custom-class="overflow-hidden rounded-full "
                 :width="72"
                 :height="72"
                 :src="memberInfo?.avatar || NetImages.DefaultAvatar"
@@ -385,7 +410,7 @@ defineExpose({
           </wd-button>
         </div>
         <div class="flex-1" v-if="isOwn && !isShared">
-          <button
+          <!-- <button
             v-if="features.shareMoment"
             class="p-0 after:b-none"
             block
@@ -403,7 +428,17 @@ defineExpose({
             }"
           >
             <wd-button block :round="false">分享</wd-button>
-          </button>
+          </button> -->
+		  <button
+		    v-if="features.shareMoment"
+		    class="p-0 after:b-none"
+		    block
+		    :round="false"
+		    :open-type="features.shareMoment ? 'share' : ''"
+			 @click="clickByPermission('share', () => {})"
+		  >
+		    <wd-button block :round="false">分享</wd-button>
+		  </button>
           <template v-else>
             <!--            1-->
             <wd-button block :round="false" @click="clickByPermission('share', () => {})">

+ 6 - 2
packages/app/src/pages-sub/mine/honors/detail/index.vue

@@ -44,8 +44,8 @@ const createPoster = () => {
           NetImages.TopSpotlight,
           data.value.quantity ? data.value.activedImage : data.value.image,
           designer.value.headImgUrl || userInfo.value?.avatar || NetImages.DefaultAvatar,
-          data.value.quantity ? data.value.activedImage : data.value.image,
-          designer.value.headImgUrl || userInfo.value?.avatar || NetImages.DefaultAvatar,
+          NetImages.Logo,
+          designer.value?.qrcodeUrl,
           'https://image.zhuchaohui.com/zhucaohui/9f89604f285c33200b7e6fda9acc82e130f34c2f5687cfeb78f3541e1fabcc28.png',
           'https://image.zhuchaohui.com/zhucaohui/2467be55426018856150bd94bbd21865df3d73ce982bc1c82b7585cf26c822f0.png',
         ].map((it) => uni.getImageInfo({ src: it }).then(({ path }) => path)),
@@ -128,6 +128,10 @@ const setBadgesPath = (type: string) => {
     uni.redirectTo({
       url: `/pages-sub/home/offline-activity/index`,
     })
+  } else if(type === '游学徽章' || type === '典藏勋章') {
+    uni.switchTab({
+      url: `/pages/home/index`,
+    })
   } else {
     uni.switchTab({
       url: `/pages/home/index`,

+ 20 - 8
packages/app/src/pages-sub/mine/honors/index.vue

@@ -182,13 +182,18 @@ onLoad(async (query?: Record<string | 'active' | 'id' | 'isShared', string>) =>
       </template>
     </div>
     <template v-if="active === 'badge'">
-      <view class="h-[145px]" v-if="String(userInfo.userId) === id">
+	<!-- <view class="h-[145px]" v-if="String(userInfo.userId) === id">	 -->
+      <view class="h-[145px]">
         <swiper :autoplay="autoplay" @change="handleSwiperChange">
           <swiper-item v-for="item in collectionBadges" :key="item.id">
             <Card custom-class="border border-solid bg-[#25221f]! border-[rgba(255,236,185,0.20)]">
               <div class="grid grid-cols-[90px_1fr] gap-x-4">
-                <div class="grid-row-start-1 grid-row-end-4 col-start-1">
-                  <wd-img
+                <div class="grid-row-start-1 grid-row-end-4 col-start-1" @click="
+                  router.push(
+                    `/pages-sub/mine/honors/detail/index?type=badge&data=${JSON.stringify(item)}`,
+                  )
+                ">
+                  <!-- <wd-img
                     width="90"
                     height="90"
                     :src="
@@ -196,11 +201,21 @@ onLoad(async (query?: Record<string | 'active' | 'id' | 'isShared', string>) =>
                         ? item.badgeYesObtainedImage
                         : item.badgeNotObtainedImage
                     "
-                  ></wd-img>
+                  ></wd-img> -->
+				  <wd-img
+				    width="90"
+				    height="90"
+				    :src="item.badgeYesObtainedImage"
+				  ></wd-img>
                 </div>
                 <div class="row-start-1 col-start-2 flex items-center justify-between">
                   <div
                     class="text-center text-[#ffecb9] text-lg font-normal font-['PingFang_SC'] leading-relaxed"
+					@click="
+					  router.push(
+					    `/pages-sub/mine/honors/detail/index?type=badge&data=${JSON.stringify(item)}`,
+					  )
+					"
                   >
                     {{ item.badgeName }}
                   </div>
@@ -265,10 +280,7 @@ onLoad(async (query?: Record<string | 'active' | 'id' | 'isShared', string>) =>
       </view>
 
       <template v-for="([key, it], index) in Object.entries(badges)" :key="index">
-        <Card
-          v-if="!((!isOwner || isShared) && ['积分徽章', '积分徽章'].includes(key))"
-          custom-class="bg-[#171615]! text-white border border-solid border-[rgba(255,236,185,0.20)]"
-        >
+        <Card v-if="!((!isOwner || isShared) && ['积分徽章', '积分徽章'].includes(key))" custom-class="bg-[#171615]! text-white border border-solid border-[rgba(255,236,185,0.20)]">
           <div class="flex items-center gap-2 py-4">
             <div class="w-1.5 h-1.5 bg-[#ffecb9] rounded-full"></div>
             <SectionHeading :title="key.toString()" dark></SectionHeading>

+ 11 - 2
packages/app/src/pages-sub/mine/invite/index.vue

@@ -27,6 +27,7 @@ const form = ref<{
   userId?: number
   videoNumber?: string
 }>()
+const windowInfo  = ref<{}>
 const { data, run: setData } = useRequest(() => getDesignerInfo(userInfo.value.userId))
 const { loading, run: submiting } = useRequest(() => updateDesignerInfo(form.value))
 const posterUrl = ref()
@@ -35,10 +36,11 @@ const createPoster = () => {
   return new Promise((resolve, reject) => {
     ;(async () => {
       uni.showLoading({ title: '生成中' })
-      const [path, bgPath, logoPath, avatarPath, icon1, icon2, icon3, icon4] = await Promise.all(
+      const [path, bgPath, qrcode, logoPath, avatarPath, icon1, icon2, icon3, icon4] = await Promise.all(
         [
           data.value.sharePageUrl,
           NetImages.InviteBg,
+		  data.value.qrcodeUrl,
           NetImages.Logo,
           data.value.headImgUrl || userInfo.value?.avatar || NetImages.DefaultAvatar,
           'https://image.zhuchaohui.com/zhucaohui/315c5ca680bc6b47a5344dbff701cf1e6802d8a240754e25ef3d4308bc1deef6.png',
@@ -60,6 +62,7 @@ const createPoster = () => {
           ctx.drawImage(path, 0, 0, w, w / 1.56)
           canvas.CircleImage(avatarPath, 17, 21, 14)
           canvas.Image(logoPath, 17, 230, 24, 24)
+		  canvas.Image(qrcode, 200, 350, 100, 100)
           canvas.FillText(userInfo.value?.nickname, '#ffffff', 14, 53, 40)
           canvas.FillText('筑巢荟—助力设计师成长平台', '#ffffff', 18, 53, 248)
           canvas.FillText('国内外设计游学', '#ffffff', 12, 62, 303)
@@ -77,6 +80,8 @@ const createPoster = () => {
               canvasId: 'firstCanvas',
               width: 300,
               height: 460,
+			  fileType: "jpg",
+			  quality: 1,
               success: (res) => {
                 // console.log('生成海报', res)
                 uni.hideLoading()
@@ -117,6 +122,7 @@ const share = () => {
 onMounted(async () => {
   await setData()
   form.value = pick(data.value, ['id', 'userId', 'videoNumber'])
+  uni.getWindowInfo()
   posterUrl.value = await createPoster()
 })
 // onAppShare(() => {})
@@ -140,9 +146,12 @@ onMounted(async () => {
           :src="posterUrl"
           @displayed="canvasHidden = true"
         ></ImageEvo>
-        <div class="absolute bottom-5.5 left-5.5" v-if="canvasHidden">
+        <div class="absolute bottom-5.5 left-5.5 flex justify-between" v-if="canvasHidden">
           <!-- <cover-view> -->
           <wd-button custom-class="bg-white/10!" @click="save">保存到相册</wd-button>
+		  <!-- <div style="margin-left: 100rpx;">
+			  <wd-img :width="50" :height="50" :src="data.qrcodeUrl"></wd-img>
+		  </div> -->
           <!-- </cover-view> -->
           <!-- <wd-button @click="share">微信</wd-button>
         <wd-button @click="share">朋友圈</wd-button> -->

+ 30 - 28
packages/app/src/pages-sub/mine/levels/components/level-card.vue

@@ -49,33 +49,35 @@ const isLowerThanCurrent = computed(() => {
     <!--    {{ userInfo.level.point }}-->
     <!--    {{ userInfo.level.point }}-->
     <!--    {{ percentage }}-->
-    <template v-if="isHigherThanCurrent">
-      <div class="text-[#61311b] text-xs font-normal font-['PingFang_SC'] leading-relaxed">
-        <!--        还差{{ props.option[props.index]?.points - userInfo.level.point }}积分升级-->
-        当前高于该等级
-      </div>
-    </template>
-    <template v-else-if="isLowerThanCurrent">
-      <div class="text-[#61311b] text-xs font-normal font-['PingFang_SC'] leading-relaxed">
-        <!--        还差{{ props.option[props.index]?.points - userInfo.level.point }}积分升级-->
-        距{{ option[index].memberLevelName }}还需{{
-          option[index].points - userInfo.level.point
-        }}积分
-      </div>
-      <wd-progress :percentage="(userInfo.level.point / option[index].points) * 100" hide-text />
-    </template>
-    <template v-else-if="isMaxLevel">
-      <div class="text-[#61311b] text-xs font-normal font-['PingFang_SC'] leading-relaxed">
-        当前积分{{ userInfo.level.point }}
-      </div>
-    </template>
-    <template v-else>
-      <div class="text-[#61311b] text-xs font-normal font-['PingFang_SC'] leading-relaxed">
-        距{{ option[index + 1].memberLevelName }}还需{{
-          option[index + 1].points - userInfo.level.point
-        }}积分
-      </div>
-      <wd-progress :percentage="percentage" hide-text />
-    </template>
+    <template v-if="userInfo">
+		<template v-if="isHigherThanCurrent">
+		  <div class="text-[#61311b] text-xs font-normal font-['PingFang_SC'] leading-relaxed">
+		    <!--        还差{{ props.option[props.index]?.points - userInfo.level.point }}积分升级-->
+		    当前高于该等级
+		  </div>
+		</template>
+		<template v-else-if="isLowerThanCurrent">
+		  <div class="text-[#61311b] text-xs font-normal font-['PingFang_SC'] leading-relaxed">
+		    <!--        还差{{ props.option[props.index]?.points - userInfo.level.point }}积分升级-->
+		    距{{ option[index].memberLevelName }}还需{{
+		      option[index].points - userInfo.level.point
+		    }}积分
+		  </div>
+		  <wd-progress :percentage="(userInfo.level.point / option[index].points) * 100" hide-text />
+		</template>
+		<template v-else-if="isMaxLevel">
+		  <div class="text-[#61311b] text-xs font-normal font-['PingFang_SC'] leading-relaxed">
+		    当前积分{{ userInfo.level.point }}
+		  </div>
+		</template>
+		<template v-else>
+		  <div class="text-[#61311b] text-xs font-normal font-['PingFang_SC'] leading-relaxed">
+		    距{{ option[index + 1].memberLevelName }}还需{{
+		      option[index + 1].points - userInfo.level.point
+		    }}积分
+		  </div>
+		  <wd-progress :percentage="percentage" hide-text />
+		</template>
+	</template>
   </div>
 </template>

+ 2 - 1
packages/app/src/pages-sub/mine/levels/index.vue

@@ -28,8 +28,9 @@ onMounted(async () => {
   current.value = sort(levelConfigs.value, (it) => it.memberLevel)?.findIndex(
     (it) => it.memberLevel === userInfo.value?.level?.level,
   )
+ console.log(current.value)
  if (current.value == -1){
-   current.value = 4
+   current.value = 0
  }
 })
 </script>

+ 1 - 1
packages/app/src/pages-sub/mine/levels/rules/index.vue

@@ -56,7 +56,7 @@ const tab = ref(0)
                 :class="['bg-[#fffcf6]', 'bg-[#fff8eb]', 'bg-[#fff6e3]', 'bg-[#fff3d9]'][i]"
               >
                 <wd-img
-                  v-if="it.id === userInfo.level.level"
+                  v-if="it.id === userInfo?.level?.level"
                   custom-class="absolute! left-10vw "
                   width="14"
                   height="14"

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

@@ -310,4 +310,8 @@ onShareAppMessage(shareAppMessage)
 		width: 100%;
 		z-index: 9999;
 	}
+	:deep(.level-circle){
+		top: -10rpx;
+		left:-7rpx;
+	}
 </style>

+ 3 - 0
packages/app/src/pages/material/detail/index.vue

@@ -55,6 +55,7 @@ const copy = (url) =>{
 		data:url,
 		success: () => {
 			console.log("已复制")
+			downloadMaterials({ materialsId: id.value })
 		}
 	})
 }
@@ -109,9 +110,11 @@ onLoad(async (query: { id: number }) => {
 })
 onShareAppMessage(() => ({
   title: data.value?.materialsName,
+  imageUrl:data.value?.bannerUrl,
 }))
 onShareTimeline(() => ({
   title: data.value?.materialsName,
+  imageUrl:data.value?.bannerUrl,
 }))
 </script>
 <template>

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

@@ -67,6 +67,8 @@ const handleJump = () => {
       query.createTime = String(props.options.createTime)
       query.viewsCount = props.options.viewCount
       break
+	case 14:
+	  query.type = 	props.options.couponType
     default:
       break
   }

+ 1 - 7
packages/app/src/pages/messages/index.vue

@@ -184,13 +184,7 @@ onShow(async () => {
 
 <template>
   <view class="flex-grow flex flex-col bg">
-    <PageHelperEvo
-      ref="pageHelperRef"
-      class="flex-grow flex"
-      :request="getMessages"
-      :query="query"
-      :automatic="false"
-    >
+    <PageHelperEvo ref="pageHelperRef" class="flex-grow flex" :request="getMessages" :query="query" :automatic="false">
       <template #top>
         <wd-tabs v-model="tab" @change="handleChange">
           <block v-for="({ label, badgeProps }, i) in tabs" :key="i">

+ 3 - 4
packages/app/src/pages/mine/index.vue

@@ -265,8 +265,7 @@ onPageScroll(({ scrollTop }: { scrollTop: number }) => {
         <!-- <img class="w-[72px] h-[72px] rounded-full border border-white" :src="avatar" /> -->
 		<div class="relative">
 			<wd-img
-			  v-if="userInfo?.level"
-			  custom-class="rounded-full border border-white"
+			  custom-class="rounded-full border border-white overflow-hidden"
 			  :width="72"
 			  :height="72"
 			  :src="avatar"
@@ -378,7 +377,7 @@ onPageScroll(({ scrollTop }: { scrollTop: number }) => {
       </div>
       <div class="mx-3.5 box-border absolute left-0 right-0 top-0 p-3.5">
         <div class="flex items-center" @click="router.push('/pages-sub/mine/levels/index')">
-          <wd-img custom-class="vertical-bottom" :src="vip" width="35" mode="widthFix"></wd-img>
+          <wd-img :src="vip" width="35" mode="widthFix"></wd-img>
           <div
             class="ml-2 text-center text-[#faeac6] text-sm font-normal font-['PingFang_SC'] leading-normal"
           >
@@ -480,7 +479,7 @@ onPageScroll(({ scrollTop }: { scrollTop: number }) => {
     </view>
 	<wd-overlay :show="official" @click="official = false">
 		<view class="wrapper" @click.stop="">
-		    <wd-img :width="'100%'" :height="'100%'" src="https://image.zhuchaohui.com/zhucaohui/86236d61c75904763cd1247db239b25fa2d8cb8222e4575d29581f58e5d69036.png" mode="widthFix"></wd-img>
+		    <wd-img :width="'100%'" :height="'100%'" src="https://image.zhuchaohui.com/zhucaohui/de0f43be81ba577eda016a994ab203bb79149f09a7a919b7598ec2c0cb04c75d.png" mode="widthFix"></wd-img>
 			<wd-img @click="official = false" :src="close" width="28" height="28" custom-class="vertical-bottom"></wd-img>
 		</view>
 	</wd-overlay>

+ 1 - 1
packages/app/src/style/index.scss

@@ -44,4 +44,4 @@ page {
   flex-direction: column;
   flex-grow: 1;
 }
-/* endif */
+/* endif */