job_detail.html
4.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
{% extends "base.html" %}
{% block title %}任务详情 - WeChat Viewer{% endblock %}
{% block body %}
<style>
body{overflow-y:auto!important;height:auto!important;}
.detail-container{max-width:960px;margin:0 auto;padding:20px;}
.detail-header{display:flex;align-items:center;gap:12px;margin-bottom:16px;}
.detail-header a{color:#3498db;text-decoration:none;font-size:14px;}
.detail-header h1{font-size:20px;color:#2c3e50;margin:0;}
.meta-card{background:white;border-radius:8px;padding:14px 18px;margin-bottom:16px;box-shadow:0 1px 2px rgba(0,0,0,0.05);display:flex;gap:24px;flex-wrap:wrap;font-size:13px;}
.meta-card .item{display:flex;flex-direction:column;gap:2px;}
.meta-card .label{color:#999;font-size:11px;}
.meta-card .value{color:#333;font-weight:600;}
.badge{display:inline-block;padding:2px 10px;border-radius:10px;font-size:11px;font-weight:600;}
.badge.running{background:#d4edda;color:#155724;}
.badge.completed{background:#d6eaf8;color:#1a5276;}
.badge.failed{background:#fadbd8;color:#922b21;}
.actions{display:flex;gap:8px;margin-bottom:16px;}
.actions button{padding:6px 14px;border:none;border-radius:6px;cursor:pointer;font-size:13px;}
.btn-refresh{background:#3498db;color:white;}
.btn-auto{background:#27ae60;color:white;}
.btn-auto.off{background:#95a5a6;}
.btn-delete{background:#e74c3c;color:white;}
.log-box{background:#1e1e1e;border-radius:8px;padding:16px;font-family:Menlo,Consolas,monospace;font-size:12px;line-height:1.6;color:#d4d4d4;max-height:70vh;overflow-y:auto;white-space:pre-wrap;word-break:break-all;}
</style>
<div class="detail-container">
<div class="detail-header">
<a href="/jobs">← 返回任务列表</a>
<h1 id="title">加载中...</h1>
</div>
<div class="meta-card">
<div class="item"><span class="label">任务ID</span><span class="value" id="mId">-</span></div>
<div class="item"><span class="label">类型</span><span class="value" id="mType">-</span></div>
<div class="item"><span class="label">状态</span><span class="value"><span class="badge" id="mStatus">-</span></span></div>
<div class="item"><span class="label">开始</span><span class="value" id="mStart">-</span></div>
<div class="item"><span class="label">完成</span><span class="value" id="mEnd">-</span></div>
</div>
<div class="actions">
<button class="btn-refresh" onclick="loadLog()">🔄 刷新</button>
<button class="btn-auto" id="btnAuto" onclick="toggleAuto()">▶ 自动刷新</button>
<button class="btn-delete" onclick="del()">🗑 删除</button>
</div>
<div class="log-box" id="log">加载中...</div>
</div>
<script>
var TID = "{{ task_id }}";
var TYPES = {daily_report:"日报生成",report_image:"日报图片",article_summary:"文章摘要",article_learn:"文章学习",article_image:"文章图片"};
var STATS = {running:"运行中",completed:"已完成",failed:"失败"};
var timer = null;
function esc(s){return String(s).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");}
function loadMeta(){
fetch("/api/job/"+TID).then(function(r){return r.json()}).then(function(j){
if(!j.ok)return;
var t=j.data;
document.getElementById("title").textContent=t.job_name||"未命名";
document.getElementById("mId").textContent=t.task_id;
document.getElementById("mType").textContent=TYPES[t.job_type]||t.job_type;
document.getElementById("mStatus").textContent=STATS[t.status]||t.status;
document.getElementById("mStatus").className="badge "+t.status;
document.getElementById("mStart").textContent=t.started_at||"-";
document.getElementById("mEnd").textContent=t.completed_at||(t.status=="running"?"进行中...":"-");
});
}
function loadLog(){
fetch("/api/job/"+TID+"/log").then(function(r){return r.json()}).then(function(j){
var el=document.getElementById("log");
if(!j.ok){el.textContent="加载失败: "+(j.error||"未知");return;}
var d=j.data;
el.textContent=d.content||"(暂无输出)";
el.scrollTop=el.scrollHeight;
if(d.status=="completed"||d.status=="failed"){
if(timer){clearInterval(timer);timer=null;document.getElementById("btnAuto").className="btn-auto off";document.getElementById("btnAuto").textContent="▶ 自动刷新";}
}
}).catch(function(e){document.getElementById("log").textContent="加载失败: "+e.message;});
}
function toggleAuto(){
if(timer){clearInterval(timer);timer=null;document.getElementById("btnAuto").className="btn-auto off";document.getElementById("btnAuto").textContent="▶ 自动刷新";}
else{timer=setInterval(loadLog,2000);document.getElementById("btnAuto").className="btn-auto";document.getElementById("btnAuto").textContent="⏸ 停止刷新";loadLog();}
}
function del(){
if(!confirm("确定删除?"))return;
fetch("/api/job/"+TID+"/delete",{method:"POST"}).then(function(r){return r.json()}).then(function(j){
if(j.ok)location.href="/jobs";else alert("失败: "+(j.error||""));
});
}
loadMeta();
loadLog();
</script>
{% endblock %}