refactor: rewrite SMS login UI using pure bricks patterns

- login.ui: use actiontype:urlwidget for Form submit → code_login.dspy
- Removed custom JavaScript (phone_login.js)
- Send code button: minimal script action to fetch and set form value
- Login flow: bricks returns Message/Error/VBox widgets directly
- Multi-account selection: code_login.dspy returns VBox with Buttons
This commit is contained in:
yumoqing 2026-05-29 11:58:30 +08:00
parent 8528eebf10
commit 342fc6652a
2 changed files with 32 additions and 140 deletions

View File

@ -1,53 +0,0 @@
/* Sage Phone Login - Multi-account Selection Handler
Called when user selects an account from the multi-account list
*/
window.sageSelectAccount = async function(selectedId) {
var form = bricks.getWidgetById('phone_form', bricks.app);
if (!form) return;
var vals = form._getValue();
var btn = bricks.getWidgetById('phone_login_btn', bricks.app);
if (btn) { btn.disabled = true; if (btn.text_w) btn.text_w.set_otext('登录中...'); }
var body = 'cellphone=' + encodeURIComponent(vals.cell_no)
+ '&key=' + encodeURIComponent(vals.codeid)
+ '&sms_code=' + encodeURIComponent(vals.check_code)
+ '&selected_id=' + encodeURIComponent(selectedId);
// Get phone_login URL from the page context
var baseUrl = bricks.app.baseUrl || '';
var loginUrl = baseUrl + '/rbac/phone_login.dspy?_webbricks_=1';
try {
var resp = await fetch(loginUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: body
});
var d = await resp.json();
if (btn) { btn.disabled = false; if (btn.text_w) btn.text_w.set_otext('登录'); }
if (d.status === 'ok') {
var u = d.data.user;
var nick = u.nick_name || u.username;
var msgW = {
widgettype: 'Message',
options: { timeout: 3, auto_open: true, title: '登录成功', message: nick + ' 欢迎' },
binds: [
{ wid: 'self', event: 'dismissed', actiontype: 'script', target: 'self',
script: 'if(bricks.app&&bricks.app.dispatch)bricks.app.dispatch("user_logined")' },
{ wid: 'self', event: 'dismissed', actiontype: 'script', target: 'body.login_window',
script: 'this.destroy()' }
]
};
var w = await bricks.widgetBuild(msgW, bricks.app);
if (w) bricks.app.add_widget(w);
} else {
alert(d.data.message || '登录失败');
}
} catch (e) {
if (btn) { btn.disabled = false; if (btn.text_w) btn.text_w.set_otext('登录'); }
alert('网络错误: ' + e);
}
};

View File

