120 lines
7.4 KiB
JavaScript
120 lines
7.4 KiB
JavaScript
// 待办角标: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);
|
||
})();
|