邹景立 7e2834b6fa style(queue): 优化队列任务执行窗口
重构队列进度弹窗模板,增加任务编号、状态区域和执行日志头部,并注入独立样式让进度条、日志面板和弹窗标题更清晰。

调整队列弹窗尺寸和皮肤,保持日志区域可滚动展示,减少旧模板中 textarea 风格对实时日志阅读体验的影响。

为队列页面操作按钮补充语义化颜色:优化、启动、关闭、清理和批量删除分别使用不同按钮样式,提升危险操作和普通操作的辨识度。
2026-05-20 23:19:28 +08:00

154 lines
9.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// +----------------------------------------------------------------------
// | Static Plugin for ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
// +----------------------------------------------------------------------
// | 官方网站: https://thinkadmin.top
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// | 免责声明 ( https://thinkadmin.top/disclaimer )
// +----------------------------------------------------------------------
// | gitee 代码仓库https://gitee.com/zoujingli/think-plugs-static
// | github 代码仓库https://github.com/zoujingli/think-plugs-static
// +----------------------------------------------------------------------
layui.define(function (exports) {
let template = [
'<div class="ta-queue-box" data-queue-load="{{d.code}}">',
' <div class="ta-queue-status">',
' <div class="ta-queue-status-title layui-elip notselect nowrap" data-message-title><b class="color-desc">...</b></div>',
' <div class="ta-queue-status-code"># {{d.code}}</div>',
' </div>',
' <div class="layui-progress layui-progress-big ta-queue-progress" lay-showPercent="yes"><div class="layui-progress-bar transition layui-bg-blue" lay-percent="0.00%"></div></div>',
' <div class="ta-queue-log">',
' <div class="ta-queue-log-head"><span>执行日志</span><small>实时刷新</small></div>',
' <code></code>',
' </div>',
'</div>'
].join('');
function injectStyle() {
if (document.getElementById('ta-queue-style')) return;
let style = document.createElement('style');
style.id = 'ta-queue-style';
style.innerHTML = [
'.ta-queue-layer{border-radius:10px;overflow:hidden;}',
'.ta-queue-layer .layui-layer-title{height:48px;line-height:48px;font-weight:600;border-bottom:1px solid #edf0f5;background:#fff;}',
'.ta-queue-layer .layui-layer-content{overflow:hidden;background:#f6f8fb;}',
'.ta-queue-box{padding:18px 20px 20px;background:#f6f8fb;}',
'.ta-queue-status{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:13px 15px;background:#fff;border:1px solid #edf0f5;border-radius:10px;box-shadow:0 4px 18px rgba(15,35,60,.04);}',
'.ta-queue-status-title{min-width:0;flex:1;font-weight:600;}',
'.ta-queue-status-title b{font-weight:600;}',
'.ta-queue-status-code{flex-shrink:0;max-width:220px;color:#8c98a8;font-size:12px;line-height:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}',
'.ta-queue-progress{height:12px;margin:14px 2px 0;border-radius:999px;background:#e8edf5;overflow:hidden;}',
'.ta-queue-progress .layui-progress-bar{border-radius:999px;}',
'.ta-queue-progress .layui-progress-text{top:-6px;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.2);}',
'.ta-queue-log{margin-top:14px;border-radius:10px;background:#222b33;border:1px solid #1a222a;overflow:hidden;box-shadow:inset 0 0 0 1px rgba(255,255,255,.02);}',
'.ta-queue-log-head{height:36px;display:flex;align-items:center;justify-content:space-between;padding:0 14px;background:#172027;color:#dce5ee;font-size:13px;}',
'.ta-queue-log-head small{font-size:12px;font-weight:400;color:#7f8b98;}',
'.ta-queue-log code{display:block;height:185px;margin:0;padding:12px 14px;border:0;background:#222b33;color:#dce5ee;font-family:Consolas,Monaco,Menlo,monospace;font-size:12px;line-height:22px;white-space:normal;overflow:auto;}',
'.ta-queue-log code p{height:22px;line-height:22px;margin:0;color:#dce5ee;}',
'.ta-queue-log code .color-desc{color:#8c98a8!important;}'
].join('');
document.head.appendChild(style);
}
function Queue(code, doScript, element) {
let queue = this;
injectStyle();
(this.doAjax = true) && (this.doReload = false) || layer.open({
type: 1, title: '任务执行进度', area: ['620px', '390px'], skin: 'ta-queue-layer', anim: 2, shadeClose: false, end: function () {
queue.doAjax = queue.doReload && doScript && $.layTable.reload(((element || {}).dataset || {}).tableId || true) && false;
}, content: laytpl(template).render({code: code}), success: function ($elem) {
new Progress($elem, code, queue, doScript);
}
});
}
function Progress($elem, code, queue, doScript) {
let that = this;
this.$box = $elem.find('[data-queue-load=' + code + ']');
if (queue.doAjax === false || this.$box.length < 1) return false;
this.$code = this.$box.find('code');
this.$title = this.$box.find('[data-message-title]');
this.$percent = this.$box.find('.layui-progress div');
// 设置数据缓存
this.SetCache = function (code, index, value) {
let ckey = code + '_' + index, ctype = 'admin-queue-script';
return value !== undefined ? layui.data(ctype, {key: ckey, value: value}) : layui.data(ctype)[ckey] || 0;
};
// 更新任务显示状态
this.SetState = function (status, message) {
if (message.indexOf('javascript:') === -1) if (status === 1) {
that.$title.html('<b class="color-text">' + message + '</b>').addClass('text-center');
that.$percent.addClass('layui-bg-blue').removeClass('layui-bg-green layui-bg-red');
} else if (status === 2) {
if (message.indexOf('>>>') > -1) {
that.$title.html('<b class="color-blue">' + message + '</b>').addClass('text-center');
} else {
that.$title.html('<b class="color-blue">正在处理:</b>' + message).removeClass('text-center');
}
that.$percent.addClass('layui-bg-blue').removeClass('layui-bg-green layui-bg-red');
} else if (status === 3) {
queue.doReload = true;
that.$title.html('<b class="color-green">' + message + '</b>').addClass('text-center');
that.$percent.addClass('layui-bg-green').removeClass('layui-bg-blue layui-bg-red');
} else if (status === 4) {
that.$title.html('<b class="color-red">' + message + '</b>').addClass('text-center');
that.$percent.addClass('layui-bg-red').removeClass('layui-bg-blue layui-bg-green');
}
};
// 读取任务进度信息
this.LoadProgress = function () {
if (queue.doAjax === false || that.$box.length < 1) return false;
$.form.load(tapiRoot + '/queue/progress', {code: code}, 'post', function (ret) {
if (parseInt(ret.code, 10) === 200) {
let data = ret && typeof ret.data === 'object' && ret.data ? ret.data : {};
let status = parseInt(data.status || '0');
let progress = parseFloat(data.progress || '0.00');
let message = typeof data.message === 'string' && data.message.length ? data.message : '>>> 等待任务状态更新 <<<';
let history = Array.isArray(data.history) ? data.history : [];
let lines = [];
for (let idx in history) {
let line = history[idx] || {}, text = String(line.message || ''), percent = '[ ' + (line.progress || '0.00') + '% ] ';
if (!text.length) {
continue;
}
if (text.indexOf('javascript:') === -1) {
lines.push(text.indexOf('>>>') > -1 ? text : percent + text);
} else if (!that.SetCache(code, idx) && doScript !== false) {
that.SetCache(code, idx, 1)
$.form.goto(text);
}
}
if (!isFinite(progress)) {
progress = 0;
}
that.$code.html(lines.length ? '<p class="layui-elip">' + lines.join('</p><p class="layui-elip">') + '</p>' : '<p class="layui-elip color-desc">暂无执行日志</p>').animate({scrollTop: that.$code[0].scrollHeight + 'px'}, 200);
if (status > 0) {
that.SetState(status, message);
that.$percent.attr('lay-percent', progress.toFixed(2) + '%') && layui.element.render();
status === 3 || status === 4 || setTimeout(that.LoadProgress, Math.floor(Math.random() * 200));
} else {
that.$title.html('<b class="color-desc">' + message + '</b>').addClass('text-center');
that.$percent.attr('lay-percent', progress.toFixed(2) + '%') && layui.element.render();
setTimeout(that.LoadProgress, Math.floor(Math.random() * 500) + 200);
}
return false;
}
}, false);
};
// 首页加载进度信息
this.LoadProgress();
}
exports('taQueue', Queue);
});