feat: WFJ Panel v0.1.0 - 完整功能版

- SSH 服务器连接管理 + 登录页自动预填
- 服务器概览监控(CPU/内存/硬盘/网络/进程,进程卡片支持排序和端口显示)
- 远程文件管理(浏览/上传/下载/新建/删除,实时进度条)
- 交互式终端(xterm.js + ssh2 PTY)
- Docker 容器管理(三连接架构,概览/容器列表/镜像/应用商店/任务中心/配置/网络/卷)
- 应用商店一键部署(Redis/MySQL/Halo,在线模板同步,数据驱动 options/showWhen/extraArgs)
- Docker 镜像源配置(daemon.json 编辑 + 自动重启)
- Docker 强制停止修复(三步强制停止 + 轮询确认)
- 系统防火墙管理(firewalld/ufw/iptables 自动检测 + GUI 管理)
- 客户端版本检查(/api/version 接口 + 更新弹窗)
- 品牌名统一为 WFJ Panel
- electron-builder 打包配置(NSIS 安装包,国内镜像)
- .npmrc 配置 Electron 国内镜像
This commit is contained in:
2026-09-08 01:25:54 +08:00
parent e929d4842e
commit 90bc4bd398
46 changed files with 14841 additions and 57 deletions
+290
View File
@@ -0,0 +1,290 @@
-- ============================================================
-- 应用商店数据库 —— 建表 + 初始数据
-- 数据库: my_panel
-- 字符集: utf8mb4
-- ============================================================
-- ─── 主表 ───
CREATE TABLE IF NOT EXISTS app_templates (
id INT AUTO_INCREMENT PRIMARY KEY,
app_key VARCHAR(64) NOT NULL UNIQUE COMMENT '唯一标识 (redis / mysql)',
name VARCHAR(128) NOT NULL COMMENT '显示名称',
tagline VARCHAR(256) DEFAULT NULL COMMENT '一句话描述',
description TEXT DEFAULT NULL COMMENT '详细描述',
icon VARCHAR(32) DEFAULT NULL COMMENT '图标标识 (redis / mysql)',
category VARCHAR(64) DEFAULT NULL COMMENT '分类',
image VARCHAR(256) NOT NULL COMMENT 'Docker 镜像',
container_name VARCHAR(128) NOT NULL COMMENT '容器名称',
network VARCHAR(128) DEFAULT '' COMMENT 'Docker 网络',
restart VARCHAR(32) DEFAULT 'always' COMMENT '重启策略',
hostname VARCHAR(128) DEFAULT '' COMMENT '容器主机名',
workdir VARCHAR(256) DEFAULT '' COMMENT '工作目录',
command TEXT DEFAULT NULL COMMENT '启动命令',
extra_args TEXT DEFAULT NULL COMMENT '额外 docker run 参数模板 (含 {{}} 占位符)',
sort_order INT DEFAULT 0 COMMENT '排序权重',
is_active TINYINT(1) DEFAULT 1 COMMENT '是否上架 1=是 0=否',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='应用模板主表';
-- ─── 子表:端口映射 ───
CREATE TABLE IF NOT EXISTS app_ports (
id INT AUTO_INCREMENT PRIMARY KEY,
template_id INT NOT NULL,
host_port VARCHAR(16) NOT NULL COMMENT '宿主机端口',
container_port VARCHAR(16) NOT NULL COMMENT '容器端口',
protocol VARCHAR(8) DEFAULT 'tcp' COMMENT '协议',
sort_order INT DEFAULT 0,
FOREIGN KEY (template_id) REFERENCES app_templates(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ─── 子表:挂载卷 ───
CREATE TABLE IF NOT EXISTS app_volumes (
id INT AUTO_INCREMENT PRIMARY KEY,
template_id INT NOT NULL,
host_path VARCHAR(512) NOT NULL COMMENT '宿主机路径',
container_path VARCHAR(512) NOT NULL COMMENT '容器路径',
mode VARCHAR(4) DEFAULT 'rw' COMMENT '读写模式',
sort_order INT DEFAULT 0,
FOREIGN KEY (template_id) REFERENCES app_templates(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ─── 子表:环境变量 ───
CREATE TABLE IF NOT EXISTS app_envs (
id INT AUTO_INCREMENT PRIMARY KEY,
template_id INT NOT NULL,
env_key VARCHAR(256) NOT NULL COMMENT '变量名',
env_value TEXT DEFAULT NULL COMMENT '变量值 (含 {{}} 占位符)',
sort_order INT DEFAULT 0,
FOREIGN KEY (template_id) REFERENCES app_templates(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ─── 子表:自动创建目录 ───
CREATE TABLE IF NOT EXISTS app_mkdirs (
id INT AUTO_INCREMENT PRIMARY KEY,
template_id INT NOT NULL,
dir_path VARCHAR(512) NOT NULL COMMENT '宿主机目录',
sort_order INT DEFAULT 0,
FOREIGN KEY (template_id) REFERENCES app_templates(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ─── 子表:自动写入配置文件 ───
CREATE TABLE IF NOT EXISTS app_write_files (
id INT AUTO_INCREMENT PRIMARY KEY,
template_id INT NOT NULL,
file_path VARCHAR(512) NOT NULL COMMENT '宿主机文件路径',
file_content LONGTEXT NOT NULL COMMENT '文件内容 (含 {{}} 占位符)',
sort_order INT DEFAULT 0,
FOREIGN KEY (template_id) REFERENCES app_templates(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ─── 子表:用户参数 ───
CREATE TABLE IF NOT EXISTS app_params (
id INT AUTO_INCREMENT PRIMARY KEY,
template_id INT NOT NULL,
param_key VARCHAR(64) NOT NULL COMMENT '参数键',
label VARCHAR(128) NOT NULL COMMENT '显示标签',
type VARCHAR(16) DEFAULT 'text' COMMENT 'text/password/number',
placeholder VARCHAR(256) DEFAULT NULL,
default_value VARCHAR(256) DEFAULT '' COMMENT '默认值',
required TINYINT(1) DEFAULT 0 COMMENT '是否必填',
options TEXT DEFAULT NULL COMMENT '下拉选项 JSON 数组 [{"value":"","label":""}]',
show_when VARCHAR(128) DEFAULT NULL COMMENT '条件显示 param_key:value',
sort_order INT DEFAULT 0,
FOREIGN KEY (template_id) REFERENCES app_templates(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ============================================================
-- 初始数据:Redis 模板
-- ============================================================
INSERT INTO app_templates (app_key, name, tagline, description, icon, category, image, container_name, network, restart, hostname, workdir, command, sort_order, is_active)
VALUES ('redis', 'Redis', '高性能内存数据库 / 缓存',
'Redis 是开源的内存数据结构存储,用作数据库、缓存、消息队列和流引擎。支持字符串、哈希、列表、集合等多种数据结构。',
'redis', '缓存', 'redis:8.10.0', 'redis', '', 'always', 'redis', '/data',
'redis-server /etc/redis/redis.conf', 1, 1);
SET @redis_id = LAST_INSERT_ID();
INSERT INTO app_ports (template_id, host_port, container_port, protocol, sort_order) VALUES
(@redis_id, '6379', '6379', 'tcp', 0);
INSERT INTO app_volumes (template_id, host_path, container_path, mode, sort_order) VALUES
(@redis_id, '/opt/redis/data', '/data', 'rw', 0),
(@redis_id, '/opt/redis/conf/redis.conf', '/etc/redis/redis.conf', 'rw', 1),
(@redis_id, '/opt/redis/logs', '/logs', 'rw', 2);
INSERT INTO app_mkdirs (template_id, dir_path, sort_order) VALUES
(@redis_id, '/opt/redis/data', 0),
(@redis_id, '/opt/redis/conf', 1),
(@redis_id, '/opt/redis/logs', 2);
INSERT INTO app_write_files (template_id, file_path, file_content, sort_order) VALUES
(@redis_id, '/opt/redis/conf/redis.conf',
'# Redis 配置文件
bind 0.0.0.0
protected-mode no
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 密码(部署时替换,留空则无密码)
{{REDIS_PASSWORD_LINE}}', 0);
INSERT INTO app_params (template_id, param_key, label, type, placeholder, default_value, required, sort_order) VALUES
(@redis_id, 'REDIS_PASSWORD', 'Redis 密码', 'password', '留空则无密码', '', 0, 0),
(@redis_id, 'PORT', '宿主机端口', 'number', '6379', '6379', 1, 1);
-- ============================================================
-- 初始数据:MySQL 模板
-- ============================================================
INSERT INTO app_templates (app_key, name, tagline, description, icon, category, image, container_name, network, restart, hostname, workdir, command, sort_order, is_active)
VALUES ('mysql', 'MySQL', '关系型数据库',
'MySQL 是最流行的开源关系型数据库管理系统,支持事务、存储过程、触发器、视图等完整 SQL 功能。此模板基于 MySQL 8.4 LTS。',
'mysql', '数据库', 'mysql:8.4.11', 'mysql', '', 'always', 'mysql', '/', '', 2, 1);
SET @mysql_id = LAST_INSERT_ID();
INSERT INTO app_ports (template_id, host_port, container_port, protocol, sort_order) VALUES
(@mysql_id, '3306', '3306', 'tcp', 0);
INSERT INTO app_volumes (template_id, host_path, container_path, mode, sort_order) VALUES
(@mysql_id, '/opt/mysql/data', '/var/lib/mysql', 'rw', 0),
(@mysql_id, '/opt/mysql/conf/my.cnf', '/etc/my.cnf', 'rw', 1),
(@mysql_id, '/opt/mysql/log', '/var/log/mysql', 'rw', 2),
(@mysql_id, '/etc/timezone', '/etc/timezone', 'ro', 3),
(@mysql_id, '/etc/localtime', '/etc/localtime', 'ro', 4);
INSERT INTO app_envs (template_id, env_key, env_value, sort_order) VALUES
(@mysql_id, 'MYSQL_ROOT_PASSWORD', '{{MYSQL_ROOT_PASSWORD}}', 0);
INSERT INTO app_mkdirs (template_id, dir_path, sort_order) VALUES
(@mysql_id, '/opt/mysql/data', 0),
(@mysql_id, '/opt/mysql/conf', 1),
(@mysql_id, '/opt/mysql/log', 2);
INSERT INTO app_write_files (template_id, file_path, file_content, sort_order) VALUES
(@mysql_id, '/opt/mysql/conf/my.cnf',
'# MySQL 配置文件
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
secure-file-priv= NULL
# 字符集
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 最大连接数
max_connections = 200
# Innodb
innodb_buffer_pool_size = 128M
innodb_log_file_size = 48M
innodb_flush_log_at_trx_commit = 1
# 日志
log-error = /var/log/mysql/error.log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
# 端口
port = 3306
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4', 0);
INSERT INTO app_params (template_id, param_key, label, type, placeholder, default_value, required, sort_order) VALUES
(@mysql_id, 'MYSQL_ROOT_PASSWORD', 'Root 密码', 'password', '设置 root 用户密码', '', 1, 0),
(@mysql_id, 'PORT', '宿主机端口', 'number', '3306', '3306', 1, 1);
-- ============================================================
-- 初始数据:Halo 模板
-- ============================================================
INSERT INTO app_templates (app_key, name, tagline, description, icon, category, image, container_name, network, restart, hostname, workdir, command, extra_args, sort_order, is_active)
VALUES ('halo', 'Halo', '强大易用的开源建站工具',
'Halo 是一款开源的建站工具,支持博客、CMS、企业官网等多种场景。内置主题管理、插件系统、多用户、SEO 等功能。社区版基于开源仓库构建,免费使用。',
'halo', '建站', 'registry.fit2cloud.com/halo/halo:2.26', 'halo', '', 'always', 'halo', '', '', '{{HALO_DB_ARGS}}', 3, 1);
SET @halo_id = LAST_INSERT_ID();
INSERT INTO app_ports (template_id, host_port, container_port, protocol, sort_order) VALUES
(@halo_id, '{{PORT}}', '8090', 'tcp', 0);
INSERT INTO app_volumes (template_id, host_path, container_path, mode, sort_order) VALUES
(@halo_id, '/opt/halo/data', '/root/.halo2', 'rw', 0);
INSERT INTO app_envs (template_id, env_key, env_value, sort_order) VALUES
(@halo_id, 'JVM_OPTS', '-Xmx{{JVM_MAX}} -Xms{{JVM_MIN}}', 0);
INSERT INTO app_mkdirs (template_id, dir_path, sort_order) VALUES
(@halo_id, '/opt/halo/data', 0);
INSERT INTO app_params (template_id, param_key, label, type, placeholder, default_value, required, options, show_when, sort_order) VALUES
(@halo_id, 'PORT', '宿主机端口', 'number', '8090', '8090', 1, NULL, NULL, 0),
(@halo_id, 'JVM_MAX', 'JVM 最大内存', 'text', '256m', '256m', 1, NULL, NULL, 1),
(@halo_id, 'JVM_MIN', 'JVM 初始内存', 'text', '256m', '256m', 1, NULL, NULL, 2),
(@halo_id, 'DB_TYPE', '数据库', 'select', 'H2 内置数据库', 'h2', 1, '[{"value":"h2","label":"H2 内置数据库(零配置)"},{"value":"mysql","label":"MySQL 外部数据库"}]', NULL, 3),
(@halo_id, 'DB_HOST', 'MySQL 地址', 'text', '127.0.0.1', '127.0.0.1', 0, NULL, 'DB_TYPE:mysql', 4),
(@halo_id, 'DB_PORT', 'MySQL 端口', 'number', '3306', '3306', 0, NULL, 'DB_TYPE:mysql', 5),
(@halo_id, 'DB_NAME', 'MySQL 库名', 'text', 'halodb', 'halodb', 0, NULL, 'DB_TYPE:mysql', 6),
(@halo_id, 'DB_USER', 'MySQL 用户名', 'text', 'root', 'root', 0, NULL, 'DB_TYPE:mysql', 7),
(@halo_id, 'DB_PASSWORD', 'MySQL 密码', 'password', '数据库密码', '', 0, NULL, 'DB_TYPE:mysql', 8);
-- Halo 的 extra_args ({{HALO_DB_ARGS}}) 由前端 tplWithDerived 函数动态解析,
-- 根据 DB_TYPE 参数自动生成 MySQL 连接环境变量或留空(H2 模式)
-- ============================================================
-- 客户端版本管理表
-- ============================================================
CREATE TABLE IF NOT EXISTS app_version (
id INT AUTO_INCREMENT PRIMARY KEY,
version VARCHAR(32) NOT NULL UNIQUE COMMENT '版本号 (如 v0.0.1)',
download_url VARCHAR(512) NOT NULL COMMENT '下载地址',
release_notes TEXT DEFAULT NULL COMMENT '更新说明',
is_latest TINYINT(1) DEFAULT 0 COMMENT '是否为最新版本 1=是 0=否',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='客户端版本管理';
-- 初始版本数据:v0.0.1
INSERT INTO app_version (version, download_url, release_notes, is_latest, created_at)
VALUES ('v0.0.1', 'https://114.66.55.63:3001/download/wfj-panel-v0.0.1.exe',
'WFJ Panel 首个版本 v0.0.1
功能列表:
- SSH 远程服务器连接管理
- 服务器概览监控(CPU/内存/硬盘/网络/进程)
- 远程文件管理(上传/下载/新建/删除)
- 交互式终端(xterm.js)
- Docker 容器管理(概览/容器列表/镜像/应用商店/任务中心/配置/网络/卷)
- 应用商店一键部署(Redis/MySQL/Halo)
- 系统防火墙管理(firewalld/ufw/iptables)', 1, NOW());