From 342fc6652acce28a40dcbab9a490ba5667193565 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Fri, 29 May 2026 11:58:30 +0800 Subject: [PATCH] refactor: rewrite SMS login UI using pure bricks patterns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- wwwroot/phone_login.js | 53 ------------------ wwwroot/user/login.ui | 119 +++++++++++------------------------------ 2 files changed, 32 insertions(+), 140 deletions(-) delete mode 100644 wwwroot/phone_login.js diff --git a/wwwroot/phone_login.js b/wwwroot/phone_login.js deleted file mode 100644 index 103d70d..0000000 --- a/wwwroot/phone_login.js +++ /dev/null @@ -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); - } -}; diff --git a/wwwroot/user/login.ui b/wwwroot/user/login.ui index 005c518..8bd54b6 100644 --- a/wwwroot/user/login.ui +++ b/wwwroot/user/login.ui @@ -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='

该手机号关联多个账号,请选择:

';for(var i=0;i'+users[i].username+''}html+='
';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": [