mirror of
https://github.com/SECTL/SecScore.git
synced 2026-07-19 21:14:21 +08:00
feat: 设置页新增应用重启与退出快捷按钮
This commit is contained in:
@@ -86,3 +86,20 @@ pub async fn register_url_protocol(
|
||||
Ok(IpcResponse::error("URL protocol registration is not supported on this platform"))
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn app_quit(
|
||||
app: AppHandle,
|
||||
_state: tauri::State<'_, Arc<RwLock<AppState>>>,
|
||||
) -> Result<(), String> {
|
||||
app.exit(0);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn app_restart(
|
||||
app: AppHandle,
|
||||
_state: tauri::State<'_, Arc<RwLock<AppState>>>,
|
||||
) -> Result<(), String> {
|
||||
app.restart();
|
||||
}
|
||||
|
||||
@@ -107,6 +107,8 @@ pub fn run() {
|
||||
http_server_stop,
|
||||
http_server_status,
|
||||
register_url_protocol,
|
||||
app_quit,
|
||||
app_restart,
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
||||
@@ -68,6 +68,8 @@ export const Settings: React.FC<{ permission: permissionLevel }> = ({ permission
|
||||
const [settleDialogVisible, setSettleDialogVisible] = useState(false)
|
||||
|
||||
const [urlRegisterLoading, setUrlRegisterLoading] = useState(false)
|
||||
const [appQuitLoading, setAppQuitLoading] = useState(false)
|
||||
const [appRestartLoading, setAppRestartLoading] = useState(false)
|
||||
const canAdmin = permission === "admin"
|
||||
const [messageApi, contextHolder] = message.useMessage()
|
||||
|
||||
@@ -418,6 +420,45 @@ export const Settings: React.FC<{ permission: permissionLevel }> = ({ permission
|
||||
|
||||
const currentYear = new Date().getFullYear()
|
||||
|
||||
const confirmQuitApp = () => {
|
||||
Modal.confirm({
|
||||
title: t("settings.app.confirmQuitTitle"),
|
||||
content: t("settings.app.confirmQuitContent"),
|
||||
okText: t("settings.app.quit"),
|
||||
okButtonProps: { danger: true },
|
||||
cancelText: t("common.cancel"),
|
||||
onOk: async () => {
|
||||
if (!(window as any).api) return
|
||||
setAppQuitLoading(true)
|
||||
try {
|
||||
await (window as any).api.appQuit()
|
||||
} catch (e: any) {
|
||||
setAppQuitLoading(false)
|
||||
messageApi.error(e?.message || t("settings.app.quitFailed"))
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const confirmRestartApp = () => {
|
||||
Modal.confirm({
|
||||
title: t("settings.app.confirmRestartTitle"),
|
||||
content: t("settings.app.confirmRestartContent"),
|
||||
okText: t("settings.app.restart"),
|
||||
cancelText: t("common.cancel"),
|
||||
onOk: async () => {
|
||||
if (!(window as any).api) return
|
||||
setAppRestartLoading(true)
|
||||
try {
|
||||
await (window as any).api.appRestart()
|
||||
} catch (e: any) {
|
||||
setAppRestartLoading(false)
|
||||
messageApi.error(e?.message || t("settings.app.restartFailed"))
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const tabItems = [
|
||||
{
|
||||
key: "appearance",
|
||||
@@ -967,13 +1008,32 @@ export const Settings: React.FC<{ permission: permissionLevel }> = ({ permission
|
||||
</div>
|
||||
<Divider />
|
||||
<div style={{ marginTop: "16px" }}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
;(window as any).api?.toggleDevTools()
|
||||
}}
|
||||
>
|
||||
{t("settings.about.toggleDevTools")}
|
||||
</Button>
|
||||
<Space>
|
||||
<Button
|
||||
onClick={() => {
|
||||
;(window as any).api?.toggleDevTools()
|
||||
}}
|
||||
>
|
||||
{t("settings.about.toggleDevTools")}
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
<Divider />
|
||||
<div style={{ fontSize: "16px", fontWeight: 600, marginBottom: "8px" }}>
|
||||
{t("settings.app.title")}
|
||||
</div>
|
||||
<div style={{ color: "var(--ss-text-secondary)", marginBottom: "12px", fontSize: "12px" }}>
|
||||
{t("settings.app.description")}
|
||||
</div>
|
||||
<div style={{ marginTop: "8px" }}>
|
||||
<Space>
|
||||
<Button onClick={confirmRestartApp} loading={appRestartLoading}>
|
||||
{t("settings.app.restart")}
|
||||
</Button>
|
||||
<Button danger onClick={confirmQuitApp} loading={appQuitLoading}>
|
||||
{t("settings.app.quit")}
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</Card>
|
||||
),
|
||||
|
||||
@@ -263,6 +263,18 @@
|
||||
"registerFailed": "Registration failed",
|
||||
"installerRequired": "Requires installed SecScore, may not work in development mode."
|
||||
},
|
||||
"app": {
|
||||
"title": "App Controls",
|
||||
"description": "Quickly restart or quit the app.",
|
||||
"restart": "Restart App",
|
||||
"quit": "Quit App",
|
||||
"confirmRestartTitle": "Restart the app now?",
|
||||
"confirmRestartContent": "The app will close and start again immediately.",
|
||||
"confirmQuitTitle": "Quit the app now?",
|
||||
"confirmQuitContent": "The app will exit immediately.",
|
||||
"restartFailed": "Restart failed",
|
||||
"quitFailed": "Quit failed"
|
||||
},
|
||||
"about": {
|
||||
"title": "About",
|
||||
"appName": "Education Points Management",
|
||||
|
||||
@@ -263,6 +263,18 @@
|
||||
"registerFailed": "注册失败",
|
||||
"installerRequired": "需要安装版 SecScore,开发模式下可能无效。"
|
||||
},
|
||||
"app": {
|
||||
"title": "应用控制",
|
||||
"description": "快速重启或退出应用。",
|
||||
"restart": "重启应用",
|
||||
"quit": "退出应用",
|
||||
"confirmRestartTitle": "确认重启应用?",
|
||||
"confirmRestartContent": "应用将立即关闭并重新启动。",
|
||||
"confirmQuitTitle": "确认退出应用?",
|
||||
"confirmQuitContent": "应用将立即退出。",
|
||||
"restartFailed": "重启失败",
|
||||
"quitFailed": "退出失败"
|
||||
},
|
||||
"about": {
|
||||
"title": "关于",
|
||||
"appName": "教育积分管理",
|
||||
|
||||
@@ -304,6 +304,8 @@ const api = {
|
||||
data?: { registered: boolean }
|
||||
message?: string
|
||||
}> => invoke("register_url_protocol"),
|
||||
appQuit: (): Promise<void> => invoke("app_quit"),
|
||||
appRestart: (): Promise<void> => invoke("app_restart"),
|
||||
|
||||
// Auto Score
|
||||
autoScoreGetRules: (): Promise<{ success: boolean; data: any[] }> =>
|
||||
|
||||
Reference in New Issue
Block a user