Skip to content

Commit fa3e14a

Browse files
committed
feat: 增加缓冲管理
1 parent 24426e1 commit fa3e14a

File tree

5 files changed

+314
-2
lines changed

5 files changed

+314
-2
lines changed

src-tauri/src/cache.rs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
use log::info;
2+
use serde::{Deserialize, Serialize};
3+
use std::fs;
4+
use std::path::PathBuf;
5+
6+
#[derive(Debug, Serialize, Deserialize)]
7+
pub struct CacheInfo {
8+
pub plugins_cache_size: u64,
9+
pub total_cache_size: u64,
10+
}
11+
12+
// 获取缓存目录
13+
fn get_cache_dir() -> Result<PathBuf, String> {
14+
let home_dir = dirs::home_dir().ok_or("无法获取用户主目录")?;
15+
Ok(home_dir.join(".codeforge").join("cache"))
16+
}
17+
18+
// 获取插件缓存目录
19+
fn get_plugins_cache_dir() -> Result<PathBuf, String> {
20+
let cache_dir = get_cache_dir()?;
21+
Ok(cache_dir.join("plugins"))
22+
}
23+
24+
// 计算目录大小
25+
fn calculate_dir_size(path: &PathBuf) -> u64 {
26+
if !path.exists() {
27+
return 0;
28+
}
29+
30+
let mut total_size = 0u64;
31+
32+
if let Ok(entries) = fs::read_dir(path) {
33+
for entry in entries.flatten() {
34+
let path = entry.path();
35+
if path.is_file() {
36+
if let Ok(metadata) = fs::metadata(&path) {
37+
total_size += metadata.len();
38+
}
39+
} else if path.is_dir() {
40+
total_size += calculate_dir_size(&path);
41+
}
42+
}
43+
}
44+
45+
total_size
46+
}
47+
48+
// 获取缓存信息
49+
#[tauri::command]
50+
pub fn get_cache_info() -> Result<CacheInfo, String> {
51+
info!("获取缓存信息");
52+
53+
let cache_dir = get_cache_dir()?;
54+
let plugins_cache_dir = get_plugins_cache_dir()?;
55+
56+
let plugins_cache_size = calculate_dir_size(&plugins_cache_dir);
57+
let total_cache_size = calculate_dir_size(&cache_dir);
58+
59+
Ok(CacheInfo {
60+
plugins_cache_size,
61+
total_cache_size,
62+
})
63+
}
64+
65+
// 清理插件缓存
66+
#[tauri::command]
67+
pub fn clear_plugins_cache() -> Result<(), String> {
68+
info!("清理插件缓存");
69+
70+
let plugins_cache_dir = get_plugins_cache_dir()?;
71+
72+
if plugins_cache_dir.exists() {
73+
fs::remove_dir_all(&plugins_cache_dir)
74+
.map_err(|e| format!("删除插件缓存目录失败: {}", e))?;
75+
76+
// 重新创建空目录
77+
fs::create_dir_all(&plugins_cache_dir)
78+
.map_err(|e| format!("创建插件缓存目录失败: {}", e))?;
79+
}
80+
81+
info!("插件缓存已清理");
82+
Ok(())
83+
}
84+
85+
// 清理所有缓存
86+
#[tauri::command]
87+
pub fn clear_all_cache() -> Result<(), String> {
88+
info!("清理所有缓存");
89+
90+
let cache_dir = get_cache_dir()?;
91+
92+
if cache_dir.exists() {
93+
fs::remove_dir_all(&cache_dir).map_err(|e| format!("删除缓存目录失败: {}", e))?;
94+
95+
// 重新创建空目录
96+
fs::create_dir_all(&cache_dir).map_err(|e| format!("创建缓存目录失败: {}", e))?;
97+
}
98+
99+
info!("所有缓存已清理");
100+
Ok(())
101+
}

src-tauri/src/main.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
windows_subsystem = "windows"
44
)]
55

6+
mod cache;
67
mod config;
78
mod env_commands;
89
mod env_manager;
@@ -17,6 +18,7 @@ mod setup;
1718
mod update;
1819
mod utils;
1920

