diff --git a/data/GetWorkOrderListPage.js b/data/api/GetWorkOrderListPage.js similarity index 94% rename from data/GetWorkOrderListPage.js rename to data/api/GetWorkOrderListPage.js index f3236ba..84cee83 100644 --- a/data/GetWorkOrderListPage.js +++ b/data/api/GetWorkOrderListPage.js @@ -3,7 +3,8 @@ fetch("https://crm.yunvip123.com/api/DemandManage/GetWorkOrderListPage", { accept: "application/json, text/javascript, */*; q=0.01", "accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7", "content-type": "application/x-www-form-urlencoded; charset=UTF-8", - "sec-ch-ua": '"Not:A-Brand";v="99", "Google Chrome";v="145", "Chromium";v="145"', + "sec-ch-ua": + '"Not:A-Brand";v="99", "Google Chrome";v="145", "Chromium";v="145"', "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": '"Windows"', "sec-fetch-dest": "empty", @@ -11,7 +12,8 @@ fetch("https://crm.yunvip123.com/api/DemandManage/GetWorkOrderListPage", { "sec-fetch-site": "same-origin", "x-requested-with": "XMLHttpRequest", }, - referrer: "https://crm.yunvip123.com/WebUI/DemandManagement/DemandListNew.html?v=2.0.4.12", + referrer: + "https://crm.yunvip123.com/WebUI/DemandManagement/DemandListNew.html?v=2.0.4.12", body: "DL_ProductID=&DL_ID=&isSelect=8&Solution=&OrderType=&DL_TaskName=&CreatGID=&CreatTimeStart=&CreatTimeEnd=&SloveGID=&SloveTimeStart=&SloveTimeEnd=&ShowTable=DemandList&isShow=3&IsExport=0&PageIndex=1&PageSize=20", method: "POST", mode: "cors", diff --git a/data/Login.js b/data/api/Login.js similarity index 99% rename from data/Login.js rename to data/api/Login.js index 3939bfe..8d681e3 100644 --- a/data/Login.js +++ b/data/api/Login.js @@ -6,7 +6,8 @@ * 所有接口都要带 cookie: ASP.NET_SessionId=td0mirxws4klqpm0bydhvgjj */ -const requestData = "UserAcount=&PassWord=123456&VerifyCode=&Account=18688886666_777&ValidateCode="; +const requestData = + "UserAcount=&PassWord=123456&VerifyCode=&Account=18688886666_777&ValidateCode="; const responseBody = { success: true, diff --git a/data/QueryIndexCount.js b/data/api/QueryIndexCount.js similarity index 100% rename from data/QueryIndexCount.js rename to data/api/QueryIndexCount.js diff --git a/src/App.vue b/src/App.vue index e6dddd7..b99b9fd 100644 --- a/src/App.vue +++ b/src/App.vue @@ -14,11 +14,13 @@ import MonitorControl from "@/components/MonitorControl.vue"; import SettingsPanel from "@/components/SettingsPanel.vue"; import StatusHeader from "@/components/StatusHeader.vue"; import UpdateDialog from "@/components/UpdateDialog.vue"; +import { useTray } from "@/composables/useTray"; import { useAppStore } from "@/stores/app"; import { useLogStore } from "@/stores/log"; import { useMonitorStore } from "@/stores/monitor"; import { useNetworkStore } from "@/stores/network"; import { useUpdaterStore } from "@/stores/updater"; +import { migrateFromLocalStorage } from "@/utils/storage"; const activeTab = ref("monitor"); const store = useMonitorStore(); @@ -26,6 +28,8 @@ const appStore = useAppStore(); const logStore = useLogStore(); const updater = useUpdaterStore(); const networkStore = useNetworkStore(); +const { setupTray } = useTray(); +const closeDialogRef = ref | null>(null); /** 通知动作事件的取消监听函数 */ let unlistenNotification: UnlistenFn | null = null; @@ -43,18 +47,19 @@ const statusItems = computed(() => { }); onMounted(async () => { - appStore.loadConfig(); - store.loadCredentials(); - await store.setupTray(); - - try { - const enabled = await isAutostartEnabled(); - appStore.autoStartEnabled = enabled; - appStore.config.auto_start = enabled; - } catch { - /* ignore */ + const migrated = await migrateFromLocalStorage(); + if (migrated) { + logStore.addLog("INFO", "已将本地 localStorage 配置迁移到文件存储", "CONFIG"); } + await appStore.loadConfig(); + await store.loadCredentials(); + await setupTray(); + + const enabled = await isAutostartEnabled(); + appStore.autoStartEnabled = enabled; + appStore.config.auto_start = enabled; + unlistenNotification = await listen("notification-action", (event) => { if (event.payload === "postpone_1h") store.postponeMonitoring(); else if (event.payload === "go_handle") store.pauseForHandle(); @@ -67,30 +72,24 @@ onMounted(async () => { } else if (action === "close") { await getCurrentWindow().destroy(); } else { - appStore.showCloseDialog = true; + closeDialogRef.value?.openDialog(); } }); logStore.addLog("INFO", "应用程序启动完成", "SYSTEM"); if (appStore.config.silent_start) { - try { - await getCurrentWindow().hide(); - logStore.addLog("INFO", "静默启动:窗口已隐藏到托盘", "SYSTEM"); - } catch { - /* ignore */ - } + await getCurrentWindow().hide(); + logStore.addLog("INFO", "静默启动:窗口已隐藏到托盘", "SYSTEM"); } if (import.meta.env.DEV) { getCurrentWindow().setTitle(import.meta.env.VITE_APP_NAME); } - getVersion() - .then((v) => { - updater.currentVersion = v; - }) - .catch(() => {}); + getVersion().then((v) => { + updater.currentVersion = v; + }); networkStore.checkNetworkStatus(); updater.checkForUpdates(); @@ -152,7 +151,7 @@ onUnmounted(() => { - + diff --git a/src/api/example-usage.ts b/src/api/example-usage.ts new file mode 100644 index 0000000..9304263 --- /dev/null +++ b/src/api/example-usage.ts @@ -0,0 +1,173 @@ +// 使用示例:展示新的泛型 request 函数和 HTTP 方法辅助函数如何使用 + +import { + request, + get, + post, + put, + del, + patch, + type RequestOptions, +} from "@/api/client"; +import type { ApiResponse, LoginResponseData } from "@/api/types"; + +// 示例1:GET 请求 +interface UserProfile { + id: number; + name: string; + email: string; +} + +async function getUserProfile(userId: number) { + // 只需要指定响应类型 + const response = await request(`/users/${userId}`, { + method: "GET", + }); + return response; +} + +// 示例2:POST 请求,带请求数据和响应类型 +interface LoginRequest { + username: string; + password: string; +} + +async function login(username: string, password: string) { + // 指定响应类型和请求类型 + const response = await request, LoginRequest>( + "/login", + { + method: "POST", + data: { username, password }, + }, + ); + return response; +} + +// 示例3:PUT 请求 +interface UpdateUserRequest { + name: string; + email: string; +} + +interface UpdateUserResponse { + success: boolean; + message: string; +} + +async function updateUser(userId: number, name: string, email: string) { + const response = await request( + `/users/${userId}`, + { + method: "PUT", + data: { name, email }, + }, + ); + return response; +} + +// 示例4:不指定类型(使用默认 any) +async function genericRequest() { + const response = await request("/some-endpoint"); + return response; +} + +// 示例5:使用 RequestOptions 类型定义 +interface SearchParams { + keyword: string; + page: number; + limit: number; +} + +interface SearchResult { + items: any[]; + total: number; +} + +function createSearchOptions( + keyword: string, + page: number, + limit: number, +): RequestOptions { + return { + method: "POST", + data: { keyword, page, limit }, + headers: { + "Custom-Header": "search-request", + }, + }; +} + +async function searchUsers(keyword: string, page: number, limit: number) { + const options: RequestOptions = createSearchOptions( + keyword, + page, + limit, + ); + const response = await request( + "/search", + options, + ); + return response; +} + +// 示例6:使用 HTTP 方法辅助函数 + +async function getUserById(userId: number) { + // 使用 get 辅助函数 + const user = await get(`/users/${userId}`); + return user; +} + +async function createUser(name: string, email: string) { + // 使用 post 辅助函数 + const newUser = await post( + "/users", + { name, email }, + ); + return newUser; +} + +async function updateUserProfile( + userId: number, + updates: Partial, +) { + // 使用 put 辅助函数 + const updatedUser = await put>( + `/users/${userId}`, + updates, + ); + return updatedUser; +} + +async function deleteUser(userId: number) { + // 使用 del 辅助函数 + const result = await del<{ success: boolean }>(`/users/${userId}`); + return result; +} + +async function partialUpdateUser( + userId: number, + updates: Partial, +) { + // 使用 patch 辅助函数 + const updatedUser = await patch>( + `/users/${userId}`, + updates, + ); + return updatedUser; +} + +// 导出函数以避免未使用变量的警告 +export { + getUserProfile, + login, + updateUser, + genericRequest, + searchUsers, + getUserById, + createUser, + updateUserProfile, + deleteUser, + partialUpdateUser, +}; diff --git a/src/components/CloseDialog.vue b/src/components/CloseDialog.vue index 22cbcc6..821a659 100644 --- a/src/components/CloseDialog.vue +++ b/src/components/CloseDialog.vue @@ -1,18 +1,49 @@