mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-31 08:45:13 +08:00
🏅 Sync 2026-04-01 20:32:41
This commit is contained in:
1 parent
dae86ac53e
commit
a71872cb4e
19 files changed
+1830
-113
No files matched your search
@@ -12,6 +12,9 @@ function index()
|
||||
-- 配置管理 (View — 嵌入 oc-config Web 终端)
|
||||
entry({"admin", "services", "openclaw", "advanced"}, template("openclaw/advanced"), _("配置管理"), 20).leaf = true
|
||||
|
||||
-- 微信配置 (View — 微信渠道配置向导)
|
||||
entry({"admin", "services", "openclaw", "wechat"}, template("openclaw/wechat"), _("微信配置"), 25).leaf = true
|
||||
|
||||
-- Web 控制台 (View — 嵌入 OpenClaw Web UI)
|
||||
entry({"admin", "services", "openclaw", "console"}, template("openclaw/console"), _("Web 控制台"), 30).leaf = true
|
||||
|
||||
@@ -44,6 +47,67 @@ function index()
|
||||
|
||||
-- 系统配置检测 API (安装前检测)
|
||||
entry({"admin", "services", "openclaw", "check_system"}, call("action_check_system"), nil).leaf = true
|
||||
|
||||
-- 微信状态 API (检测插件安装和登录状态)
|
||||
entry({"admin", "services", "openclaw", "wechat_status"}, call("action_wechat_status"), nil).leaf = true
|
||||
|
||||
-- 微信插件安装 API (后台安装)
|
||||
entry({"admin", "services", "openclaw", "wechat_install"}, call("action_wechat_install"), nil).leaf = true
|
||||
|
||||
-- 微信安装日志轮询 API
|
||||
entry({"admin", "services", "openclaw", "wechat_install_log"}, call("action_wechat_install_log"), nil).leaf = true
|
||||
|
||||
-- 微信登录 API (启动登录流程)
|
||||
entry({"admin", "services", "openclaw", "wechat_login"}, call("action_wechat_login"), nil).leaf = true
|
||||
|
||||
-- 微信登录状态/二维码 API
|
||||
entry({"admin", "services", "openclaw", "wechat_login_status"}, call("action_wechat_login_status"), nil).leaf = true
|
||||
|
||||
-- 微信插件卸载 API
|
||||
entry({"admin", "services", "openclaw", "wechat_uninstall"}, call("action_wechat_uninstall"), nil).leaf = true
|
||||
|
||||
-- 微信插件检测升级 API
|
||||
entry({"admin", "services", "openclaw", "wechat_check_upgrade"}, call("action_wechat_check_upgrade"), nil).leaf = true
|
||||
|
||||
-- 微信插件升级 API
|
||||
entry({"admin", "services", "openclaw", "wechat_upgrade_plugin"}, call("action_wechat_upgrade_plugin"), nil).leaf = true
|
||||
|
||||
-- 微信退出/删除账号 API
|
||||
entry({"admin", "services", "openclaw", "wechat_logout"}, call("action_wechat_logout"), nil).leaf = true
|
||||
end-- ═══════════════════════════════════════════
|
||||
-- 获取实际安装路径 (辅助函数)
|
||||
-- ═══════════════════════════════════════════
|
||||
local function get_actual_install_path()
|
||||
local sys = require "luci.sys"
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
|
||||
-- 从 UCI 读取用户配置的基础路径
|
||||
local install_path_uci = uci:get("openclaw", "main", "install_path") or "/opt"
|
||||
local uci_install_path = install_path_uci .. "/openclaw"
|
||||
|
||||
-- 方法1: 从运行中的 gateway 进程检测实际路径
|
||||
local actual_path = sys.exec("ps w 2>/dev/null | grep -E 'openclaw.*gateway|openclaw-gateway' | grep -v grep | head -1"):gsub("%s+", "")
|
||||
if actual_path and actual_path ~= "" then
|
||||
local matched_path = actual_path:match("(/[^ ]+)/data/")
|
||||
if matched_path and nixio.fs.stat(matched_path .. "/data/.openclaw/openclaw.json", "type") then
|
||||
return matched_path
|
||||
end
|
||||
end
|
||||
|
||||
-- 方法2: 检查常见安装位置 (优先检查实际存在的配置)
|
||||
local possible_paths = {
|
||||
uci_install_path, -- UCI 配置的路径
|
||||
"/mnt/data/openclaw", -- 常见的外置存储路径
|
||||
"/opt/openclaw", -- 默认路径
|
||||
}
|
||||
for _, p in ipairs(possible_paths) do
|
||||
if nixio.fs.stat(p .. "/data/.openclaw/openclaw.json", "type") then
|
||||
return p
|
||||
end
|
||||
end
|
||||
|
||||
-- 方法3: 如果都没找到,返回 UCI 配置的路径 (即使不存在,安装时会创建)
|
||||
return uci_install_path
|
||||
end
|
||||
|
||||
-- ═══════════════════════════════════════════
|
||||
@@ -57,9 +121,9 @@ function action_status()
|
||||
local port = uci:get("openclaw", "main", "port") or "18789"
|
||||
local pty_port = uci:get("openclaw", "main", "pty_port") or "18793"
|
||||
local enabled = uci:get("openclaw", "main", "enabled") or "0"
|
||||
local install_path_uci = uci:get("openclaw", "main", "install_path") or "/opt"
|
||||
-- 实际安装路径会在用户路径下创建 openclaw 子目录
|
||||
local install_path = install_path_uci .. "/openclaw"
|
||||
|
||||
-- 使用 get_actual_install_path 获取实际安装路径
|
||||
local install_path = get_actual_install_path()
|
||||
|
||||
-- 验证端口值为纯数字,防止命令注入
|
||||
if not port:match("^%d+$") then port = "18789" end
|
||||
@@ -150,6 +214,9 @@ function action_status()
|
||||
|
||||
-- 读取已配置的渠道列表
|
||||
local channels = {}
|
||||
if content:match('"openclaw%-weixin"%s*:%s*{') then
|
||||
channels[#channels+1] = "微信"
|
||||
end
|
||||
if content:match('"qqbot"%s*:%s*{') and content:match('"appId"%s*:%s*"[^"]+"') then
|
||||
channels[#channels+1] = "QQ"
|
||||
end
|
||||
@@ -952,3 +1019,513 @@ function action_check_system()
|
||||
http.prepare_content("application/json")
|
||||
http.write_json(result)
|
||||
end
|
||||
|
||||
-- ═══════════════════════════════════════════
|
||||
-- 微信状态 API: 检测插件安装和登录状态
|
||||
-- ═══════════════════════════════════════════
|
||||
function action_wechat_status()
|
||||
local http = require "luci.http"
|
||||
local sys = require "luci.sys"
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
|
||||
-- 获取安装路径 (优先从运行环境检测)
|
||||
local install_path_uci = uci:get("openclaw", "main", "install_path") or "/opt"
|
||||
local install_path = install_path_uci .. "/openclaw"
|
||||
|
||||
-- 检测实际运行的安装路径 (通过查找 gateway 进程)
|
||||
local actual_path = sys.exec("ps w 2>/dev/null | grep -E 'openclaw.*gateway|openclaw-gateway' | grep -v grep | head -1"):gsub("%s+", "")
|
||||
if actual_path and actual_path ~= "" then
|
||||
-- 从进程命令行提取路径
|
||||
local matched_path = actual_path:match("(/[^ ]+)/data/")
|
||||
if matched_path and nixio.fs.stat(matched_path, "type") then
|
||||
install_path = matched_path
|
||||
end
|
||||
end
|
||||
|
||||
-- 也检查常见安装位置
|
||||
local possible_paths = {
|
||||
install_path,
|
||||
"/mnt/data/openclaw",
|
||||
"/opt/openclaw",
|
||||
}
|
||||
for _, p in ipairs(possible_paths) do
|
||||
if nixio.fs.stat(p .. "/data/.openclaw/openclaw.json", "type") then
|
||||
install_path = p
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local result = {
|
||||
plugin_installed = false,
|
||||
logged_in = false,
|
||||
accounts = {},
|
||||
install_path = install_path
|
||||
}
|
||||
|
||||
-- 检测微信插件是否已安装
|
||||
local wechat_ext_dir = install_path .. "/data/.openclaw/extensions/openclaw-weixin"
|
||||
local wechat_plugin_json = wechat_ext_dir .. "/openclaw.plugin.json"
|
||||
local wechat_package_json = wechat_ext_dir .. "/package.json"
|
||||
|
||||
if nixio.fs.stat(wechat_plugin_json, "type") then
|
||||
result.plugin_installed = true
|
||||
-- 尝试读取版本号
|
||||
if nixio.fs.stat(wechat_package_json, "type") then
|
||||
local pf = io.open(wechat_package_json, "r")
|
||||
if pf then
|
||||
local p_content = pf:read("*a")
|
||||
pf:close()
|
||||
local ver = p_content:match('"version"%s*:%s*"([^"]+)"')
|
||||
if ver then
|
||||
result.plugin_version = ver
|
||||
end
|
||||
end
|
||||
end
|
||||
end -- 从 openclaw.json 和 accounts.json 读取微信账号配置
|
||||
local config_file = install_path .. "/data/.openclaw/openclaw.json"
|
||||
local accounts_file = install_path .. "/data/.openclaw/openclaw-weixin/accounts.json"
|
||||
|
||||
-- 新版 OpenClaw WeChat 插件状态读取
|
||||
if nixio.fs.stat(accounts_file, "type") then
|
||||
local af = io.open(accounts_file, "r")
|
||||
if af then
|
||||
local content = af:read("*a")
|
||||
af:close()
|
||||
local count = 0
|
||||
for acc in content:gmatch('"([^"]+)"') do
|
||||
count = count + 1
|
||||
table.insert(result.accounts, {name = acc})
|
||||
end
|
||||
if count > 0 then
|
||||
result.logged_in = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local cf = io.open(config_file, "r")
|
||||
if cf then
|
||||
local content = cf:read("*a")
|
||||
cf:close()
|
||||
|
||||
if content:match('"openclaw%-weixin"%s*:%s*{') then
|
||||
-- 兼容旧版
|
||||
local accounts_str = content:match('"accounts"%s*:%s*%[([^%]]*)%]')
|
||||
if accounts_str and accounts_str ~= "" then
|
||||
local count = 0
|
||||
for _ in accounts_str:gmatch('"wxid') do count = count + 1 end
|
||||
for _ in accounts_str:gmatch('"nickName"') do count = count + 1 end
|
||||
if count > 0 and not result.logged_in then
|
||||
result.logged_in = true
|
||||
result.accounts = {{name = "微信账号"}}
|
||||
end
|
||||
end
|
||||
|
||||
if content:match('"credential"%s*:%s*{') and not result.logged_in then
|
||||
result.logged_in = true
|
||||
result.accounts = {{name = "微信账号"}}
|
||||
end
|
||||
end
|
||||
end http.prepare_content("application/json")
|
||||
http.write_json(result)
|
||||
end
|
||||
|
||||
-- ═══════════════════════════════════════════
|
||||
-- 微信插件安装 API (后台安装)
|
||||
-- ═══════════════════════════════════════════
|
||||
function action_wechat_install()
|
||||
local http = require "luci.http"
|
||||
local sys = require "luci.sys"
|
||||
|
||||
local install_path = get_actual_install_path()
|
||||
local node_bin = install_path .. "/node/bin/node"
|
||||
local npx_bin = install_path .. "/node/bin/npx"
|
||||
local oc_data = install_path .. "/data"
|
||||
|
||||
-- 清理旧日志和状态
|
||||
sys.exec("rm -f /tmp/openclaw-wechat-install.log /tmp/openclaw-wechat-install.pid /tmp/openclaw-wechat-install.exit")
|
||||
|
||||
-- 后台执行安装
|
||||
local install_cmd = string.format(
|
||||
"( " ..
|
||||
"echo '开始安装微信插件...' > /tmp/openclaw-wechat-install.log; " ..
|
||||
"echo '安装路径: %s' >> /tmp/openclaw-wechat-install.log; " ..
|
||||
"cd %s && " ..
|
||||
"su -s /bin/sh openclaw -c 'HOME=%s OPENCLAW_HOME=%s OPENCLAW_STATE_DIR=%s/.openclaw " ..
|
||||
"PATH=%s/node/bin:%s/global/bin:$PATH " ..
|
||||
"%s -y @tencent-weixin/openclaw-weixin-cli install' >> /tmp/openclaw-wechat-install.log 2>&1; " ..
|
||||
"RC=$?; echo $RC > /tmp/openclaw-wechat-install.exit; " ..
|
||||
"if [ $RC -eq 0 ]; then echo '✅ 微信插件安装成功!' >> /tmp/openclaw-wechat-install.log; " ..
|
||||
"else echo '❌ 安装失败 (exit: '$RC')' >> /tmp/openclaw-wechat-install.log; fi " ..
|
||||
") & echo $! > /tmp/openclaw-wechat-install.pid",
|
||||
install_path, oc_data, oc_data, oc_data, oc_data, install_path, install_path, npx_bin
|
||||
) sys.exec(install_cmd)
|
||||
|
||||
http.prepare_content("application/json")
|
||||
http.write_json({ status = "ok", message = "微信插件安装已在后台启动..." })
|
||||
end
|
||||
|
||||
-- ═══════════════════════════════════════════
|
||||
-- 微信安装日志轮询 API
|
||||
-- ═══════════════════════════════════════════
|
||||
function action_wechat_install_log()
|
||||
local http = require "luci.http"
|
||||
local sys = require "luci.sys"
|
||||
|
||||
local log = ""
|
||||
local f = io.open("/tmp/openclaw-wechat-install.log", "r")
|
||||
if f then
|
||||
log = f:read("*a") or ""
|
||||
f:close()
|
||||
end
|
||||
|
||||
local running = false
|
||||
local pid_file = io.open("/tmp/openclaw-wechat-install.pid", "r")
|
||||
if pid_file then
|
||||
local pid = pid_file:read("*a"):gsub("%s+", "")
|
||||
pid_file:close()
|
||||
if pid ~= "" then
|
||||
local check = sys.exec("kill -0 " .. pid .. " 2>/dev/null && echo yes || echo no"):gsub("%s+", "")
|
||||
running = (check == "yes")
|
||||
end
|
||||
end
|
||||
|
||||
local exit_code = -1
|
||||
if not running then
|
||||
local exit_file = io.open("/tmp/openclaw-wechat-install.exit", "r")
|
||||
if exit_file then
|
||||
local code = exit_file:read("*a"):gsub("%s+", "")
|
||||
exit_file:close()
|
||||
exit_code = tonumber(code) or -1
|
||||
end
|
||||
end
|
||||
|
||||
local state = "idle"
|
||||
if running then
|
||||
state = "running"
|
||||
elseif exit_code == 0 then
|
||||
state = "success"
|
||||
elseif exit_code > 0 then
|
||||
state = "failed"
|
||||
end
|
||||
|
||||
http.prepare_content("application/json")
|
||||
http.write_json({
|
||||
status = "ok",
|
||||
log = log,
|
||||
state = state,
|
||||
running = running,
|
||||
exit_code = exit_code
|
||||
})
|
||||
end
|
||||
|
||||
-- ═══════════════════════════════════════════
|
||||
-- 微信登录 API (启动登录流程并获取二维码)
|
||||
-- ═══════════════════════════════════════════
|
||||
function action_wechat_login()
|
||||
local http = require "luci.http"
|
||||
local sys = require "luci.sys"
|
||||
|
||||
local install_path = get_actual_install_path()
|
||||
local node_bin = install_path .. "/node/bin/node"
|
||||
local oc_data = install_path .. "/data"
|
||||
local oc_entry = ""
|
||||
|
||||
-- 查找 openclaw 入口
|
||||
local search_dirs = {
|
||||
install_path .. "/global/lib/node_modules/openclaw",
|
||||
install_path .. "/global/node_modules/openclaw",
|
||||
install_path .. "/node/lib/node_modules/openclaw",
|
||||
}
|
||||
for _, d in ipairs(search_dirs) do
|
||||
if nixio.fs.stat(d .. "/openclaw.mjs", "type") then
|
||||
oc_entry = d .. "/openclaw.mjs"
|
||||
break
|
||||
elseif nixio.fs.stat(d .. "/dist/cli.js", "type") then
|
||||
oc_entry = d .. "/dist/cli.js"
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if oc_entry == "" then
|
||||
http.prepare_content("application/json")
|
||||
http.write_json({ status = "error", message = "OpenClaw 未安装" })
|
||||
return
|
||||
end
|
||||
|
||||
-- 清理旧状态和可能的残留进程
|
||||
sys.exec("kill -9 $(cat /tmp/openclaw-wechat-login.pid 2>/dev/null) 2>/dev/null")
|
||||
sys.exec("pkill -f 'channels login --channel openclaw-weixin' 2>/dev/null")
|
||||
sys.exec("rm -f /tmp/openclaw-wechat-qrcode.txt /tmp/openclaw-wechat-login.pid /tmp/openclaw-wechat-login.exit /tmp/openclaw-wechat-restarted") -- 后台启动登录流程,将二维码输出到文件
|
||||
local login_cmd = string.format(
|
||||
"( " ..
|
||||
"echo '正在启动微信登录...' > /tmp/openclaw-wechat-qrcode.txt; " ..
|
||||
"echo '安装路径: %s' >> /tmp/openclaw-wechat-qrcode.txt; " ..
|
||||
"cd %s && " ..
|
||||
"su -s /bin/sh openclaw -c 'HOME=%s OPENCLAW_HOME=%s OPENCLAW_STATE_DIR=%s/.openclaw OPENCLAW_CONFIG_PATH=%s/.openclaw/openclaw.json " ..
|
||||
"PATH=%s/node/bin:%s/global/bin:$PATH " ..
|
||||
"%s %s channels login --channel openclaw-weixin' >> /tmp/openclaw-wechat-qrcode.txt 2>&1; " ..
|
||||
"echo $? > /tmp/openclaw-wechat-login.exit; " ..
|
||||
") >/dev/null 2>&1 & echo $! > /tmp/openclaw-wechat-login.pid",
|
||||
install_path, oc_data, oc_data, oc_data, oc_data, oc_data, install_path, install_path, node_bin, oc_entry
|
||||
) sys.exec(login_cmd)
|
||||
|
||||
http.prepare_content("application/json")
|
||||
http.write_json({ status = "ok", message = "微信登录流程已启动" })
|
||||
end
|
||||
|
||||
-- ═══════════════════════════════════════════
|
||||
-- 微信登录状态/二维码 API
|
||||
-- ═══════════════════════════════════════════
|
||||
function action_wechat_login_status()
|
||||
local http = require "luci.http"
|
||||
local sys = require "luci.sys"
|
||||
|
||||
-- 读取二维码输出
|
||||
local qrcode = ""
|
||||
local f = io.open("/tmp/openclaw-wechat-qrcode.txt", "r")
|
||||
if f then
|
||||
qrcode = f:read("*a") or ""
|
||||
f:close()
|
||||
end
|
||||
|
||||
-- 检查进程状态
|
||||
local running = false
|
||||
local pid_file = io.open("/tmp/openclaw-wechat-login.pid", "r")
|
||||
if pid_file then
|
||||
local pid = pid_file:read("*a"):gsub("%s+", "")
|
||||
pid_file:close()
|
||||
if pid ~= "" then
|
||||
local check = sys.exec("kill -0 " .. pid .. " 2>/dev/null && echo yes || echo no"):gsub("%s+", "")
|
||||
running = (check == "yes")
|
||||
end
|
||||
end
|
||||
|
||||
local exit_code = -1
|
||||
if not running then
|
||||
local exit_file = io.open("/tmp/openclaw-wechat-login.exit", "r")
|
||||
if exit_file then
|
||||
local code = exit_file:read("*a"):gsub("%s+", "")
|
||||
exit_file:close()
|
||||
exit_code = tonumber(code) or -1
|
||||
end
|
||||
end
|
||||
|
||||
-- 提取最后生成的二维码 URL
|
||||
local qrcode_url = ""
|
||||
for url in qrcode:gmatch("https?://[^\n\r]+") do
|
||||
qrcode_url = url
|
||||
end -- 检查是否登录成功
|
||||
local logged_in = qrcode:find("登录成功") ~= nil or qrcode:find("成功登录") ~= nil or qrcode:find("Login success") ~= nil or qrcode:find("Logged in") ~= nil
|
||||
|
||||
local state = "idle"
|
||||
if logged_in then
|
||||
state = "success"
|
||||
elseif running and qrcode_url ~= "" then
|
||||
state = "qrcode"
|
||||
elseif running then
|
||||
state = "starting"
|
||||
elseif exit_code == 0 then
|
||||
state = "success"
|
||||
elseif exit_code > 0 then
|
||||
state = "failed"
|
||||
end
|
||||
|
||||
-- 如果刚登录成功,触发一次重启,确保主进程加载微信
|
||||
if state == "success" and not nixio.fs.stat("/tmp/openclaw-wechat-restarted", "type") then
|
||||
sys.exec("touch /tmp/openclaw-wechat-restarted")
|
||||
sys.exec("/etc/init.d/openclaw restart &")
|
||||
end http.prepare_content("application/json")
|
||||
http.write_json({
|
||||
status = "ok",
|
||||
state = state,
|
||||
qrcode = qrcode,
|
||||
qrcode_url = qrcode_url,
|
||||
running = running,
|
||||
exit_code = exit_code,
|
||||
logged_in = logged_in
|
||||
})
|
||||
end
|
||||
|
||||
-- ═══════════════════════════════════════════
|
||||
-- 微信插件卸载 API
|
||||
-- ═══════════════════════════════════════════
|
||||
function action_wechat_uninstall()
|
||||
local http = require "luci.http"
|
||||
local sys = require "luci.sys"
|
||||
|
||||
local install_path = get_actual_install_path()
|
||||
|
||||
-- 删除微信插件目录
|
||||
local wechat_ext_dir = install_path .. "/data/.openclaw/extensions/openclaw-weixin"
|
||||
if nixio.fs.stat(wechat_ext_dir, "type") then
|
||||
sys.exec("rm -rf " .. wechat_ext_dir)
|
||||
end
|
||||
|
||||
-- 从配置中删除微信相关配置
|
||||
local config_file = install_path .. "/data/.openclaw/openclaw.json"
|
||||
if nixio.fs.stat(config_file, "type") then
|
||||
-- 读取配置
|
||||
local cf = io.open(config_file, "r")
|
||||
local content = ""
|
||||
if cf then
|
||||
content = cf:read("*a") or ""
|
||||
cf:close()
|
||||
end
|
||||
|
||||
-- 删除微信配置块 (简单字符串替换)
|
||||
content = content:gsub(',?%s*"openclaw%-weixin"%s*:%s*%b{}', "")
|
||||
content = content:gsub('"openclaw%-weixin"%s*:%s*%b{}%s*,?', "")
|
||||
|
||||
-- 写回配置
|
||||
local wf = io.open(config_file, "w")
|
||||
if wf then
|
||||
wf:write(content)
|
||||
wf:close()
|
||||
end
|
||||
end
|
||||
|
||||
-- 清理临时文件
|
||||
sys.exec("rm -f /tmp/openclaw-wechat-*.log /tmp/openclaw-wechat-*.pid /tmp/openclaw-wechat-*.exit /tmp/openclaw-wechat-qrcode.txt")
|
||||
|
||||
http.prepare_content("application/json")
|
||||
http.write_json({ status = "ok", message = "微信插件已卸载" })
|
||||
end
|
||||
|
||||
-- ═══════════════════════════════════════════
|
||||
-- 微信插件检测升级 API
|
||||
-- ═══════════════════════════════════════════
|
||||
function action_wechat_check_upgrade()
|
||||
local http = require "luci.http"
|
||||
local sys = require "luci.sys"
|
||||
|
||||
local install_path = get_actual_install_path()
|
||||
local npx_bin = install_path .. "/node/bin/npx"
|
||||
local oc_data = install_path .. "/data"
|
||||
|
||||
-- 获取当前已安装版本
|
||||
local current_version = ""
|
||||
local wechat_ext_dir = install_path .. "/data/.openclaw/extensions/openclaw-weixin"
|
||||
local plugin_json = wechat_ext_dir .. "/openclaw.plugin.json"
|
||||
local pf = io.open(plugin_json, "r")
|
||||
if pf then
|
||||
local content = pf:read("*a") or ""
|
||||
pf:close()
|
||||
current_version = content:match('"version"%s*:%s*"([^"]+)"') or ""
|
||||
end
|
||||
|
||||
-- 检测最新版本 (通过 npm view)
|
||||
local latest_version = ""
|
||||
local env_prefix = string.format(
|
||||
"HOME=%s PATH=%s/node/bin:%s/global/bin:$PATH",
|
||||
oc_data, install_path, install_path
|
||||
)
|
||||
local check_cmd = string.format(
|
||||
"%s %s view @tencent-weixin/openclaw-weixin version 2>/dev/null",
|
||||
env_prefix, npx_bin
|
||||
)
|
||||
latest_version = sys.exec(check_cmd):gsub("%s+", "")
|
||||
|
||||
local has_upgrade = false
|
||||
if current_version ~= "" and latest_version ~= "" and current_version ~= latest_version then
|
||||
has_upgrade = true
|
||||
end
|
||||
|
||||
http.prepare_content("application/json")
|
||||
http.write_json({
|
||||
status = "ok",
|
||||
current_version = current_version,
|
||||
latest_version = latest_version,
|
||||
has_upgrade = has_upgrade
|
||||
})
|
||||
end
|
||||
|
||||
-- ═══════════════════════════════════════════
|
||||
-- 微信插件升级 API (后台执行安装命令)
|
||||
-- ═══════════════════════════════════════════
|
||||
function action_wechat_upgrade_plugin()
|
||||
local http = require "luci.http"
|
||||
local sys = require "luci.sys"
|
||||
|
||||
local install_path = get_actual_install_path()
|
||||
local npx_bin = install_path .. "/node/bin/npx"
|
||||
local oc_data = install_path .. "/data"
|
||||
|
||||
-- 清理旧日志和状态
|
||||
sys.exec("rm -f /tmp/openclaw-wechat-install.log /tmp/openclaw-wechat-install.pid /tmp/openclaw-wechat-install.exit")
|
||||
|
||||
-- 后台执行升级 (其实就是重新安装最新版)
|
||||
local upgrade_cmd = string.format(
|
||||
"( " ..
|
||||
"echo '正在升级微信插件...' > /tmp/openclaw-wechat-install.log; " ..
|
||||
"echo '安装路径: %s' >> /tmp/openclaw-wechat-install.log; " ..
|
||||
"cd %s && " ..
|
||||
"su -s /bin/sh openclaw -c 'HOME=%s OPENCLAW_HOME=%s OPENCLAW_STATE_DIR=%s/.openclaw " ..
|
||||
"PATH=%s/node/bin:%s/global/bin:$PATH " ..
|
||||
"%s -y @tencent-weixin/openclaw-weixin-cli install' >> /tmp/openclaw-wechat-install.log 2>&1; " ..
|
||||
"RC=$?; echo $RC > /tmp/openclaw-wechat-install.exit; " ..
|
||||
"if [ $RC -eq 0 ]; then echo '✅ 微信插件升级成功!' >> /tmp/openclaw-wechat-install.log; " ..
|
||||
"else echo '❌ 升级失败 (exit: '$RC')' >> /tmp/openclaw-wechat-install.log; fi " ..
|
||||
") & echo $! > /tmp/openclaw-wechat-install.pid",
|
||||
install_path, oc_data, oc_data, oc_data, oc_data, install_path, install_path, npx_bin
|
||||
) sys.exec(upgrade_cmd)
|
||||
|
||||
http.prepare_content("application/json")
|
||||
http.write_json({ status = "ok", message = "微信插件升级已在后台启动..." })
|
||||
end
|
||||
|
||||
-- ═══════════════════════════════════════════
|
||||
-- 微信退出/删除账号 API
|
||||
-- ═══════════════════════════════════════════
|
||||
function action_wechat_logout()
|
||||
local http = require "luci.http"
|
||||
local sys = require "luci.sys"
|
||||
local account_id = http.formvalue("account")
|
||||
|
||||
if not account_id or account_id == "" then
|
||||
http.prepare_content("application/json")
|
||||
http.write_json({ status = "error", message = "参数错误:未提供账号 ID" })
|
||||
return
|
||||
end
|
||||
|
||||
local install_path = get_actual_install_path()
|
||||
local node_bin = install_path .. "/node/bin/node"
|
||||
local oc_data = install_path .. "/data"
|
||||
local oc_entry = ""
|
||||
|
||||
local search_dirs = {
|
||||
install_path .. "/global/lib/node_modules/openclaw",
|
||||
install_path .. "/global/node_modules/openclaw",
|
||||
install_path .. "/node/lib/node_modules/openclaw",
|
||||
}
|
||||
for _, d in ipairs(search_dirs) do
|
||||
if nixio.fs.stat(d .. "/openclaw.mjs", "type") then
|
||||
oc_entry = d .. "/openclaw.mjs"
|
||||
break
|
||||
elseif nixio.fs.stat(d .. "/dist/cli.js", "type") then
|
||||
oc_entry = d .. "/dist/cli.js"
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if oc_entry == "" then
|
||||
http.prepare_content("application/json")
|
||||
http.write_json({ status = "error", message = "OpenClaw 未安装" })
|
||||
return
|
||||
end
|
||||
|
||||
-- 在后台执行 logout
|
||||
local logout_cmd = string.format(
|
||||
"cd %s && su -s /bin/sh openclaw -c 'HOME=%s OPENCLAW_HOME=%s OPENCLAW_STATE_DIR=%s/.openclaw OPENCLAW_CONFIG_PATH=%s/.openclaw/openclaw.json " ..
|
||||
"PATH=%s/node/bin:%s/global/bin:$PATH " ..
|
||||
"%s %s channels logout --channel openclaw-weixin --account \"%s\"'",
|
||||
oc_data, oc_data, oc_data, oc_data, oc_data, install_path, install_path, node_bin, oc_entry, account_id
|
||||
)
|
||||
|
||||
sys.exec(logout_cmd .. " >/dev/null 2>&1")
|
||||
|
||||
-- 重启服务
|
||||
sys.exec("/etc/init.d/openclaw restart &")
|
||||
|
||||
http.prepare_content("application/json")
|
||||
http.write_json({ status = "ok", message = "已下线账号: " .. account_id })
|
||||
end
|
||||
Reference in new issue
Block a user