feat: add permission control for material list page
Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { login } from '@/api/auth'
|
||||
import { getRolePermissions } from '@/api/system/permission'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export const useUserStore = defineStore('user', () => {
|
||||
@ -7,6 +8,7 @@ export const useUserStore = defineStore('user', () => {
|
||||
const token = ref(localStorage.getItem('token') || '')
|
||||
const role = ref(localStorage.getItem('role') || '')
|
||||
const username = ref(localStorage.getItem('username') || '')
|
||||
const permissions = ref<string[]>(JSON.parse(localStorage.getItem('permissions') || '[]'))
|
||||
|
||||
// 2. Actions
|
||||
// 登录逻辑
|
||||
@ -44,6 +46,25 @@ export const useUserStore = defineStore('user', () => {
|
||||
// 持久化存储 Token
|
||||
localStorage.setItem('token', data.access_token)
|
||||
|
||||
// 登录成功后,根据角色获取权限
|
||||
if (role.value) {
|
||||
try {
|
||||
const permRes = await getRolePermissions(role.value)
|
||||
const permData = permRes.data || permRes
|
||||
// 合并 menus 和 elements 两个数组
|
||||
const allPerms = [
|
||||
...(permData.menus || []),
|
||||
...(permData.elements || [])
|
||||
]
|
||||
permissions.value = allPerms
|
||||
localStorage.setItem('permissions', JSON.stringify(allPerms))
|
||||
} catch (error) {
|
||||
console.error('获取权限失败:', error)
|
||||
permissions.value = []
|
||||
localStorage.setItem('permissions', '[]')
|
||||
}
|
||||
}
|
||||
|
||||
return true // 返回 true 表示登录成功
|
||||
}
|
||||
|
||||
@ -53,11 +74,13 @@ export const useUserStore = defineStore('user', () => {
|
||||
token.value = ''
|
||||
role.value = ''
|
||||
username.value = ''
|
||||
permissions.value = []
|
||||
|
||||
// 2. 清空 LocalStorage (硬盘)
|
||||
localStorage.removeItem('token')
|
||||
localStorage.removeItem('role')
|
||||
localStorage.removeItem('username')
|
||||
localStorage.removeItem('permissions')
|
||||
}
|
||||
|
||||
// 3. Getters / Helpers
|
||||
@ -66,12 +89,19 @@ export const useUserStore = defineStore('user', () => {
|
||||
return roles.includes(role.value)
|
||||
}
|
||||
|
||||
// 判断当前用户是否拥有某个权限(菜单或元素)
|
||||
const hasPermission = (code: string) => {
|
||||
return permissions.value.includes(code)
|
||||
}
|
||||
|
||||
return {
|
||||
token,
|
||||
role,
|
||||
username,
|
||||
permissions,
|
||||
handleLogin,
|
||||
logout,
|
||||
hasRole
|
||||
hasRole,
|
||||
hasPermission
|
||||
}
|
||||
})
|
||||
|
||||
@ -214,7 +214,7 @@
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" min-width="150" fixed="right" align="center">
|
||||
<el-table-column v-if="userStore.hasPermission('operation')" label="操作" min-width="150" fixed="right" align="center">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button link type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
|
||||
@ -420,6 +420,7 @@ import { ref, reactive, onMounted, nextTick } from 'vue';
|
||||
import { Plus, Document, Refresh, Setting, Rank, Camera, Link, Download } from '@element-plus/icons-vue';
|
||||
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus';
|
||||
import type { FormInstance, FormRules } from 'element-plus';
|
||||
import { useUserStore } from '@/stores/user';
|
||||
|
||||
import {
|
||||
listMaterialBase,
|
||||
@ -432,6 +433,8 @@ import {
|
||||
import { uploadFile, deleteFile } from '@/api/common/upload';
|
||||
import WebRtcCamera from '@/components/Camera/WebRtcCamera.vue';
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
// --- 类型定义 ---
|
||||
interface MaterialBaseVO {
|
||||
id: number;
|
||||
@ -1043,4 +1046,4 @@ onMounted(() => {
|
||||
.long-dropdown .el-select-dropdown__wrap {
|
||||
max-height: 600px !important; /* 可以根据屏幕大小适当调整 */
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user