Files
luci-app-openclaw/luasrc/view/openclaw/console.htm
2026-03-26 14:08:52 +08:00

220 lines
6.8 KiB
HTML
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.
<%#
luci-app-openclaw — Web 控制台页面
嵌入 OpenClaw 官方 Web UI用户可在此配置模型/渠道并直接对话
-%>
<%+header%>
<%
local uci = require "luci.model.uci".cursor()
local port = uci:get("openclaw", "main", "port") or "18789"
%>
<style type="text/css">
.oc-page-header { margin: 0 0 16px 0; }
.oc-page-header h2 { font-size: 18px; font-weight: 600; color: #333; margin: 0 0 6px 0; }
.oc-page-header p { font-size: 13px; color: #666; margin: 0; line-height: 1.6; }
.oc-console-info {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 16px;
margin-bottom: 16px;
background: #f6f8fa;
border: 1px solid #e1e4e8;
border-radius: 6px;
font-size: 13px;
color: #555;
flex-wrap: wrap;
}
.oc-console-info .label { color: #888; }
.oc-console-info .value { font-family: monospace; color: #333; font-weight: 500; }
.oc-console-info .sep { color: #ddd; }
.oc-console-info .btn-open {
margin-left: auto;
padding: 4px 14px;
background: #4a90d9;
color: #fff;
border: none;
border-radius: 4px;
font-size: 12px;
cursor: pointer;
text-decoration: none;
}
.oc-console-info .btn-open:hover { background: #357abd; }
.oc-console-wrap {
border: 2px solid #e0e0e0;
border-radius: 8px;
overflow: hidden;
background: #fff;
box-shadow: 0 1px 4px rgba(0,0,0,0.06);
}
.oc-console-loading {
display: flex; flex-direction: column; align-items: center; justify-content: center;
min-height: 320px; color: #666; font-size: 14px; background: #fafafa;
padding: 32px 24px;
text-align: center;
}
.oc-console-loading .spinner {
width: 32px; height: 32px; border: 3px solid #e0e0e0; border-top: 3px solid #4a90d9;
border-radius: 50%; animation: oc-spin .8s linear infinite; margin-bottom: 12px;
}
@keyframes oc-spin { to { transform: rotate(360deg); } }
.oc-console-note {
max-width: 640px;
line-height: 1.8;
}
.oc-console-note strong {
color: #333;
}
.oc-console-note code {
padding: 2px 6px;
background: #f0f3f6;
border-radius: 4px;
font-family: monospace;
}
.oc-console-actions {
display: flex;
justify-content: center;
gap: 10px;
flex-wrap: wrap;
margin-top: 16px;
}
.oc-console-link {
font-size: 12px;
color: #666;
word-break: break-all;
margin-top: 14px;
}
.oc-console-link a {
color: #4a90d9;
text-decoration: none;
}
</style>
<div class="oc-page-header">
<h2>🖥️ Web 控制台</h2>
<p>OpenClaw 官方 Web 管理界面 — 在这里可以配置 AI 模型、消息渠道QQ、Telegram、Discord 等),直接与 AI 进行对话,以及管理所有功能。</p>
</div>
<div class="oc-console-info">
<span class="label">网关地址:</span>
<span class="value" id="oc-console-addr">-</span>
<span class="sep">|</span>
<span class="label">活跃模型:</span>
<span class="value" id="oc-console-model" style="color:#555;">-</span>
<span class="sep">|</span>
<span class="label">状态:</span>
<span id="oc-console-status-text">检查中...</span>
<a id="oc-console-open-btn" class="btn-open" href="#" target="_blank" rel="noopener" style="display:none;">
↗ 新窗口打开
</a>
</div>
<div class="oc-console-wrap">
<div id="oc-console-container">
<div class="oc-console-loading" id="oc-console-loading">
<div class="spinner"></div>
<span>正在连接 OpenClaw 控制台...</span>
</div>
</div>
</div>
<script type="text/javascript">
//<![CDATA[
(function() {
var gwPort = '<%=port%>';
var gwToken = '';
var statusUrl = '<%=luci.dispatcher.build_url("admin", "services", "openclaw", "status_api")%>';
var tokenUrl = '<%=luci.dispatcher.build_url("admin", "services", "openclaw", "get_token")%>';
var container = document.getElementById('oc-console-container');
var loading = document.getElementById('oc-console-loading');
var addrEl = document.getElementById('oc-console-addr');
var modelEl = document.getElementById('oc-console-model');
var statusTextEl = document.getElementById('oc-console-status-text');
var openBtn = document.getElementById('oc-console-open-btn');
function getConsoleUrl() {
var host = window.location.hostname;
var url = 'http://' + host + ':' + gwPort + '/';
if (gwToken) url += '#token=' + encodeURIComponent(gwToken);
return url;
}
function showOpenMessage(url) {
loading.innerHTML =
'<div class="oc-console-note">' +
'<div style="font-size:42px;margin-bottom:12px;">🪟</div>' +
'<div style="font-size:16px;margin-bottom:8px;"><strong>请在新窗口中打开 OpenClaw 控制台</strong></div>' +
'<div style="font-size:13px;color:#666;">' +
'OpenClaw 控制台会返回浏览器安全头,拒绝被 LuCI 页面内嵌。' +
'请点击上方「新窗口打开」访问控制台。' +
'</div>' +
'<div class="oc-console-actions">' +
'<a class="btn cbi-button cbi-button-action" href="' + url + '" target="_blank" rel="noopener">↗ 新窗口打开</a>' +
'</div>' +
'<div class="oc-console-link">直接地址:<a href="' + url + '" target="_blank" rel="noopener">' + url + '</a></div>' +
'</div>';
}
function checkAndLoad() {
addrEl.textContent = window.location.hostname + ':' + gwPort;
// 先获取 token再检查状态
(new XHR()).get(tokenUrl, null, function(tx) {
try {
var td = JSON.parse(tx.responseText);
gwToken = td.token || '';
} catch(e) {}
(new XHR()).get(statusUrl, null, function(x) {
try {
var d = JSON.parse(x.responseText);
var url = getConsoleUrl();
if (d.active_model) {
modelEl.textContent = d.active_model;
}
if (d.gateway_running) {
statusTextEl.innerHTML = '<span style="color:#1a7f37;">● 网关运行中</span>';
openBtn.href = url;
openBtn.style.display = '';
showOpenMessage(url);
} else if (d.gateway_starting) {
statusTextEl.innerHTML = '<span style="color:#9a6700;">⏳ 网关正在启动</span>';
openBtn.style.display = 'none';
loading.innerHTML = '<div style="text-align:center;color:#666;">' +
'<div style="font-size:40px;margin-bottom:12px;">⏳</div>' +
'<div style="font-size:15px;margin-bottom:6px;">OpenClaw 网关正在启动中...</div>' +
'<div style="font-size:12px;color:#999;">首次启动可能需要 2~5 分钟,请耐心等待,页面会自动刷新。</div>' +
'</div>';
} else {
statusTextEl.innerHTML = '<span style="color:#cf222e;">● 网关未运行</span>';
openBtn.style.display = 'none';
loading.innerHTML = '<div style="text-align:center;color:#666;">' +
'<div style="font-size:40px;margin-bottom:12px;">🧠</div>' +
'<div style="font-size:15px;margin-bottom:6px;">OpenClaw 网关未运行</div>' +
'<div style="font-size:12px;color:#999;">请先在「基本设置」页面启用服务并启动。</div>' +
'</div>';
}
} catch(e) {
statusTextEl.textContent = '查询失败';
}
});
});
}
checkAndLoad();
})();
//]]>
</script>
<%+footer%>