diff --git a/src/backend/bisheng/api/services/role_group_service.py b/src/backend/bisheng/api/services/role_group_service.py index ef70f504d..7616dfde2 100644 --- a/src/backend/bisheng/api/services/role_group_service.py +++ b/src/backend/bisheng/api/services/role_group_service.py @@ -3,7 +3,7 @@ from uuid import UUID from fastapi.encoders import jsonable_encoder -from fastapi import Request +from fastapi import Request, HTTPException from bisheng.api.services.assistant import AssistantService from bisheng.api.services.audit_log import AuditLogService @@ -16,7 +16,9 @@ from bisheng.database.models.group import Group, GroupCreate, GroupDao, GroupRead, DefaultGroup from bisheng.database.models.group_resource import GroupResourceDao, ResourceTypeEnum from bisheng.database.models.knowledge import KnowledgeDao +from bisheng.database.models.role import AdminRole from bisheng.database.models.user import User, UserDao +from bisheng.database.models.user_role import UserRoleDao from bisheng.database.models.user_group import UserGroupCreate, UserGroupDao, UserGroupRead from loguru import logger @@ -141,7 +143,7 @@ def insert_user_group(self, user_group: UserGroupCreate) -> UserGroupRead: def replace_user_groups(self, request: Request, login_user: UserPayload, user_id: int, group_ids: List[int]): """ 覆盖用户的所在的用户组 """ # 判断下被操作用户是否是超级管理员 - user_role_list = UserRoleDao.get_user_role(user_id) + user_role_list = UserRoleDao.get_user_roles(user_id) if any(one.role_id == AdminRole for one in user_role_list): raise HTTPException(status_code=500, detail='系统管理员不允许编辑') diff --git a/src/backend/bisheng/api/v1/user.py b/src/backend/bisheng/api/v1/user.py index d112d2db1..937478552 100644 --- a/src/backend/bisheng/api/v1/user.py +++ b/src/backend/bisheng/api/v1/user.py @@ -510,6 +510,8 @@ async def user_addrole(*, user_role_list = UserRoleDao.get_user_roles(user_role.user_id) if any(one.role_id == AdminRole for one in user_role_list): raise HTTPException(status_code=500, detail='系统管理员不允许编辑') + if any(one == AdminRole for one in user_role.role_id): + raise HTTPException(status_code=500, detail='不允许设置为系统管理员') if not login_user.is_admin(): # 判断拥有哪些用户组的管理权限 diff --git a/src/backend/bisheng/database/models/role.py b/src/backend/bisheng/database/models/role.py index da69dda3b..66f121688 100644 --- a/src/backend/bisheng/database/models/role.py +++ b/src/backend/bisheng/database/models/role.py @@ -47,14 +47,14 @@ class RoleDao(RoleBase): @classmethod def get_role_by_groups(cls, group: List[int], keyword: str = None, page: int = 0, limit: int = 0) -> List[Role]: """ - 获取用户组内的角色列表 + 获取用户组内的角色列表, 不包含系统管理员角色 params: group: 用户组ID列表 page: 页数 limit: 每页条数 return: 角色列表 """ - statement = select(Role) + statement = select(Role).where(Role.id > AdminRole) if group: statement = statement.where(Role.group_id.in_(group)) if keyword: @@ -69,7 +69,7 @@ def count_role_by_groups(cls, group: List[int], keyword: str = None) -> int: """ 统计用户组内的角色数量,参数如上 """ - statement = select(func.count(Role.id)) + statement = select(func.count(Role.id)).where(Role.id > AdminRole) if group: statement = statement.where(Role.group_id.in_(group)) if keyword: diff --git a/src/frontend/src/components/bs-comp/sheets/TaggingSheet.tsx b/src/frontend/src/components/bs-comp/sheets/TaggingSheet.tsx new file mode 100644 index 000000000..8e0404d66 --- /dev/null +++ b/src/frontend/src/components/bs-comp/sheets/TaggingSheet.tsx @@ -0,0 +1,47 @@ +import { + Sheet, + SheetContent, + SheetTitle, + SheetTrigger, +} from "../../bs-ui/sheet"; +import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd'; + +export default function TaggingSheet({children}) { + const buttons = [ + {id:'01',name:'Button01'}, + {id:'02',name:'Button02'}, + {id:'03',name:'Button03'}, + ] + + return + {children} + + 给助手打标签 +
+
+ +
+
+ console.log('-------------')}> + + {(provided) => ( +
+ {buttons.map((b,index) => ( + + {(provided) => ( +
+ {b.name} +
+ )} +
+ ))} +
+ )} +
+
+
+
+
+
+} \ No newline at end of file diff --git a/src/frontend/src/components/bs-ui/select/select.tsx b/src/frontend/src/components/bs-ui/select/select.tsx new file mode 100644 index 000000000..df55eb6a0 --- /dev/null +++ b/src/frontend/src/components/bs-ui/select/select.tsx @@ -0,0 +1,44 @@ +import React, { ChangeEvent } from "react" +import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/bs-ui/select"; +import { SearchInput } from "../input"; + +interface SelectSearchProps { + value: string, + options: {label: string, value: string}[], + selectPlaceholder?:string, + inputPlaceholder?:string, + onOpenChange?: (open:boolean) => void, + onValueChange: (value: string) => void, + onChange: (e:ChangeEvent) => void, + selectClass?: string, + contentClass?: string +} + +const SelectSearch: React.FC = ({ + value, + options, + selectPlaceholder = '', + inputPlaceholder = '', + onOpenChange, + onValueChange, + onChange, + selectClass = '', + contentClass = '' +}) => { + return +} + +export default React.memo(SelectSearch) \ No newline at end of file diff --git a/src/frontend/src/pages/SkillPage/components/editAssistant/Setting.tsx b/src/frontend/src/pages/SkillPage/components/editAssistant/Setting.tsx index 65761c545..bb7313661 100644 --- a/src/frontend/src/pages/SkillPage/components/editAssistant/Setting.tsx +++ b/src/frontend/src/pages/SkillPage/components/editAssistant/Setting.tsx @@ -32,6 +32,7 @@ import ModelSelect from "./ModelSelect"; import Temperature from "./Temperature"; import { locationContext } from "@/contexts/locationContext"; import { useContext } from "react"; +import TaggingSheet from "@/components/bs-comp/sheets/TaggingSheet"; export default function Setting() { const { t } = useTranslation(); @@ -303,6 +304,12 @@ export default function Setting() { + + e.stopPropagation()} + > + ); diff --git a/src/frontend/src/pages/SystemPage/components/Roles.tsx b/src/frontend/src/pages/SystemPage/components/Roles.tsx index cf0971bc3..c64e6bfea 100644 --- a/src/frontend/src/pages/SystemPage/components/Roles.tsx +++ b/src/frontend/src/pages/SystemPage/components/Roles.tsx @@ -1,7 +1,6 @@ import { PlusIcon } from "@/components/bs-icons/plus"; import { bsConfirm } from "@/components/bs-ui/alertDialog/useConfirm"; import { Label } from "@/components/bs-ui/label"; -import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/bs-ui/select"; import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { Button } from "../../../components/bs-ui/button"; @@ -19,6 +18,7 @@ import { delRoleApi, getRolesByGroupApi, getUserGroupsApi } from "../../../contr import { captureAndAlertRequestErrorHoc } from "../../../controllers/request"; import { ROLE } from "../../../types/api/user"; import EditRole from "./EditRole"; +import SelectSearch from "@/components/bs-ui/select/select" interface State { roles: ROLE[]; @@ -71,7 +71,7 @@ export default function Roles() { inputDom.value = ''; } try { - const data: any = await getRolesByGroupApi('', [state.group]); + const data:any = await getRolesByGroupApi('', [state.group]); dispatch({ type: 'SET_ROLES', payload: data }); allRolesRef.current = data; } catch (error) { @@ -80,7 +80,7 @@ export default function Roles() { }, [state.group]); useEffect(() => { - getUserGroupsApi().then((res: any) => { + getUserGroupsApi().then((res:any) => { const groups = res.records.map(ug => ({ label: ug.group_name, value: ug.id })) // 获取最近修改用户组 dispatch({ type: 'SET_GROUP', payload: groups[0].value }); @@ -142,26 +142,17 @@ export default function Roles() {
- + { + !open && setKeyWord('') + }} + onValueChange={(value) => { + dispatch({ type: 'SET_GROUP', payload: value}) + }} + onChange={e => setKeyWord(e.target.value)} + />
@@ -187,7 +178,7 @@ export default function Roles() { {el.role_name} {el.create_time.replace('T', ' ')} - + diff --git a/src/frontend/src/pages/SystemPage/components/UserRoleItem.tsx b/src/frontend/src/pages/SystemPage/components/UserRoleItem.tsx index 7cd3296d2..6b1ce79c2 100644 --- a/src/frontend/src/pages/SystemPage/components/UserRoleItem.tsx +++ b/src/frontend/src/pages/SystemPage/components/UserRoleItem.tsx @@ -2,8 +2,9 @@ import { DelIcon } from "@/components/bs-icons"; import { Button } from "@/components/bs-ui/button"; import MultiSelect from "@/components/bs-ui/select/multi"; import { getRolesByGroupApi, getUserGroupsApi } from "@/controllers/API/user"; -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; +import SelectSearch from "@/components/bs-ui/select/select" export default function UserRoleItem({ showDel, groupId, selectedRoles, onDelete, onChange }: { showDel: boolean, groupId: null | string, selectedRoles: any[], onDelete: any, onChange: any }) { @@ -11,24 +12,36 @@ export default function UserRoleItem({ showDel, groupId, selectedRoles, onDelete // 用户组 const [groups, setGroups] = useState([]) + const groupsRef = useRef([]) const [userGroupSelected, setUserGroupSelected] = useState(groupId ? [groupId] : []) - useEffect(() => { - // 用户组option列表 + const loadGroups = () => { getUserGroupsApi().then((res: any) => { - setGroups(res.records.map((ug) => { + const groups = res.records.map((ug) => { return { label: ug.group_name, value: ug.id.toString() } - })) + }) + setGroups(groups) + groupsRef.current = groups }) + } + useEffect(() => { + // 用户组option列表 + loadGroups() }, []) - const handleSelectGroup = (values) => { - onChange(values, []) - setUserGroupSelected(values); + const handleSelectGroup = (value) => { //单选之后value要改成数组传出去 + onChange([value], []) + setUserGroupSelected([value]); setSelected([]) } + const handleSearch = (e) => { + const keyword = e.target.value + const newGroups = groupsRef.current.filter(g => g.label.toUpperCase().includes(keyword.toUpperCase()) + || g.value === userGroupSelected[0]) + setGroups(newGroups) + } // 角色 const [roles, setRoles] = useState([]) @@ -53,14 +66,14 @@ export default function UserRoleItem({ showDel, groupId, selectedRoles, onDelete } return
- - + onOpenChange={() => setGroups(groupsRef.current)} + onValueChange={handleSelectGroup} + onChange={handleSearch} + />