From 71566bea56481c5f2f60dfa834964ae034dd0cd8 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Tue, 25 Aug 2026 14:59:09 +0800 Subject: [PATCH] =?UTF-8?q?refactor(todo=5Fbadge):=20=E5=BE=85=E5=8A=9E?= =?UTF-8?q?=E5=88=97=E8=A1=A8/=E8=AF=A6=E6=83=85=E6=94=B9=E7=94=B1=20dspy?= =?UTF-8?q?=20=E8=BF=94=E5=9B=9E=20bricks=20widget=20=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=EF=BC=8CJS=20=E5=8F=AA=E8=B4=9F=E8=B4=A3=E8=A7=92=E6=A0=87?= =?UTF-8?q?=E4=B8=8E=E6=89=93=E5=BC=80=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wwwroot/todo_badge.js | 101 +++++++----------------------------------- 1 file changed, 17 insertions(+), 84 deletions(-) diff --git a/wwwroot/todo_badge.js b/wwwroot/todo_badge.js index 8f52c8a..8f9918f 100644 --- a/wwwroot/todo_badge.js +++ b/wwwroot/todo_badge.js @@ -1,5 +1,8 @@ // 待办角标:1 分钟定时刷新 + 点击打开待办列表 // 由 HTML shell 自动加载(configuredServer.get_js_files 收集 wwwroot 下 .js,在 bricks.js 之后引入) +// 列表与详情的界面全部由后端 dspy 返回 bricks widget 描述渲染: +// /pipeline-sdlc/api/my_todos_popup.dspy → 待办列表弹窗 +// /pipeline-sdlc/api/todo_detail.dspy → 待办详情(正文 MdWidget + VScrollPanel 滚动 + 操作按钮) (function(){ if (typeof bricks === 'undefined') return; @@ -16,93 +19,23 @@ }; window.openMyTodos = function(){ - var pw = new bricks.PopupWindow({title:'我的待办', width:'72%', height:'80%', auto_open:true}); - var vs = new bricks.VScrollPanel({css:'filler', padding:'12px', gap:'8px'}); - pw.content_w.add_widget(vs); - fetch('/pipeline-sdlc/api/my_todos.dspy') + // 已打开则先关掉,避免叠加多个列表弹窗 + var old = bricks.getWidgetById && bricks.getWidgetById('my_todos_pw', bricks.app); + if (old && old.destroy) { old.destroy(); } + return fetch('/pipeline-sdlc/api/my_todos_popup.dspy') .then(function(r){ return r.json(); }) - .then(function(d){ - var todos = (d && d.todos) || []; - if (todos.length === 0) { - vs.add_widget(new bricks.Text({text:'暂无待办', cfontsize:0.9, color:'#94a3b8'})); + .then(function(desc){ + if (!desc) { return; } + if (desc.error || desc.success === false) { + var m = new bricks.Message({title:'打开失败', message: desc.error || '无法加载待办'}); + m.open(); return; } - todos.forEach(function(t){ - var src = t.source || ''; - var title = src === 'question' ? (t.question || '') : (t.title || ''); - var label = src === 'question' ? '问题' : (t.task_type === 'bug_acceptance' ? 'Bug验收' : (t.task_type === 'requirement_confirmation' ? '需求确认' : (t.task_type === 'design_confirmation' ? '设计确认' : '人类任务'))); - var card = new bricks.VBox({bgcolor:'#fff', border:'1px solid #e2e8f0', borderRadius:'8px', padding:'10px 14px', gap:'6px', marginBottom:'4px'}); - var hdr = new bricks.HBox({alignItems:'center', gap:'8px'}); - hdr.add_widget(new bricks.Text({text:label, cfontsize:0.7, color:'#ffffff', padding:'1px 8px', style:{background: src==='question' ? '#8b5cf6' : (t.task_type==='bug_acceptance' ? '#f0a040' : '#2563eb'), borderRadius:'10px', fontWeight:'bold'}})); - hdr.add_widget(new bricks.Text({text:title, cfontsize:0.9, color:'#1e293b', fontWeight:'bold'})); - card.add_widget(hdr); - if (t.project_name) { - card.add_widget(new bricks.Text({text:'项目:' + t.project_name, cfontsize:0.7, color:'#94a3b8'})); - } - if (src === 'human_task' && t.task_type === 'bug_acceptance') { - var hb = new bricks.HBox({gap:'6px'}); - var okb = new bricks.Button({label:'通过', css:'small'}); - okb.bind('click', function(){ - fetch('/pipeline-sdlc/api/bug_accept.dspy', {method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body:'bug_id='+encodeURIComponent(t.bug_id)+'&accept=1'}) - .then(function(r){ return r.json(); }) - .then(function(d){ - alert(d.success ? '验收通过,Bug已关闭' : (d.error || '失败')); - if (d.success) { pw.destroy(); refreshTodo(); } - }); - }); - var nob = new bricks.Button({label:'不通过', css:'small'}); - nob.bind('click', function(){ - fetch('/pipeline-sdlc/api/bug_accept.dspy', {method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body:'bug_id='+encodeURIComponent(t.bug_id)+'&accept=0'}) - .then(function(r){ return r.json(); }) - .then(function(d){ - alert(d.success ? '验收不通过,Bug已重新打开' : (d.error || '失败')); - if (d.success) { pw.destroy(); refreshTodo(); } - }); - }); - hb.add_widget(okb); - hb.add_widget(nob); - card.add_widget(hb); - } else if (src === 'human_task' && (t.task_type === 'requirement_confirmation' || t.task_type === 'design_confirmation')) { - var cb = new bricks.HBox({gap:'6px'}); - var okb2 = new bricks.Button({label:'确认通过', css:'small'}); - okb2.bind('click', function(){ - fetch('/pipeline-sdlc/api/stage_confirm.dspy', {method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body:'human_task_id='+encodeURIComponent(t.id)+'&confirmed=1'}) - .then(function(r){ return r.json(); }) - .then(function(d){ - alert(d.success ? (d.message || '已确认,继续后续任务') : (d.error || '失败')); - if (d.success) { pw.destroy(); refreshTodo(); } - }); - }); - var rb2 = new bricks.Button({label:'不确定,退回重做', css:'small'}); - rb2.bind('click', function(){ - var v = prompt('请填写修改意见(将退回重做):', ''); - if (v === null) return; - fetch('/pipeline-sdlc/api/stage_confirm.dspy', {method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body:'human_task_id='+encodeURIComponent(t.id)+'&confirmed=0&comment='+encodeURIComponent(v)}) - .then(function(r){ return r.json(); }) - .then(function(d){ - alert(d.success ? (d.message || '已退回重做') : (d.error || '失败')); - if (d.success) { pw.destroy(); refreshTodo(); } - }); - }); - cb.add_widget(okb2); - cb.add_widget(rb2); - card.add_widget(cb); - } else if (src === 'human_task') { - var db = new bricks.Button({label:'处理', css:'small'}); - db.bind('click', function(){ - var v = prompt('请输入处理结果:', ''); - if (v === null) return; - fetch('/pipeline-sdlc/api/human_task_complete.dspy', {method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'}, body:'human_task_id='+encodeURIComponent(t.id)+'&result_data='+encodeURIComponent(JSON.stringify({content:v}))}) - .then(function(r){ return r.json(); }) - .then(function(d){ - alert(d.success ? '已提交,等待QC检查' : (d.error || '失败')); - if (d.success) { pw.destroy(); refreshTodo(); } - }); - }); - card.add_widget(db); - } - vs.add_widget(card); - }); + return bricks.widgetBuild(desc, bricks.app); + }) + .catch(function(e){ + var m2 = new bricks.Message({title:'打开失败', message:'网络错误:' + e}); + m2.open(); }); };