diff --git a/backend/controller/menu.py b/backend/controller/menu.py
index b97ec60..145f285 100644
--- a/backend/controller/menu.py
+++ b/backend/controller/menu.py
@@ -1,6 +1,7 @@
from fastapi import Query
-from dbhelper.menu import del_menu, get_menus, insert_menu, put_menu
+from core.utils import list_to_tree
+from dbhelper.menu import del_menu, get_menus, get_tree_menu, insert_menu, put_menu
from schemas import ListAll, MenuIn, MenuRead, Response
@@ -11,10 +12,9 @@ async def menu_add(data: MenuIn) -> Response[MenuRead]:
async def menu_arr(
offset: int = Query(default=1, description="偏移量"),
limit: int = Query(default=10, description="数量"),
-) -> Response[ListAll[list[MenuRead]]]:
- skip = (offset - 1) * limit
- menus, count = await get_menus(skip, limit)
- return Response(data=ListAll(total=count, items=menus))
+) -> Response:
+ menus = await get_tree_menu()
+ return Response(data=list_to_tree(menus))
async def menu_del(pk: int) -> Response:
diff --git a/backend/controller/role.py b/backend/controller/role.py
index c103ccd..4204a5c 100644
--- a/backend/controller/role.py
+++ b/backend/controller/role.py
@@ -16,7 +16,9 @@ from schemas import ListAll, Response, RoleIn, RoleInfo, RoleMenuIn, RoleQuery,
async def role_add(data: RoleIn) -> Response[RoleInfo]:
- return Response(data=await new_role(data))
+ if result := await new_role(data):
+ return Response(data=result)
+ return Response(code=400, msg="菜单不存在")
async def role_has_menu(rid: int):
diff --git a/backend/controller/user.py b/backend/controller/user.py
index 058ac64..5f0ca22 100644
--- a/backend/controller/user.py
+++ b/backend/controller/user.py
@@ -19,10 +19,10 @@ async def user_add(data: UserAdd) -> Response[UserRead]:
"""新增用户并分配角色 一步到位"""
if await get_user({"username": data.username}) is not None:
return Response(code=400, msg="用户名已存在")
- roles = data.rids
- del data.rids
+ rids = data.roles
+ del data.roles
data.password = get_password_hash(data.password)
- result = await insert_user(data, roles)
+ result = await insert_user(data, rids)
if isinstance(result, int):
return Response(code=400, msg=f"角色{result}不存在")
return Response(data=result)
diff --git a/backend/dbhelper/menu.py b/backend/dbhelper/menu.py
index b59c069..5369052 100644
--- a/backend/dbhelper/menu.py
+++ b/backend/dbhelper/menu.py
@@ -25,7 +25,11 @@ async def get_menus(skip: int, limit: int, kwargs: dict = None):
else:
kwargs = {}
result = MenuModel.filter(status__not=9, **kwargs).all().order_by("-created")
- return await result.offset(skip).limit(limit), await result.count()
+ return await result.offset(skip).limit(limit)
+
+
+async def get_tree_menu():
+ return await MenuModel.filter(status__not=9).all().values()
async def get_menu(kwargs):
diff --git a/backend/dbhelper/role.py b/backend/dbhelper/role.py
index 512d6fe..db78eed 100644
--- a/backend/dbhelper/role.py
+++ b/backend/dbhelper/role.py
@@ -1,6 +1,6 @@
from tortoise import connections
-from models import RoleModel
+from models import MenuModel, RoleMenuModel, RoleModel
from schemas.role import RoleIn
@@ -20,7 +20,16 @@ async def get_role_menus(rid: int):
async def new_role(role: RoleIn):
"""新增角色"""
- return await RoleModel.create(**role.dict())
+ # 校验菜单是否存在
+ if not all([await MenuModel.filter(id=mid).first() for mid in role.menus]):
+ return False
+
+ obj = await RoleModel.create(name=role.name, remark=role.remark)
+ # 写入菜单
+ await RoleMenuModel.bulk_create(
+ [RoleMenuModel(rid=obj.id, mid=mid) for mid in role.menus]
+ )
+ return obj
async def get_roles(skip: int, limit: int, kwargs: dict = None):
diff --git a/backend/dbhelper/user.py b/backend/dbhelper/user.py
index c0fc401..ce10bb4 100644
--- a/backend/dbhelper/user.py
+++ b/backend/dbhelper/user.py
@@ -32,19 +32,9 @@ async def get_user_info(user: UserModel):
[user.id],
)
- # 当前激活角色的按钮权限列表
- perm_result = await db.execute_query_dict(
- """
- select m.identifier from sys_role_menu as rm, sys_menu as m where rm.mid = m.id and rm.rid = (?) and
- m.identifier not null and m.identifier != "" and rm.status != 9
- """,
- [sql_result[0]["id"]],
- )
-
return {
**jsonable_encoder(user),
"roles": sql_result,
- "permissions": [i["identifier"] for i in perm_result],
}
@@ -64,7 +54,6 @@ async def get_users(skip: int, limit: int, kwargs: dict = None):
else:
kwargs = {}
result = UserModel.filter(**kwargs).all().order_by("-created")
- print(await result.offset(skip).limit(limit))
return await result.offset(skip).limit(limit), await result.count()
diff --git a/backend/mini.db b/backend/mini.db
index 5bd9955..bdd6874 100644
Binary files a/backend/mini.db and b/backend/mini.db differ
diff --git a/backend/mini.db-shm b/backend/mini.db-shm
new file mode 100644
index 0000000..dff6755
Binary files /dev/null and b/backend/mini.db-shm differ
diff --git a/backend/mini.db-wal b/backend/mini.db-wal
new file mode 100644
index 0000000..bc8e865
Binary files /dev/null and b/backend/mini.db-wal differ
diff --git a/backend/schemas/role.py b/backend/schemas/role.py
index fa11675..0478c99 100644
--- a/backend/schemas/role.py
+++ b/backend/schemas/role.py
@@ -20,7 +20,7 @@ class RoleBasic(BaseModel):
class RoleIn(RoleBasic):
- pass
+ menus: list[int] = Field(..., description="菜单id列表")
class RoleRead(RoleBasic, ReadBase):
diff --git a/backend/schemas/user.py b/backend/schemas/user.py
index d795419..eda3c62 100644
--- a/backend/schemas/user.py
+++ b/backend/schemas/user.py
@@ -41,7 +41,6 @@ class UserInfo(UserRead):
"""用户信息模型"""
roles: list[UserHasRole] = Field(..., description="用户拥有角色")
- permissions: list[str] = Field(..., description="角色拥有的按钮权限标识")
class RoleActive(BaseModel):
@@ -52,7 +51,7 @@ class RoleActive(BaseModel):
class UserAdd(UserIn):
"""新增用户模型"""
- rids: list[RoleActive] = Field(..., description="选择角色列表")
+ roles: list[RoleActive] = Field(..., description="选择角色列表")
class UserQuery(QueryData):
diff --git a/frontend/src/stores/menu.js b/frontend/src/stores/menu.js
new file mode 100644
index 0000000..e69de29
diff --git a/frontend/src/stores/role.js b/frontend/src/stores/role.js
new file mode 100644
index 0000000..e69de29
diff --git a/frontend/src/stores/user.js b/frontend/src/stores/user.js
index 38132a0..1604aeb 100644
--- a/frontend/src/stores/user.js
+++ b/frontend/src/stores/user.js
@@ -3,7 +3,7 @@ import { defineStore } from 'pinia'
import { message } from 'ant-design-vue'
import router from '@/router'
-import { loadRouter, loadDefaultMenu } from '@/utils/loadCpn'
+import { loadRouter, getPermissions } from '@/utils/loadCpn'
import { getMenus, getUserInfo, login, selectRole } from '@/service/user'
export const userStore = defineStore(
@@ -12,6 +12,7 @@ export const userStore = defineStore(
const token = ref('')
const userInfo = ref({})
const userMenus = ref([])
+ const permissions = ref([])
const selectKey = ref(null)
@@ -26,6 +27,7 @@ export const userStore = defineStore(
token.value = ''
userInfo.value = {}
userMenus.value = []
+ permissions.value = []
}
/**
@@ -41,16 +43,19 @@ export const userStore = defineStore(
const menus = await getMenus(info.data.roles[0].id)
userMenus.value = menus.data
- // 3.1 加载权限
+ // 3.1 加载路由权限
loadRouter(menus.data)
- // 3.2 默认跳转路由
- const defaultMenu = loadDefaultMenu(menus.data)
+ // 3.2 加载按钮权限
+ const [btnPermissions, firstMenu] = getPermissions(menus.data)
+ permissions.value = btnPermissions
- selectKey.value = [defaultMenu.id]
- // 4. 跳转
- if (defaultMenu.path) {
- router.push(defaultMenu.path)
+ // 3.2 默认打开菜单
+ selectKey.value = [firstMenu.id]
+
+ // 4. 跳转路由
+ if (firstMenu?.path) {
+ router.push(firstMenu.path)
} else {
router.push('/main')
}
@@ -82,6 +87,7 @@ export const userStore = defineStore(
accessToken,
userInfo,
userMenus,
+ permissions,
isLoading,
selectKey,
$reset,
diff --git a/frontend/src/utils/directive.js b/frontend/src/utils/directive.js
index fe809a6..9ca1fa1 100644
--- a/frontend/src/utils/directive.js
+++ b/frontend/src/utils/directive.js
@@ -6,7 +6,7 @@ export default (app) => {
mounted(el, binding) {
if (
// 是否存在
- userStore().userInfo.permissions.indexOf(binding.value) === -1
+ userStore().permissions.indexOf(binding.value) === -1
) {
// 删除元素
el.parentNode && el.parentNode.removeChild(el)
diff --git a/frontend/src/utils/loadCpn.js b/frontend/src/utils/loadCpn.js
index 1233931..c9cf42d 100644
--- a/frontend/src/utils/loadCpn.js
+++ b/frontend/src/utils/loadCpn.js
@@ -35,11 +35,26 @@ function loadRouter(menus) {
}
}
-// 默认打开第一个
-function loadDefaultMenu(menus) {
- for (const menu of menus) {
- return menu.children.find((e) => e.type === 1)
+// 获取按钮权限列表,和第一个选中菜单
+function getPermissions(menuArr) {
+ let arr = []
+ let firstMenu = null
+
+ function _forMenu(menus) {
+ for (const menu of menus) {
+ if (menu.type === 1 && firstMenu === null) {
+ firstMenu = menu
+ }
+ if (menu.type !== 2 && menu.children) {
+ _forMenu(menu.children)
+ } else {
+ arr.push(menu.identifier)
+ }
+ }
}
+
+ _forMenu(menuArr)
+ return [arr.filter((e) => e !== null), firstMenu]
}
-export { loadIconCpn, loadRouter, loadDefaultMenu }
+export { loadIconCpn, loadRouter, getPermissions }
diff --git a/frontend/src/views/main/system/menu/menu.vue b/frontend/src/views/main/system/menu/menu.vue
index 03b8044..852b872 100644
--- a/frontend/src/views/main/system/menu/menu.vue
+++ b/frontend/src/views/main/system/menu/menu.vue
@@ -1,13 +1,16 @@
@@ -172,7 +192,7 @@ const onCancelPut = () => {
-
@@ -229,6 +249,11 @@ const onCancelPut = () => {
+
+
+ {{ name }}
+
+
@@ -248,6 +273,11 @@ const onCancelPut = () => {
+
+
+ {{ name }}
+
+
diff --git a/frontend/src/views/main/system/user/user.vue b/frontend/src/views/main/system/user/user.vue
index 0552828..ce45dbf 100644
--- a/frontend/src/views/main/system/user/user.vue
+++ b/frontend/src/views/main/system/user/user.vue
@@ -106,9 +106,8 @@ const addClick = () => {
const onOk = () => {
formRef.value.validateFields().then(() => {
// 表单验证通过
- const { username, nickname, password, roles } = newUserForm
- let rids = roles.map((e, i) => ({ rid: e, status: i === 0 ? 5 : 1 }))
- addUser({ username, nickname, password, rids }).then((res) => {
+ newUserForm.roles = newUserForm.roles.map((e, i) => ({ rid: e, status: i === 0 ? 5 : 1 }))
+ addUser(newUserForm).then((res) => {
if (res.msg === '请求成功') {
message.success('新增成功')
// 1. 关闭 modal