@ -1,5 +1,5 @@
{% set sms_code_url = entire_url('/rbac/gen_sms_code.dspy') %}
{% set phone_login_url = entire_url('/rbac/phone_login.dspy') %}
{% set code_login_url = entire_url('/rbac/user/code_login.dspy') %}
{
"id": "login_window",
"widgettype": "PopupWindow",
@ -28,16 +28,8 @@
"options": {
"cols": 1,
"fields": [
{
"name": "username",
"label": "用户名",
"uitype": "str"
},
{
"name": "password",
"label": "密码",
"uitype": "password"
}
{"name": "username", "label": "用户名", "uitype": "str"},
{"name": "password", "label": "密码", "uitype": "password"}
]
},
"binds": [
@ -59,10 +51,6 @@
"label": "手机验证码",
"content": {
"widgettype": "VBox",
"options": {
"padding": "8px",
"gap": "8px"
},
"subwidgets": [
{
"widgettype": "Form",
@ -71,62 +59,35 @@
"description": "限中国国内手机号",
"cols": 1,
"fields": [
{
"name": "cell_no",
"label": "手机号",
"uitype": "str"
},
{
"name": "codeid",
"uitype": "hide",
"value": ""
},
{
"name": "check_code",
"label": "验证码",
"uitype": "str"
}
{"name": "cell_no", "label": "手机号", "uitype": "str"},
{"name": "codeid", "uitype": "hide", "value": ""},
{"name": "check_code", "label": "验证码", "uitype": "str"}
]
}
},
"binds": [
{
"wid": "self",
"event": "submit",
"actiontype": "urlwidget",
"target": "self",
"options": {
"method": "POST",
"url": "{{code_login_url}}"
}
}
]
},
{
"widgettype": "HBox",
"options": {
"gap": "8px"
},
"subwidgets": [
"widgettype": "Button",
"id": "gen_code_btn",
"options": {"label": "发送验证码"},
"binds": [
{
"widgettype": "Button",
"id": "gen_code_btn",
"options": {
"label": "发送验证码"
},
"binds": [
{
"wid": "self",
"event": "click",
"actiontype": "script",
"target": "self",
"script": "var form=bricks.getWidgetById('phone_form',bricks.app);if(!form){alert('form not found');return;}var vals=form._getValue();var cell=vals.cell_no;if(!cell||cell.length<11){alert('请输入正确的手机号');return;}var btn=bricks.getWidgetById('gen_code_btn',bricks.app);btn.disabled=true;if(btn.text_w)btn.text_w.set_otext('发送中...');fetch('{{sms_code_url}}?_webbricks_=1&cellphone='+encodeURIComponent(cell)).then(function(r){return r.json()}).then(function(d){if(d.status==='ok'){form.setValue({codeid:d.data.key});if(btn.text_w)btn.text_w.set_otext('已发送');var sec=60;var tmr=setInterval(function(){sec--;if(sec<=0){clearInterval(tmr);btn.disabled=false;if(btn.text_w)btn.text_w.set_otext('重新发送')}else{if(btn.text_w)btn.text_w.set_otext(sec+'s')}},1000)}else{alert(d.data.message||'发送验证码出错');btn.disabled=false;if(btn.text_w)btn.text_w.set_otext('发送验证码')}}).catch(function(e){alert('网络错误: '+e);btn.disabled=false;if(btn.text_w)btn.text_w.set_otext('发送验证码')})"
}
]
},
{
"widgettype": "Button",
"id": "phone_login_btn",
"options": {
"label": "登录",
"css": "sage-btn-primary"
},
"binds": [
{
"wid": "self",
"event": "click",
"actiontype": "script",
"target": "self",
"script": "var form=bricks.getWidgetById('phone_form',bricks.app);if(!form)return;var vals=form._getValue();if(!vals.cell_no){alert('请输入手机号');return;}if(!vals.check_code){alert('请输入验证码');return;}if(!vals.codeid){alert('请先发送验证码');return;}var btn=bricks.getWidgetById('phone_login_btn',bricks.app);btn.disabled=true;if(btn.text_w)btn.text_w.set_otext('登录中...');var body='cellphone='+encodeURIComponent(vals.cell_no)+'&key='+encodeURIComponent(vals.codeid)+'&sms_code='+encodeURIComponent(vals.check_code);fetch('{{phone_login_url}}?_webbricks_=1',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:body}).then(function(r){return r.json()}).then(function(d){btn.disabled=false;if(btn.text_w)btn.text_w.set_otext('登录');if(d.status==='ok'){var u=d.data.user;var nick=u.nick_name||u.username;var msgW={widgettype:'Message',options:{timeout:3,auto_open:true,title:'登录成功',message:nick+' 欢迎'},binds:[{wid:'self',event:'dismissed',actiontype:'script',target:'self',script:'if(bricks.app&&bricks.app.dispatch)bricks.app.dispatch(\"user_logined\")'},{wid:'self',event:'dismissed',actiontype:'script',target:'body.login_window',script:'this.destroy()'}]};bricks.widgetBuild(msgW,bricks.app).then(function(w){if(w)bricks.app.add_widget(w)})}else if(d.status==='choose'){var users=d.data.users;var html='<div style=\"padding:12px\"><p style=\"margin:0 0 12px\">该手机号关联多个账号,请选择:</p>';for(var i=0;i<users.length;i++){html+='<button onclick=\"sageSelectAccount(\\x27'+users[i].id+'\\x27)\" style=\"display:block;width:100%;padding:10px;margin:4px 0;cursor:pointer;border:1px solid #ccc;border-radius:4px;background:#f5f5f5;text-align:left;font-size:14px\">'+users[i].username+'</button>'}html+='</div>';var cw=bricks.getWidgetById('choose_container',bricks.app);if(cw){cw.dom_element.innerHTML=html;cw.dom_element.style.display=''}else{var div=document.createElement('div');div.id='choose_container';div.innerHTML=html;form.dom_element.parentElement.appendChild(div)}form.dom_element.style.display='none'}else{alert(d.data.message||'登录失败')}}).catch(function(e){btn.disabled=false;if(btn.text_w)btn.text_w.set_otext('登录');alert('网络错误: '+e)})"
}
]
"wid": "self",
"event": "click",
"actiontype": "script",
"target": "self",
"script": "var form=bricks.getWidgetById('phone_form',bricks.app);if(!form)return;var cell=form._getValue().cell_no;if(!cell||cell.length<11){alert('请输入正确的手机号');return;}var btn=this;btn.disabled=true;btn.text_w&&btn.text_w.set_otext('发送中...');fetch('{{sms_code_url}}?_webbricks_=1&cellphone='+encodeURIComponent(cell)).then(function(r){return r.json()}).then(function(d){if(d.status==='ok'){form.setValue({codeid:d.data.key});btn.text_w&&btn.text_w.set_otext('已发送');var s=60;var t=setInterval(function(){s--;if(s<=0){clearInterval(t);btn.disabled=false;btn.text_w&&btn.text_w.set_otext('重新发送')}else btn.text_w&&btn.text_w.set_otext(s+'s')},1000)}else{alert(d.data.message||'发送验证码出错');btn.disabled=false;btn.text_w&&btn.text_w.set_otext('发送验证码')}}).catch(function(e){alert('网络错误: '+e);btn.disabled=false;btn.text_w&&btn.text_w.set_otext('发送验证码')})"
}
]
}
@ -141,26 +102,10 @@
"options": {
"cols": 1,
"fields": [
{
"name": "username",
"label": "用户名",
"uitype": "str"
},
{
"name": "mobile",
"label": "手机号",
"uitype": "str"
},
{
"name": "password",
"label": "密码",
"uitype": "password"
},
{
"name": "cfm_password",
"label": "确认密码",
"uitype": "password"
}
{"name": "username", "label": "用户名", "uitype": "str"},
{"name": "mobile", "label": "手机号", "uitype": "str"},
{"name": "password", "label": "密码", "uitype": "password"},
{"name": "cfm_password", "label": "确认密码", "uitype": "password"}
]
},
"binds": [