From 1c5e6d03d95d3226d2ac58f6f92690649c269a76 Mon Sep 17 00:00:00 2001 From: fengsilin Date: Thu, 21 May 2026 09:23:06 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=A6=81=E6=AD=A2=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E7=94=A8=E6=88=B7=E4=BD=99=E9=A2=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 同步用户余额由主节点管理,从节点不应允许管理员修改其余额。 前端禁用额度输入和添加额度按钮,后端增加校验拦截。 --- controller/user.go | 4 ++++ i18n/keys.go | 1 + i18n/locales/en.yaml | 1 + i18n/locales/zh-CN.yaml | 1 + i18n/locales/zh-TW.yaml | 1 + web/src/components/table/users/modals/EditUserModal.jsx | 6 +++++- 6 files changed, 13 insertions(+), 1 deletion(-) diff --git a/controller/user.go b/controller/user.go index 98ca026..357b63b 100644 --- a/controller/user.go +++ b/controller/user.go @@ -562,6 +562,10 @@ func UpdateUser(c *gin.Context) { common.ApiError(c, err) return } + if originUser.IsSyncedUser() && originUser.Quota != updatedUser.Quota { + common.ApiErrorI18n(c, i18n.MsgSyncedUserQuotaCannotModify) + return + } myRole := c.GetInt("role") if myRole <= originUser.Role && myRole != common.RoleRootUser { common.ApiErrorI18n(c, i18n.MsgUserNoPermissionHigherLevel) diff --git a/i18n/keys.go b/i18n/keys.go index 13bcd57..187a451 100644 --- a/i18n/keys.go +++ b/i18n/keys.go @@ -78,6 +78,7 @@ const ( MsgUserNoPermissionHigherLevel = "user.no_permission_higher_level" MsgUserCannotCreateHigherLevel = "user.cannot_create_higher_level" MsgUserCannotDeleteRootUser = "user.cannot_delete_root_user" + MsgSyncedUserQuotaCannotModify = "user.synced_user_quota_cannot_modify" MsgUserCannotDisableRootUser = "user.cannot_disable_root_user" MsgUserCannotDemoteRootUser = "user.cannot_demote_root_user" MsgUserAlreadyAdmin = "user.already_admin" diff --git a/i18n/locales/en.yaml b/i18n/locales/en.yaml index fcb80ec..b9609f2 100644 --- a/i18n/locales/en.yaml +++ b/i18n/locales/en.yaml @@ -68,6 +68,7 @@ user.no_permission_same_level: "No permission to access users of same or higher user.no_permission_higher_level: "No permission to update users of same or higher permission level" user.cannot_create_higher_level: "Cannot create users with permission level equal to or higher than yourself" user.cannot_delete_root_user: "Cannot delete super administrator account" +user.synced_user_quota_cannot_modify: "Synced user quota is managed by the master node and cannot be modified" user.cannot_disable_root_user: "Cannot disable super administrator user" user.cannot_demote_root_user: "Cannot demote super administrator user" user.already_admin: "This user is already an administrator" diff --git a/i18n/locales/zh-CN.yaml b/i18n/locales/zh-CN.yaml index ec52e55..73711f0 100644 --- a/i18n/locales/zh-CN.yaml +++ b/i18n/locales/zh-CN.yaml @@ -69,6 +69,7 @@ user.no_permission_same_level: "无权获取同级或更高等级用户的信息 user.no_permission_higher_level: "无权更新同权限等级或更高权限等级的用户信息" user.cannot_create_higher_level: "无法创建权限大于等于自己的用户" user.cannot_delete_root_user: "不能删除超级管理员账户" +user.synced_user_quota_cannot_modify: "同步用户余额由主节点管理,不可修改" user.cannot_disable_root_user: "无法禁用超级管理员用户" user.cannot_demote_root_user: "无法降级超级管理员用户" user.already_admin: "该用户已经是管理员" diff --git a/i18n/locales/zh-TW.yaml b/i18n/locales/zh-TW.yaml index 75c5479..c83f2f5 100644 --- a/i18n/locales/zh-TW.yaml +++ b/i18n/locales/zh-TW.yaml @@ -69,6 +69,7 @@ user.no_permission_same_level: "無權獲取同級或更高等級使用者的資 user.no_permission_higher_level: "無權更新同權限等級或更高權限等級的使用者資訊" user.cannot_create_higher_level: "無法建立權限大於等於自己的使用者" user.cannot_delete_root_user: "不能刪除超級管理員帳號" +user.synced_user_quota_cannot_modify: "同步使用者餘額由主節點管理,不可修改" user.cannot_disable_root_user: "無法禁用超級管理員使用者" user.cannot_demote_root_user: "無法降級超級管理員使用者" user.already_admin: "該使用者已經是管理員" diff --git a/web/src/components/table/users/modals/EditUserModal.jsx b/web/src/components/table/users/modals/EditUserModal.jsx index ebd936e..9586470 100644 --- a/web/src/components/table/users/modals/EditUserModal.jsx +++ b/web/src/components/table/users/modals/EditUserModal.jsx @@ -72,6 +72,7 @@ const EditUserModal = (props) => { const [groupOptions, setGroupOptions] = useState([]); const [bindingModalVisible, setBindingModalVisible] = useState(false); const formApiRef = useRef(null); + const [isSyncedUser, setIsSyncedUser] = useState(false); const isEdit = Boolean(userId); @@ -110,6 +111,7 @@ const EditUserModal = (props) => { const { success, message, data } = res.data; if (success) { data.password = ''; + setIsSyncedUser(data.source === 'synced'); formApiRef.current?.setValues({ ...getInitValues(), ...data }); } else { showError(message); @@ -322,9 +324,10 @@ const EditUserModal = (props) => { label={t('剩余额度')} placeholder={t('请输入新的剩余额度')} step={500000} - extraText={renderQuotaWithPrompt(values.quota || 0)} + extraText={isSyncedUser ? t('同步用户余额由主节点管理,不可修改') : renderQuotaWithPrompt(values.quota || 0)} rules={[{ required: true, message: t('请输入额度') }]} style={{ width: '100%' }} + disabled={isSyncedUser} /> @@ -333,6 +336,7 @@ const EditUserModal = (props) => {