mirror of
https://github.com/qingchencloud/clawpanel.git
synced 2026-05-06 20:02:49 +08:00
优化:初始设置页面自动创建默认配置文件
当检测到 OpenClaw CLI 已安装但 openclaw.json 不存在时: 1. 自动创建包含合理默认值的配置文件(mode:local, tools:full 等) 2. 如果自动创建失败,显示「一键初始化配置」按钮供手动操作 3. 新增 init_openclaw_config API(dev-api.js + Tauri Rust 后端) 4. 用户不再需要去终端手动执行 openclaw configure
This commit is contained in:
@@ -583,6 +583,26 @@ const handlers = {
|
||||
return 'Gateway 服务已卸载'
|
||||
},
|
||||
|
||||
// 自动初始化配置文件(CLI 已装但 openclaw.json 不存在时)
|
||||
init_openclaw_config() {
|
||||
if (fs.existsSync(CONFIG_PATH)) return { created: false, message: '配置文件已存在' }
|
||||
if (!fs.existsSync(OPENCLAW_DIR)) fs.mkdirSync(OPENCLAW_DIR, { recursive: true })
|
||||
const defaultConfig = {
|
||||
"$schema": "https://openclaw.ai/schema/config.json",
|
||||
meta: { lastTouchedVersion: "2026.1.1" },
|
||||
mode: "local",
|
||||
models: { providers: {} },
|
||||
gateway: {
|
||||
port: 18789,
|
||||
auth: { mode: "none" },
|
||||
controlUi: { allowedOrigins: ["*"], allowInsecureAuth: true }
|
||||
},
|
||||
tools: { profile: "full", sessions: { visibility: "all" } }
|
||||
}
|
||||
fs.writeFileSync(CONFIG_PATH, JSON.stringify(defaultConfig, null, 2))
|
||||
return { created: true, message: '配置文件已创建' }
|
||||
},
|
||||
|
||||
get_deploy_config() {
|
||||
try {
|
||||
const config = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'))
|
||||
|
||||
@@ -627,6 +627,46 @@ pub async fn upgrade_openclaw(app: tauri::AppHandle, source: String) -> Result<S
|
||||
Ok(msg)
|
||||
}
|
||||
|
||||
/// 自动初始化配置文件(CLI 已装但 openclaw.json 不存在时)
|
||||
#[tauri::command]
|
||||
pub fn init_openclaw_config() -> Result<Value, String> {
|
||||
let dir = super::openclaw_dir();
|
||||
let config_path = dir.join("openclaw.json");
|
||||
let mut result = serde_json::Map::new();
|
||||
|
||||
if config_path.exists() {
|
||||
result.insert("created".into(), Value::Bool(false));
|
||||
result.insert("message".into(), Value::String("配置文件已存在".into()));
|
||||
return Ok(Value::Object(result));
|
||||
}
|
||||
|
||||
// 确保目录存在
|
||||
if !dir.exists() {
|
||||
std::fs::create_dir_all(&dir).map_err(|e| format!("创建目录失败: {e}"))?;
|
||||
}
|
||||
|
||||
let default_config = serde_json::json!({
|
||||
"$schema": "https://openclaw.ai/schema/config.json",
|
||||
"meta": { "lastTouchedVersion": "2026.1.1" },
|
||||
"mode": "local",
|
||||
"models": { "providers": {} },
|
||||
"gateway": {
|
||||
"port": 18789,
|
||||
"auth": { "mode": "none" },
|
||||
"controlUi": { "allowedOrigins": ["*"], "allowInsecureAuth": true }
|
||||
},
|
||||
"tools": { "profile": "full", "sessions": { "visibility": "all" } }
|
||||
});
|
||||
|
||||
let content = serde_json::to_string_pretty(&default_config)
|
||||
.map_err(|e| format!("序列化失败: {e}"))?;
|
||||
std::fs::write(&config_path, content).map_err(|e| format!("写入失败: {e}"))?;
|
||||
|
||||
result.insert("created".into(), Value::Bool(true));
|
||||
result.insert("message".into(), Value::String("配置文件已创建".into()));
|
||||
Ok(Value::Object(result))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn check_installation() -> Result<Value, String> {
|
||||
let dir = super::openclaw_dir();
|
||||
|
||||
@@ -20,6 +20,7 @@ pub fn run() {
|
||||
config::write_mcp_config,
|
||||
config::get_version_info,
|
||||
config::check_installation,
|
||||
config::init_openclaw_config,
|
||||
config::check_node,
|
||||
config::check_node_at_path,
|
||||
config::scan_node_paths,
|
||||
|
||||
@@ -286,6 +286,7 @@ export const api = {
|
||||
|
||||
// 安装/部署
|
||||
checkInstallation: () => cachedInvoke('check_installation', {}, 60000),
|
||||
initOpenclawConfig: () => { invalidate('check_installation'); return invoke('init_openclaw_config') },
|
||||
checkNode: () => cachedInvoke('check_node', {}, 60000),
|
||||
checkNodeAtPath: (nodeDir) => invoke('check_node_at_path', { node_dir: nodeDir }),
|
||||
scanNodePaths: () => invoke('scan_node_paths'),
|
||||
|
||||
@@ -56,7 +56,20 @@ async function runDetect(page) {
|
||||
const cliOk = clawRes.status === 'fulfilled'
|
||||
&& clawRes.value?.length > 0
|
||||
&& clawRes.value[0]?.cli_installed !== false
|
||||
const config = configRes.status === 'fulfilled' ? configRes.value : { installed: false }
|
||||
let config = configRes.status === 'fulfilled' ? configRes.value : { installed: false }
|
||||
|
||||
// CLI 已装但配置缺失 → 自动创建默认配置
|
||||
if (cliOk && !config.installed) {
|
||||
try {
|
||||
const initResult = await api.initOpenclawConfig()
|
||||
if (initResult?.created) {
|
||||
// 重新检测配置
|
||||
config = await api.checkInstallation()
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[setup] 自动初始化配置失败:', e)
|
||||
}
|
||||
}
|
||||
|
||||
renderSteps(page, { node, cliOk, config })
|
||||
}
|
||||
@@ -129,8 +142,9 @@ function renderSteps(page, { node, cliOk, config }) {
|
||||
${config.installed
|
||||
? `<p style="color:var(--success);font-size:var(--font-size-sm)">配置文件位于 ${config.path || ''}</p>`
|
||||
: `<p style="color:var(--text-secondary);font-size:var(--font-size-sm);margin-bottom:var(--space-sm)">
|
||||
安装 CLI 后会自动生成配置,也可手动执行 <code>openclaw configure</code>
|
||||
</p>`
|
||||
配置文件不存在,点击下方按钮自动创建默认配置。
|
||||
</p>
|
||||
<button class="btn btn-primary btn-sm" id="btn-init-config">一键初始化配置</button>`
|
||||
}
|
||||
</div>
|
||||
`
|
||||
@@ -187,6 +201,26 @@ function bindEvents(page, nodeOk) {
|
||||
window.location.hash = '/dashboard'
|
||||
})
|
||||
|
||||
// 一键初始化配置
|
||||
page.querySelector('#btn-init-config')?.addEventListener('click', async () => {
|
||||
const btn = page.querySelector('#btn-init-config')
|
||||
btn.disabled = true
|
||||
btn.textContent = '初始化中...'
|
||||
try {
|
||||
const result = await api.initOpenclawConfig()
|
||||
if (result?.created) {
|
||||
toast('配置文件已创建', 'success')
|
||||
} else {
|
||||
toast(result?.message || '配置文件已存在', 'info')
|
||||
}
|
||||
setTimeout(() => runDetect(page), 500)
|
||||
} catch (e) {
|
||||
toast('初始化失败: ' + e, 'error')
|
||||
btn.disabled = false
|
||||
btn.textContent = '一键初始化配置'
|
||||
}
|
||||
})
|
||||
|
||||
// 自动扫描 Node.js
|
||||
page.querySelector('#btn-scan-node')?.addEventListener('click', async () => {
|
||||
const btn = page.querySelector('#btn-scan-node')
|
||||
|
||||
Reference in New Issue
Block a user