// 待办角标:1 分钟定时刷新 + 点击打开待办列表 // 由 HTML shell 自动加载(configuredServer.get_js_files 收集 wwwroot 下 .js,在 bricks.js 之后引入) (function(){ if (typeof bricks === 'undefined') return; window.refreshTodo = function(){ fetch('/pipeline-sdlc/api/project_human_count.dspy') .then(function(r){ return r.json(); }) .then(function(d){ var n = (d && d.count) || 0; var b = bricks.getWidgetById && bricks.getWidgetById('todo_badge', bricks.app); if (b && b.text_w) { b.text_w.set_text(n > 0 ? ('🔔 待办 ' + n) : '🔔 待办'); } }); }; 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') .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'})); 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); }); }); }; // 等 app 初始化完成后启动定时刷新(.js 在 app.run 之前加载,故轮询等 app 就绪) function _start(){ if (bricks.app && bricks.getWidgetById){ setInterval(function(){ window.refreshTodo(); }, 60000); setTimeout(function(){ window.refreshTodo(); }, 800); } else { setTimeout(_start, 300); } } setTimeout(_start, 300); })();