Skip to content

Commit 55c5f7c

Browse files
committed
feat: 支持 Clojure 语言环境安装
1 parent 83e628e commit 55c5f7c

9 files changed

Lines changed: 796 additions & 17 deletions

File tree

src-tauri/src/config.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ pub struct EditorConfig {
2222
pub space_dot_omission: Option<bool>, // 是否显示空格省略
2323
}
2424

25+
#[derive(Debug, Clone, Serialize, Deserialize)]
26+
pub struct EnvironmentMirrorConfig {
27+
pub enabled: Option<bool>,
28+
pub base_url: Option<String>,
29+
}
30+
2531
#[derive(Debug, Clone, Serialize, Deserialize)]
2632
pub struct AppConfig {
2733
pub log_directory: Option<String>,
@@ -30,6 +36,7 @@ pub struct AppConfig {
3036
pub theme: Option<String>,
3137
pub plugins: Option<Vec<PluginConfig>>,
3238
pub editor: Option<EditorConfig>,
39+
pub environment_mirror: Option<EnvironmentMirrorConfig>,
3340
}
3441

3542
impl Default for AppConfig {
@@ -50,6 +57,10 @@ impl Default for AppConfig {
5057
show_function_help: Some(false),
5158
space_dot_omission: Some(false),
5259
}),
60+
environment_mirror: Some(EnvironmentMirrorConfig {
61+
enabled: Some(true),
62+
base_url: Some("http://cdn.global.devlive.top".to_string()),
63+
}),
5364
}
5465
}
5566
}
@@ -113,6 +124,15 @@ impl ConfigManager {
113124
println!("读取配置 -> 添加默认 editor 配置");
114125
}
115126

127+
// 检查并设置 environment_mirror 默认配置
128+
if config.environment_mirror.is_none() {
129+
config.environment_mirror = Some(EnvironmentMirrorConfig {
130+
enabled: Some(true),
131+
base_url: Some("http://cdn.global.devlive.top".to_string()),
132+
});
133+
println!("读取配置 -> 添加默认 environment_mirror 配置");
134+
}
135+
116136
Ok(config)
117137
}
118138
Err(e) => {
@@ -218,6 +238,10 @@ impl ConfigManager {
218238
show_function_help: Some(false),
219239
space_dot_omission: Some(false),
220240
}),
241+
environment_mirror: Some(EnvironmentMirrorConfig {
242+
enabled: Some(true),
243+
base_url: Some("http://cdn.global.devlive.top".to_string()),
244+
}),
221245
}
222246
}
223247

src-tauri/src/env_commands.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::env_manager::{EnvironmentInfo, EnvironmentManager};
22
use log::info;
3-
use tauri::{AppHandle, State};
3+
use tauri::{AppHandle, Emitter, State};
44
use tokio::sync::Mutex;
55

66
pub type EnvironmentManagerState = Mutex<EnvironmentManager>;
@@ -24,20 +24,37 @@ pub async fn download_and_install_version(
2424
) -> Result<String, String> {
2525
info!("下载并安装 {} 版本 {}", language, version);
2626
let manager = env_manager.lock().await;
27-
manager
28-
.download_and_install_version(&language, &version, app_handle)
29-
.await
27+
let result = manager
28+
.download_and_install_version(&language, &version, app_handle.clone())
29+
.await;
30+
31+
if result.is_ok() {
32+
// 发送配置更新事件通知前端刷新配置
33+
app_handle.emit("config-updated", ()).ok();
34+
info!("已发送配置更新事件");
35+
}
36+
37+
result
3038
}
3139

3240
#[tauri::command]
3341
pub async fn switch_environment_version(
3442
language: String,
3543
version: String,
44+
app_handle: AppHandle,
3645
env_manager: State<'_, EnvironmentManagerState>,
3746
) -> Result<(), String> {
3847
info!("切换 {} 到版本 {}", language, version);
3948
let manager = env_manager.lock().await;
40-
manager.switch_version(&language, &version).await
49+
let result = manager.switch_version(&language, &version).await;
50+
51+
if result.is_ok() {
52+
// 发送配置更新事件通知前端刷新配置
53+
app_handle.emit("config-updated", ()).ok();
54+
info!("已发送配置更新事件");
55+
}
56+
57+
result
4158
}
4259

4360
#[tauri::command]

