mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-07-07 02:22:48 +08:00
feat(timer): 新增定时器配置、日志和主机的后台管理界面
T10: TimerConfig CURD - task management with run_type/status editing,
manual trigger button, task_name read-only, no add/delete
T11: TimerLog CURD - read-only log viewer with filters and color badges
T12: Host list enhanced - is_master column, setMaster button
This commit is contained in:
11
app/admin/view/system/timer_log/_common.js
Normal file
11
app/admin/view/system/timer_log/_common.js
Normal file
@@ -0,0 +1,11 @@
|
||||
var init = {
|
||||
tableElem: '#currentTable',
|
||||
tableRenderId: 'currentTableRenderId',
|
||||
indexUrl: 'system.timer_log/index',
|
||||
addUrl: '',
|
||||
editUrl: '',
|
||||
readUrl: 'system.timer_log/read',
|
||||
deleteUrl: '',
|
||||
exportUrl: '',
|
||||
modifyUrl: '',
|
||||
};
|
||||
9
app/admin/view/system/timer_log/index.html
Normal file
9
app/admin/view/system/timer_log/index.html
Normal file
@@ -0,0 +1,9 @@
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<table id="currentTable" class="layui-table layui-hide"
|
||||
data-auth-index="{:auth('system.timer_log/index')}"
|
||||
data-auth-read="{:auth('system.timer_log/read')}"
|
||||
lay-filter="currentTable">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
99
app/admin/view/system/timer_log/index.js
Normal file
99
app/admin/view/system/timer_log/index.js
Normal file
@@ -0,0 +1,99 @@
|
||||
$(function(){
|
||||
// 状态徽章模板
|
||||
var statusTemplet = function(d) {
|
||||
var statusMap = {
|
||||
'success': {text: '成功', color: '#5FB878', bgColor: '#e8f8ef'},
|
||||
'error': {text: '失败', color: '#FF5722', bgColor: '#ffe8e2'},
|
||||
'running': {text: '运行中', color: '#1E9FFF', bgColor: '#e2f1ff'},
|
||||
};
|
||||
var item = statusMap[d.status] || {text: d.status, color: '#999', bgColor: '#f5f5f5'};
|
||||
return '<span style="display:inline-block;padding:2px 10px;border-radius:3px;color:'+item.color+';background:'+item.bgColor+';font-size:12px;">'+item.text+'</span>';
|
||||
};
|
||||
|
||||
// 时间格式化模板
|
||||
var timeTemplet = function(d) {
|
||||
if (!d.start_time || d.start_time === 0) return '<span style="color:#999">-</span>';
|
||||
var date = new Date(d.start_time * 1000);
|
||||
var Y = date.getFullYear();
|
||||
var M = (date.getMonth()+1).toString().padStart(2,'0');
|
||||
var D = date.getDate().toString().padStart(2,'0');
|
||||
var h = date.getHours().toString().padStart(2,'0');
|
||||
var m = date.getMinutes().toString().padStart(2,'0');
|
||||
var s = date.getSeconds().toString().padStart(2,'0');
|
||||
return Y+'-'+M+'-'+D+' '+h+':'+m+':'+s;
|
||||
};
|
||||
|
||||
var endTimeTemplet = function(d) {
|
||||
if (!d.end_time || d.end_time === 0) return '<span style="color:#999">-</span>';
|
||||
var date = new Date(d.end_time * 1000);
|
||||
var Y = date.getFullYear();
|
||||
var M = (date.getMonth()+1).toString().padStart(2,'0');
|
||||
var D = date.getDate().toString().padStart(2,'0');
|
||||
var h = date.getHours().toString().padStart(2,'0');
|
||||
var m = date.getMinutes().toString().padStart(2,'0');
|
||||
var s = date.getSeconds().toString().padStart(2,'0');
|
||||
return Y+'-'+M+'-'+D+' '+h+':'+m+':'+s;
|
||||
};
|
||||
|
||||
// 耗时格式化模板
|
||||
var durationTemplet = function(d) {
|
||||
if (!d.duration || d.duration === 0) return '<span style="color:#999">-</span>';
|
||||
if (d.duration < 1000) {
|
||||
return d.duration + ' ms';
|
||||
}
|
||||
return (d.duration / 1000).toFixed(2) + ' s';
|
||||
};
|
||||
|
||||
// 错误信息截断模板
|
||||
var errorMsgTemplet = function(d) {
|
||||
if (!d.error_message) return '<span style="color:#999">-</span>';
|
||||
var text = d.error_message;
|
||||
if (text.length > 50) {
|
||||
return '<span title="'+text.replace(/"/g,'"').replace(/'/g,''')+'" style="cursor:pointer;" lay-event="showError">'+text.substring(0,50)+'...</span>';
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
||||
ua.table.render({
|
||||
init: init,
|
||||
cols: [[
|
||||
{type: 'checkbox'},
|
||||
{field: 'id', title: 'ID', width: 80, sort: true},
|
||||
{field: 'task_name', title: '任务名称', width: 160, search: 'select', searchUrl: 'system.timer_log/index?selectFields=task_name'},
|
||||
{field: 'node_id', title: '节点ID', width: 120, search: 'select', searchUrl: 'system.timer_log/index?selectFields=node_id'},
|
||||
{field: 'run_type', title: '运行类型', width: 100},
|
||||
{field: 'start_time', title: '开始时间', width: 170, templet: timeTemplet, search: 'range'},
|
||||
{field: 'end_time', title: '结束时间', width: 170, templet: endTimeTemplet},
|
||||
{field: 'duration', title: '耗时', width: 100, templet: durationTemplet},
|
||||
{field: 'status', title: '状态', width: 100, templet: statusTemplet, search: 'select', selectList: {success:'成功', error:'失败', running:'运行中'}},
|
||||
{field: 'error_message', title: '错误信息', minWidth: 200, templet: errorMsgTemplet},
|
||||
{
|
||||
width: 100, title: '操作', templet: ua.table.tool, fixed: 'right', operat: [
|
||||
[{
|
||||
class: 'layui-btn layui-btn-primary layui-btn-xs',
|
||||
method: 'tab',
|
||||
field: 'id',
|
||||
text: '详情',
|
||||
title: '查看详情',
|
||||
auth: 'read',
|
||||
url: init.readUrl,
|
||||
icon: ''
|
||||
}]
|
||||
]
|
||||
},
|
||||
]],
|
||||
});
|
||||
|
||||
// 点击错误信息查看完整内容
|
||||
ua.table.on('tool(currentTable)', function(obj) {
|
||||
if (obj.event === 'showError') {
|
||||
var text = obj.data.error_message || '';
|
||||
layer.alert('<pre style="white-space:pre-wrap;word-break:break-all;max-height:400px;overflow-y:auto;">'+text.replace(/</g,'<').replace(/>/g,'>')+'</pre>', {
|
||||
title: '错误信息详情',
|
||||
area: ['600px', '400px']
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
ua.listen();
|
||||
})
|
||||
139
app/admin/view/system/timer_log/read.html
Normal file
139
app/admin/view/system/timer_log/read.html
Normal file
@@ -0,0 +1,139 @@
|
||||
<div class="layuimini-container detail-container">
|
||||
<div class="layuimini-main">
|
||||
<div class="layui-card detail-card">
|
||||
<div class="layui-card-header detail-header">
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-md9">
|
||||
<h2 class="detail-title">#{$row.id} {$title}</h2>
|
||||
<div class="detail-id">ID: {$row.id}</div>
|
||||
</div>
|
||||
<div class="layui-col-md3 text-right detail-actions">
|
||||
<button class="layui-btn layui-btn-primary" layuimini-content-href="{$Request.param.backTagId}" data-back="1">返回</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-card-body detail-content">
|
||||
<div class="layui-row layui-col-space12">
|
||||
<!-- 左侧主体内容 -->
|
||||
<div class="layui-col-md8 detail-main">
|
||||
<div class="detail-field-group">
|
||||
<div class="detail-field-item">
|
||||
<div class="detail-field-label">任务名称</div>
|
||||
<div class="detail-field-value">
|
||||
{notempty name="row.task_name"}
|
||||
{$row.task_name}
|
||||
{else/}
|
||||
<span class="layui-text-em">暂无数据</span>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-field-item">
|
||||
<div class="detail-field-label">执行节点ID</div>
|
||||
<div class="detail-field-value">
|
||||
{notempty name="row.node_id"}
|
||||
{$row.node_id}
|
||||
{else/}
|
||||
<span class="layui-text-em">暂无数据</span>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-field-item">
|
||||
<div class="detail-field-label">运行类型</div>
|
||||
<div class="detail-field-value">
|
||||
{notempty name="row.run_type"}
|
||||
{$row.run_type}
|
||||
{else/}
|
||||
<span class="layui-text-em">暂无数据</span>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-field-item">
|
||||
<div class="detail-field-label">开始时间</div>
|
||||
<div class="detail-field-value">
|
||||
{notempty name="row.start_time"}
|
||||
{:date('Y-m-d H:i:s', $row['start_time'])}
|
||||
{else/}
|
||||
<span class="layui-text-em">暂无数据</span>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-field-item">
|
||||
<div class="detail-field-label">结束时间</div>
|
||||
<div class="detail-field-value">
|
||||
{notempty name="row.end_time"}
|
||||
{:date('Y-m-d H:i:s', $row['end_time'])}
|
||||
{else/}
|
||||
<span class="layui-text-em">暂无数据</span>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-field-item">
|
||||
<div class="detail-field-label">耗时</div>
|
||||
<div class="detail-field-value">
|
||||
{notempty name="row.duration"}
|
||||
{:php echo ($row['duration'] < 1000) ? $row['duration'].' ms' : round($row['duration']/1000, 2).' s';}
|
||||
{else/}
|
||||
<span class="layui-text-em">暂无数据</span>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-field-item">
|
||||
<div class="detail-field-label">错误信息</div>
|
||||
<div class="detail-field-value" style="white-space: pre-wrap;">
|
||||
{notempty name="row.error_message"}
|
||||
{$row.error_message|raw}
|
||||
{else/}
|
||||
<span class="layui-text-em">暂无内容</span>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-field-item">
|
||||
<div class="detail-field-label">并发分片ID</div>
|
||||
<div class="detail-field-value">
|
||||
{notempty name="row.concurrency_id"}
|
||||
{$row.concurrency_id}
|
||||
{else/}
|
||||
<span class="layui-text-em">暂无数据</span>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧基础信息 -->
|
||||
<div class="layui-col-md4 detail-side">
|
||||
<h3 class="detail-side-title">基础信息</h3>
|
||||
<div class="detail-field-group">
|
||||
<div class="detail-field-item">
|
||||
<div class="detail-field-label">ID</div>
|
||||
<div class="detail-field-value">{$row.id}</div>
|
||||
</div>
|
||||
<div class="detail-field-item">
|
||||
<div class="detail-field-label">状态</div>
|
||||
<div class="detail-field-value">
|
||||
{switch name="row.status"}
|
||||
{case value="success"}<span style="display:inline-block;padding:2px 10px;border-radius:3px;color:#5FB878;background:#e8f8ef;font-size:12px;">成功</span>{/case}
|
||||
{case value="error"}<span style="display:inline-block;padding:2px 10px;border-radius:3px;color:#FF5722;background:#ffe8e2;font-size:12px;">失败</span>{/case}
|
||||
{case value="running"}<span style="display:inline-block;padding:2px 10px;border-radius:3px;color:#1E9FFF;background:#e2f1ff;font-size:12px;">运行中</span>{/case}
|
||||
{default /}<span style="color:#999">{$row.status}</span>
|
||||
{/switch}
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-field-item">
|
||||
<div class="detail-field-label">创建时间</div>
|
||||
<div class="detail-field-value">
|
||||
{notempty name="row.create_time"}
|
||||
{$row.create_time|date="Y-m-d H:i:s"}
|
||||
{else/}
|
||||
<span class="layui-text-em">暂无数据</span>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
3
app/admin/view/system/timer_log/read.js
Normal file
3
app/admin/view/system/timer_log/read.js
Normal file
@@ -0,0 +1,3 @@
|
||||
$(function(){
|
||||
ua.listen();
|
||||
})
|
||||
Reference in New Issue
Block a user