diff --git a/frontend/src/models/admin.js b/frontend/src/models/admin.js index 336e987..31794c2 100644 --- a/frontend/src/models/admin.js +++ b/frontend/src/models/admin.js @@ -246,6 +246,30 @@ const Admin = { return false; }); }, + depts: async () => { + return await fetch(`${API_BASE}/dept/list`, { + method: "GET", + headers: baseHeaders(), + }) + .then((res) => res.json()) + .then((res) => res?.depts || []) + .catch((e) => { + console.error(e); + return []; + }); + }, + addDepts: async (data) => { + return await fetch(`${API_BASE}/dept/add`, { + method: "POST", + headers: baseHeaders(), + body: JSON.stringify(data), + }) + .then((res) => res.json()) + .catch((e) => { + console.error(e); + return { depts: null, error: e.message }; + }); + }, }; export default Admin; diff --git a/frontend/src/pages/Admin/Section/index.jsx b/frontend/src/pages/Admin/Section/index.jsx index f7f5640..f3a474f 100644 --- a/frontend/src/pages/Admin/Section/index.jsx +++ b/frontend/src/pages/Admin/Section/index.jsx @@ -1,18 +1,18 @@ -import { useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import Sidebar from "@/components/SettingsSidebar"; import { isMobile } from "react-device-detect"; import * as Skeleton from "react-loading-skeleton"; import "react-loading-skeleton/dist/skeleton.css"; -import { UserPlus } from "@phosphor-icons/react"; +import { Folder, FolderOpen, Pencil, Trash } from "@phosphor-icons/react"; import Admin from "@/models/admin"; -import UserRow from "../Users/UserRow"; import useUser from "@/hooks/useUser"; -import NewUserModal from "../Users/NewUserModal"; import { useModal } from "@/hooks/useModal"; import ModalWrapper from "@/components/ModalWrapper"; import CTAButton from "@/components/lib/CTAButton"; +import { TreeSelect } from "antd"; // 使用 antd 的 TreeSelect 组件 +import "antd/dist/reset.css"; // 引入 antd 样式 -export default function AdminUsers() { +export default function AdminDepartments() { const { isOpen, openModal, closeModal } = useModal(); return ( @@ -26,11 +26,11 @@ export default function AdminUsers() {

- 部门 + 部门管理

- 部门树状结构 + 管理所有部门及其层级结构。删除部门将同时删除其子部门。

@@ -38,33 +38,33 @@ export default function AdminUsers() { onClick={openModal} className="mt-3 mr-0 mb-4 md:-mb-6 z-10" > - Add user + 添加部门
- +
- + ); } -function UsersContainer() { +function DepartmentsContainer() { const { user: currUser } = useUser(); const [loading, setLoading] = useState(true); - const [users, setUsers] = useState([]); + const [departments, setDepartments] = useState([]); useEffect(() => { - async function fetchUsers() { - const _users = await Admin.users(); - setUsers(_users); + async function fetchDepartments() { + const _departments = await Admin.depts(); + setDepartments(buildTree(_departments)); // 将部门列表转换为树状结构 setLoading(false); } - fetchUsers(); + fetchDepartments(); }, []); if (loading) { @@ -84,114 +84,202 @@ function UsersContainer() { return ( - - - - - - + + + + + + + - {users.map((user) => ( - - ))} + {departments.map((dept) => ( + + ))}
- Username - - Role - - Date Added - - {" "} -
+ 部门名称 + + 排序 + + 状态 + + 创建时间 + + 操作 +
); } -const ROLE_HINT = { - default: [ - "Can only send chats with workspaces they are added to by admin or managers.", - "Cannot modify any settings at all.", - ], - manager: [ - "Can view, create, and delete any workspaces and modify workspace-specific settings.", - "Can create, update and invite new users to the instance.", - "Cannot modify LLM, vectorDB, embedding, or other connections.", - ], - admin: [ - "Highest user level privilege.", - "Can see and do everything across the system.", - ], -}; - -export function RoleHintDisplay({ role }) { +function DepartmentRow({ dept }) { + const [expanded, setExpanded] = useState(false); + + const toggleExpand = () => { + setExpanded(!expanded); + }; + return ( -
-

Permissions

- -
+ <> + + +
+ {dept.children && dept.children.length > 0 ? ( + + ) : ( + + )} + {dept.deptName} +
+ + {dept.orderNum} + + + {dept.status === 0 ? "启用" : "停用"} + + + + {new Date(dept.createdAt).toLocaleDateString()} + + +
+ + +
+ + + {expanded && + dept.children && + dept.children.map((child) => ( + + ))} + ); } -export function MessageLimitInput({ enabled, limit, updateState, role }) { - if (role === "admin") return null; +function NewDepartmentModal({ closeModal }) { + const [formData, setFormData] = useState({ + deptName: "", + parentId: null, // 上级部门 ID + orderNum: 0, + status: 0, + }); + + const [departments, setDepartments] = useState([]); // 部门数据 + const [treeData, setTreeData] = useState([]); // 树状结构数据 + + // 获取部门数据并转换为树状结构 + useEffect(() => { + async function fetchDepartments() { + const _departments = await Admin.depts(); + setDepartments(_departments); + setTreeData(buildTree(_departments)); // 将部门数据转换为树状结构 + } + fetchDepartments(); + }, []); + + // 将部门数据转换为树状结构 + function buildTree(depts, parentId = 0) { + return depts + .filter((dept) => dept.parentId === parentId) + .map((dept) => ({ + title: dept.deptName, // 显示部门名称 + value: dept.deptId, // 部门 ID + children: buildTree(depts, dept.deptId), // 递归查找子部门 + })); + } + + // 处理表单提交 + const handleSubmit = async () => { + await Admin.addDepts(formData); + closeModal(); + }; + return ( -
-
-
-

- Limit messages per day -

-