Преглед изворни кода

feat(权限管理): 添加分享功能的等级限制

- 在 permissions.ts 中为 'share' 功能添加了最低等级限制
- 在 messages.ts 中添加了等级不足的提示消息
- 修改了 honors 页面,只有荣誉主人可以看到分享按钮
- 调整了 homepage 中分享按钮的显示逻辑
EvilDragon пре 4 месеци
родитељ
комит
0d5bfda2b1

+ 1 - 1
packages/app/src/components/moment-item.vue

@@ -190,7 +190,7 @@ onMounted(async () => {
           </template>
           <template v-else>
             <view
-              @click.stop="clickByPermission('share', () => emits('share', options))"
+              @click.stop="clickByPermission('share', () => {})"
               class="flex items-center text-[rgba(0,0,0,0.85)] text-3.5 font-400 line-height-5.5"
             >
               <wd-img width="15" height="15" src="/static/svgs/share.svg"></wd-img>

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

@@ -102,7 +102,7 @@ export const usePermissions = () => {
        * 活动游学兑换
        */
       { name: 'exchange', meta: { canNotLogin: false, canNotDesigner: false } },
-      { name: 'share', meta: { canNotLogin: false, canNotDesigner: false } },
+      { name: 'share', meta: { canNotLogin: false, canNotDesigner: false, minLevel: 2 } },
     ]
     const feature = features.find((item) => item.name === name)
     if (feature) {
@@ -116,6 +116,10 @@ export const usePermissions = () => {
         useRouter().push('/pages/mine/authentication/index')
         return
       }
+      if (feature.meta.minLevel && userInfo.value.level.level < feature.meta.minLevel) {
+        uni.showToast({ title: messages.components.toast.levelNotEnough, icon: 'none' }).then()
+        return
+      }
     }
     callback()
   }

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

@@ -18,6 +18,7 @@ export const messages = {
     toast: {
       pleaseLogin: '请先登录',
       pleaseAuthentication: '请先完成认证',
+      levelNotEnough: '等级不足',
     },
   },
 }

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

@@ -932,25 +932,25 @@ export const updateHonorPopUp = (query: { bizId: string; bizType: string }) =>
  * 获取徽章列表
  */
 export const getBadges = (query = {}) =>
-  httpGet<{ [key: string]: Badge[] }>('/app-api/member/stylist-honor/get-badge-list')
+  httpGet<{ [key: string]: Badge[] }>('/app-api/member/stylist-honor/get-badge-list', query)
 /**
  * 获取个人徽章
  */
 export const getOwnBadges = (query = {}) =>
-  httpGet<Badge[]>('/app-api/member/stylist-honor/getConferBadgeList')
+  httpGet<Badge[]>('/app-api/member/stylist-honor/getConferBadgeList', query)
 /**
  * 获取证书列表
  */
 export const getCertificates = (query = {}) =>
-  httpGet<Certificate[]>('/app-api/member/stylist-honor/get-certificate-list')
+  httpGet<Certificate[]>('/app-api/member/stylist-honor/get-certificate-list', query)
 /**
  * 获取荣誉统计
  */
-export const getHonorStatistics = () =>
+export const getHonorStatistics = (query = {}) =>
   httpGet<{
     certCount: number
     badgeCount: number
-  }>('/app-api/member/stylist-honor/get-honor-count')
+  }>('/app-api/member/stylist-honor/get-honor-count', query)
 /**
  * 获取骑行下拉
  */

+ 14 - 7
packages/app/src/pages/mine/homepage/index.vue

@@ -34,10 +34,10 @@ import { usePermissions } from '../../../composables/permissions'
 import ImageEvo from '@/components/image-evo.vue'
 import more from '@designer-hub/assets/src/libs/assets/more'
 import qrCode from '@designer-hub/assets/src/libs/assets/qrCode'
-import {useShare} from "@/composables/share";
+import { useShare } from '@/composables/share'
 
 const { features, clickByPermission } = usePermissions()
-const {shareAppMessage} = useShare()
+const { shareAppMessage } = useShare()
 const { alert, confirm } = useMessage()
 const router = useRouter()
 const userStore = useUserStore()
