diff --git a/client/shared/i18n/langs/en-US/translation.json b/client/shared/i18n/langs/en-US/translation.json index 9e5d491a..9d1514b1 100644 --- a/client/shared/i18n/langs/en-US/translation.json +++ b/client/shared/i18n/langs/en-US/translation.json @@ -28,6 +28,7 @@ "k206eff71": "Nickname can not be blank", "k21ee7a1f": "Roles", "k22856100": "Not found", + "k22ffe5e9": "Allow to manage users", "k23a3bd72": "Abnormal", "k2426e452": "Friend Service", "k2488f9ee": "Friend Request", @@ -272,6 +273,7 @@ "kdef84ee6": "Plugin", "kdf6e53ca": "Converse does not have permission", "ke0161a83": "Reset to default address", + "ke071c620": "Allow members to manage users, such as banning, removing users, etc.", "ke17b2c87": "Do not upload pictures that violate local laws and regulations", "ke187440d": "Panel type cannot be empty", "ke59ffe49": "Muted, there are {{remain}} left", diff --git a/client/shared/i18n/langs/zh-CN/translation.json b/client/shared/i18n/langs/zh-CN/translation.json index dc0e0176..e09bfc2a 100644 --- a/client/shared/i18n/langs/zh-CN/translation.json +++ b/client/shared/i18n/langs/zh-CN/translation.json @@ -28,6 +28,7 @@ "k206eff71": "昵称不能为空", "k21ee7a1f": "身份组", "k22856100": "未找到", + "k22ffe5e9": "允许管理用户", "k23a3bd72": "异常", "k2426e452": "好友服务", "k2488f9ee": "申请好友", @@ -272,6 +273,7 @@ "kdef84ee6": "插件", "kdf6e53ca": "会话没有权限", "ke0161a83": "重置为默认地址", + "ke071c620": "允许成员管理用户,如禁言、移除用户等操作", "ke17b2c87": "请勿上传违反当地法律法规的图片", "ke187440d": "面板类型不能为空", "ke59ffe49": "禁言中, 还剩 {{remain}}", diff --git a/client/shared/utils/role-helper.ts b/client/shared/utils/role-helper.ts index faa0a134..84129a81 100644 --- a/client/shared/utils/role-helper.ts +++ b/client/shared/utils/role-helper.ts @@ -39,6 +39,7 @@ export const PERMISSION = { invite: 'core.invite', unlimitedInvite: 'core.unlimitedInvite', groupDetail: 'core.groupDetail', + manageUser: 'core.manageUser', managePanel: 'core.managePanel', manageInvite: 'core.manageInvite', manageRoles: 'core.manageRoles', @@ -71,6 +72,13 @@ export const getPermissionList = (): PermissionItemType[] => [ desc: t('允许成员查看群组详情'), default: false, }, + { + key: PERMISSION.core.manageUser, + title: t('允许管理用户'), + desc: t('允许成员管理用户,如禁言、移除用户等操作'), + default: false, + required: [PERMISSION.core.groupDetail], + }, { key: PERMISSION.core.managePanel, title: t('允许管理频道'), diff --git a/client/web/src/components/Panel/group/MembersPanel.tsx b/client/web/src/components/Panel/group/MembersPanel.tsx index 8ce9366e..1c08e421 100644 --- a/client/web/src/components/Panel/group/MembersPanel.tsx +++ b/client/web/src/components/Panel/group/MembersPanel.tsx @@ -9,12 +9,13 @@ import { GroupMember, humanizeMsDuration, model, + PERMISSION, showToasts, t, useAsyncRequest, useCachedOnlineStatus, useGroupInfo, - useIsGroupOwner, + useHasGroupPermission, UserBaseInfo, useSearch, useUserInfoList, @@ -95,7 +96,9 @@ export const MembersPanel: React.FC = React.memo((props) => { const membersOnlineStatus = useCachedOnlineStatus( members.map((m) => m.userId) ); - const isGroupOwner = useIsGroupOwner(groupId); + const [allowManageUser] = useHasGroupPermission(groupId, [ + PERMISSION.core.manageUser, + ]); const { searchText, @@ -137,7 +140,7 @@ export const MembersPanel: React.FC = React.memo((props) => { const renderUser = (member: UserBaseInfo) => { const hasMute = getMembersHasMute(members, member._id); - if (isGroupOwner) { + if (allowManageUser) { const menu: MenuProps = { items: hasMute ? [ diff --git a/server/packages/sdk/src/services/lib/role.ts b/server/packages/sdk/src/services/lib/role.ts index dd5ad71b..2fbb8e44 100644 --- a/server/packages/sdk/src/services/lib/role.ts +++ b/server/packages/sdk/src/services/lib/role.ts @@ -8,6 +8,7 @@ export const PERMISSION = { invite: 'core.invite', unlimitedInvite: 'core.unlimitedInvite', groupDetail: 'core.groupDetail', + manageUser: 'core.manageUser', managePanel: 'core.managePanel', manageInvite: 'core.manageInvite', manageRoles: 'core.manageRoles', diff --git a/server/services/core/group/group.service.ts b/server/services/core/group/group.service.ts index 8fa175a8..fbfc74ea 100644 --- a/server/services/core/group/group.service.ts +++ b/server/services/core/group/group.service.ts @@ -954,8 +954,18 @@ class GroupService extends TcService { const { groupId, memberId, muteMs } = ctx.params; const userId = ctx.meta.userId; const language = ctx.meta.language; + const t = ctx.meta.t; const isUnmute = muteMs < 0; + const [hasPermission] = await call(ctx).checkUserPermissions( + groupId, + userId, + [PERMISSION.core.manageUser] + ); + if (!hasPermission) { + throw new NoPermissionError(t('没有操作权限')); + } + const group = await this.adapter.model.updateGroupMemberField( groupId, memberId,