From a6be3aa5e2392bde79ec02533139ee12fa64b5d8 Mon Sep 17 00:00:00 2001 From: sunqh <253801736@qq.com> Date: Thu, 22 Jan 2026 16:52:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Header/HeaderUserInfo.tsx | 49 +++++++- src/configs/menuConfig.tsx | 16 +-- src/configs/routes.ts | 2 + src/layouts/AppLayout.tsx | 7 +- src/pages/Company/List/index.tsx | 1 - src/pages/Login/index.tsx | 9 +- src/pages/Staff/Auth/index.tsx | 137 +++++++++++++++++++++++ src/pages/Staff/Grp/index.tsx | 56 ++++----- src/pages/Staff/List/index.tsx | 57 +++++----- src/pages/Staff/dep/index.tsx | 57 +++++----- src/pages/User/List/index.tsx | 38 +++---- src/services/AdminServices.ts | 2 + src/store/type.ts | 65 +++++------ 13 files changed, 341 insertions(+), 155 deletions(-) create mode 100644 src/pages/Staff/Auth/index.tsx diff --git a/src/components/Header/HeaderUserInfo.tsx b/src/components/Header/HeaderUserInfo.tsx index c2ab48f..7d05e52 100644 --- a/src/components/Header/HeaderUserInfo.tsx +++ b/src/components/Header/HeaderUserInfo.tsx @@ -1,4 +1,5 @@ -import { Button, Popconfirm } from 'antd'; +import { DownOutlined } from '@ant-design/icons'; +import { Button, Dropdown, Popconfirm, Space } from 'antd'; import { useUserStore } from '@/store/UserStore'; import { GapBox } from '../GapBox'; @@ -7,7 +8,51 @@ export const HeaderUserInfo: React.FC = () => { return ( -
{userInfo.login_name}
+ {/* 用户信息 Dropdown */} + + {userInfo.username} + ({userInfo.nickname}) + + ), + }, + ], + }} + > +
+ + 欢迎您, + + {userInfo.username} + + + +
+
+ + {/* 退出登录 */} { diff --git a/src/configs/menuConfig.tsx b/src/configs/menuConfig.tsx index 9983d7d..f996306 100644 --- a/src/configs/menuConfig.tsx +++ b/src/configs/menuConfig.tsx @@ -19,23 +19,23 @@ interface MenuDataItem { const userMenu: MenuDataItem = { name: '用户管理', icon: , - children: [{ name: '用户信息', path: '/user/list', auth: '' }], //SF_ERP_USER_VIEW + children: [{ name: '用户信息', path: '/user/list', auth: 'SF_ADMIN_USER_VIEW' }], }; const companyMenu: MenuDataItem = { name: '企业管理', icon: , - children: [{ name: '企业信息', path: '/company/list', auth: '' }], //SF_ERP_COMPANY_VIEW + children: [{ name: '企业信息', path: '/company/list', auth: 'SF_ADMIN_COMPANY_VIEW' }], }; const authMenu: MenuDataItem = { name: '权限管理', icon: , children: [ - { name: '管理员信息', path: '/staff/list', auth: '' }, //SF_ERP_ADMIN_VIEW - { name: '组织架构', path: '/staff/dep', auth: '' }, //SF_ERP_DEPART_VIEW - { name: '岗位角色', path: '/staff/group', auth: '' }, //SF_ERP_GROUP_VIEW - { name: '我的权限', path: '/staff/my', auth: '' }, //SF_MY_RIGHT_VIEW - { name: '登录日志', path: '/staff/login', auth: '' }, //SF_LOGIN_LOG_VIEW - { name: '操作日志', path: '/staff/sys', auth: '' }, //SF_OPERATE_LOG_VIEW + { name: '管理员信息', path: '/staff/list', auth: 'SF_ADMIN_ADMIN_VIEW' }, + { name: '组织架构', path: '/staff/dep', auth: 'SF_ADMIN_DEPART_VIEW' }, + { name: '岗位角色', path: '/staff/group', auth: 'SF_ADMIN_GROUP_VIEW' }, + { name: '我的权限', path: '/staff/auth', auth: 'SF_ADMIN_AUTH_VIEW' }, + { name: '登录日志', path: '/staff/login', auth: 'SF_LOGIN_LOG_VIEW' }, + { name: '操作日志', path: '/staff/sys', auth: 'SF_OPERATE_LOG_VIEW' }, ], }; diff --git a/src/configs/routes.ts b/src/configs/routes.ts index 8cdb669..026ca19 100644 --- a/src/configs/routes.ts +++ b/src/configs/routes.ts @@ -6,6 +6,7 @@ import ErrorPage from '@/pages/Error'; import Index from '@/pages/Index'; import Login from '@/pages/Record/Login'; import Sys from '@/pages/Record/Sys'; +import Auth from '@/pages/Staff/Auth'; import Dep from '@/pages/Staff/Dep'; import Grp from '@/pages/Staff/Grp'; import StaffList from '@/pages/Staff/List'; @@ -45,6 +46,7 @@ export const routes: IRouteItem[] = [ { path: '/list', Component: StaffList }, { path: '/dep', Component: Dep }, { path: '/group', Component: Grp }, + { path: '/auth', Component: Auth }, { path: '/login', Component: Login }, { path: '/sys', Component: Sys }, ], diff --git a/src/layouts/AppLayout.tsx b/src/layouts/AppLayout.tsx index ff96c70..4aae76a 100644 --- a/src/layouts/AppLayout.tsx +++ b/src/layouts/AppLayout.tsx @@ -25,10 +25,9 @@ const AppLayout = () => { useEffect(() => { setLoading(true); loginState().then((res) => { - // console.log(res); - userStore.updateUser(toObject(res.user_info)); - authStore.updateAuth(toObject(res.auth_info) as any); - localStorage.setItem('admin_user_id', res?.user_info?.user_id); + userStore.updateUser(toObject(res.admin)); + authStore.updateAuth(toObject(res.auth) as any); + localStorage.setItem('admin_id', res?.admin?.admin_id); setLoading(false); }); }, []); diff --git a/src/pages/Company/List/index.tsx b/src/pages/Company/List/index.tsx index 5212cb4..0179fd6 100644 --- a/src/pages/Company/List/index.tsx +++ b/src/pages/Company/List/index.tsx @@ -105,7 +105,6 @@ const CompanyListForm: React.FC = () => { function page(curr: number) { if (!userLoading) { params.curr_page = curr; - console.log(params); userRequest(stringify(params)); } } diff --git a/src/pages/Login/index.tsx b/src/pages/Login/index.tsx index 96c6404..8d58320 100644 --- a/src/pages/Login/index.tsx +++ b/src/pages/Login/index.tsx @@ -5,21 +5,14 @@ import loginBg from '@/assets/loginBg.jpg'; import { FormItemPlugin, FormPlugin } from '@/components/FormPlugin'; import { DefaultERPName } from '@/configs/config'; import { AdminServices } from '@/services/AdminServices'; -import { type IAuth, useAuthStore } from '@/store/AuthStore'; -import { useUserStore } from '@/store/UserStore'; -import { toObject } from '@/utils/common'; import { notificationEventBus } from '@/utils/EventBus'; import { useRequest } from '@/utils/useRequest'; const Login = () => { - const user = useUserStore(); - const auth = useAuthStore(); const [userInfo, setUserInfo] = useState({ username: 'admin', password: '123456', login_type: 1 }); const { request, loading } = useRequest(AdminServices.login, { - onSuccessCodeZero: (res) => { + onSuccessCodeZero: () => { notificationEventBus.emit({ description: '登录成功' }); - user.updateUser(res.admin); - auth.updateAuth(toObject(res.auth) as IAuth); location.href = '#/'; }, }); diff --git a/src/pages/Staff/Auth/index.tsx b/src/pages/Staff/Auth/index.tsx new file mode 100644 index 0000000..c43b9d4 --- /dev/null +++ b/src/pages/Staff/Auth/index.tsx @@ -0,0 +1,137 @@ +import { Tree } from 'antd'; +import type React from 'react'; +import { useEffect, useState } from 'react'; +import PageContainerPlugin from '@/components/PageContainer/PageContainerPlugin'; +import { AdminServices } from '@/services/AdminServices'; +import { useAuthStore } from '@/store/AuthStore'; +import { useRequest } from '@/utils/useRequest'; + +/** 登录管理员权限列表页面 */ +const AuthForm: React.FC = () => { + const auth = useAuthStore().auth; + + const [menuTree, setMenuTree] = useState([]); + const [checkedKeys, setCheckedKeys] = useState([]); + const [expandedKeys, setExpandedKeys] = useState([]); + + /** 将后端数据转换为 Tree 节点 */ + const transformToTreeNodes = (menus: any[]): any[] => { + return menus.map((menu) => { + const childrenNodes: any[] = []; + + // 子菜单 + if (menu.children?.length) { + menu.children.forEach((child: any) => { + const childNodes: any[] = []; + + // 子菜单下的子菜单功能 + if (child.children?.length) { + child.children.forEach((func: any) => { + childNodes.push({ + title: func.function_ch_name, + key: `func_${func.function_id}`, + isLeaf: true, + }); + }); + } + + // 子菜单自己的功能 + if (child.functions?.length) { + child.functions.forEach((func: any) => { + childNodes.push({ + title: func.function_ch_name, + key: `func_${func.function_id}`, + isLeaf: true, + }); + }); + } + + childrenNodes.push({ + title: child.menu_ch_name, + key: `menu_${child.menu_id}`, + children: childNodes.length ? childNodes : undefined, + }); + }); + } + + // 顶级菜单功能 + if (menu.functions?.length) { + menu.functions.forEach((func: any) => { + childrenNodes.push({ + title: func.function_ch_name, + key: `func_${func.function_id}`, + isLeaf: true, + }); + }); + } + + return { + title: menu.menu_ch_name, + key: `menu_${menu.menu_id}`, + children: childrenNodes.length ? childrenNodes : undefined, + }; + }); + }; + + /** 获取 Tree 所有 key(用于默认全展开) */ + const getAllTreeKeys = (nodes: any[]): React.Key[] => { + const keys: React.Key[] = []; + + const loop = (list: any[]) => { + list.forEach((item) => { + keys.push(item.key); + if (item.children) { + loop(item.children); + } + }); + }; + + loop(nodes); + return keys; + }; + + /** 获取当前管理员权限 */ + const { loading: listLoading, request: listRequest } = useRequest(AdminServices.auth, { + onSuccessCodeZero: (res) => { + const tree = transformToTreeNodes(res.rule); + setMenuTree(tree); + + setExpandedKeys(getAllTreeKeys(tree)); // ⭐ 关键:全展开 + + // 如果后端返回的是 function_id 列表,这里可以顺便做回显 + if (res?.auth) { + //const keys = res.auth.split(',').map((id: string) => `func_${id}`); + const keys = res.auth.map((id: number) => `func_${id}`); + setCheckedKeys(keys); + } else { + setCheckedKeys([]); + } + }, + }); + + useEffect(() => { + if (!listLoading) { + listRequest(); + } + }, []); + + return ( + setExpandedKeys(keys)} + onCheck={() => {}} // 只读 + /> + ); +}; + +const Auth = () => ( + + + +); + +export default Auth; diff --git a/src/pages/Staff/Grp/index.tsx b/src/pages/Staff/Grp/index.tsx index 94b5cc9..4bbe2a9 100644 --- a/src/pages/Staff/Grp/index.tsx +++ b/src/pages/Staff/Grp/index.tsx @@ -61,23 +61,27 @@ const GrpListForm: React.FC = () => { {item?.group_id != 1 && ( <> - - { - deleteAdminGroupRequest(stringify({ group_id: item.group_id })); - }} - > - - + {auth.SF_ADMIN_GROUP_EDIT && ( + + )} + {auth.SF_ADMIN_GROUP_DEL && ( + { + deleteAdminGroupRequest(stringify({ group_id: item.group_id })); + }} + > + + + )} )} @@ -190,14 +194,16 @@ const GrpListForm: React.FC = () => { - + {auth.SF_ADMIN_GROUP_ADD && ( + + )} { {item?.admin_id != 1 && ( <> - - { - deleteAdminRequest(stringify({ admin_id: item.admin_id })); - }} - > - - + {auth.SF_ADMIN_ADMIN_EDIT && ( + + )} + {auth.SF_ADMIN_ADMIN_DEL && ( + { + deleteAdminRequest(stringify({ admin_id: item.admin_id })); + }} + > + + + )} )} @@ -107,7 +111,6 @@ const AdminListForm: React.FC = () => { function page(curr: number) { if (!listLoading) { params.curr_page = curr; - console.log(params); listRequest(stringify(params)); } } @@ -219,14 +222,16 @@ const AdminListForm: React.FC = () => { - + {auth.SF_ADMIN_ADMIN_ADD && ( + + )} { {item?.admin_id != 1 && ( <> - - { - deleteAdminDepartmentRequest(stringify({ department_id: item.department_id })); - }} - > - - + {auth.SF_ADMIN_DEPART_EDIT && ( + + )} + {auth.SF_ADMIN_DEPART_DEL && ( + { + deleteAdminDepartmentRequest(stringify({ department_id: item.department_id })); + }} + > + + + )} )} @@ -99,7 +103,6 @@ const DepListForm: React.FC = () => { function page(curr: number) { if (!listLoading) { params.curr_page = curr; - console.log(params); listRequest(stringify(params)); } } @@ -193,14 +196,16 @@ const DepListForm: React.FC = () => { - + {auth.SF_ADMIN_DEPART_ADD && ( + + )} { + const user = useUserStore().user; + console.log('user', user); const auth = useAuthStore().auth; - + console.log('auth', auth); const [ajaxData, setAjaxData] = useState({ count: 0, data: [] }); const [showMoreSearch, setShowMoreSearch] = useState(false); const UserEditModalRef = useRef(null); @@ -59,15 +62,7 @@ const UserListForm: React.FC = () => { fixed: tableFixedByPhone('left'), render: (_, item) => ( - - {auth.SF_ERP_USER_EDIT && ( + {auth.SF_ADMIN_USER_EDIT && ( + {auth.SF_ADMIN_USER_ADD && ( + + )}