diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index 97e5733..41097e6 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -37,7 +37,8 @@
"Bash(pnpm run tauri build)",
"Bash(start \"\" \"D:\\\\Projects\\\\tauri\\\\tauri-app\\\\src-tauri\\\\target\\\\release\\\\bundle\\\\nsis\\\\tauri-app_0.1.0_x64-setup.exe\")",
"Bash(pnpm run build)",
- "Bash(pnpm add pinia)"
+ "Bash(pnpm add pinia)",
+ "Bash(pnpm add dayjs)"
]
}
}
diff --git a/package-lock.json b/package-lock.json
index 77d29f5..7d419b2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,6 +15,7 @@
"@tauri-apps/plugin-notification": "^2.3.3",
"@tauri-apps/plugin-opener": "^2.5.3",
"ant-design-vue": "^4.2.6",
+ "dayjs": "^1.11.19",
"pinia": "^3.0.4",
"vue": "^3.5.29"
},
diff --git a/package.json b/package.json
index 1229beb..137defd 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"@tauri-apps/plugin-notification": "^2.3.3",
"@tauri-apps/plugin-opener": "^2.5.3",
"ant-design-vue": "^4.2.6",
+ "dayjs": "^1.11.19",
"pinia": "^3.0.4",
"vue": "^3.5.29"
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3c72bbb..1507a80 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -29,6 +29,9 @@ importers:
ant-design-vue:
specifier: ^4.2.6
version: 4.2.6(vue@3.5.29(typescript@5.9.3))
+ dayjs:
+ specifier: ^1.11.19
+ version: 1.11.19
pinia:
specifier: ^3.0.4
version: 3.0.4(typescript@5.9.3)(vue@3.5.29(typescript@5.9.3))
diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs
index e40c61c..efe1421 100644
--- a/src-tauri/src/lib.rs
+++ b/src-tauri/src/lib.rs
@@ -2,7 +2,7 @@ use std::io::{Read, Write};
use std::net::TcpListener;
use std::sync::atomic::{AtomicU16, Ordering};
-use tauri::{Emitter, Manager};
+use tauri::Emitter;
use tauri_plugin_autostart::MacosLauncher;
mod notification;
@@ -25,34 +25,42 @@ fn start_notification_callback_server(app_handle: tauri::AppHandle) {
});
}
-fn handle_callback_request(app_handle: &tauri::AppHandle, mut stream: std::net::TcpStream) {
- let mut buf = [0u8; 1024];
- let n = stream.read(&mut buf).unwrap_or(0);
- let request = String::from_utf8_lossy(&buf[..n]);
-
- let (action, html) = if request.contains("GET /postpone") {
- let _ = app_handle.emit("notification-action", "postpone_1h");
- if let Some(w) = app_handle.get_webview_window("main") {
- let _ = w.unminimize();
- let _ = w.show();
- let _ = w.set_focus();
- }
- ("postpone", "已推迟1小时,监控将在1小时后恢复")
- } else {
- ("unknown", "未知操作")
- };
-
- log::info!("Notification callback: {}", action);
-
- let body = format!(
+fn simple_page(msg: &str) -> String {
+ format!(
"
\
\
\
",
- html
- );
+ msg
+ )
+}
+
+fn redirect_page(url: &str) -> String {
+ format!(
+ "\
+ \
+ 正在跳转..."
+ )
+}
+
+fn handle_callback_request(app_handle: &tauri::AppHandle, mut stream: std::net::TcpStream) {
+ let mut buf = [0u8; 1024];
+ let n = stream.read(&mut buf).unwrap_or(0);
+ let request = String::from_utf8_lossy(&buf[..n]);
+
+ let (action, body) = if request.contains("GET /postpone") {
+ let _ = app_handle.emit("notification-action", "postpone_1h");
+ ("postpone", simple_page("已推迟1小时,监控将在1小时后恢复"))
+ } else if request.contains("GET /handle") {
+ let _ = app_handle.emit("notification-action", "go_handle");
+ ("handle", redirect_page("https://crm.yunvip123.com/index.html"))
+ } else {
+ ("unknown", simple_page("未知操作"))
+ };
+
+ log::info!("Notification callback: {}", action);
let response = format!(
"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{}",
diff --git a/src-tauri/src/notification.rs b/src-tauri/src/notification.rs
index f140e2b..df1926c 100644
--- a/src-tauri/src/notification.rs
+++ b/src-tauri/src/notification.rs
@@ -37,7 +37,7 @@ pub fn send_interactive_toast(
-
+
"#,
port = port,
diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json
index 3877ef4..1198dd4 100644
--- a/src-tauri/tauri.conf.json
+++ b/src-tauri/tauri.conf.json
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "工单系统监测",
- "version": "0.1.1",
+ "version": "0.1.2",
"identifier": "com.administrator.tauri-app",
"build": {
"beforeDevCommand": "pnpm dev",
diff --git a/src/App.vue b/src/App.vue
index 3002700..67c04bc 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,5 +1,5 @@
@@ -61,7 +71,7 @@ onUnmounted(() => store.cleanup());
-
+
diff --git a/src/components/AppStatusBar.vue b/src/components/AppStatusBar.vue
index 3ca559e..a4635b4 100644
--- a/src/components/AppStatusBar.vue
+++ b/src/components/AppStatusBar.vue
@@ -1,22 +1,43 @@
-
- 监控已推迟,1小时后自动恢复
-
-
-
- {{ store.message }}
-
+
+
+
+
+ {{ item.content }}
+
+
@@ -38,12 +59,6 @@ const store = useMonitorStore();
padding: 0 10px;
height: 100%;
}
-.statusbar-item--warning {
- color: #ffe58f;
-}
-.statusbar-item--info {
- color: rgba(255, 255, 255, 0.85);
-}
.statusbar-sep {
width: 1px;
height: 14px;
diff --git a/src/components/SettingsPanel.vue b/src/components/SettingsPanel.vue
index d863e0e..d55efc0 100644
--- a/src/components/SettingsPanel.vue
+++ b/src/components/SettingsPanel.vue
@@ -1,18 +1,33 @@
-
-
+
+ 最短 10 秒,当前 {{ store.config.check_interval }} 秒
+
+
+
每次询问
diff --git a/src/stores/monitor.ts b/src/stores/monitor.ts
index 8b26b23..91ef6a7 100644
--- a/src/stores/monitor.ts
+++ b/src/stores/monitor.ts
@@ -68,6 +68,7 @@ export const useMonitorStore = defineStore("monitor", () => {
notification_sound: true,
network_timeout: 30,
close_action: "ask" as "ask" | "minimize" | "close",
+ handle_pause_minutes: 20,
});
const showCloseDialog = ref(false);
@@ -233,8 +234,9 @@ export const useMonitorStore = defineStore("monitor", () => {
async function tryReLogin(): Promise {
if (loginMode.value === "token") {
- addLog("WARN", "Token 模式下无法自动重登录,请更换新的 Token", "SESSION");
- message.value = "Token 可能已过期,请更换新的 Token";
+ addLog("ERROR", "Token 已失效,监控已停止,请更换新的 Token 后重新开始", "SESSION");
+ message.value = "Token 已失效,监控已停止";
+ stopMonitoring();
return;
}
if (!username.value || !password.value) {
@@ -453,6 +455,24 @@ export const useMonitorStore = defineStore("monitor", () => {
}, 60 * 60 * 1000);
}
+ function pauseForHandle() {
+ if (!isMonitoring.value) return;
+ if (monitorTimer) { clearInterval(monitorTimer); monitorTimer = null; }
+ if (postponeTimer) { clearTimeout(postponeTimer); }
+ isPostponed.value = true;
+ const minutes = config.value.handle_pause_minutes;
+ addLog("INFO", `点击"去处理",监控已暂停 ${minutes} 分钟`, "MONITOR");
+ message.value = `监控已暂停 ${minutes} 分钟,将在 ${minutes} 分钟后自动恢复`;
+ postponeTimer = setTimeout(() => {
+ isPostponed.value = false;
+ postponeTimer = null;
+ apiCheckStatus();
+ monitorTimer = setInterval(() => apiCheckStatus(), config.value.check_interval * 1000);
+ addLog("INFO", "暂停结束,监控已自动恢复", "MONITOR");
+ message.value = "暂停结束,监控已自动恢复";
+ }, minutes * 60 * 1000);
+ }
+
async function manualCheck() {
if (!isLoggedIn.value) { message.value = "请先开始监控(登录)"; return; }
isLoading.value = true;
@@ -564,6 +584,7 @@ export const useMonitorStore = defineStore("monitor", () => {
} catch { /* ignore */ }
unlistenNotification = await listen("notification-action", (event) => {
if (event.payload === "postpone_1h") postponeMonitoring();
+ else if (event.payload === "go_handle") pauseForHandle();
});
unlistenClose = await listen("close-requested", async () => {
const action = config.value.close_action;