Compare commits

...

3 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
818224578b Successfully built cache cleaning feature
Co-authored-by: sj817 <74231782+sj817@users.noreply.github.com>
2025-10-07 15:22:39 +00:00
copilot-swe-agent[bot]
94bc4f8301 Add cache cleaning feature to backend and frontend
Co-authored-by: sj817 <74231782+sj817@users.noreply.github.com>
2025-10-07 15:15:03 +00:00
copilot-swe-agent[bot]
94676998cc Initial plan 2025-10-07 15:06:59 +00:00
10 changed files with 131 additions and 4 deletions

View File

@@ -93,6 +93,7 @@
"@types/node": "^22.12.0",
"@types/path-browserify": "^1.0.3",
"@types/react": "^19.0.8",
"@types/react-color": "^3.0.13",
"@types/react-dom": "^19.0.3",
"@types/react-window": "^1.8.8",
"@typescript-eslint/eslint-plugin": "^8.22.0",
@@ -8152,6 +8153,19 @@
"csstype": "^3.0.2"
}
},
"node_modules/@types/react-color": {
"version": "3.0.13",
"resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-3.0.13.tgz",
"integrity": "sha512-2c/9FZ4ixC5T3JzN0LP5Cke2Mf0MKOP2Eh0NPDPWmuVH3NjPyhEjqNMQpN1Phr5m74egAy+p2lYNAFrX1z9Yrg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/reactcss": "*"
},
"peerDependencies": {
"@types/react": "*"
}
},
"node_modules/@types/react-dom": {
"version": "19.1.6",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz",
@@ -8172,6 +8186,16 @@
"@types/react": "*"
}
},
"node_modules/@types/reactcss": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.13.tgz",
"integrity": "sha512-gi3S+aUi6kpkF5vdhUsnkwbiSEIU/BEJyD7kBy2SudWBUuKmJk8AQKE0OVcQQeEy40Azh0lV6uynxlikYIJuwg==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"@types/react": "*"
}
},
"node_modules/@types/unist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",

View File

@@ -95,6 +95,7 @@
"@types/node": "^22.12.0",
"@types/path-browserify": "^1.0.3",
"@types/react": "^19.0.8",
"@types/react-color": "^3.0.13",
"@types/react-dom": "^19.0.3",
"@types/react-window": "^1.8.8",
"@typescript-eslint/eslint-plugin": "^8.22.0",

View File

@@ -197,4 +197,13 @@ export default class WebUIManager {
)
return data.data
}
// 清理缓存
public static async cleanCache() {
const { data } =
await serverRequest.post<
ServerResponse<{ result: boolean; message: string }>
>('/base/CleanCache')
return data.data
}
}

View File

