Browse Source

feat(core): 添加权限控制并优化路由管理

- 新增 usePermissions 钩子用于权限控制- 重构 useRouter 函数,支持权限控制和切换Tab
- 在多个页面中集成权限控制逻辑- 优化路由跳转逻辑,支持根据不同权限进行跳转
EvilDragon 5 tháng trước cách đây
mục cha
commit
6cd3e5089f

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

@@ -8,6 +8,7 @@ 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'
+import { currRoute } from '../utils'
 
 const props = withDefaults(
   defineProps<{
@@ -48,16 +49,12 @@ const toDetail = () => {
   })
 }
 const handleDelete = async () => {
-  console.log(1111)
   emits('delete', props.options.id)
-  // try {
-  //   alert({ title: '警告', msg: '确定删除吗?' })
-  // } catch (e) {
-  //   console.log(e)
-  // }
 }
 onMounted(async () => {
   // console.log('加载')
+  // console.log(currRoute().path)
+
   if (
     props.options.bannerUrls?.length === 1 &&
     isImageOrVideo(props.options.bannerUrls[0]) === 'image'
@@ -86,7 +83,10 @@ onMounted(async () => {
       <view class="flex items-center">
         <view
           class="overflow-hidden rounded-full mr-2"
-          @click.stop="router.push(`/pages/mine/homepage/index?id=${options.stylistId}`)"
+          @click.stop="
+            currRoute().path !== '/pages/mine/homepage/index' &&
+              router.push(`/pages/mine/homepage/index?id=${options.stylistId}`)
+          "
         >
           <wd-img
             custom-class="vertical-bottom"

+ 37 - 0
packages/app/src/composables/permissions.ts

@@ -0,0 +1,37 @@
+import { useUserStore } from '../store'
+import { storeToRefs } from 'pinia'
+
+export const usePermissions = () => {
+  const userStore = useUserStore()
+  const { isLogined, isDesigner } = storeToRefs(userStore)
+  const routes = [
+    { path: '/pages/mine/homepage/index', meta: { canNotLogin: false } },
+    { path: '/pages/material/mini-class/index', meta: { canNotLogin: false, showToast: true } },
+    { path: '/pages/material/recommend/index', meta: { canNotLogin: false, showToast: true } },
+    { path: '/pages/publish/moment/index', meta: { canNotLogin: false, showToast: true } },
+    { path: '/pages/publish/moment/index', meta: { canNotLogin: false, showToast: true } },
+    { path: '/pages/messages/index', meta: { canNotLogin: false, showToast: true } },
+    { path: '/pages/mine/setting/index', meta: { canNotLogin: false, showToast: true } },
+    {
+      path: '/pages/mine/homepage/statistics/index',
+      meta: { canNotLogin: false, showToast: true },
+    },
+    {
+      path: '/pages/mine/points/index',
+      meta: { canNotLogin: false, showToast: true },
+    },
+    {
+      path: '/pages/mine/coupons/index',
+      meta: { canNotLogin: false, showToast: true },
+    },
+    {
+      path: '/pages/mine/orders/index',
+      meta: { canNotLogin: false, showToast: true },
+    },
+    {
+      path: '/pages/mine/agents/index',
+      meta: { canNotLogin: false, showToast: true },
+    },
+  ]
+  return { isLogined, isDesigner, routes }
+}

+ 18 - 2
packages/app/src/core/utils/router.ts

@@ -1,9 +1,25 @@
+import { usePermissions } from '../../composables/permissions'
+
 export const back = () => {
   uni.navigateBack()
 }
 export const useRouter = () => {
-  const push = async (path: string) => {
-    uni.navigateTo({ url: path })
+  const { routes, isLogined } = usePermissions()
+  const push = async (url: string, switchTab = false) => {
+    // console.log(url)
+    const path = url.split('?')[0]
+    const route = routes.find((it) => it.path === path)
+    if (route && !route.meta.canNotLogin && !isLogined.value) {
+      if (route.meta.showToast) {
+        uni.showToast({ title: '暂无权限', icon: 'none' })
+      }
+      return false
+    }
+    if (switchTab) {
+      uni.switchTab({ url: path })
+    } else {
+      uni.navigateTo({ url: path })
+    }
   }
   const replace = async (path: string) => {
     uni.redirectTo({ url: path })

+ 6 - 3
packages/app/src/layouts/tabbar.vue

@@ -14,7 +14,9 @@ import {
 } from '../core/libs/svgs'
 import { currRoute } from '../utils'
 import { defaultThemeVars } from '../core/themes/default'
+import { useRouter } from '../core/utils/router'
 
+const router = useRouter()
 const publishState = ref(false)
 const items = [
   {
@@ -54,14 +56,15 @@ const handleTabbarItemClick = (path: string) => {
     publishState.value = true
     return
   }
-  uni.switchTab({ url: path })
+  router.push(path, true)
+  // uni.switchTab({ url: path })
 }
 const toPublishMoment = () => {
-  uni.navigateTo({ url: '/pages/publish/moment/index?circleType=1' })
+  router.push('/pages/publish/moment/index?circleType=1')
   publishState.value = false
 }
 const toPublishCase = () => {
-  uni.navigateTo({ url: '/pages/publish/moment/index?circleType=2' })
+  router.push('/pages/publish/moment/index?circleType=2')
   publishState.value = false
 }
 </script>

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

@@ -19,11 +19,14 @@ import { getCircles, getSetIndexConfigs } from '../../core/libs/requests'
 import { logo } from '../../core/libs/svgs'
 import PageHelper from '@/components/page-helper.vue'
 import { ComponentExposed } from 'vue-component-type-helpers'
+import { usePermissions } from '../../composables/permissions'
+import { storeToRefs } from 'pinia'
 
 defineOptions({
   name: 'Home',
 })
 const instance = getCurrentInstance()
+const { isLogined, isDesigner } = usePermissions()
 const pageHelperRef = ref<ComponentExposed<typeof PageHelper>>()
 const { data: indexConfigsData, run: setIndexConfigsData } = useRequest(
   () => getSetIndexConfigs(),
@@ -103,7 +106,7 @@ onShareAppMessage(() => ({}))
       <!-- <view class="my-6 mx-3.5">
         <HotActivity></HotActivity>
       </view> -->
-      <view class="my-6 mx-3.5" @click="toAbout()">
+      <view v-if="isDesigner" class="my-6 mx-3.5" @click="toAbout()">
         <Card>
           <div class="flex items-center gap-2">
             <wd-img width="28" height="28" :src="logo"></wd-img>

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

@@ -9,10 +9,12 @@ import { abc, calculator } from '../../core/libs/pngs'
 import { getAppMaterials, getBanners, getByDictType } from '../../core/libs/requests'
 import { close, phone } from '../../core/libs/svgs'
 import { BannerMode, DictType, MaterialDealer, MaterialsList } from '../../core/libs/models'
-import router from '@designer-hub/assets/src/assets/svgs/router'
+import routerIcon from '@designer-hub/assets/src/assets/svgs/router'
 import Banner from '../home/components/banner.vue'
 import materialDealers from '@designer-hub/assets/src/libs/assets/materialDealers'
+import { useRouter } from '../../core/utils/router'
 
+const router = useRouter()
 const { data: materialDealerData, run: setMaterialDealerData } = useRequest(
   () => getAppMaterials(),
   { initialData: [] },
@@ -68,7 +70,7 @@ const current = ref<number>(0)
 const swiperList = computed(() => banners.value.map((it) => it.bannerImgUrl))
 const materialsByBrandLevel = ref<{ list: MaterialDealer[] }[]>([])
 const handleMenuItemClick = ({ path }: any) => {
-  uni.navigateTo({ url: path })
+  router.push(path)
 }
 const toDetail = (id: number) => {
   uni.navigateTo({
@@ -275,7 +277,7 @@ onMounted(async () => {
                   custom-class=" bg-[#f2f2f2]! p-0! ml-4"
                   @click="handleGo({ name: shopName, address: shopAddr })"
                 >
-                  <wd-img width="28" height="28" :src="router"></wd-img>
+                  <wd-img width="28" height="28" :src="routerIcon"></wd-img>
                 </wd-button>
               </div>
             </template>

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

@@ -159,7 +159,7 @@ const handleToHomepage = () => {
   uni.navigateTo({ url: '/pages/mine/homepage/index' })
 }
 const handleMenuClick = (path) => {
-  path && uni.navigateTo({ url: path })
+  path && router.push(path)
 }
 const handleClickScan = async () => {
   const { result } = await uni.scanCode({})
@@ -217,6 +217,7 @@ onPageScroll(({ scrollTop }: { scrollTop: number }) => {
     >
       <template #left>
         <wd-button
+          v-if="isLogined"
           type="text"
           size="small"
           custom-class="p-0!"
@@ -268,7 +269,7 @@ onPageScroll(({ scrollTop }: { scrollTop: number }) => {
         <div class="flex items-center">
           <div class="text-white text-base font-normal font-['PingFang_SC'] leading-normal mr-1">
             <!-- 0 -->
-            {{ designerInfo?.shareCount }}
+            {{ designerInfo?.shareCount || 0 }}
           </div>
           <div
             class="text-center text-[#e9e7e4] text-xs font-normal font-['PingFang_SC'] leading-normal"
@@ -296,7 +297,7 @@ onPageScroll(({ scrollTop }: { scrollTop: number }) => {
         <div class="flex items-center">
           <div class="text-white text-base font-normal font-['PingFang_SC'] leading-normal mr-1">
             <!-- 0 -->
-            {{ designerInfo?.viewCount }}
+            {{ designerInfo?.viewCount || 0 }}
           </div>
           <div
             class="text-center text-[#e9e7e4] text-xs font-normal font-['PingFang_SC'] leading-normal"
@@ -394,6 +395,7 @@ onPageScroll(({ scrollTop }: { scrollTop: number }) => {
         </template>
       </div>
       <TasksCard
+        v-if="isLogined"
         custom-class="my-6"
         :items="
           taskData.list.map((it, i) => ({

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

@@ -66,7 +66,14 @@ const handleLogout = () => {
         更换头像
       </div>
     </div>
-    <SectionHeading title="姓名" size="sm" :end-text="userInfo.nickname" end-arrow></SectionHeading>
+    <button class="w-full p-0 leading-0 bg-transparent hover:bg-transparent" open-type="choose">
+      <SectionHeading
+        title="姓名"
+        size="sm"
+        :end-text="userInfo.nickname"
+        end-arrow
+      ></SectionHeading>
+    </button>
     <SectionHeading title="性别" size="sm" end-text="设置" end-arrow></SectionHeading>
     <SectionHeading title="生日" size="sm" end-text="设置" end-arrow></SectionHeading>