|
8 | 8 | </h3> |
9 | 9 |
|
10 | 10 | <div class="space-y-4"> |
11 | | - <!-- 当前日志目录 --> |
12 | | - <div> |
13 | | - <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> |
14 | | - 当前日志目录 |
15 | | - </label> |
| 11 | + <Label label="当前日志目录"> |
16 | 12 | <div class="bg-gray-50 dark:bg-gray-700 rounded-lg p-3 text-sm text-gray-600 dark:text-gray-400 font-mono"> |
17 | 13 | {{ currentLogDir || '加载中...' }} |
18 | 14 | </div> |
19 | | - </div> |
| 15 | + </Label> |
20 | 16 |
|
21 | | - <!-- 修改日志目录 --> |
22 | | - <div> |
23 | | - <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> |
24 | | - 选择新的日志目录 |
25 | | - </label> |
| 17 | + <Label label="选择新的日志目录"> |
26 | 18 | <div class="flex gap-2"> |
27 | 19 | <input v-model="newLogDir" |
28 | 20 | type="text" |
|
36 | 28 | @click="selectLogDirectory"> |
37 | 29 | </Button> |
38 | 30 | </div> |
39 | | - </div> |
| 31 | + </Label> |
40 | 32 |
|
41 | 33 | <!-- 操作按钮 --> |
42 | 34 | <div class="flex gap-3 pt-0.5"> |
|
54 | 46 | </Button> |
55 | 47 | </div> |
56 | 48 |
|
57 | | - <!-- 日志文件列表 --> |
58 | | - <div v-if="logFiles.length > 0"> |
59 | | - <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> |
60 | | - 最近的日志文件 |
61 | | - </label> |
| 49 | + <Label v-if="logFiles.length > 0" label="最近的日志文件"> |
62 | 50 | <div class="bg-gray-50 dark:bg-gray-700 rounded-lg p-3 max-h-32 overflow-y-auto"> |
63 | 51 | <div v-for="file in logFiles.slice(0, 5)" :key="file" |
64 | 52 | class="text-sm text-gray-600 dark:text-gray-400 font-mono py-1 hover:text-blue-600 dark:hover:text-blue-400 cursor-pointer" |
65 | 53 | @click="openLogFile(file)"> |
66 | 54 | {{ file }} |
67 | 55 | </div> |
68 | 56 | </div> |
69 | | - </div> |
| 57 | + </Label> |
70 | 58 | </div> |
71 | 59 | </div> |
72 | 60 |
|
|
78 | 66 | </h3> |
79 | 67 |
|
80 | 68 | <div class="space-y-4"> |
81 | | - <!-- 清理旧日志 --> |
82 | | - <div> |
83 | | - <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"> |
84 | | - 自动清理日志 |
85 | | - </label> |
| 69 | + <Label label="清理日志"> |
86 | 70 | <div class="flex items-center gap-3"> |
87 | 71 | <Select v-model="keepDays" |
88 | 72 | class="w-36" |
|
93 | 77 | 立即清理 |
94 | 78 | </Button> |
95 | 79 | </div> |
96 | | - </div> |
| 80 | + </Label> |
97 | 81 | </div> |
98 | 82 | </div> |
99 | 83 | </div> |
100 | 84 | </template> |
101 | 85 |
|
102 | 86 | <script setup lang="ts"> |
103 | | -import { onMounted, ref } from 'vue' |
104 | | -import { invoke } from '@tauri-apps/api/core' |
105 | | -import { open as openDialog } from '@tauri-apps/plugin-dialog' |
106 | | -import { openPath } from '@tauri-apps/plugin-opener' |
| 87 | +import { onMounted } from 'vue' |
107 | 88 | import { FileText, Folder, Settings2 } from 'lucide-vue-next' |
108 | 89 | import Select from '../../ui/Select.vue' |
109 | 90 | import Button from '../../ui/Button.vue' |
110 | | -import { useToast } from '../../plugins/toast' |
| 91 | +import Label from '../../ui/Label.vue' |
| 92 | +import { useLogDirectory } from '../../composables/useLogDirectory' |
| 93 | +import { useLogCleanup } from '../../composables/useLogCleanup' |
111 | 94 |
|
112 | 95 | const emit = defineEmits<{ |
113 | 96 | 'settings-changed': [type: string, value: any] |
114 | 97 | 'error': [message: string] |
115 | 98 | }>() |
116 | 99 |
|
117 | | -const toast = useToast() |
118 | | -
|
119 | | -const currentLogDir = ref('') |
120 | | -const newLogDir = ref('') |
121 | | -const logFiles = ref<string[]>([]) |
122 | | -const keepDays = ref(30) |
123 | | -
|
124 | | -const keepDaysOptions = [ |
125 | | - { label: '保留 1 天', value: 1 }, |
126 | | - { label: '保留 7 天', value: 7 }, |
127 | | - { label: '保留 14 天', value: 14 }, |
128 | | - { label: '保留 30 天', value: 30 }, |
129 | | - { label: '保留 90 天', value: 90 } |
130 | | -] |
131 | | -
|
132 | | -const loadLogDirectory = async () => { |
133 | | - try { |
134 | | - const logDir = await invoke<string>('get_log_directory') |
135 | | - currentLogDir.value = logDir |
136 | | - newLogDir.value = logDir |
137 | | - } |
138 | | - catch (error) { |
139 | | - console.error('Failed to get current log directory:', error) |
140 | | - toast.error('获取日志目录失败 - 错误信息: ' + error) |
141 | | - emit('error', '获取日志目录失败') |
142 | | - } |
143 | | -} |
144 | | -
|
145 | | -const loadLogFiles = async () => { |
146 | | - try { |
147 | | - logFiles.value = await invoke<string[]>('get_log_files') |
148 | | - } |
149 | | - catch (error) { |
150 | | - console.error('Failed to get log files:', error) |
151 | | - emit('error', '获取日志文件列表失败') |
152 | | - } |
153 | | -} |
154 | | -
|
155 | | -const selectLogDirectory = async () => { |
156 | | - try { |
157 | | - const selected = await openDialog({ |
158 | | - directory: true, |
159 | | - multiple: false, |
160 | | - title: '选择日志目录' |
161 | | - }) |
162 | | -
|
163 | | - if (selected) { |
164 | | - newLogDir.value = selected as string |
165 | | - } |
166 | | - } |
167 | | - catch (error) { |
168 | | - console.error('Failed to select directory:', error) |
169 | | - emit('error', '选择目录失败') |
170 | | - } |
171 | | -} |
172 | | -
|
173 | | -const applyLogDirChange = async () => { |
174 | | - try { |
175 | | - await invoke('set_log_directory', { path: newLogDir.value }) |
176 | | - currentLogDir.value = newLogDir.value |
177 | | - await loadLogFiles() |
178 | | - toast.success('日志目录已更新') |
179 | | - emit('settings-changed', 'logDirectory', newLogDir.value) |
180 | | - } |
181 | | - catch (error) { |
182 | | - console.error('Failed to set log directory:', error) |
183 | | - const errorMessage = '日志目录更新失败, 错误信息: ' + error |
184 | | - toast.error(errorMessage) |
185 | | - emit('error', errorMessage) |
186 | | - } |
187 | | -} |
188 | | -
|
189 | | -const openLogDirectory = async () => { |
190 | | - try { |
191 | | - await openPath(currentLogDir.value) |
192 | | - } |
193 | | - catch (error) { |
194 | | - console.error('Failed to open log directory:', error) |
195 | | - emit('error', '打开日志目录失败') |
196 | | - } |
197 | | -} |
198 | | -
|
199 | | -const resetLogDirectory = async () => { |
200 | | - try { |
201 | | - await invoke('reset_log_directory') |
202 | | - await loadLogDirectory() |
203 | | - await loadLogFiles() |
204 | | - toast.success('日志目录已重置为默认') |
205 | | - emit('settings-changed', 'logDirectory', 'reset') |
206 | | - } |
207 | | - catch (error) { |
208 | | - console.error('Failed to reset log directory:', error) |
209 | | - const errorMessage = '日志目录重置失败, 错误信息: ' + error |
210 | | - toast.error(errorMessage) |
211 | | - emit('error', errorMessage) |
212 | | - } |
213 | | -} |
214 | | -
|
215 | | -const openLogFile = async (filename: string) => { |
216 | | - try { |
217 | | - const logPath = `${ currentLogDir.value }/${ filename }` |
218 | | - await openPath(logPath) |
219 | | - } |
220 | | - catch (error) { |
221 | | - console.error('Failed to open log file:', error) |
222 | | - toast.error('打开日志文件失败 - 错误信息: ' + error) |
223 | | - emit('error', '打开日志文件失败') |
224 | | - } |
225 | | -} |
226 | | -
|
227 | | -const clearLogs = async () => { |
228 | | - try { |
229 | | - await invoke('clear_logs', { keepDays: parseInt(keepDays.value.toString()) }) |
230 | | - await loadLogFiles() |
231 | | - toast.success(`已清理 ${ keepDays.value } 天前的日志`) |
232 | | - emit('settings-changed', 'logCleanup', keepDays.value) |
233 | | - } |
234 | | - catch (error) { |
235 | | - console.error('Failed to clear old logs:', error) |
236 | | - const errorMessage = '清理日志失败, 错误信息: ' + error |
237 | | - toast.error(errorMessage) |
238 | | - emit('error', errorMessage) |
239 | | - } |
240 | | -} |
| 100 | +const { |
| 101 | + currentLogDir, |
| 102 | + newLogDir, |
| 103 | + logFiles, |
| 104 | + loadLogDirectory, |
| 105 | + loadLogFiles, |
| 106 | + selectLogDirectory, |
| 107 | + applyLogDirChange, |
| 108 | + openLogDirectory, |
| 109 | + resetLogDirectory, |
| 110 | + openLogFile |
| 111 | +} = useLogDirectory(emit) |
| 112 | +
|
| 113 | +const { |
| 114 | + keepDays, |
| 115 | + keepDaysOptions, |
| 116 | + clearLogs |
| 117 | +} = useLogCleanup(emit, loadLogFiles) |
241 | 118 |
|
242 | 119 | // 暴露方法给父组件 |
243 | 120 | defineExpose({ |
|
0 commit comments