@@ -59,7 +59,7 @@ const { data: memberInfo, run: setMemberInfo } = useRequest(() => getUserInfoByI
 const { data: designerInfo, run: setDesignerInfo } = useRequest(() => getDesignerInfo(id.value), {
   initialData: {},
 })
-const { data: badges, run: setBadges } = useRequest(() => getOwnBadges())
+const { data: badges, run: setBadges } = useRequest(() => getOwnBadges({ userId: id.value }))
 const isOwn = computed(() => userInfo.value?.userId === id.value)
 const skills = computed(() =>
   [
@@ -222,7 +222,7 @@ defineExpose({
       </div>
     </div>
     <div class="flex-grow flex flex-col bg-white rounded-t-2xl relative bottom-4 gap-5 px-3.5 pt-5">
-      <div class="flex gap-4" v-if="skills.length">
+      <div class="flex gap-4" v-if="skills?.length">
         <template v-for="(it, i) in skills" :key="i">
           <div>
             <span
@@ -249,12 +249,12 @@ defineExpose({
         >
           <div class="">
             <div class="flex items-center gap-4">
-              <template v-for="(it, i) in badges.slice(0, badges.length > 5 ? 3 : 4)" :key="i">
+              <template v-for="(it, i) in badges?.slice(0, badges?.length > 5 ? 3 : 4)" :key="i">
                 <!-- <div class="bg-[#fa9d3b]"> -->
                 <wd-img width="26" mode="widthFix" :src="it.badgeYesObtainedImage"></wd-img>
                 <!-- </div> -->
               </template>
-              <div v-if="badges.length > 5" class="flex">
+              <div v-if="badges?.length > 5" class="flex">
                 <wd-img custom-class="m-a" width="26" mode="widthFix" :src="more"></wd-img>
               </div>
             </div>
@@ -270,7 +270,7 @@ defineExpose({
         </div>
         <div
           class="w-[76px] h-[30px] px-3 right-0 top-1.5 absolute bg-black/90 rounded-tl-[30px] rounded-bl-[30px] justify-center items-center gap-2.5 inline-flex"
-          @click="router.push('/pages/mine/honors/index')"
+          @click="router.push(`/pages/mine/honors/index?id=${id}`)"
         >
           <div class="text-center text-white text-xs font-normal font-['PingFang_SC']">
             查看荣誉
@@ -370,6 +370,7 @@ defineExpose({
         </div>
         <div class="flex-1" v-if="userInfo.userId === Number(id)">
           <button
+            v-if="features.shareMoment"
             class="p-0 after:b-none"
             block
             :round="false"
@@ -387,6 +388,12 @@ defineExpose({
           >
             <wd-button block :round="false">分享</wd-button>
           </button>
+          <template v-else>
+            <!--            1-->
+            <wd-button block :round="false" @click="clickByPermission('share', () => {})">
+              分享
+            </wd-button>
+          </template>
         </div>
         <div class="flex-1" v-if="userInfo.userId !== Number(id)">
           <wd-button

+ 29 - 7
packages/app/src/pages/mine/honors/index.vue

@@ -17,25 +17,39 @@ import { NetImages } from '../../../core/libs/net-images'
 import ProgressEvo from '@/components/progress-evo.vue'
 import { Certificate } from '@/core/libs/models'
 import dayjs from 'dayjs'
+import { useUserStore } from '@/store'
+import { storeToRefs } from 'pinia'
 
+const id = ref()
 const router = useRouter()
+const userStore = useUserStore()
+const { userInfo } = storeToRefs(userStore)
 const active = ref('badge')
 const tabs = ref([
   { label: '徽章', value: 'badge' },
   { label: '证书', value: 'certificate' },
 ])
-const { data: statistics, run: setStatistics } = useRequest(() => getHonorStatistics())
-const { data: badges, run: setBadges } = useRequest(() => getBadges({}), {
+const { data: statistics, run: setStatistics } = useRequest(() =>
+  getHonorStatistics({ userId: id.value }),
+)
+const { data: badges, run: setBadges } = useRequest(() => getBadges({ userId: id.value }), {
   initialData: {},
 })
-const { data: certificates, run: setCertificates } = useRequest(() => getCertificates({}), {
-  initialData: [],
-})
+const { data: certificates, run: setCertificates } = useRequest(
+  () => getCertificates({ userId: id.value }),
+  {
+    initialData: [],
+  },
+)
 const currentCertificate = ref<Certificate | undefined>()
-onLoad(async (query?: Record<string | 'active', string>) => {
+const isOwner = computed(() => String(userInfo.value?.userId) === id.value)
+onLoad(async (query?: Record<string | 'active' | 'id', string>) => {
   if (query?.active) {
     active.value = query.active
   }
+  if (query?.id) {
+    id.value = query.id
+  }
   await setStatistics()
   await setBadges()
   await setCertificates()
@@ -108,10 +122,15 @@ onLoad(async (query?: Record<string | 'active', string>) => {
       </template>
     </div>
     <template v-if="active === 'badge'">
+      <!--      v-if="String(userInfo.userId) === 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 width="90" height="90" src="https://via.placeholder.com/86x91"></wd-img>
+            <wd-img
+              width="90"
+              height="90"
+              src="https://image.zhuchaohui.com/zhucaohui/1f8f9129cc24b2a9bc25d8a2821da64233994c38efea36a80f4b1aade0476bab.png"
+            ></wd-img>
           </div>
           <div class="row-start-1 col-start-2 flex items-center justify-between">
             <div
@@ -166,8 +185,10 @@ onLoad(async (query?: Record<string | 'active', string>) => {
           </div>
         </div>
       </Card>
+
       <template v-for="([key, it], index) in Object.entries(badges)" :key="index">
         <Card
+          v-if="!(!isOwner && ['积分徽章'].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">
@@ -212,6 +233,7 @@ onLoad(async (query?: Record<string | 'active', string>) => {
                 height="100%"
                 :src="it.certificateImage"
                 mode="aspectFill"
+                custom-class="vertical-bottom"
               ></wd-img>
             </div>
           </template>