mirror of
https://github.com/qingchencloud/clawpanel.git
synced 2026-06-26 02:01:59 +08:00
chore: release v0.8.4 — 移除龙虾军团入口,精简前端
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -30,6 +30,7 @@ release_body.md.bak
|
||||
# 内部开发文档(不入公开仓)
|
||||
BLOCKING_ISSUES_REPORT.md
|
||||
__clawapp-chat-ref.js
|
||||
LOBSTER-LEGION-ARCHIVE.md
|
||||
|
||||
# 大文件(宣传视频·原始版本)
|
||||
docs/promo-video.mp4
|
||||
|
||||
@@ -5,6 +5,13 @@
|
||||
格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
|
||||
版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
||||
|
||||
## [0.8.4] - 2026-03-13
|
||||
|
||||
### 改进 (Improvements)
|
||||
|
||||
- **移除龙虾军团入口** — 精简产品功能,移除 Docker 集群管理页面及相关军事化主题 UI,聚焦"简单好用"的核心体验
|
||||
- **前端瘦身** — 删除 3 个专用模块(docker.js / docker-tasking.js / pixel-roles.js),pages.css 减少约 700 行,tauri-api.js 清理 30 个未使用 API 方法
|
||||
|
||||
## [0.8.3] - 2026-03-12
|
||||
|
||||
### 修复 (Fixes)
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"description": "OpenClaw AI Agent 可视化管理面板,基于 Tauri v2 的跨平台桌面应用。支持仪表盘监控、多模型配置、消息渠道管理、内置 QQ 机器人、实时 AI 聊天、记忆管理、Agent 管理、网关配置、内网穿透等功能。",
|
||||
"url": "https://claw.qt.cool/",
|
||||
"downloadUrl": "https://github.com/qingchencloud/clawpanel/releases/latest",
|
||||
"softwareVersion": "0.8.2",
|
||||
"softwareVersion": "0.8.4",
|
||||
"author": {
|
||||
"@type": "Organization",
|
||||
"name": "晴辰云 QingchenCloud",
|
||||
@@ -1133,7 +1133,7 @@
|
||||
<div class="orb orb-2" style="top:auto;bottom:-100px"></div>
|
||||
<div class="container-sm" style="position:relative;z-index:10">
|
||||
<div class="section-header">
|
||||
<div class="reveal download-version"><span class="pulse"></span> v0.8.2 最新版</div>
|
||||
<div class="reveal download-version"><span class="pulse"></span> v0.8.4 最新版</div>
|
||||
<h2 class="reveal section-title"><span class="gradient-text">下载安装</span></h2>
|
||||
<p class="reveal section-desc">选择你的操作系统,一键下载安装</p>
|
||||
</div>
|
||||
@@ -1143,11 +1143,11 @@
|
||||
<h3>macOS</h3>
|
||||
<p class="dl-desc">支持 Apple Silicon 和 Intel 芯片</p>
|
||||
<div class="dl-links">
|
||||
<a class="dl-link" href="https://claw.qt.cool/proxy/dl/github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.8.2_aarch64.dmg" target="_blank" rel="noopener">
|
||||
<a class="dl-link" href="https://claw.qt.cool/proxy/dl/github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.8.4_aarch64.dmg" target="_blank" rel="noopener">
|
||||
Apple Silicon (M1/M2/M3/M4)
|
||||
<span class="dl-format">.dmg</span>
|
||||
</a>
|
||||
<a class="dl-link" href="https://claw.qt.cool/proxy/dl/github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.8.2_x64.dmg" target="_blank" rel="noopener">
|
||||
<a class="dl-link" href="https://claw.qt.cool/proxy/dl/github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.8.4_x64.dmg" target="_blank" rel="noopener">
|
||||
Intel 芯片
|
||||
<span class="dl-format">.dmg</span>
|
||||
</a>
|
||||
@@ -1165,11 +1165,11 @@
|
||||
<h3>Windows</h3>
|
||||
<p class="dl-desc">支持 Windows 10 及以上版本</p>
|
||||
<div class="dl-links">
|
||||
<a class="dl-link" href="https://claw.qt.cool/proxy/dl/github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.8.2_x64-setup.exe" target="_blank" rel="noopener">
|
||||
<a class="dl-link" href="https://claw.qt.cool/proxy/dl/github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.8.4_x64-setup.exe" target="_blank" rel="noopener">
|
||||
安装程序
|
||||
<span class="dl-format">.exe</span>
|
||||
</a>
|
||||
<a class="dl-link" href="https://claw.qt.cool/proxy/dl/github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.8.2_x64_en-US.msi" target="_blank" rel="noopener">
|
||||
<a class="dl-link" href="https://claw.qt.cool/proxy/dl/github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.8.4_x64_en-US.msi" target="_blank" rel="noopener">
|
||||
MSI 安装包
|
||||
<span class="dl-format">.msi</span>
|
||||
</a>
|
||||
@@ -1180,11 +1180,11 @@
|
||||
<h3>Linux</h3>
|
||||
<p class="dl-desc">支持主流 Linux 发行版</p>
|
||||
<div class="dl-links">
|
||||
<a class="dl-link" href="https://claw.qt.cool/proxy/dl/github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.8.2_amd64.AppImage" target="_blank" rel="noopener">
|
||||
<a class="dl-link" href="https://claw.qt.cool/proxy/dl/github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.8.4_amd64.AppImage" target="_blank" rel="noopener">
|
||||
通用版
|
||||
<span class="dl-format">.AppImage</span>
|
||||
</a>
|
||||
<a class="dl-link" href="https://claw.qt.cool/proxy/dl/github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.8.2_amd64.deb" target="_blank" rel="noopener">
|
||||
<a class="dl-link" href="https://claw.qt.cool/proxy/dl/github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.8.4_amd64.deb" target="_blank" rel="noopener">
|
||||
Debian / Ubuntu
|
||||
<span class="dl-format">.deb</span>
|
||||
</a>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "clawpanel",
|
||||
"version": "0.8.3",
|
||||
"version": "0.8.4",
|
||||
"private": true,
|
||||
"description": "ClawPanel - OpenClaw 可视化管理面板,基于 Tauri v2 的跨平台桌面应用",
|
||||
"type": "module",
|
||||
|
||||
@@ -12,7 +12,7 @@ import { fileURLToPath } from 'url'
|
||||
import net from 'net'
|
||||
import http from 'http'
|
||||
import crypto from 'crypto'
|
||||
import { DOCKER_TASK_TIMEOUT_MS } from '../src/lib/docker-tasking.js'
|
||||
const DOCKER_TASK_TIMEOUT_MS = 10 * 60 * 1000
|
||||
|
||||
const __dev_dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const OPENCLAW_DIR = path.join(homedir(), '.openclaw')
|
||||
|
||||
2
src-tauri/Cargo.lock
generated
2
src-tauri/Cargo.lock
generated
@@ -328,7 +328,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clawpanel"
|
||||
version = "0.8.3"
|
||||
version = "0.8.4"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "clawpanel"
|
||||
version = "0.8.3"
|
||||
version = "0.8.4"
|
||||
edition = "2021"
|
||||
description = "ClawPanel - OpenClaw 可视化管理面板"
|
||||
authors = ["qingchencloud"]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/tauri-apps/tauri/dev/crates/tauri-config-schema/schema.json",
|
||||
"productName": "ClawPanel",
|
||||
"version": "0.8.3",
|
||||
"version": "0.8.4",
|
||||
"identifier": "ai.openclaw.clawpanel",
|
||||
"build": {
|
||||
"frontendDist": "../dist",
|
||||
|
||||
@@ -42,12 +42,6 @@ const NAV_ITEMS_FULL = [
|
||||
{ route: '/skills', label: 'Skills', icon: 'skills' },
|
||||
]
|
||||
},
|
||||
{
|
||||
section: '龙虾军团',
|
||||
items: [
|
||||
{ route: '/docker', label: '龙虾军团', icon: 'docker' },
|
||||
]
|
||||
},
|
||||
{
|
||||
section: '',
|
||||
items: [
|
||||
@@ -89,7 +83,6 @@ const ICONS = {
|
||||
assistant: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09z"/><path d="M18.259 8.715L18 9.75l-.259-1.035a3.375 3.375 0 00-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 002.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 002.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 00-2.456 2.456z"/></svg>',
|
||||
security: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0110 0v4"/></svg>',
|
||||
skills: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.7 6.3a1 1 0 000 1.4l1.6 1.6a1 1 0 001.4 0l3.77-3.77a6 6 0 01-7.94 7.94l-6.91 6.91a2.12 2.12 0 01-3-3l6.91-6.91a6 6 0 017.94-7.94l-3.76 3.76z"/></svg>',
|
||||
docker: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="1" y="11" width="4" height="3" rx=".5"/><rect x="6" y="11" width="4" height="3" rx=".5"/><rect x="11" y="11" width="4" height="3" rx=".5"/><rect x="6" y="7" width="4" height="3" rx=".5"/><rect x="11" y="7" width="4" height="3" rx=".5"/><rect x="16" y="11" width="4" height="3" rx=".5"/><rect x="11" y="3" width="4" height="3" rx=".5"/><path d="M2 17c1 3 4 5 10 5s9-2 10-5"/></svg>',
|
||||
channels: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>',
|
||||
clock: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>',
|
||||
debug: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/><circle cx="12" cy="12" r="3"/></svg>',
|
||||
@@ -287,7 +280,7 @@ async function _toggleInstanceDropdown(sidebarEl) {
|
||||
const h = healthMap[inst.id] || {}
|
||||
const active = inst.id === activeId ? ' active' : ''
|
||||
const dot = h.online !== false ? 'online' : 'offline'
|
||||
const badge = inst.type === 'docker' ? '<span class="instance-badge docker">🦞 龙虾</span>' : inst.type === 'remote' ? '<span class="instance-badge remote">远程</span>' : ''
|
||||
const badge = inst.type === 'docker' ? '<span class="instance-badge docker">Docker</span>' : inst.type === 'remote' ? '<span class="instance-badge remote">远程</span>' : ''
|
||||
const port = inst.endpoint ? inst.endpoint.match(/:(\d+)/)?.[1] : ''
|
||||
const portTag = port ? `<span class="instance-port">:${port}</span>` : ''
|
||||
html += `<div class="instance-option${active}" data-id="${inst.id}">
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
export const DOCKER_TASK_TIMEOUT_MS = 10 * 60 * 1000
|
||||
|
||||
export function buildDockerDispatchTargets(targets = []) {
|
||||
if (!Array.isArray(targets)) return []
|
||||
return targets.map(target => ({
|
||||
containerId: target.id,
|
||||
containerName: target.name,
|
||||
nodeId: target.nodeId || null,
|
||||
}))
|
||||
}
|
||||
|
||||
export function buildDockerInstanceSwitchContext({ containerId, name, port, gatewayPort, nodeId }) {
|
||||
if (!containerId) throw new Error('缺少容器 ID')
|
||||
if (!name) throw new Error('缺少容器名称')
|
||||
|
||||
const panelPort = parseRequiredPort(port, '面板端口')
|
||||
const parsedGatewayPort = parseOptionalPort(gatewayPort, 18789)
|
||||
|
||||
return {
|
||||
instanceId: `docker-${containerId.slice(0, 12)}`,
|
||||
reloadRoute: true,
|
||||
registration: {
|
||||
name,
|
||||
type: 'docker',
|
||||
endpoint: `http://127.0.0.1:${panelPort}`,
|
||||
gatewayPort: parsedGatewayPort,
|
||||
containerId,
|
||||
nodeId: nodeId || null,
|
||||
note: 'Added from Docker page',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function parseRequiredPort(value, label) {
|
||||
const port = Number.parseInt(value, 10)
|
||||
if (Number.isInteger(port) && port > 0) return port
|
||||
throw new Error(`${label}无效`)
|
||||
}
|
||||
|
||||
function parseOptionalPort(value, fallback) {
|
||||
const port = Number.parseInt(value, 10)
|
||||
if (Number.isInteger(port) && port > 0) return port
|
||||
return fallback
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
// 像素风格龙虾兵角色图
|
||||
// 每个角色是一个 16x16 像素画,用 SVG rects 渲染
|
||||
// 调色板:0=制服主色 1=制服亮色 2=制服暗色 3=虾红(头/钳) 4=深色(眼) 5=白 6=装备色 .=透明
|
||||
// 制服用兵种色 → 每个角色外观差异明显
|
||||
|
||||
const PIXEL_CHARS = {
|
||||
// 步兵 — 灰蓝制服 + 钢盔
|
||||
general: {
|
||||
palette: ['#64748b', '#94a3b8', '#475569', '#e74c3c', '#1e293b', '#ffffff', '#cbd5e1'],
|
||||
pixels: [
|
||||
'................',
|
||||
'......0022......',
|
||||
'.....006622.....',
|
||||
'....00000000....',
|
||||
'..3..044440..3..',
|
||||
'..3..055550..3..',
|
||||
'.33..044440..33.',
|
||||
'.....000000.....',
|
||||
'....00011000....',
|
||||
'....00000000....',
|
||||
'.....000000.....',
|
||||
'.....000000.....',
|
||||
'......0000......',
|
||||
'.....00..00.....',
|
||||
'.....00..00.....',
|
||||
'.....22..22.....',
|
||||
],
|
||||
},
|
||||
// 突击兵(coder) — 金黄制服 + 护目镜 + 闪电
|
||||
coder: {
|
||||
palette: ['#f59e0b', '#fbbf24', '#b45309', '#e74c3c', '#1e293b', '#ffffff', '#fef3c7'],
|
||||
pixels: [
|
||||
'.......66.......',
|
||||
'......6666......',
|
||||
'.....666666.....',
|
||||
'....00066000....',
|
||||
'..3..044440..3..',
|
||||
'..3..055550..3..',
|
||||
'.33..044440..33.',
|
||||
'.....000000.....',
|
||||
'....00011000....',
|
||||
'....00000000....',
|
||||
'.....000000.....',
|
||||
'.6...000000...6.',
|
||||
'.66...0000...66.',
|
||||
'.....00..00.....',
|
||||
'.....00..00.....',
|
||||
'.....22..22.....',
|
||||
],
|
||||
},
|
||||
// 翻译官 — 青色制服 + 贝雷帽 + 卷轴
|
||||
translator: {
|
||||
palette: ['#06b6d4', '#22d3ee', '#0e7490', '#e74c3c', '#1e293b', '#ffffff', '#ecfeff'],
|
||||
pixels: [
|
||||
'....1100........',
|
||||
'...011000.......',
|
||||
'...0000000......',
|
||||
'....000000......',
|
||||
'..3..044440..3..',
|
||||
'..3..055550..3..',
|
||||
'.33..044440..33.',
|
||||
'.....000000.....',
|
||||
'....00011000....',
|
||||
'....00000000..66',
|
||||
'.....000000..646',
|
||||
'.....000000..646',
|
||||
'......0000...66.',
|
||||
'.....00..00.....',
|
||||
'.....00..00.....',
|
||||
'.....22..22.....',
|
||||
],
|
||||
},
|
||||
// 文书官 — 紫色制服 + 文人帽 + 羽毛笔
|
||||
writer: {
|
||||
palette: ['#8b5cf6', '#a78bfa', '#6d28d9', '#e74c3c', '#1e293b', '#ffffff', '#ede9fe'],
|
||||
pixels: [
|
||||
'..............6.',
|
||||
'.....0011....6..',
|
||||
'....001100..6...',
|
||||
'....000000.6....',
|
||||
'..3..044440..3..',
|
||||
'..3..055550..3..',
|
||||
'.33..044440..33.',
|
||||
'.....000000.....',
|
||||
'....00011000....',
|
||||
'....00000000....',
|
||||
'.....000000.....',
|
||||
'.....000000.....',
|
||||
'......0000......',
|
||||
'.....00..00.....',
|
||||
'.....00..00.....',
|
||||
'.....22..22.....',
|
||||
],
|
||||
},
|
||||
// 参谋(analyst) — 绿色制服 + 眼镜 + 图表板
|
||||
analyst: {
|
||||
palette: ['#22c55e', '#4ade80', '#15803d', '#e74c3c', '#1e293b', '#ffffff', '#dcfce7'],
|
||||
pixels: [
|
||||
'................',
|
||||
'......4444......',
|
||||
'.....444444.....',
|
||||
'....44444444....',
|
||||
'..3.066.660.3...',
|
||||
'..3..055550..3..',
|
||||
'.33..044440..33.',
|
||||
'.....000000.....',
|
||||
'....00011000....',
|
||||
'....00000000.66.',
|
||||
'.....000000.626.',
|
||||
'.....000000.626.',
|
||||
'......0000..66..',
|
||||
'.....00..00.....',
|
||||
'.....00..00.....',
|
||||
'.....22..22.....',
|
||||
],
|
||||
},
|
||||
// 特种兵(custom) — 深红制服 + 战术面罩 + 扳手
|
||||
custom: {
|
||||
palette: ['#ef4444', '#f87171', '#b91c1c', '#dc2626', '#1e293b', '#ffffff', '#fee2e2'],
|
||||
pixels: [
|
||||
'......0022......',
|
||||
'.....020020.....',
|
||||
'....00000000....',
|
||||
'....04444400....',
|
||||
'..3..044440..3..',
|
||||
'..3..055550..3..',
|
||||
'.33..044440..33.',
|
||||
'.....000000.....',
|
||||
'....00011000....',
|
||||
'....00000000....',
|
||||
'.....000000.....',
|
||||
'.4...000000...4.',
|
||||
'.44...0000...44.',
|
||||
'.....00..00.....',
|
||||
'.....00..00.....',
|
||||
'.....22..22.....',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
// 军营(Docker 节点)像素图
|
||||
const PIXEL_BARRACKS = {
|
||||
palette: ['#92400e', '#b45309', '#fbbf24', '#d97706', '#78350f', '#ffffff', '#f59e0b'],
|
||||
pixels: [
|
||||
'......6666......',
|
||||
'.....666666.....',
|
||||
'....33333333....',
|
||||
'...3333333333...',
|
||||
'..333333333333..',
|
||||
'..300053005300..',
|
||||
'..300053005300..',
|
||||
'..300053005300..',
|
||||
'..333333333333..',
|
||||
'..300053005300..',
|
||||
'..300053005300..',
|
||||
'..300053005300..',
|
||||
'..333333333333..',
|
||||
'..333300003333..',
|
||||
'..333300003333..',
|
||||
'..444444444444..',
|
||||
],
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成像素角色 SVG
|
||||
* @param {string} role - 兵种 key
|
||||
* @param {number} size - 显示尺寸 (px)
|
||||
* @returns {string} SVG HTML string
|
||||
*/
|
||||
function _renderPixelSvg(data, size) {
|
||||
const { palette, pixels } = data
|
||||
const grid = 16
|
||||
let rects = ''
|
||||
for (let y = 0; y < pixels.length; y++) {
|
||||
const row = pixels[y]
|
||||
for (let x = 0; x < row.length; x++) {
|
||||
const ch = row[x]
|
||||
if (ch === '.') continue
|
||||
const colorIdx = parseInt(ch)
|
||||
if (isNaN(colorIdx) || !palette[colorIdx]) continue
|
||||
rects += `<rect x="${x}" y="${y}" width="1" height="1" fill="${palette[colorIdx]}"/>`
|
||||
}
|
||||
}
|
||||
return `<svg viewBox="0 0 ${grid} ${grid}" width="${size}" height="${size}" xmlns="http://www.w3.org/2000/svg" style="image-rendering:pixelated">${rects}</svg>`
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成像素角色 SVG
|
||||
* @param {string} role - 兵种 key
|
||||
* @param {number} size - 显示尺寸 (px)
|
||||
* @returns {string} SVG HTML string
|
||||
*/
|
||||
export function pixelRole(role, size = 32) {
|
||||
return _renderPixelSvg(PIXEL_CHARS[role] || PIXEL_CHARS.general, size)
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成军营像素 SVG
|
||||
* @param {number} size - 显示尺寸 (px)
|
||||
* @returns {string} SVG HTML string
|
||||
*/
|
||||
export function pixelBarracks(size = 32) {
|
||||
return _renderPixelSvg(PIXEL_BARRACKS, size)
|
||||
}
|
||||
@@ -2,18 +2,11 @@
|
||||
* Tauri API 封装层
|
||||
* Tauri 环境用 invoke,Web 模式走 dev-api 后端
|
||||
*/
|
||||
import { DOCKER_TASK_TIMEOUT_MS } from './docker-tasking.js'
|
||||
|
||||
const isTauri = !!window.__TAURI_INTERNALS__
|
||||
|
||||
// 仅在 Node.js 后端实现的命令(Tauri Rust 不处理),强制走 webInvoke
|
||||
const WEB_ONLY_CMDS = new Set([
|
||||
'docker_test_endpoint',
|
||||
'docker_info', 'docker_list_containers', 'docker_create_container',
|
||||
'docker_start_container', 'docker_stop_container', 'docker_restart_container',
|
||||
'docker_remove_container', 'docker_rebuild_container', 'docker_container_logs', 'docker_container_exec', 'docker_init_worker', 'docker_gateway_chat', 'docker_agent', 'docker_agent_broadcast', 'docker_dispatch_task', 'docker_dispatch_broadcast', 'docker_task_status', 'docker_task_list', 'docker_pull_image', 'docker_pull_status',
|
||||
'docker_list_images', 'docker_list_nodes', 'docker_add_node', 'docker_remove_node',
|
||||
'docker_cluster_overview',
|
||||
'instance_list', 'instance_add', 'instance_remove', 'instance_set_active',
|
||||
'instance_health_check', 'instance_health_all',
|
||||
'get_deploy_mode',
|
||||
@@ -270,34 +263,6 @@ export const api = {
|
||||
instanceHealthCheck: (id) => invoke('instance_health_check', { id }),
|
||||
instanceHealthAll: () => invoke('instance_health_all'),
|
||||
|
||||
// Docker 集群管理
|
||||
getDeployMode: () => cachedInvoke('get_deploy_mode', {}, 60000),
|
||||
dockerClusterOverview: () => invoke('docker_cluster_overview'),
|
||||
dockerTestEndpoint: (endpoint) => invoke('docker_test_endpoint', { endpoint }),
|
||||
dockerInfo: (nodeId) => invoke('docker_info', { nodeId }),
|
||||
dockerListContainers: (nodeId, all = true) => invoke('docker_list_containers', { nodeId, all }),
|
||||
dockerCreateContainer: (opts) => invoke('docker_create_container', opts),
|
||||
dockerStartContainer: (nodeId, containerId) => { invalidate('docker_cluster_overview', 'docker_list_containers'); return invoke('docker_start_container', { nodeId, containerId }) },
|
||||
dockerStopContainer: (nodeId, containerId) => { invalidate('docker_cluster_overview', 'docker_list_containers'); return invoke('docker_stop_container', { nodeId, containerId }) },
|
||||
dockerRestartContainer: (nodeId, containerId) => { invalidate('docker_cluster_overview', 'docker_list_containers'); return invoke('docker_restart_container', { nodeId, containerId }) },
|
||||
dockerRemoveContainer: (nodeId, containerId, force = false) => { invalidate('docker_cluster_overview', 'docker_list_containers'); return invoke('docker_remove_container', { nodeId, containerId, force }) },
|
||||
dockerContainerLogs: (nodeId, containerId, tail = 200) => invoke('docker_container_logs', { nodeId, containerId, tail }),
|
||||
dockerContainerExec: (nodeId, containerId, cmd) => invoke('docker_container_exec', { nodeId, containerId, cmd }),
|
||||
dockerInitWorker: (nodeId, containerId, role) => invoke('docker_init_worker', { nodeId, containerId, role }),
|
||||
dockerGatewayChat: (nodeId, containerId, message, timeout = DOCKER_TASK_TIMEOUT_MS) => invoke('docker_gateway_chat', { nodeId, containerId, message, timeout }),
|
||||
dockerAgent: (nodeId, containerId, cmd) => invoke('docker_agent', { nodeId, containerId, cmd }),
|
||||
dockerAgentBroadcast: (nodeId, containerIds, message, timeout = DOCKER_TASK_TIMEOUT_MS) => invoke('docker_agent_broadcast', { nodeId, containerIds, message, timeout }),
|
||||
dockerDispatchTask: (nodeId, containerId, containerName, message, timeout = DOCKER_TASK_TIMEOUT_MS) => invoke('docker_dispatch_task', { nodeId, containerId, containerName, message, timeout }),
|
||||
dockerDispatchBroadcast: (nodeId, targets, message, timeout = DOCKER_TASK_TIMEOUT_MS) => invoke('docker_dispatch_broadcast', { nodeId, targets, message, timeout }),
|
||||
dockerTaskStatus: (taskId) => invoke('docker_task_status', { taskId }),
|
||||
dockerTaskList: (containerId, status) => invoke('docker_task_list', { containerId, status }),
|
||||
dockerRebuildContainer: (nodeId, containerId, pullLatest = true) => invoke('docker_rebuild_container', { nodeId, containerId, pullLatest }),
|
||||
dockerPullImage: (nodeId, image, tag, requestId) => invoke('docker_pull_image', { nodeId, image, tag, requestId }),
|
||||
dockerPullStatus: (requestId) => invoke('docker_pull_status', { requestId }),
|
||||
dockerListImages: (nodeId) => invoke('docker_list_images', { nodeId }),
|
||||
dockerListNodes: () => cachedInvoke('docker_list_nodes', {}, 30000),
|
||||
dockerAddNode: (name, endpoint) => { invalidate('docker_list_nodes', 'docker_cluster_overview'); return invoke('docker_add_node', { name, endpoint }) },
|
||||
dockerRemoveNode: (nodeId) => { invalidate('docker_list_nodes', 'docker_cluster_overview'); return invoke('docker_remove_node', { nodeId }) },
|
||||
|
||||
// 前端热更新
|
||||
checkFrontendUpdate: () => invoke('check_frontend_update'),
|
||||
|
||||
@@ -302,7 +302,6 @@ async function boot() {
|
||||
registerRoute('/about', () => import('./pages/about.js'))
|
||||
registerRoute('/assistant', () => import('./pages/assistant.js'))
|
||||
registerRoute('/setup', () => import('./pages/setup.js'))
|
||||
registerRoute('/docker', () => import('./pages/docker.js'))
|
||||
registerRoute('/channels', () => import('./pages/channels.js'))
|
||||
registerRoute('/cron', () => import('./pages/cron.js'))
|
||||
|
||||
|
||||
1733
src/pages/docker.js
1733
src/pages/docker.js
File diff suppressed because it is too large
Load Diff
1395
src/style/pages.css
1395
src/style/pages.css
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user