21+
use crate::cache::{clear_all_cache, clear_plugins_cache, get_cache_info};
2022
use crate::env_commands::{
2123
EnvironmentManagerState, download_and_install_version, get_environment_info,
2224
get_supported_environment_languages, switch_environment_version, uninstall_environment_version,
@@ -107,6 +109,10 @@ fn main() {
107109
get_app_config,
108110
update_app_config,
109111
get_config_path,
112+
// 缓存相关命令
113+
get_cache_info,
114+
clear_plugins_cache,
115+
clear_all_cache,
110116
// 更新相关命令
111117
check_for_updates,
112118
start_update,

src/components/Settings.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
<template #network>
2626
<Network v-if="activeTab === 'network'" @settings-changed="handleNetworkSettingsChanged" @error="handleEditorError"/>
2727
</template>
28+
29+
<!-- 缓存管理 -->
30+
<template #cache>
31+
<Cache v-if="activeTab === 'cache'"/>
32+
</template>
2833
</Tabs>
2934
</Modal>
3035
</template>
@@ -37,6 +42,7 @@ import General from './setting/General.vue'
3742
import Language from './setting/Language.vue'
3843
import Editor from './setting/Editor.vue'
3944
import Network from './setting/Network.vue'
45+
import Cache from './setting/Cache.vue'
4046
import { useSettings } from '../composables/useSettings.ts'
4147
4248
const emit = defineEmits<{

src/components/setting/Cache.vue

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
<template>
2+
<div class="space-y-6">
3+
<div class="space-y-4">
4+
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100">缓存管理</h3>
5+
<p class="text-sm text-gray-600 dark:text-gray-400">
6+
管理应用缓存,包括代码执行临时文件等
7+
</p>
8+
</div>
9+
10+
<!-- 缓存统计 -->
11+
<div v-if="cacheInfo" class="grid grid-cols-1 md:grid-cols-2 gap-4">
12+
<div class="p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
13+
<div class="flex items-center justify-between">
14+
<div>
15+
<p class="text-sm text-gray-600 dark:text-gray-400">插件执行缓存</p>
16+
<p class="text-2xl font-semibold text-gray-900 dark:text-gray-100 mt-1">
17+
{{ formatSize(cacheInfo.plugins_cache_size) }}
18+
</p>
19+
</div>
20+
<FolderOpen class="w-8 h-8 text-blue-600 dark:text-blue-400"/>
21+
</div>
22+
</div>
23+
24+
<div class="p-4 bg-green-50 dark:bg-green-900/20 rounded-lg">
25+
<div class="flex items-center justify-between">
26+
<div>
27+
<p class="text-sm text-gray-600 dark:text-gray-400">总缓存大小</p>
28+
<p class="text-2xl font-semibold text-gray-900 dark:text-gray-100 mt-1">
29+
{{ formatSize(cacheInfo.total_cache_size) }}
30+
</p>
31+
</div>
32+
<HardDrive class="w-8 h-8 text-green-600 dark:text-green-400"/>
33+
</div>
34+
</div>
35+
</div>
36+
37+
<!-- 加载状态 -->
38+
<div v-if="isLoading" class="flex items-center justify-center py-8">
39+
<div class="flex items-center space-x-2 text-sm text-gray-600 dark:text-gray-400">
40+
<svg class="animate-spin h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
41+
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
42+
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
43+
</svg>
44+
<span>加载中...</span>
45+
</div>
46+
</div>
47+
48+
<!-- 错误信息 -->
49+
<div v-if="error" class="p-3 bg-red-50 dark:bg-red-900/20 rounded-lg">
50+
<div class="flex items-center space-x-2 text-red-600 dark:text-red-400">
51+
<AlertCircle class="w-5 h-5"/>
52+
<span class="text-sm">{{ error }}</span>
53+
</div>
54+
</div>
55+
56+
<!-- 成功信息 -->
57+
<div v-if="success" class="p-3 bg-green-50 dark:bg-green-900/20 rounded-lg">
58+
<div class="flex items-center space-x-2 text-green-600 dark:text-green-400">
59+
<CheckCircle class="w-5 h-5"/>
60+
<span class="text-sm">{{ success }}</span>
61+
</div>
62+
</div>
63+
64+
<!-- 缓存清理选项 -->
65+
<div class="space-y-4">
66+
<div class="flex items-center justify-between p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
67+
<div class="flex-1">
68+
<h4 class="font-medium text-gray-900 dark:text-gray-100">清理插件执行缓存</h4>
69+
<p class="text-sm text-gray-600 dark:text-gray-400 mt-1">
70+
清理代码执行产生的临时文件
71+
</p>
72+
</div>
73+
<Button
74+
type="danger"
75+
:icon="Trash2"
76+
:disabled="isClearing"
77+
@click="clearPluginsCache">
78+
清理
79+
</Button>
80+
</div>
81+
82+
<div class="flex items-center justify-between p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
83+
<div class="flex-1">
84+
<h4 class="font-medium text-gray-900 dark:text-gray-100">清理所有缓存</h4>
85+
<p class="text-sm text-gray-600 dark:text-gray-400 mt-1">
86+
清理应用所有缓存数据
87+
</p>
88+
</div>
89+
<Button
90+
type="danger"
91+
:icon="Trash2"
92+
:disabled="isClearing"
93+
@click="clearAllCache">
94+
清理
95+
</Button>
96+
</div>
97+
</div>
98+
</div>
99+
</template>
100+
101+
<script setup lang="ts">
102+
import { onMounted, ref } from 'vue'
103+
import { invoke } from '@tauri-apps/api/core'
104+
import { AlertCircle, CheckCircle, FolderOpen, HardDrive, Trash2 } from 'lucide-vue-next'
105+
import Button from '../../ui/Button.vue'
106+
107+
interface CacheInfo {
108+
plugins_cache_size: number
109+
total_cache_size: number
110+
}
111+
112+
const cacheInfo = ref<CacheInfo | null>(null)
113+
const isLoading = ref(false)
114+
const isClearing = ref(false)
115+
const error = ref<string | null>(null)
116+
const success = ref<string | null>(null)
117+
118+
// 格式化文件大小
119+
const formatSize = (bytes: number) => {
120+
if (bytes === 0) return '0 B'
121+
const k = 1024
122+
const sizes = ['B', 'KB', 'MB', 'GB']
123+
const i = Math.floor(Math.log(bytes) / Math.log(k))
124+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
125+
}
126+
127+
// 获取缓存信息
128+
const fetchCacheInfo = async () => {
129+
isLoading.value = true
130+
error.value = null
131+
132+
try {
133+
const info = await invoke<CacheInfo>('get_cache_info')
134+
cacheInfo.value = info
135+
}
136+
catch (e) {
137+
error.value = e as string
138+
console.error('获取缓存信息失败:', e)
139+
}
140+
finally {
141+
isLoading.value = false
142+
}
143+
}
144+
145+
// 清理插件缓存
146+
const clearPluginsCache = async () => {
147+
isClearing.value = true
148+
error.value = null
149+
success.value = null
150+
151+
try {
152+
await invoke('clear_plugins_cache')
153+
success.value = '插件执行缓存已清理'
154+
await fetchCacheInfo()
155+
156+
// 3秒后清除成功信息
157+
setTimeout(() => {
158+
success.value = null
159+
}, 3000)
160+
}
161+
catch (e) {
162+
error.value = e as string
163+
console.error('清理插件缓存失败:', e)
164+
}
165+
finally {
166+
isClearing.value = false
167+
}
168+
}
169+
170+
// 清理所有缓存
171+
const clearAllCache = async () => {
172+
isClearing.value = true
173+
error.value = null
174+
success.value = null
175+
176+
try {
177+
await invoke('clear_all_cache')
178+
success.value = '所有缓存已清理'
179+
await fetchCacheInfo()
180+
181+
// 3秒后清除成功信息
182+
setTimeout(() => {
183+
success.value = null
184+
}, 3000)
185+
}
186+
catch (e) {
187+
error.value = e as string
188+
console.error('清理所有缓存失败:', e)
189+
}
190+
finally {
191+
isClearing.value = false
192+
}
193+
}
194+
195+
onMounted(async () => {
196+
await fetchCacheInfo()
197+
})
198+
</script>

src/composables/useSettings.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { nextTick, ref } from 'vue'
2-
import { BracesIcon, CodeIcon, Globe, ShieldIcon } from 'lucide-vue-next'
2+
import { BracesIcon, CodeIcon, Database, Globe, ShieldIcon } from 'lucide-vue-next'
33

44
export function useSettings(emit: any)
55
{
@@ -12,7 +12,8 @@ export function useSettings(emit: any)
1212
{ key: 'general', label: '通用', icon: ShieldIcon },
1313
{ key: 'editor', label: '编辑器', icon: CodeIcon },
1414
{ key: 'language', label: '语言', icon: BracesIcon },
15-
{ key: 'network', label: '网络', icon: Globe }
15+
{ key: 'network', label: '网络', icon: Globe },
16+
{ key: 'cache', label: '缓存', icon: Database }
1617
]
1718

1819
const handleEditorSettingsChanged = (config: any) => {

0 commit comments

Comments
 (0)