src-tauri/src/env_manager.rs

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ impl EnvironmentManager {
9898
let provider = self
9999
.providers
100100
.get(language)
101-
.ok_or_else(|| format!("暂未支持 {} 语言,请前往 github 提供 issus", language))?;
101+
.ok_or_else(|| format!("暂未支持 {} 语言,请前往 github 提供 issues", language))?;
102102

103103
info!("获取 {} 环境信息", language);
104104

@@ -126,7 +126,7 @@ impl EnvironmentManager {
126126
let provider = self
127127
.providers
128128
.get(language)
129-
.ok_or_else(|| format!("暂未支持 {} 语言,请前往 github 提供 issus", language))?;
129+
.ok_or_else(|| format!("暂未支持 {} 语言,请前往 github 提供 issues", language))?;
130130

131131
info!("开始下载并安装 {} 版本 {}", language, version);
132132
provider.download_and_install(version, app_handle).await
@@ -136,7 +136,7 @@ impl EnvironmentManager {
136136
let provider = self
137137
.providers
138138
.get(language)
139-
.ok_or_else(|| format!("暂未支持 {} 语言,请前往 github 提供 issus", language))?;
139+
.ok_or_else(|| format!("暂未支持 {} 语言,请前往 github 提供 issues", language))?;
140140

141141
info!("切换 {} 到版本 {}", language, version);
142142
provider.switch_version(version).await
@@ -175,3 +175,84 @@ pub fn emit_download_progress(
175175
error!("发送下载进度事件失败: {}", e);
176176
}
177177
}
178+
179+
// 将 GitHub 下载 URL 转换为 CDN 镜像 URL
180+
pub fn convert_to_cdn_url(
181+
original_url: &str,
182+
language: &str,
183+
version: &str,
184+
) -> Result<String, String> {
185+
use crate::config::get_app_config_internal;
186+
187+
let config = get_app_config_internal().map_err(|e| format!("获取配置失败: {}", e))?;
188+
189+
let mirror_config = config.environment_mirror.as_ref();
190+
let enabled = mirror_config.and_then(|m| m.enabled).unwrap_or(false);
191+
192+
if !enabled {
193+
return Ok(original_url.to_string());
194+
}
195+
196+
let base_url = mirror_config
197+
.and_then(|m| m.base_url.as_ref())
198+
.ok_or_else(|| "CDN 基础 URL 未配置".to_string())?;
199+
200+
// 从原始 URL 中提取文件名
201+
let file_name = original_url
202+
.split('/')
203+
.last()
204+
.ok_or_else(|| "无效的下载 URL".to_string())?;
205+
206+
// 构建 CDN URL: {base_url}/{language}/{version}/{filename}
207+
let cdn_url = format!(
208+
"{}/{}/{}/{}",
209+
base_url.trim_end_matches('/'),
210+
language,
211+
version,
212+
file_name
213+
);
214+
215+
info!("转换下载 URL: {} -> {}", original_url, cdn_url);
216+
Ok(cdn_url)
217+
}
218+
219+
// 尝试从 CDN 下载,失败则回退到原始 URL
220+
pub async fn download_with_fallback(
221+
client: &reqwest::Client,
222+
original_url: &str,
223+
language: &str,
224+
version: &str,
225+
) -> Result<reqwest::Response, String> {
226+
// 首先尝试从 CDN 下载
227+
match convert_to_cdn_url(original_url, language, version) {
228+
Ok(cdn_url) if cdn_url != original_url => {
229+
info!("尝试从 CDN 下载: {}", cdn_url);
230+
match client.get(&cdn_url).send().await {
231+
Ok(response) if response.status().is_success() => {
232+
info!("CDN 下载成功");
233+
return Ok(response);
234+
}
235+
Ok(response) => {
236+
info!("CDN 下载失败 (HTTP {}), 回退到原始 URL", response.status());
237+
}
238+
Err(e) => {
239+
info!("CDN 下载失败 ({}), 回退到原始 URL", e);
240+
}
241+
}
242+
}
243+
Ok(_) => {
244+
info!("CDN 镜像未启用,使用原始 URL");
245+
}
246+
Err(e) => {
247+
info!("CDN URL 转换失败 ({}), 使用原始 URL", e);
248+
}
249+
}
250+
251+
// 回退到原始 URL
252+
info!("从原始 URL 下载: {}", original_url);
253+
client
254+
.get(original_url)
255+
.send()
256+
.await
257+
.map_err(|e| format!("下载失败: {}", e))
258+
}

0 commit comments

Comments
 (0)