@@ -21,6 +21,7 @@ export default function Admin() {
2121 const [ usersLoading , setUsersLoading ] = useState ( false ) ;
2222 const [ allSubmissions , setAllSubmissions ] = useState < any [ ] > ( [ ] ) ;
2323 const [ allLoading , setAllLoading ] = useState ( false ) ;
24+ const [ dbOptimizing , setDbOptimizing ] = useState ( false ) ;
2425
2526 const fetchData = useCallback ( async ( ) => {
2627 setLoading ( true ) ;
@@ -250,6 +251,35 @@ export default function Admin() {
250251 </ div >
251252 ) }
252253
254+ { /* Database Tools */ }
255+ { user ?. role === 'admin' && (
256+ < div className = "card p-6 mb-6" >
257+ < h2 className = "text-lg font-semibold text-white mb-4 flex items-center gap-2" >
258+ < Activity className = "w-5 h-5 text-orange-400" /> 数据库维护
259+ </ h2 >
260+ < button
261+ onClick = { async ( ) => {
262+ setDbOptimizing ( true ) ;
263+ try {
264+ const res = await fetch ( '/api/problems/admin/optimize' , {
265+ method : 'POST' ,
266+ headers : { Authorization : `Bearer ${ localStorage . getItem ( 'oj_token' ) } ` } ,
267+ } ) ;
268+ const data = await res . json ( ) ;
269+ toast . success ( data . message || '数据库优化完成' ) ;
270+ } catch { toast . error ( '优化失败' ) ; }
271+ finally { setDbOptimizing ( false ) ; }
272+ } }
273+ disabled = { dbOptimizing }
274+ className = "btn-secondary text-sm inline-flex items-center gap-2"
275+ >
276+ { dbOptimizing ? < Loader2 className = "w-4 h-4 animate-spin" /> : < Activity size = { 16 } /> }
277+ { dbOptimizing ? '优化中...' : '优化数据库' }
278+ </ button >
279+ < p className = "text-xs text-dark-500 mt-2" > 执行 ANALYZE + VACUUM,优化查询性能并回收空间</ p >
280+ </ div >
281+ ) }
282+
253283 { /* User Management */ }
254284 < div className = "card p-6 mb-6" >
255285 < h2 className = "text-lg font-semibold text-white mb-4 flex items-center gap-2" >
0 commit comments