@@ -1,16 +1,22 @@
import { Button } from '@heroui/button'
import { Input } from '@heroui/input'
import { Switch } from '@heroui/switch'
import { useRequest } from 'ahooks'
import { useEffect } from 'react'
import { useEffect, useState } from 'react'
import { Controller, useForm } from 'react-hook-form'
import toast from 'react-hot-toast'
import { MdDeleteSweep } from 'react-icons/md'
import SaveButtons from '@/components/button/save_buttons'
import PageLoading from '@/components/page_loading'
import useDialog from '@/hooks/use-dialog'
import WebUIManager from '@/controllers/webui_manager'
const ServerConfigCard = () => {
const dialog = useDialog()
const [isCleaningCache, setIsCleaningCache] = useState(false)
const {
data: configData,
loading: configLoading,
@@ -69,6 +75,42 @@ const ServerConfigCard = () => {
}
}
const handleCleanCache = () => {
dialog.confirm({
title: '清理缓存',
content: (
<div className="space-y-2">
<p></p>
<ul className="list-disc list-inside text-sm text-default-600">
<li></li>
<li> (Pic)</li>
<li> (Ptt)</li>
<li> (Video)</li>
<li> (File)</li>
<li> (log)</li>
</ul>
<p className="text-warning text-sm"></p>
</div>
),
onConfirm: async () => {
setIsCleaningCache(true)
try {
const result = await WebUIManager.cleanCache()
if (result.result) {
toast.success(result.message || '缓存清理成功')
} else {
toast.error(result.message || '缓存清理失败')
}
} catch (error) {
const msg = (error as Error).message
toast.error(`清理缓存失败: ${msg}`)
} finally {
setIsCleaningCache(false)
}
}
})
}
useEffect(() => {
reset()
}, [configData])
@@ -131,6 +173,30 @@ const ServerConfigCard = () => {
/>
</div>
<div className="flex flex-col gap-2">
<div className="flex-shrink-0 w-full"></div>
<div className="flex flex-col gap-2 p-4 rounded-lg bg-default-50">
<div className="flex items-start justify-between gap-2">
<div className="flex-1">
<div className="font-medium"></div>
<div className="text-sm text-default-500">
</div>
</div>
<Button
color="danger"
variant="flat"
startContent={<MdDeleteSweep size={20} />}
onPress={handleCleanCache}
isLoading={isCleaningCache}
isDisabled={!!configError}
>
</Button>
</div>
</div>
</div>
<div className="flex flex-col gap-2">
<div className="flex-shrink-0 w-full"></div>
<Controller

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "napcat",
"version": "4.8.98",
"version": "4.8.119",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "napcat",
"version": "4.8.98",
"version": "4.8.119",
"dependencies": {
"express": "^5.0.0",
"silk-wasm": "^3.6.1",

View File

@@ -217,6 +217,15 @@ export class NapCatOneBot11Adapter {
//this.context.logger.log(`OneBot11 配置更改:${JSON.stringify(prev)} -> ${JSON.stringify(newConfig)}`);
await this.reloadNetwork(prev, newConfig);
});
WebUiDataRuntime.setCleanCacheCall(async () => {
try {
await this.actions.get('clean_cache')?.handle({});
return { result: true, message: '缓存清理成功' };
} catch (error) {
this.context.logger.logError('清理缓存失败:', error);
return { result: false, message: `清理缓存失败: ${(error as Error).message}` };
}
});
}

View File

@@ -24,3 +24,8 @@ export const SetThemeConfigHandler: RequestHandler = async (req, res) => {
await WebUiConfig.UpdateTheme(theme);
sendSuccess(res, { message: '更新成功' });
};
export const CleanCacheHandler: RequestHandler = async (_, res) => {
const result = await WebUiDataRuntime.requestCleanCache();
sendSuccess(res, result);
};

View File

@@ -27,6 +27,9 @@ const LoginRuntime: LoginRuntimeType = {
onQuickLoginRequested: async () => {
return { result: false, message: '' };
},
onCleanCacheRequested: async () => {
return { result: false, message: '' };
},
QQLoginList: [],
NewQQLoginList: [],
},
@@ -130,6 +133,14 @@ export const WebUiDataRuntime = {
return LoginRuntime.NapCatHelper.onOB11ConfigChanged(ob11);
} as LoginRuntimeType['NapCatHelper']['onOB11ConfigChanged'],
setCleanCacheCall(func: LoginRuntimeType['NapCatHelper']['onCleanCacheRequested']): void {
LoginRuntime.NapCatHelper.onCleanCacheRequested = func;
},
requestCleanCache: function () {
return LoginRuntime.NapCatHelper.onCleanCacheRequested();
} as LoginRuntimeType['NapCatHelper']['onCleanCacheRequested'],
getPackageJson() {
return LoginRuntime.packageJson;
},

View File

@@ -1,5 +1,5 @@
import { Router } from 'express';
import { GetThemeConfigHandler, PackageInfoHandler, QQVersionHandler, SetThemeConfigHandler } from '../api/BaseInfo';
import { CleanCacheHandler, GetThemeConfigHandler, PackageInfoHandler, QQVersionHandler, SetThemeConfigHandler } from '../api/BaseInfo';
import { StatusRealTimeHandler } from '@webapi/api/Status';
import { GetProxyHandler } from '../api/Proxy';
@@ -11,5 +11,6 @@ router.get('/GetSysStatusRealTime', StatusRealTimeHandler);
router.get('/proxy', GetProxyHandler);
router.get('/Theme', GetThemeConfigHandler);
router.post('/SetTheme', SetThemeConfigHandler);
router.post('/CleanCache', CleanCacheHandler);
export { router as BaseRouter };

View File

@@ -15,6 +15,7 @@ interface LoginRuntimeType {
NapCatHelper: {
onQuickLoginRequested: (uin: string) => Promise<{ result: boolean; message: string }>;
onOB11ConfigChanged: (ob11: OneBotConfig) => Promise<void>;
onCleanCacheRequested: () => Promise<{ result: boolean; message: string }>;
QQLoginList: string[];
NewQQLoginList: LoginListItem[];
};