From 06a7cd9abd4404f72bf4daee3fa0c8a1a2d1701c Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Tue, 10 Feb 2026 00:09:48 +0800 Subject: [PATCH] =?UTF-8?q?feat(auth):=20=E8=A7=92=E8=89=B2=E7=AE=A1?= =?UTF-8?q?=E7=90=86CRUD=E4=B8=8E=E8=A7=92=E8=89=B2=E6=9D=83=E9=99=90?= =?UTF-8?q?=E7=BB=91=E5=AE=9A=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增角色创建/编辑/删除接口和角色-权限绑定接口,支持管理员自定义角色并灵活配置权限。 前端新增角色CRUD弹窗、按模块分组的权限配置面板,内置角色禁止删除但允许编辑和配置权限。 Co-Authored-By: Claude Opus 4.6 --- .../application/AuthApplicationService.java | 53 +++ .../auth/domain/model/AuthRoleInfo.java | 1 + .../exception/AuthErrorCode.java | 5 +- .../persistence/mapper/AuthMapper.java | 22 ++ .../auth/interfaces/rest/AuthController.java | 32 ++ .../rest/dto/BindRolePermissionsRequest.java | 13 + .../rest/dto/CreateRoleRequest.java | 13 + .../rest/dto/RoleWithPermissionsResponse.java | 14 + .../rest/dto/UpdateRoleRequest.java | 13 + .../src/main/resources/mappers/AuthMapper.xml | 82 ++++- .../SettingsPage/UserPermissionManagement.tsx | 305 +++++++++++++++++- .../src/pages/SettingsPage/settings.apis.ts | 36 +++ 12 files changed, 583 insertions(+), 6 deletions(-) create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/BindRolePermissionsRequest.java create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/CreateRoleRequest.java create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/RoleWithPermissionsResponse.java create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/UpdateRoleRequest.java diff --git a/backend/shared/domain-common/src/main/java/com/datamate/common/auth/application/AuthApplicationService.java b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/application/AuthApplicationService.java index 183dfd3..1cc6d63 100644 --- a/backend/shared/domain-common/src/main/java/com/datamate/common/auth/application/AuthApplicationService.java +++ b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/application/AuthApplicationService.java @@ -10,6 +10,7 @@ import com.datamate.common.auth.interfaces.rest.dto.AuthCurrentUserResponse; import com.datamate.common.auth.interfaces.rest.dto.AuthLoginResponse; import com.datamate.common.auth.interfaces.rest.dto.AuthUserView; import com.datamate.common.auth.interfaces.rest.dto.AuthUserWithRolesResponse; +import com.datamate.common.auth.interfaces.rest.dto.RoleWithPermissionsResponse; import com.datamate.common.infrastructure.exception.BusinessAssert; import com.datamate.common.security.JwtUtils; import io.jsonwebtoken.Claims; @@ -17,6 +18,7 @@ import io.jsonwebtoken.JwtException; import lombok.RequiredArgsConstructor; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.time.Duration; import java.util.ArrayList; @@ -26,6 +28,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.UUID; import java.util.stream.Collectors; /** @@ -129,6 +132,56 @@ public class AuthApplicationService { authMapper.insertUserRoles(userId, new ArrayList<>(distinctRoleIds)); } + public AuthRoleInfo createRole(String roleCode, String roleName, String description) { + AuthRoleInfo existing = authMapper.findRoleByCode(roleCode); + BusinessAssert.isTrue(existing == null, AuthErrorCode.ROLE_CODE_DUPLICATE); + + String id = UUID.randomUUID().toString(); + authMapper.insertRole(id, roleCode, roleName, description); + return authMapper.findRoleById(id); + } + + public AuthRoleInfo updateRole(String roleId, String roleName, String description, Boolean enabled) { + AuthRoleInfo role = authMapper.findRoleById(roleId); + BusinessAssert.notNull(role, AuthErrorCode.ROLE_NOT_FOUND); + + authMapper.updateRole(roleId, roleName, description, enabled); + return authMapper.findRoleById(roleId); + } + + @Transactional + public void deleteRole(String roleId) { + AuthRoleInfo role = authMapper.findRoleById(roleId); + BusinessAssert.notNull(role, AuthErrorCode.ROLE_NOT_FOUND); + BusinessAssert.isTrue(!Boolean.TRUE.equals(role.getIsBuiltIn()), AuthErrorCode.ROLE_DELETE_BUILT_IN); + + authMapper.deleteRolePermissions(roleId); + authMapper.deleteUserRolesByRoleId(roleId); + authMapper.deleteRoleById(roleId); + } + + public RoleWithPermissionsResponse getRoleWithPermissions(String roleId) { + AuthRoleInfo role = authMapper.findRoleById(roleId); + BusinessAssert.notNull(role, AuthErrorCode.ROLE_NOT_FOUND); + + List permissionIds = authMapper.findPermissionIdsByRoleId(roleId); + return new RoleWithPermissionsResponse(role, permissionIds); + } + + @Transactional + public void bindRolePermissions(String roleId, List permissionIds) { + AuthRoleInfo role = authMapper.findRoleById(roleId); + BusinessAssert.notNull(role, AuthErrorCode.ROLE_NOT_FOUND); + + authMapper.deleteRolePermissions(roleId); + if (permissionIds != null && !permissionIds.isEmpty()) { + Set distinctIds = new LinkedHashSet<>(permissionIds); + int existingCount = authMapper.countPermissionsByIds(new ArrayList<>(distinctIds)); + BusinessAssert.isTrue(existingCount == distinctIds.size(), AuthErrorCode.PERMISSION_NOT_FOUND); + authMapper.insertRolePermissions(roleId, new ArrayList<>(distinctIds)); + } + } + private String buildToken(AuthBundle authBundle) { Map claims = Map.of( "userId", authBundle.user().getId(), diff --git a/backend/shared/domain-common/src/main/java/com/datamate/common/auth/domain/model/AuthRoleInfo.java b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/domain/model/AuthRoleInfo.java index adfb544..d9c8172 100644 --- a/backend/shared/domain-common/src/main/java/com/datamate/common/auth/domain/model/AuthRoleInfo.java +++ b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/domain/model/AuthRoleInfo.java @@ -14,5 +14,6 @@ public class AuthRoleInfo { private String roleName; private String description; private Boolean enabled; + private Boolean isBuiltIn; } diff --git a/backend/shared/domain-common/src/main/java/com/datamate/common/auth/infrastructure/exception/AuthErrorCode.java b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/infrastructure/exception/AuthErrorCode.java index 929c1ce..ddb1bd6 100644 --- a/backend/shared/domain-common/src/main/java/com/datamate/common/auth/infrastructure/exception/AuthErrorCode.java +++ b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/infrastructure/exception/AuthErrorCode.java @@ -15,7 +15,10 @@ public enum AuthErrorCode implements ErrorCode { TOKEN_INVALID("auth.0003", "登录状态已失效"), USER_NOT_FOUND("auth.0004", "用户不存在"), ROLE_NOT_FOUND("auth.0005", "角色不存在"), - AUTHORIZATION_DENIED("auth.0006", "无权限执行该操作"); + AUTHORIZATION_DENIED("auth.0006", "无权限执行该操作"), + ROLE_CODE_DUPLICATE("auth.0007", "角色编码已存在"), + ROLE_DELETE_BUILT_IN("auth.0008", "内置角色不允许删除"), + PERMISSION_NOT_FOUND("auth.0009", "权限不存在"); private final String code; private final String message; diff --git a/backend/shared/domain-common/src/main/java/com/datamate/common/auth/infrastructure/persistence/mapper/AuthMapper.java b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/infrastructure/persistence/mapper/AuthMapper.java index 590f3f0..32a7c4c 100644 --- a/backend/shared/domain-common/src/main/java/com/datamate/common/auth/infrastructure/persistence/mapper/AuthMapper.java +++ b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/infrastructure/persistence/mapper/AuthMapper.java @@ -35,5 +35,27 @@ public interface AuthMapper { int deleteUserRoles(@Param("userId") Long userId); int insertUserRoles(@Param("userId") Long userId, @Param("roleIds") List roleIds); + + AuthRoleInfo findRoleById(@Param("roleId") String roleId); + + AuthRoleInfo findRoleByCode(@Param("roleCode") String roleCode); + + int insertRole(@Param("id") String id, @Param("roleCode") String roleCode, + @Param("roleName") String roleName, @Param("description") String description); + + int updateRole(@Param("roleId") String roleId, @Param("roleName") String roleName, + @Param("description") String description, @Param("enabled") Boolean enabled); + + int deleteRoleById(@Param("roleId") String roleId); + + List findPermissionIdsByRoleId(@Param("roleId") String roleId); + + int deleteRolePermissions(@Param("roleId") String roleId); + + int insertRolePermissions(@Param("roleId") String roleId, @Param("permissionIds") List permissionIds); + + int countPermissionsByIds(@Param("permissionIds") List permissionIds); + + int deleteUserRolesByRoleId(@Param("roleId") String roleId); } diff --git a/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/AuthController.java b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/AuthController.java index ed475a9..d96c3cd 100644 --- a/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/AuthController.java +++ b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/AuthController.java @@ -7,12 +7,17 @@ import com.datamate.common.auth.interfaces.rest.dto.AssignUserRolesRequest; import com.datamate.common.auth.interfaces.rest.dto.AuthCurrentUserResponse; import com.datamate.common.auth.interfaces.rest.dto.AuthLoginResponse; import com.datamate.common.auth.interfaces.rest.dto.AuthUserWithRolesResponse; +import com.datamate.common.auth.interfaces.rest.dto.BindRolePermissionsRequest; +import com.datamate.common.auth.interfaces.rest.dto.CreateRoleRequest; import com.datamate.common.auth.interfaces.rest.dto.LoginRequest; +import com.datamate.common.auth.interfaces.rest.dto.RoleWithPermissionsResponse; +import com.datamate.common.auth.interfaces.rest.dto.UpdateRoleRequest; import com.datamate.common.infrastructure.exception.BusinessAssert; import com.datamate.common.auth.infrastructure.exception.AuthErrorCode; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -69,6 +74,33 @@ public class AuthController { return authApplicationService.listPermissions(); } + @PostMapping("/roles") + public AuthRoleInfo createRole(@RequestBody @Valid CreateRoleRequest request) { + return authApplicationService.createRole(request.roleCode(), request.roleName(), request.description()); + } + + @PutMapping("/roles/{roleId}") + public AuthRoleInfo updateRole(@PathVariable("roleId") String roleId, + @RequestBody @Valid UpdateRoleRequest request) { + return authApplicationService.updateRole(roleId, request.roleName(), request.description(), request.enabled()); + } + + @DeleteMapping("/roles/{roleId}") + public void deleteRole(@PathVariable("roleId") String roleId) { + authApplicationService.deleteRole(roleId); + } + + @GetMapping("/roles/{roleId}/permissions") + public RoleWithPermissionsResponse getRolePermissions(@PathVariable("roleId") String roleId) { + return authApplicationService.getRoleWithPermissions(roleId); + } + + @PutMapping("/roles/{roleId}/permissions") + public void bindRolePermissions(@PathVariable("roleId") String roleId, + @RequestBody @Valid BindRolePermissionsRequest request) { + authApplicationService.bindRolePermissions(roleId, request.permissionIds()); + } + private String extractBearerToken(String authorizationHeader) { BusinessAssert.isTrue( authorizationHeader != null && authorizationHeader.startsWith("Bearer "), diff --git a/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/BindRolePermissionsRequest.java b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/BindRolePermissionsRequest.java new file mode 100644 index 0000000..dc9edf7 --- /dev/null +++ b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/BindRolePermissionsRequest.java @@ -0,0 +1,13 @@ +package com.datamate.common.auth.interfaces.rest.dto; + +import jakarta.validation.constraints.NotNull; + +import java.util.List; + +/** + * 角色权限绑定请求 + */ +public record BindRolePermissionsRequest( + @NotNull(message = "权限列表不能为null") List permissionIds +) { +} diff --git a/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/CreateRoleRequest.java b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/CreateRoleRequest.java new file mode 100644 index 0000000..6661a20 --- /dev/null +++ b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/CreateRoleRequest.java @@ -0,0 +1,13 @@ +package com.datamate.common.auth.interfaces.rest.dto; + +import jakarta.validation.constraints.NotBlank; + +/** + * 创建角色请求 + */ +public record CreateRoleRequest( + @NotBlank(message = "角色编码不能为空") String roleCode, + @NotBlank(message = "角色名称不能为空") String roleName, + String description +) { +} diff --git a/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/RoleWithPermissionsResponse.java b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/RoleWithPermissionsResponse.java new file mode 100644 index 0000000..0958182 --- /dev/null +++ b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/RoleWithPermissionsResponse.java @@ -0,0 +1,14 @@ +package com.datamate.common.auth.interfaces.rest.dto; + +import com.datamate.common.auth.domain.model.AuthRoleInfo; + +import java.util.List; + +/** + * 角色及其权限响应 + */ +public record RoleWithPermissionsResponse( + AuthRoleInfo role, + List permissionIds +) { +} diff --git a/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/UpdateRoleRequest.java b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/UpdateRoleRequest.java new file mode 100644 index 0000000..dafebb7 --- /dev/null +++ b/backend/shared/domain-common/src/main/java/com/datamate/common/auth/interfaces/rest/dto/UpdateRoleRequest.java @@ -0,0 +1,13 @@ +package com.datamate.common.auth.interfaces.rest.dto; + +import jakarta.validation.constraints.NotBlank; + +/** + * 更新角色请求 + */ +public record UpdateRoleRequest( + @NotBlank(message = "角色名称不能为空") String roleName, + String description, + Boolean enabled +) { +} diff --git a/backend/shared/domain-common/src/main/resources/mappers/AuthMapper.xml b/backend/shared/domain-common/src/main/resources/mappers/AuthMapper.xml index 496685d..7799b90 100644 --- a/backend/shared/domain-common/src/main/resources/mappers/AuthMapper.xml +++ b/backend/shared/domain-common/src/main/resources/mappers/AuthMapper.xml @@ -73,10 +73,11 @@ @@ -116,5 +117,80 @@ (#{userId}, #{roleId}) + + + + + + + INSERT INTO t_auth_roles (id, role_code, role_name, description, is_built_in, enabled) + VALUES (#{id}, #{roleCode}, #{roleName}, #{description}, 0, 1) + + + + UPDATE t_auth_roles + SET role_name = #{roleName}, + description = #{description}, + enabled = #{enabled} + WHERE id = #{roleId} + + + + DELETE FROM t_auth_roles + WHERE id = #{roleId} + + + + + + DELETE FROM t_auth_role_permissions + WHERE role_id = #{roleId} + + + + INSERT INTO t_auth_role_permissions (role_id, permission_id) + VALUES + + (#{roleId}, #{permissionId}) + + + + + + + DELETE FROM t_auth_user_roles + WHERE role_id = #{roleId} + diff --git a/frontend/src/pages/SettingsPage/UserPermissionManagement.tsx b/frontend/src/pages/SettingsPage/UserPermissionManagement.tsx index d9d9a79..89dcf18 100644 --- a/frontend/src/pages/SettingsPage/UserPermissionManagement.tsx +++ b/frontend/src/pages/SettingsPage/UserPermissionManagement.tsx @@ -2,11 +2,18 @@ import { useCallback, useEffect, useMemo, useState } from "react"; import { Button, Card, + Checkbox, + Col, Empty, + Form, + Input, message, Modal, + Popconfirm, + Row, Select, Space, + Switch, Table, Tag, Typography, @@ -14,14 +21,20 @@ import { import type { ColumnsType } from "antd/es/table"; import { assignUserRolesUsingPut, + bindRolePermissionsUsingPut, + createRoleUsingPost, + deleteRoleUsingDelete, + getRolePermissionsUsingGet, listAuthPermissionsUsingGet, listAuthRolesUsingGet, listAuthUsersUsingGet, + updateRoleUsingPut, } from "./settings.apis"; import type { AuthPermissionInfo, AuthRoleInfo, AuthUserWithRoles, + RoleWithPermissionsResponse, } from "./settings.apis"; interface ApiResponse { @@ -49,6 +62,17 @@ export default function UserPermissionManagement({ const [selectedRoleCodes, setSelectedRoleCodes] = useState([]); const [submitting, setSubmitting] = useState(false); + // Role CRUD state + const [createRoleOpen, setCreateRoleOpen] = useState(false); + const [editingRole, setEditingRole] = useState(null); + const [createRoleForm] = Form.useForm(); + const [editRoleForm] = Form.useForm(); + + // Permission config state + const [permConfigRole, setPermConfigRole] = useState(null); + const [selectedPermissionIds, setSelectedPermissionIds] = useState([]); + const [permConfigLoading, setPermConfigLoading] = useState(false); + const canShowAnything = canManageUsers || canViewRoles || canViewPermissions; const canAssignRoles = canManageUsers && roles.length > 0; @@ -61,6 +85,17 @@ export default function UserPermissionManagement({ [roles] ); + const permissionsByModule = useMemo(() => { + const map = new Map(); + for (const perm of permissions) { + const module = perm.module || "其他"; + const list = map.get(module) ?? []; + list.push(perm); + map.set(module, list); + } + return map; + }, [permissions]); + const loadData = useCallback(async () => { setLoading(true); try { @@ -169,6 +204,14 @@ export default function UserPermissionManagement({ const roleColumns: ColumnsType = [ { title: "角色编码", dataIndex: "roleCode", key: "roleCode", width: 220 }, { title: "角色名称", dataIndex: "roleName", key: "roleName", width: 180 }, + { + title: "类型", + dataIndex: "isBuiltIn", + key: "isBuiltIn", + width: 100, + render: (isBuiltIn?: boolean) => + isBuiltIn ? 内置 : 自定义, + }, { title: "状态", dataIndex: "enabled", @@ -183,6 +226,49 @@ export default function UserPermissionManagement({ key: "description", render: (value?: string) => value || "-", }, + { + title: "操作", + key: "actions", + width: 220, + render: (_, record) => ( + + + + {!record.isBuiltIn && ( + void handleDeleteRole(record.id)} + okText="确定" + cancelText="取消" + > + + + )} + + ), + }, ]; const permissionColumns: ColumnsType = [ @@ -250,6 +336,97 @@ export default function UserPermissionManagement({ } }; + const handleCreateRole = async () => { + try { + const values = await createRoleForm.validateFields(); + setSubmitting(true); + await createRoleUsingPost({ + roleCode: values.roleCode, + roleName: values.roleName, + description: values.description, + }); + message.success("角色创建成功"); + setCreateRoleOpen(false); + createRoleForm.resetFields(); + await loadData(); + } catch (error) { + if (error && typeof error === "object" && "errorFields" in error) { + return; + } + message.error("角色创建失败"); + console.error("角色创建失败:", error); + } finally { + setSubmitting(false); + } + }; + + const handleUpdateRole = async () => { + if (!editingRole) return; + try { + const values = await editRoleForm.validateFields(); + setSubmitting(true); + await updateRoleUsingPut(editingRole.id, { + roleName: values.roleName, + description: values.description, + enabled: values.enabled, + }); + message.success("角色更新成功"); + setEditingRole(null); + editRoleForm.resetFields(); + await loadData(); + } catch (error) { + if (error && typeof error === "object" && "errorFields" in error) { + return; + } + message.error("角色更新失败"); + console.error("角色更新失败:", error); + } finally { + setSubmitting(false); + } + }; + + const handleDeleteRole = async (roleId: string) => { + try { + await deleteRoleUsingDelete(roleId); + message.success("角色删除成功"); + await loadData(); + } catch (error) { + message.error("角色删除失败"); + console.error("角色删除失败:", error); + } + }; + + const openPermissionConfig = async (role: AuthRoleInfo) => { + setPermConfigRole(role); + setPermConfigLoading(true); + try { + const response = (await getRolePermissionsUsingGet(role.id)) as ApiResponse; + setSelectedPermissionIds(response?.data?.permissionIds ?? []); + } catch (error) { + message.error("加载角色权限失败"); + console.error("加载角色权限失败:", error); + setPermConfigRole(null); + } finally { + setPermConfigLoading(false); + } + }; + + const handleBindPermissions = async () => { + if (!permConfigRole) return; + setSubmitting(true); + try { + await bindRolePermissionsUsingPut(permConfigRole.id, selectedPermissionIds); + message.success("权限配置成功"); + setPermConfigRole(null); + setSelectedPermissionIds([]); + } catch (error) { + message.error("权限配置失败"); + console.error("权限配置失败:", error); + } finally { + setSubmitting(false); + } + }; + if (!canShowAnything) { return ; } @@ -266,7 +443,14 @@ export default function UserPermissionManagement({ /> {canViewRoles && ( - + setCreateRoleOpen(true)}> + 创建角色 + + } + > )} + + {/* 分配角色 Modal */} )} + + {/* 创建角色 Modal */} + { + void handleCreateRole(); + }} + onCancel={() => { + setCreateRoleOpen(false); + createRoleForm.resetFields(); + }} + destroyOnClose + > +
+ + + + + + + + + + +
+ + {/* 编辑角色 Modal */} + { + void handleUpdateRole(); + }} + onCancel={() => { + setEditingRole(null); + editRoleForm.resetFields(); + }} + destroyOnClose + > +
+ + + + + + + + + + + + + +
+ + {/* 权限配置 Modal */} + { + void handleBindPermissions(); + }} + onCancel={() => { + setPermConfigRole(null); + setSelectedPermissionIds([]); + }} + width={640} + destroyOnClose + > + {permConfigLoading ? ( + 加载中... + ) : permissions.length === 0 ? ( + 暂无可配置权限 + ) : ( +
+ setSelectedPermissionIds(values as string[])} + style={{ width: "100%" }} + > + {Array.from(permissionsByModule.entries()).map(([module, perms]) => ( +
+ + {module} + + + {perms.map((perm) => ( +
+ + {perm.permissionName} + + + ))} + + + ))} + + + )} + ); } - diff --git a/frontend/src/pages/SettingsPage/settings.apis.ts b/frontend/src/pages/SettingsPage/settings.apis.ts index 6eae86f..3832dfa 100644 --- a/frontend/src/pages/SettingsPage/settings.apis.ts +++ b/frontend/src/pages/SettingsPage/settings.apis.ts @@ -56,6 +56,7 @@ export interface AuthRoleInfo { roleName: string; description?: string; enabled?: boolean; + isBuiltIn?: boolean; } export interface AuthPermissionInfo { @@ -85,3 +86,38 @@ export function listAuthPermissionsUsingGet() { export function assignUserRolesUsingPut(userId: number, roleIds: string[]) { return put(`/api/auth/users/${userId}/roles`, { roleIds }); } + +export interface RoleWithPermissionsResponse { + role: AuthRoleInfo; + permissionIds: string[]; +} + +export function createRoleUsingPost(data: { + roleCode: string; + roleName: string; + description?: string; +}) { + return post("/api/auth/roles", data); +} + +export function updateRoleUsingPut( + roleId: string, + data: { roleName: string; description?: string; enabled?: boolean } +) { + return put(`/api/auth/roles/${roleId}`, data); +} + +export function deleteRoleUsingDelete(roleId: string) { + return del(`/api/auth/roles/${roleId}`); +} + +export function getRolePermissionsUsingGet(roleId: string) { + return get(`/api/auth/roles/${roleId}/permissions`); +} + +export function bindRolePermissionsUsingPut( + roleId: string, + permissionIds: string[] +) { + return put(`/api/auth/roles/${roleId}/permissions`, { permissionIds }); +}