fix(users): replace script handlers with declarative urlwidget binds

- reset_password: urlwidget + PopupWindow Form (same pattern as userrole),
  hidden userid field from params_kw, password fields with required validation
- clear_login_fail: urlwidget + conform dialog, params_mapping id only
- fixes runtime crash: script bind called bricks.getWidgetById('users_tbl')
  without from_widget context -> TypeError on dom_element
- register /rbac/admin_reset_password.ui in PATHS_ADMIN (admin role only)
- i18n entries for 4 languages
This commit is contained in:
yumoqing 2026-09-09 18:38:36 +08:00
parent 5712f4091e
commit c572d4c254
7 changed files with 114 additions and 30 deletions

View File

@ -131,3 +131,7 @@ Cancel: Cancel
只读用户: Read-Only User
访问控制: Access Control
最后登录: Last Login
清除登录次数: Clear Login Fail Count
新密码: New Password
确认清除该用户的连续登录失败次数?: Clear the consecutive login failure count of this user?
为选中用户设置新密码至少8位: Set a new password (at least 8 characters) for the selected user

View File

@ -131,3 +131,7 @@ Cancel: キャンセル
只读用户: 読み取り専用ユーザー
访问控制: アクセス制御
最后登录: 最終ログイン
清除登录次数: ログイン失敗回数をクリア
新密码: 新しいパスワード
确认清除该用户的连续登录失败次数?: このユーザーの連続ログイン失敗回数をクリアしますか?
为选中用户设置新密码至少8位: 選択したユーザーに新しいパスワード8文字以上を設定

View File

@ -131,3 +131,7 @@ Cancel: 취소
只读用户: 읽기 전용 사용자
访问控制: 접근 제어
最后登录: 마지막 로그인
清除登录次数: 로그인 실패 횟수 초기화
新密码: 새 비밀번호
确认清除该用户的连续登录失败次数?: 이 사용자의 연속 로그인 실패 횟수를 초기화하시겠습니까?
为选中用户设置新密码至少8位: 선택한 사용자에게 새 비밀번호(8자 이상) 설정

View File

@ -137,3 +137,7 @@ you are not owner user: you are not owner user
需输入验证码: 需输入验证码
验证失败: 验证失败
验证码: 验证码
清除登录次数: 清除登录次数
新密码: 新密码
确认清除该用户的连续登录失败次数?: 确认清除该用户的连续登录失败次数?
为选中用户设置新密码至少8位: 为选中用户设置新密码至少8位

View File

@ -52,36 +52,60 @@
}
}
],
"binds": [
{
"wid": "self",
"event": "enable_user",
"actiontype": "script",
"target": "self",
"script": "var tid=bricks.getWidgetById('users_tbl');var d=tid.select_row.user_data;fetch('/rbac/users/enable_user.dspy?id='+d.id,{method:'POST'}).then(function(r){return r.json()}).then(function(r){if(r.widgettype==='Message'){tid.render({})}else{bricks.show_error(r.options)}})"
},
{
"wid": "self",
"event": "disable_user",
"actiontype": "script",
"target": "self",
"script": "var tid=bricks.getWidgetById('users_tbl');var d=tid.select_row.user_data;fetch('/rbac/users/disable_user.dspy?id='+d.id,{method:'POST'}).then(function(r){return r.json()}).then(function(r){if(r.widgettype==='Message'){tid.render({})}else{bricks.show_error(r.options)}})"
},
{
"wid": "self",
"event": "reset_password",
"actiontype": "script",
"target": "self",
"script": "var tid=bricks.getWidgetById('users_tbl');var d=tid.select_row.user_data;var np=prompt('为用户 '+d.username+' 设置新密码至少8位:');if(!np){return}var cp=prompt('再次输入以确认:');if(!cp){return}fetch('/rbac/api/admin_reset_password.dspy',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({userid:d.id,new_password:np,cfm_password:cp})}).then(function(r){return r.json()}).then(function(r){if(r.widgettype==='Message'){bricks.show_message(r.options);tid.render({})}else{bricks.show_error(r.options)}})"
},
{
"wid": "self",
"event": "clear_login_fail",
"actiontype": "script",
"target": "self",
"script": "var tid=bricks.getWidgetById('users_tbl');var d=tid.select_row.user_data;fetch('/rbac/api/clear_login_fail.dspy?id='+d.id,{method:'POST'}).then(function(r){return r.json()}).then(function(r){if(r.widgettype==='Message'){bricks.show_message(r.options);tid.render({})}else{bricks.show_error(r.options)}})"
}
],
"binds": [
{
"wid": "self",
"event": "enable_user",
"actiontype": "script",
"target": "self",
"script": "var tid=bricks.getWidgetById('users_tbl');var d=tid.select_row.user_data;fetch('/rbac/users/enable_user.dspy?id='+d.id,{method:'POST'}).then(function(r){return r.json()}).then(function(r){if(r.widgettype==='Message'){tid.render({})}else{bricks.show_error(r.options)}})"
},
{
"wid": "self",
"event": "disable_user",
"actiontype": "script",
"target": "self",
"script": "var tid=bricks.getWidgetById('users_tbl');var d=tid.select_row.user_data;fetch('/rbac/users/disable_user.dspy?id='+d.id,{method:'POST'}).then(function(r){return r.json()}).then(function(r){if(r.widgettype==='Message'){tid.render({})}else{bricks.show_error(r.options)}})"
},
{
"wid": "self",
"event": "reset_password",
"actiontype": "urlwidget",
"target": "PopupWindow",
"popup_options": {
"title": "重置密码",
"resizable": true,
"height": "60%",
"width": "40%"
},
"options": {
"method": "POST",
"params": {},
"url": "{{entire_url('/rbac/admin_reset_password.ui')}}"
}
},
{
"wid": "self",
"event": "clear_login_fail",
"actiontype": "urlwidget",
"target": "self",
"conform": {
"title": "清除登录次数",
"message": "确认清除该用户的连续登录失败次数?"
},
"options": {
"method": "POST",
"params": {},
"url": "{{entire_url('/rbac/api/clear_login_fail.dspy')}}"
},
"params_mapping": {
"mapping": {
"id": "id"
},
"need_others": false
}
}
],
"subtables": [
{
"field":"userid",

View File

@ -83,6 +83,7 @@ PATHS_LOGINED = [
# 管理员对他人的敏感操作端点,绝不进 PATHS_LOGINED否则任何登录用户可重置他人密码
# 与存量 /rbac/users/*.dspyenable/disable/update的 *.admin 授权口径一致。
PATHS_ADMIN = [
f"/{MOD}/admin_reset_password.ui",
f"/{MOD}/api/admin_reset_password.dspy",
f"/{MOD}/api/clear_login_fail.dspy",
]

View File

@ -0,0 +1,43 @@
{
"widgettype": "Form",
"options": {
"title": "重置密码",
"description": "为选中用户设置新密码至少8位",
"fields": [
{
"name": "userid",
"uitype": "hide",
"value": "{{params_kw.get('id','')}}"
},
{
"name": "new_password",
"type": "str",
"length": 255,
"uitype": "password",
"datatype": "str",
"required": true,
"label": "新密码"
},
{
"name": "cfm_password",
"type": "str",
"length": 255,
"uitype": "password",
"datatype": "str",
"required": true,
"label": "确认密码"
}
]
},
"binds": [
{
"wid": "self",
"event": "submit",
"actiontype": "urlwidget",
"target": "self",
"options": {
"url": "{{entire_url('api/admin_reset_password.dspy')}}"
}
}
]
}