Parcourir la source

feat(权限管理): 新增素材下载、任务完成和扫码功能的权限控制

- 在 permissions.ts 中添加了 'scan'、'task' 和 'download' 权限
- 在相关页面中实现了这些权限的检查和使用
- 优化了权限控制的逻辑,提高了系统安全性
EvilDragon il y a 1 mois
Parent
commit
af1928cb50

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

@@ -89,7 +89,10 @@ export const usePermissions = () => {
       | 'mallExchange'
       | 'thumbsUp'
       | 'exchange'
-      | 'share',
+      | 'share'
+      | 'scan'
+      | 'download'
+      | 'task',
     callback: () => void,
   ) => {
     const features = [
@@ -104,6 +107,9 @@ export const usePermissions = () => {
        */
       { name: 'exchange', meta: { canNotLogin: false, canNotDesigner: false } },
       { name: 'share', meta: { canNotLogin: false, canNotDesigner: false, minLevel: 2 } },
+      { name: 'scan', meta: { canNotLogin: false, canNotDesigner: false, minLevel: 2 } },
+      { name: 'task', meta: { canNotLogin: false, canNotDesigner: false } },
+      { name: 'download', meta: { canNotLogin: false, canNotDesigner: false } },
     ]
     const feature = features.find((item) => item.name === name)
     if (feature) {

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

@@ -352,6 +352,11 @@ export const getMaterialHomePage = (id: number) =>
   })
 export const getMaterialDetail = (query: { id: string }) =>
   httpGet<MaterialDealer>('/app-api/member/materials/getDetail', query)
+/**
+ * 下载材料商
+ */
+export const downloadMaterials = (query: { materialsId: string }) =>
+  httpGet('/app-api/member/materials/download', query)
 export const createMaterialsReferrer = (data) =>
   httpPost('/app-api/member/materials-referrer/create', data)
 export const getContents = (query: {

+ 1 - 0
packages/app/src/pages/home/components/banner.vue

@@ -13,6 +13,7 @@ const swiperList = computed(() => banners.value.map((it) => it.bannerImgUrl))
 const handleClick = ({ index }: { index: number }) => {
   const banner = banners.value[index]
   console.log(banner)
+  if (!banner.bannerLinkUrl || !banner.bannerDetailsContent) return
   if (banner.bannerDetailsType === '2') {
     if (banner.bannerLinkUrl?.startsWith('http')) {
       router.push(`/pages/common/webview/index?url=${banner.bannerLinkUrl}`)

+ 3 - 1
packages/app/src/pages/home/components/class-item.vue

@@ -47,7 +47,9 @@ const router = useRouter()
     <div
       class="w-full h-[145px] pl-39 pt-6 pr-6 pb-6 flex flex-col box-border bg-white rounded-2xl shadow"
     >
-      <div class="text-black/90 text-base font-normal font-['PingFang_SC'] leading-normal">
+      <div
+        class="text-black/90 text-base font-normal font-['PingFang_SC'] leading-normal text-ellipsis line-clamp-1 overflow-hidden"
+      >
         <!-- 2024届米兰国际家具展 -->
         {{ options.title }}
       </div>

+ 3 - 1
packages/app/src/pages/home/components/comment-item.vue

@@ -150,7 +150,9 @@ defineExpose({
         :options="it"
         :isChild="true"
         @replay="
-          (options) => emits('replay', { ...options, refreshId: props.options.id, index: index })
+          (options) => {
+            emits('replay', { ...options, refreshId: props.options.id, index: index })
+          }
         "
         @delete="emits('delete', index)"
         @upvote="emits('upvote', index)"

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

@@ -117,10 +117,10 @@ onShareTimeline(() => ({
           ¥{{ data?.productPrice }}
         </div>
         <div class="flex-1"></div>
-        <!--        <div class="text-[#999999] text-xs font-normal font-['PingFang_SC']">-->
-        <!--          &lt;!&ndash; 已售5件 &ndash;&gt;-->
-        <!--          已售{{ data?.exchangeCount || 0 }}件-->
-        <!--        </div>-->
+        <div class="text-[#999999] text-xs font-normal font-['PingFang_SC']">
+          <!-- 已售5件 -->
+          库存:{{ data?.productRepertory || 0 }}
+        </div>
       </div>
       <div class="text-black text-xl font-normal font-['PingFang_SC']">
         <!-- 阿芙佳朵 -->

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

@@ -122,8 +122,9 @@ const handleSend = async () => {
     await uni.showToast({ title: msg, icon: 'none' })
   } else {
     reviewContent.value = ''
+    console.log('refreshIndex', refreshIndex.value)
     await uni.showToast({ title: '评论成功', icon: 'none' })
-    if (refreshIndex.value) {
+    if (refreshIndex.value !== undefined) {
       console.log(instance.refs)
       await commentItemRef.value.at(refreshIndex.value).refresh()
       reviewId.value = undefined

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

@@ -4,7 +4,12 @@
 <script setup lang="ts">
 import Card from '@/components/card.vue'
 import SectionHeading from '@/components/section-heading.vue'
-import { getMaterialDetail, getByDictType, getMaterialHomePage } from '../../../core/libs/requests'
+import {
+  getMaterialDetail,
+  getByDictType,
+  getMaterialHomePage,
+  downloadMaterials,
+} from '../../../core/libs/requests'
 import NavbarEvo from '@/components/navbar-evo.vue'
 import { DictType } from '../../../core/libs/models'
 import { phone } from '../../../core/libs/svgs'
@@ -13,7 +18,9 @@ import router from '@designer-hub/assets/src/assets/svgs/router'
 import { isVideoUrl } from 'wot-design-uni/components/common/util'
 import { useUserStore } from '@/store'
 import { AnalysisEventType, useAnalysis } from '@/composables/analysis'
+import { usePermissions } from '@/composables/permissions'
 
+const { clickByPermission } = usePermissions()
 const userStore = useUserStore()
 const { option } = useAnalysis(true, false)
 const id = ref()
@@ -40,6 +47,7 @@ const { data: materialsManageBrands, run: setMaterialsManageBrands } = useReques
   { initialData: [] },
 )
 const handleDownload = async () => {
+  downloading.value = true
   const { filePath } = await uni.downloadFile({
     url: data.value.agreementFileUrl,
     filePath: `${uni.env.USER_DATA_PATH}/${data.value.materialsName}的素材包.zip`,
@@ -47,6 +55,8 @@ const handleDownload = async () => {
       'Content-Type': 'application/x-zip-compressed',
     },
   })
+  downloading.value = false
+  await downloadMaterials({ materialsId: id.value })
   const { deviceType } = await uni.getDeviceInfo()
   if (deviceType === 'pc') {
     uni.saveFileToDisk({
@@ -298,9 +308,9 @@ onShareTimeline(() => ({
 
       <wd-button
         custom-class="w-full! rounded-lg!"
-        :disabled="(data.agreementFileUrl ?? '') !== ''"
+        :disabled="(data?.agreementFileUrl ?? '') === ''"
         :loading="downloading"
-        @click="handleDownload"
+        @click="clickByPermission('download', () => handleDownload())"
       >
         {{ downloading ? '下载中...' : '下载所有素材包' }}
       </wd-button>

+ 3 - 1
packages/app/src/pages/mine/components/tasks-card.vue

@@ -2,7 +2,9 @@
 import { Task } from '../../../core/libs/models'
 import { taskCenterBg } from '../../../core/libs/pngs'
 import { useRouter } from '../../../core/utils/router'
+import { usePermissions } from '@/composables/permissions'
 
+const { clickByPermission } = usePermissions()
 const router = useRouter()
 defineProps({
   customClass: {
@@ -70,7 +72,7 @@ onMounted(async () => {})
                 plain
                 size="small"
                 :disabled="btnProps?.disabled"
-                @click="btnProps?.onClick"
+                @click="clickByPermission('task', () => btnProps?.onClick())"
               >
                 {{ btnProps?.content }}
                 <!-- {{ taskExtendsById[id]?.completed ? '已完成' : '去完成' }} -->

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

@@ -32,7 +32,7 @@ const { option, report } = useAnalysis(false)
 const router = useRouter()
 const userStore = useUserStore()
 const { isLogined, userInfo } = storeToRefs(userStore)
-const { features } = usePermissions()
+const { features, clickByPermission } = usePermissions()
 const { setUserInfo } = userStore
 const { data, run } = useRequest(getMemberUserInfo)
 const { data: taskData, run: getTaskData } = useRequest(() => getTasks({}), {
@@ -242,7 +242,7 @@ onPageScroll(({ scrollTop }: { scrollTop: number }) => {
           size="small"
           custom-class="p-0!"
           :round="false"
-          @click="handleClickScan"
+          @click="clickByPermission('scan', () => handleClickScan())"
         >
           <wd-img width="25" height="25" :src="scan" custom-class="vertical-bottom"></wd-img>
         </wd-button>

+ 3 - 3
packages/merchant/src/pages/mine/components/agent-mine.vue

@@ -99,9 +99,9 @@ onMounted(async () => {
           <div class="text-white text-lg font-normal font-['PingFang_SC'] leading-normal">
             {{ agent?.brokerName }}
           </div>
-          <div class="text-white text-xs font-normal font-['PingFang_SC'] leading-relaxed">
-            ID:{{ agent?.inviteCode }}
-          </div>
+          <!--          <div class="text-white text-xs font-normal font-['PingFang_SC'] leading-relaxed">-->
+          <!--            ID:{{ agent?.inviteCode }}-->
+          <!--          </div>-->
         </div>
         <div class="flex flex-col items-center" @click.stop="toInvite">
           <div class="w-[29px] h-[29px] relative">