diff --git a/backend/controller/menu.py b/backend/controller/menu.py index 8d913d0..b97ec60 100644 --- a/backend/controller/menu.py +++ b/backend/controller/menu.py @@ -28,4 +28,3 @@ async def menu_put(pk: int, data: MenuIn) -> Response: if await put_menu(pk, data) == 0: return Response(code=400, msg="菜单不存在") return Response() - diff --git a/backend/controller/role.py b/backend/controller/role.py index 6579935..d9e1222 100644 --- a/backend/controller/role.py +++ b/backend/controller/role.py @@ -4,10 +4,15 @@ from fastapi import Query from core.utils import list_to_tree from dbhelper.relation import role_assigned_menu -from dbhelper.role import (del_role, get_role, get_role_menus, get_roles, - new_role, put_role) -from schemas import (ListAll, Response, RoleIn, RoleInfo, RoleMenuIn, - RoleQuery, RoleRead) +from dbhelper.role import ( + del_role, + get_role, + get_role_menus, + get_roles, + new_role, + put_role, +) +from schemas import ListAll, Response, RoleIn, RoleInfo, RoleMenuIn, RoleQuery, RoleRead async def role_add(data: RoleIn) -> Response[RoleInfo]: diff --git a/backend/controller/user.py b/backend/controller/user.py index 81e9647..4d51ed4 100644 --- a/backend/controller/user.py +++ b/backend/controller/user.py @@ -1,8 +1,16 @@ -from fastapi import Query +from fastapi import Depends, Query +from starlette.requests import Request -from core.security import get_password_hash -from dbhelper.user import (del_user, get_user, get_user_info, get_users, - insert_user, put_user) +from core.security import check_token, get_password_hash +from dbhelper.user import ( + del_user, + get_user, + get_user_info, + get_users, + insert_user, + put_user, + select_role, +) from schemas import Response, UserAdd, UserInfo, UserPut, UserQuery, UserRead from schemas.common import ListAll @@ -63,3 +71,11 @@ async def user_put(pk: int, data: UserPut) -> Response: if isinstance(result, int): return Response(code=400, msg=f"角色不存在{result}") return Response() + + +async def user_select_role(rid: int, user=Depends(check_token)): + """用户切换角色""" + res = await select_role(user.id, rid) + if res == 0: + return Response(code=400, msg=f"角色不存在{res}") + return Response() diff --git a/backend/core/security.py b/backend/core/security.py index c178d0d..8492817 100644 --- a/backend/core/security.py +++ b/backend/core/security.py @@ -74,7 +74,7 @@ async def check_permissions(request: Request, user: UserModel = Depends(check_to whitelist = [f"/user/{user.id}", f"/role/{active_rid}/menu"] flag = request.url.path in whitelist and request.method == "GET" if flag: - return + return user api = request.url.path for k, v in request.path_params.items(): diff --git a/backend/dbhelper/menu.py b/backend/dbhelper/menu.py index 26256d1..b59c069 100644 --- a/backend/dbhelper/menu.py +++ b/backend/dbhelper/menu.py @@ -71,4 +71,4 @@ async def get_apis(pk: int): async def put_menu(pk: int, data): """更新菜单""" - return await MenuModel.filter(id=pk).update(**data.dict()) \ No newline at end of file + return await MenuModel.filter(id=pk).update(**data.dict()) diff --git a/backend/dbhelper/user.py b/backend/dbhelper/user.py index 708adff..ea1da61 100644 --- a/backend/dbhelper/user.py +++ b/backend/dbhelper/user.py @@ -104,3 +104,9 @@ async def put_user(uid: int, data: UserPut): await UserRoleModel.bulk_create( [UserRoleModel(uid=uid, **role.dict()) for role in roles] ) + + +async def select_role(uid: int, rid: int): + """用户切换角色""" + await UserRoleModel.filter(uid=uid, rid__not=rid).update(status=1) + return await UserRoleModel.filter(uid=uid, rid=rid).update(status=5) diff --git a/backend/mini.db-shm b/backend/mini.db-shm deleted file mode 100644 index cd21bd9..0000000 Binary files a/backend/mini.db-shm and /dev/null differ diff --git a/backend/mini.db-wal b/backend/mini.db-wal deleted file mode 100644 index 2f38425..0000000 Binary files a/backend/mini.db-wal and /dev/null differ diff --git a/backend/router/url.py b/backend/router/url.py index f146478..29111c0 100644 --- a/backend/router/url.py +++ b/backend/router/url.py @@ -4,10 +4,24 @@ from fastapi import Depends, routing from controller.common import about, login from controller.menu import menu_add, menu_arr, menu_del, menu_put -from controller.role import (assigned_menu, role_add, role_arr, role_del, - role_has_menu, role_put, role_query) -from controller.user import (user_add, user_arr, user_del, user_info, - user_list, user_put) +from controller.role import ( + assigned_menu, + role_add, + role_arr, + role_del, + role_has_menu, + role_put, + role_query, +) +from controller.user import ( + user_add, + user_arr, + user_del, + user_info, + user_list, + user_put, + user_select_role, +) from core.security import check_permissions @@ -107,9 +121,7 @@ class Route(routing.APIRoute): ) -has_perm = { - # "dependencies": [Depends(check_permissions)] -} +has_perm = {"dependencies": [Depends(check_permissions)]} routes = [ Route.post("/login", endpoint=login, tags=["公共"], summary="登录"), @@ -129,6 +141,9 @@ routes = [ Route.post( "/user/query", endpoint=user_list, tags=["用户管理"], summary="用户列表查询", **has_perm ), + Route.put( + "/user/role/{rid}", endpoint=user_select_role, tags=["用户管理"], summary="用户切换角色" + ), # 角色管理, Route.get("/role", endpoint=role_arr, tags=["角色管理"], summary="角色列表", **has_perm), Route.post("/role", endpoint=role_add, tags=["角色管理"], summary="角色新增", **has_perm), diff --git a/backend/tests/test_case.py b/backend/tests/test_case.py index b676cb2..4d708a7 100644 --- a/backend/tests/test_case.py +++ b/backend/tests/test_case.py @@ -309,20 +309,6 @@ params = [ method="DELETE", ).dict(), ), - ( - "/menu", - MenuIn( - name="修改菜单", - meta={"icon": "Update"}, - path=None, - type=2, - component=None, - pid=5, - identifier="menu:update", - api="/menu/{pk}", - method="PUT", - ).dict(), - ), # 分配权限 ( "/role/assigned/menu", diff --git a/frontend/src/components/layout/layout-header.vue b/frontend/src/components/layout/layout-header.vue new file mode 100644 index 0000000..fbd00c6 --- /dev/null +++ b/frontend/src/components/layout/layout-header.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/frontend/src/components/layout/layout-info/layout-info.vue b/frontend/src/components/layout/layout-info/layout-info.vue new file mode 100644 index 0000000..a2bec66 --- /dev/null +++ b/frontend/src/components/layout/layout-info/layout-info.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/frontend/src/components/layout/layout-info/select-role.vue b/frontend/src/components/layout/layout-info/select-role.vue new file mode 100644 index 0000000..6b418f2 --- /dev/null +++ b/frontend/src/components/layout/layout-info/select-role.vue @@ -0,0 +1,69 @@ + + + + + diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js index e2f563c..f6a53aa 100644 --- a/frontend/src/router/index.js +++ b/frontend/src/router/index.js @@ -1,7 +1,6 @@ import { createRouter, createWebHistory } from "vue-router"; import { message } from "ant-design-vue"; import { userStore } from "@/stores/user"; -import { loadRouter } from "@/utils/loadCpn"; const routes = [ { diff --git a/frontend/src/service/user.js b/frontend/src/service/user.js index 435d494..73ae873 100644 --- a/frontend/src/service/user.js +++ b/frontend/src/service/user.js @@ -21,3 +21,11 @@ export function getMenus(rid) { url: `/role/${rid}/menu`, }); } + +// 修改用户信息 +export function selectRole(rid) { + return request({ + url: `/user/role/${rid}`, + method: "put", + }); +} diff --git a/frontend/src/stores/user.js b/frontend/src/stores/user.js index 3ed7110..0744bdc 100644 --- a/frontend/src/stores/user.js +++ b/frontend/src/stores/user.js @@ -4,7 +4,7 @@ import { message } from "ant-design-vue"; import router from "@/router"; import { loadRouter, loadDefaultMenu } from "@/utils/loadCpn"; -import { getMenus, getUserInfo, login } from "@/service/user"; +import { getMenus, getUserInfo, login, selectRole } from "@/service/user"; export const userStore = defineStore( "user", @@ -28,14 +28,13 @@ export const userStore = defineStore( userMenus.value = []; }; - // 非setup语法时的actions - const loginAction = async (data) => { - // 1. 登录 - const res = await login(data); - token.value = res.data.token; - + /** + * 获取用户信息 & 菜单路由 + * @param {*} uid 用户id + */ + const getUserData = async (uid) => { // 2. 获取用户信息 - const info = await getUserInfo(res.data.id); + const info = await getUserInfo(uid); userInfo.value = info.data; // 3. 获取权限信息 @@ -55,7 +54,13 @@ export const userStore = defineStore( } else { router.push("/main"); } + }; + const loginAction = async (data) => { + // 1. 登录 + const res = await login(data); + token.value = res.data.token; + await getUserData(res.data.id); // 弹框提示登录成功 message.success("登录成功."); }; @@ -65,6 +70,13 @@ export const userStore = defineStore( loadRouter(userMenus.value); }; + // 切换角色 + const userSelectRole = async (rid) => { + await selectRole(rid); + // 重新拿用户信息 + await getUserData(userInfo.value.id); + }; + return { token, accessToken, @@ -75,6 +87,7 @@ export const userStore = defineStore( $reset, loginAction, loadRoleRouter, + userSelectRole, }; }, { diff --git a/frontend/src/utils/request.js b/frontend/src/utils/request.js index a6e2283..a633c95 100644 --- a/frontend/src/utils/request.js +++ b/frontend/src/utils/request.js @@ -25,7 +25,15 @@ export default (config) => { }, (err) => { userStore().isLoading = !userStore().isLoading; - message.error(err); + if (err.response.data?.msg) { + message.error(err.response.data.msg); + } else if (err.response.data?.detail) { + // 请求参数缺失 + message.error(err.response.data?.detail[0].msg); + } else { + message.error(err.message); + } + return Promise.reject(err); } ); diff --git a/frontend/src/views/main/main.vue b/frontend/src/views/main/main.vue index 714380a..9c6f5bf 100644 --- a/frontend/src/views/main/main.vue +++ b/frontend/src/views/main/main.vue @@ -1,17 +1,15 @@ @@ -25,7 +23,7 @@ const logout = () => { - 退出 +