3 Commits

Author SHA1 Message Date
huangzhenpc
4e11deb530 优化界面提示:1. 统一所有提示框样式,使用自定义美观对话框 2. 添加复制按钮功能,方便用户操作 3. 优化未激活会员时的提示信息展示 2025-02-12 14:57:23 +08:00
huangzhenpc
4531f12c0d feat: 优化GUI界面和用户体验
1. 优化按钮样式和布局:增加按钮尺寸和内边距,使用不同颜色区分功能按钮,添加按钮悬停和点击效果,优化按钮间距和对齐方式

2. 添加会员状态检查:实现状态缓存机制减少API请求,添加状态自动更新定时器,根据剩余时间动态调整更新间隔

3. 改进加载提示:添加加载对话框组件,实现异步API请求机制,优化加载状态显示

4. 优化购买提示界面:美化提示框样式和排版,添加多个购买渠道信息,优化文本对齐和间距

5. 其他改进:修复tkinter相关打包问题,优化错误提示信息,改进日志记录,完善异常处理
2025-02-12 14:39:50 +08:00
huangzhenpc
e3058b9e39 feat: 完成PyQt5 GUI实现,支持系统托盘和图标显示
1. 实现了基于PyQt5的GUI界面 2. 添加系统托盘功能,支持最小化到托盘 3. 修复了图标显示问题,包括窗口图标和任务栏图标 4. 优化了打包配置,支持PyInstaller打包 5. 版本更新到v3.3.1
2025-02-12 14:18:08 +08:00
14 changed files with 768 additions and 1102 deletions

View File

@@ -1,202 +0,0 @@
{
"package_json": {
"C:\\Users\\huangzhen\\AppData\\Local\\Programs\\Cursor\\resources\\app\\package.json": {
"homepage": "https://cursor.so",
"author": {
"name": "Cursor AI, Inc.",
"email": "hiring@cursor.so"
},
"productName": "Cursor",
"description": "Cursor is an AI-first coding environment.",
"main": "./out/main.js",
"dependencies": {
"@todesktop/runtime": "=1.6.1",
"@electron/asar": "^3.2.3",
"@anysphere/file-service": "0.0.0-73d604b6",
"@microsoft/1ds-core-js": "^3.2.13",
"@microsoft/1ds-post-js": "^3.2.13",
"@parcel/watcher": "2.5.0",
"@sentry/electron": "5.7.0",
"@sentry/node": "8.35.0",
"@types/semver": "^7.5.8",
"@vscode/deviceid": "^0.1.1",
"@vscode/iconv-lite-umd": "0.7.0",
"@vscode/policy-watcher": "^1.1.8",
"@vscode/proxy-agent": "^0.27.0",
"@vscode/ripgrep": "^1.15.10",
"@vscode/spdlog": "^0.15.0",
"@vscode/sqlite3": "5.1.8-vscode",
"@vscode/sudo-prompt": "9.3.1",
"@vscode/tree-sitter-wasm": "^0.0.4",
"@vscode/vscode-languagedetection": "1.0.21",
"@vscode/windows-mutex": "^0.5.0",
"@vscode/windows-process-tree": "^0.6.0",
"@vscode/windows-registry": "^1.1.0",
"@xterm/addon-clipboard": "^0.2.0-beta.53",
"@xterm/addon-image": "^0.9.0-beta.70",
"@xterm/addon-ligatures": "^0.10.0-beta.70",
"@xterm/addon-search": "^0.16.0-beta.70",
"@xterm/addon-serialize": "^0.14.0-beta.70",
"@xterm/addon-unicode11": "^0.9.0-beta.70",
"@xterm/addon-webgl": "^0.19.0-beta.70",
"@xterm/headless": "^5.6.0-beta.70",
"@xterm/xterm": "^5.6.0-beta.70",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"jschardet": "3.1.4",
"kerberos": "2.1.1",
"minimist": "^1.2.6",
"multiformats": "^13.3.1",
"native-is-elevated": "0.7.0",
"native-keymap": "^3.3.5",
"native-watchdog": "^1.4.1",
"node-fetch": "2.7.0",
"node-pty": "1.1.0-beta22",
"open": "^8.4.2",
"tas-client-umd": "0.2.0",
"v8-inspect-profiler": "^0.1.1",
"vscode-oniguruma": "1.7.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "9.1.0",
"yauzl": "^3.0.0",
"yazl": "^2.4.3"
},
"name": "cursor",
"version": "0.45.11",
"type": "module",
"desktopName": "cursor-url-handler.desktop",
"overrides": {},
"tdBuildId": "250207y6nbaw5qc",
"email": "jrxqnsoz250264@nosqli.com",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc"
}
},
"storage_json": {
"telemetry.machineId": "758a7f7f7f79078f9f2c690514878ea3e8f064c0a49e837dd396db89df58429c",
"telemetry.macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"telemetry.sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}",
"telemetry.devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"backupWorkspaces": {
"workspaces": [],
"folders": [
{
"folderUri": "file:///d%3A/W/python/001cursro.app/interactive"
}
],
"emptyWindows": [
{
"backupFolder": "1739332115293"
}
]
},
"windowControlHeight": 35,
"profileAssociations": {
"workspaces": {
"file:///d%3A/W/python/001cursro.app/interactive": "__default__profile__"
},
"emptyWindows": {
"1739332115293": "__default__profile__"
}
},
"theme": "vs-dark",
"themeBackground": "#1f1f1f",
"windowSplash": {
"zoomLevel": 0,
"baseTheme": "vs-dark",
"colorInfo": {
"foreground": "#cccccc",
"background": "#1f1f1f",
"editorBackground": "#1f1f1f",
"titleBarBackground": "#181818",
"titleBarBorder": "#2b2b2b",
"activityBarBackground": "#181818",
"activityBarBorder": "#2b2b2b",
"sideBarBackground": "#181818",
"sideBarBorder": "#2b2b2b",
"statusBarBackground": "#181818",
"statusBarBorder": "#2b2b2b",
"statusBarNoFolderBackground": "#1f1f1f"
},
"layoutInfo": {
"sideBarSide": "left",
"editorPartMinWidth": 220,
"titleBarHeight": 35,
"activityBarWidth": 0,
"sideBarWidth": 170,
"statusBarHeight": 22,
"windowBorder": false
}
}
},
"registry": {
"HKLM_MachineGuid": {
"exists": true,
"value": "776c6b6c-195f-42dc-94d6-72b70c3aca74"
},
"HKCU_cursor_shell": {
"exists": false,
"values": {}
},
"HKCU_cursor_command": {
"exists": false,
"values": {}
},
"HKCU_cursor_auth": {
"exists": false,
"values": {}
},
"HKCU_cursor_updates": {
"exists": false,
"values": {}
},
"HKCU_cursor_main": {
"exists": false,
"values": {}
}
},
"files": {
"storage": {
"exists": true,
"is_dir": false,
"size": 1891,
"modified_time": "2025-02-12T11:48:42.627574"
},
"storage_backup": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:48:26.403770"
},
"user_data": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"global_storage": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:48:47.490659"
},
"cache": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"updater": {
"exists": true,
"is_dir": false,
"size": 0,
"modified_time": "2025-02-10T17:19:39.071580"
}
},
"telemetry": {
"machineId": "758a7f7f7f79078f9f2c690514878ea3e8f064c0a49e837dd396db89df58429c",
"macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}"
}
}

View File

@@ -1,216 +0,0 @@
{
"package_json": {
"C:\\Users\\huangzhen\\AppData\\Local\\Programs\\Cursor\\resources\\app\\package.json": {
"homepage": "https://cursor.so",
"author": {
"name": "Cursor AI, Inc.",
"email": "hiring@cursor.so"
},
"productName": "Cursor",
"description": "Cursor is an AI-first coding environment.",
"main": "./out/main.js",
"dependencies": {
"@todesktop/runtime": "=1.6.1",
"@electron/asar": "^3.2.3",
"@anysphere/file-service": "0.0.0-73d604b6",
"@microsoft/1ds-core-js": "^3.2.13",
"@microsoft/1ds-post-js": "^3.2.13",
"@parcel/watcher": "2.5.0",
"@sentry/electron": "5.7.0",
"@sentry/node": "8.35.0",
"@types/semver": "^7.5.8",
"@vscode/deviceid": "^0.1.1",
"@vscode/iconv-lite-umd": "0.7.0",
"@vscode/policy-watcher": "^1.1.8",
"@vscode/proxy-agent": "^0.27.0",
"@vscode/ripgrep": "^1.15.10",
"@vscode/spdlog": "^0.15.0",
"@vscode/sqlite3": "5.1.8-vscode",
"@vscode/sudo-prompt": "9.3.1",
"@vscode/tree-sitter-wasm": "^0.0.4",
"@vscode/vscode-languagedetection": "1.0.21",
"@vscode/windows-mutex": "^0.5.0",
"@vscode/windows-process-tree": "^0.6.0",
"@vscode/windows-registry": "^1.1.0",
"@xterm/addon-clipboard": "^0.2.0-beta.53",
"@xterm/addon-image": "^0.9.0-beta.70",
"@xterm/addon-ligatures": "^0.10.0-beta.70",
"@xterm/addon-search": "^0.16.0-beta.70",
"@xterm/addon-serialize": "^0.14.0-beta.70",
"@xterm/addon-unicode11": "^0.9.0-beta.70",
"@xterm/addon-webgl": "^0.19.0-beta.70",
"@xterm/headless": "^5.6.0-beta.70",
"@xterm/xterm": "^5.6.0-beta.70",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"jschardet": "3.1.4",
"kerberos": "2.1.1",
"minimist": "^1.2.6",
"multiformats": "^13.3.1",
"native-is-elevated": "0.7.0",
"native-keymap": "^3.3.5",
"native-watchdog": "^1.4.1",
"node-fetch": "2.7.0",
"node-pty": "1.1.0-beta22",
"open": "^8.4.2",
"tas-client-umd": "0.2.0",
"v8-inspect-profiler": "^0.1.1",
"vscode-oniguruma": "1.7.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "9.1.0",
"yauzl": "^3.0.0",
"yazl": "^2.4.3"
},
"name": "cursor",
"version": "0.45.11",
"type": "module",
"desktopName": "cursor-url-handler.desktop",
"overrides": {},
"tdBuildId": "250207y6nbaw5qc",
"email": "jrxqnsoz250264@nosqli.com",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc",
"updateUrl": "",
"disableUpdate": true,
"enableNodeApiUncaughtExceptionPolicy": true,
"nodeOptions": [
"--force-node-api-uncaught-exceptions-policy=true"
]
}
},
"storage_json": {
"telemetry.machineId": "b0cbb2d13ca4c983be40d31e010819f16adb3d6083598f1457094837bdaa3def",
"telemetry.macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"telemetry.sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}",
"telemetry.devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"backupWorkspaces": {
"workspaces": [],
"folders": [
{
"folderUri": "file:///d%3A/W/python/001cursro.app/interactive"
}
],
"emptyWindows": []
},
"windowControlHeight": 35,
"profileAssociations": {
"workspaces": {
"file:///d%3A/W/python/001cursro.app/interactive": "__default__profile__"
},
"emptyWindows": {}
},
"theme": "vs-dark",
"themeBackground": "#1f1f1f",
"windowSplash": {
"zoomLevel": 0,
"baseTheme": "vs-dark",
"colorInfo": {
"foreground": "#cccccc",
"background": "#1f1f1f",
"editorBackground": "#1f1f1f",
"titleBarBackground": "#181818",
"titleBarBorder": "#2b2b2b",
"activityBarBackground": "#181818",
"activityBarBorder": "#2b2b2b",
"sideBarBackground": "#181818",
"sideBarBorder": "#2b2b2b",
"statusBarBackground": "#181818",
"statusBarBorder": "#2b2b2b",
"statusBarNoFolderBackground": "#1f1f1f"
},
"layoutInfo": {
"sideBarSide": "left",
"editorPartMinWidth": 220,
"titleBarHeight": 35,
"activityBarWidth": 0,
"sideBarWidth": 300,
"statusBarHeight": 22,
"windowBorder": false
}
},
"windowsState": {
"lastActiveWindow": {
"folder": "file:///d%3A/W/python/001cursro.app/interactive",
"backupPath": "C:\\Users\\huangzhen\\AppData\\Roaming\\Cursor\\Backups\\385f155a4a13070be99ee4e76a057235",
"uiState": {
"mode": 0,
"x": 512,
"y": 192,
"width": 1024,
"height": 768
}
},
"openedWindows": []
}
},
"registry": {
"HKLM_MachineGuid": {
"exists": true,
"value": "1deb25e7-cdd4-4367-a347-fba8b33b9b03"
},
"HKCU_cursor_shell": {
"exists": false,
"values": {}
},
"HKCU_cursor_command": {
"exists": false,
"values": {}
},
"HKCU_cursor_auth": {
"exists": false,
"values": {}
},
"HKCU_cursor_updates": {
"exists": false,
"values": {}
},
"HKCU_cursor_main": {
"exists": false,
"values": {}
}
},
"files": {
"storage": {
"exists": true,
"is_dir": false,
"size": 1980,
"modified_time": "2025-02-12T12:37:17.428609"
},
"storage_backup": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T12:37:17.371311"
},
"user_data": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"global_storage": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T12:37:14.253083"
},
"cache": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"updater": {
"exists": true,
"is_dir": false,
"size": 0,
"modified_time": "2025-02-10T17:19:39.071580"
}
},
"telemetry": {
"machineId": "b0cbb2d13ca4c983be40d31e010819f16adb3d6083598f1457094837bdaa3def",
"macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}"
}
}

View File

@@ -1,244 +0,0 @@
{
"package_json": {
"C:\\Users\\huangzhen\\AppData\\Local\\Programs\\Cursor\\resources\\app\\package.json": {
"homepage": "https://cursor.so",
"author": {
"name": "Cursor AI, Inc.",
"email": "hiring@cursor.so"
},
"productName": "Cursor",
"description": "Cursor is an AI-first coding environment.",
"main": "./out/main.js",
"dependencies": {
"@todesktop/runtime": "=1.6.1",
"@electron/asar": "^3.2.3",
"@anysphere/file-service": "0.0.0-73d604b6",
"@microsoft/1ds-core-js": "^3.2.13",
"@microsoft/1ds-post-js": "^3.2.13",
"@parcel/watcher": "2.5.0",
"@sentry/electron": "5.7.0",
"@sentry/node": "8.35.0",
"@types/semver": "^7.5.8",
"@vscode/deviceid": "^0.1.1",
"@vscode/iconv-lite-umd": "0.7.0",
"@vscode/policy-watcher": "^1.1.8",
"@vscode/proxy-agent": "^0.27.0",
"@vscode/ripgrep": "^1.15.10",
"@vscode/spdlog": "^0.15.0",
"@vscode/sqlite3": "5.1.8-vscode",
"@vscode/sudo-prompt": "9.3.1",
"@vscode/tree-sitter-wasm": "^0.0.4",
"@vscode/vscode-languagedetection": "1.0.21",
"@vscode/windows-mutex": "^0.5.0",
"@vscode/windows-process-tree": "^0.6.0",
"@vscode/windows-registry": "^1.1.0",
"@xterm/addon-clipboard": "^0.2.0-beta.53",
"@xterm/addon-image": "^0.9.0-beta.70",
"@xterm/addon-ligatures": "^0.10.0-beta.70",
"@xterm/addon-search": "^0.16.0-beta.70",
"@xterm/addon-serialize": "^0.14.0-beta.70",
"@xterm/addon-unicode11": "^0.9.0-beta.70",
"@xterm/addon-webgl": "^0.19.0-beta.70",
"@xterm/headless": "^5.6.0-beta.70",
"@xterm/xterm": "^5.6.0-beta.70",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"jschardet": "3.1.4",
"kerberos": "2.1.1",
"minimist": "^1.2.6",
"multiformats": "^13.3.1",
"native-is-elevated": "0.7.0",
"native-keymap": "^3.3.5",
"native-watchdog": "^1.4.1",
"node-fetch": "2.7.0",
"node-pty": "1.1.0-beta22",
"open": "^8.4.2",
"tas-client-umd": "0.2.0",
"v8-inspect-profiler": "^0.1.1",
"vscode-oniguruma": "1.7.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "9.1.0",
"yauzl": "^3.0.0",
"yazl": "^2.4.3"
},
"name": "cursor",
"version": "0.45.11",
"type": "module",
"desktopName": "cursor-url-handler.desktop",
"overrides": {},
"tdBuildId": "250207y6nbaw5qc",
"email": "jrxqnsoz250264@nosqli.com",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc"
}
},
"storage_json": {
"telemetry.machineId": "31b3701f1790cdb754bd8a02bad4913a9f8a3f04c9e19c519996be8c7b8cb561",
"telemetry.macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"telemetry.sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}",
"telemetry.devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"backupWorkspaces": {
"workspaces": [],
"folders": [
{
"folderUri": "file:///d%3A/W/python/001cursro.app/interactive"
},
{
"folderUri": "file:///d%3A/W/python/003cursorapiadmin"
}
],
"emptyWindows": [
{
"backupFolder": "1739329218500"
},
{
"backupFolder": "1739329245089"
}
]
},
"windowControlHeight": 35,
"profileAssociations": {
"workspaces": {
"file:///d%3A/W/python/001cursro.app/interactive": "__default__profile__",
"file:///d%3A/W/python/003cursorapiadmin": "__default__profile__"
},
"emptyWindows": {}
},
"theme": "vs-dark",
"themeBackground": "#1f1f1f",
"windowSplash": {
"zoomLevel": 0,
"baseTheme": "vs-dark",
"colorInfo": {
"foreground": "#cccccc",
"background": "#1f1f1f",
"editorBackground": "#1f1f1f",
"titleBarBackground": "#181818",
"titleBarBorder": "#2b2b2b",
"activityBarBackground": "#181818",
"activityBarBorder": "#2b2b2b",
"sideBarBackground": "#181818",
"sideBarBorder": "#2b2b2b",
"statusBarBackground": "#181818",
"statusBarBorder": "#2b2b2b",
"statusBarNoFolderBackground": "#1f1f1f"
},
"layoutInfo": {
"sideBarSide": "left",
"editorPartMinWidth": 220,
"titleBarHeight": 35,
"activityBarWidth": 0,
"sideBarWidth": 170,
"statusBarHeight": 22,
"windowBorder": false
}
},
"windowsState": {
"lastActiveWindow": {
"folder": "file:///d%3A/W/python/001cursro.app/interactive",
"backupPath": "C:\\Users\\huangzhen\\AppData\\Roaming\\Cursor\\Backups\\385f155a4a13070be99ee4e76a057235",
"uiState": {
"mode": 0,
"x": 512,
"y": 192,
"width": 1024,
"height": 768
}
},
"openedWindows": [
{
"folder": "file:///d%3A/W/python/001cursro.app/interactive",
"backupPath": "C:\\Users\\huangzhen\\AppData\\Roaming\\Cursor\\Backups\\385f155a4a13070be99ee4e76a057235",
"uiState": {
"mode": 0,
"x": 512,
"y": 192,
"width": 1024,
"height": 768
}
},
{
"folder": "file:///d%3A/W/python/003cursorapiadmin",
"backupPath": "C:\\Users\\huangzhen\\AppData\\Roaming\\Cursor\\Backups\\b6b8cfb24ed2ddb05d90d45cce5443e7",
"uiState": {
"mode": 0,
"x": 512,
"y": 192,
"width": 1024,
"height": 768
}
}
]
}
},
"registry": {
"HKLM_MachineGuid": {
"exists": true,
"value": "d890ab3d-43cd-40c8-a9ef-f5683b5a64e3"
},
"HKCU_cursor_shell": {
"exists": false,
"values": {}
},
"HKCU_cursor_command": {
"exists": false,
"values": {}
},
"HKCU_cursor_auth": {
"exists": false,
"values": {}
},
"HKCU_cursor_updates": {
"exists": false,
"values": {}
},
"HKCU_cursor_main": {
"exists": false,
"values": {}
}
},
"files": {
"storage": {
"exists": true,
"is_dir": false,
"size": 3427,
"modified_time": "2025-02-12T11:40:57.046415"
},
"storage_backup": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:00:01.555876"
},
"user_data": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"global_storage": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:47:27.627883"
},
"cache": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"updater": {
"exists": true,
"is_dir": false,
"size": 0,
"modified_time": "2025-02-10T17:19:39.071580"
}
},
"telemetry": {
"machineId": "31b3701f1790cdb754bd8a02bad4913a9f8a3f04c9e19c519996be8c7b8cb561",
"macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}"
}
}

View File

@@ -1,216 +0,0 @@
{
"package_json": {
"C:\\Users\\huangzhen\\AppData\\Local\\Programs\\Cursor\\resources\\app\\package.json": {
"homepage": "https://cursor.so",
"author": {
"name": "Cursor AI, Inc.",
"email": "hiring@cursor.so"
},
"productName": "Cursor",
"description": "Cursor is an AI-first coding environment.",
"main": "./out/main.js",
"dependencies": {
"@todesktop/runtime": "=1.6.1",
"@electron/asar": "^3.2.3",
"@anysphere/file-service": "0.0.0-73d604b6",
"@microsoft/1ds-core-js": "^3.2.13",
"@microsoft/1ds-post-js": "^3.2.13",
"@parcel/watcher": "2.5.0",
"@sentry/electron": "5.7.0",
"@sentry/node": "8.35.0",
"@types/semver": "^7.5.8",
"@vscode/deviceid": "^0.1.1",
"@vscode/iconv-lite-umd": "0.7.0",
"@vscode/policy-watcher": "^1.1.8",
"@vscode/proxy-agent": "^0.27.0",
"@vscode/ripgrep": "^1.15.10",
"@vscode/spdlog": "^0.15.0",
"@vscode/sqlite3": "5.1.8-vscode",
"@vscode/sudo-prompt": "9.3.1",
"@vscode/tree-sitter-wasm": "^0.0.4",
"@vscode/vscode-languagedetection": "1.0.21",
"@vscode/windows-mutex": "^0.5.0",
"@vscode/windows-process-tree": "^0.6.0",
"@vscode/windows-registry": "^1.1.0",
"@xterm/addon-clipboard": "^0.2.0-beta.53",
"@xterm/addon-image": "^0.9.0-beta.70",
"@xterm/addon-ligatures": "^0.10.0-beta.70",
"@xterm/addon-search": "^0.16.0-beta.70",
"@xterm/addon-serialize": "^0.14.0-beta.70",
"@xterm/addon-unicode11": "^0.9.0-beta.70",
"@xterm/addon-webgl": "^0.19.0-beta.70",
"@xterm/headless": "^5.6.0-beta.70",
"@xterm/xterm": "^5.6.0-beta.70",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"jschardet": "3.1.4",
"kerberos": "2.1.1",
"minimist": "^1.2.6",
"multiformats": "^13.3.1",
"native-is-elevated": "0.7.0",
"native-keymap": "^3.3.5",
"native-watchdog": "^1.4.1",
"node-fetch": "2.7.0",
"node-pty": "1.1.0-beta22",
"open": "^8.4.2",
"tas-client-umd": "0.2.0",
"v8-inspect-profiler": "^0.1.1",
"vscode-oniguruma": "1.7.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "9.1.0",
"yauzl": "^3.0.0",
"yazl": "^2.4.3"
},
"name": "cursor",
"version": "0.45.11",
"type": "module",
"desktopName": "cursor-url-handler.desktop",
"overrides": {},
"tdBuildId": "250207y6nbaw5qc",
"email": "jrxqnsoz250264@nosqli.com",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc",
"updateUrl": "",
"disableUpdate": true,
"enableNodeApiUncaughtExceptionPolicy": true,
"nodeOptions": [
"--force-node-api-uncaught-exceptions-policy=true"
]
}
},
"storage_json": {
"telemetry.machineId": "9eb67b11924f32572a67e6480ce4f1cabf3f61503aa4918af506b259527a4745",
"telemetry.macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"telemetry.sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}",
"telemetry.devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"backupWorkspaces": {
"workspaces": [],
"folders": [
{
"folderUri": "file:///d%3A/W/python/001cursro.app/interactive"
}
],
"emptyWindows": []
},
"windowControlHeight": 35,
"profileAssociations": {
"workspaces": {
"file:///d%3A/W/python/001cursro.app/interactive": "__default__profile__"
},
"emptyWindows": {}
},
"theme": "vs-dark",
"themeBackground": "#1f1f1f",
"windowSplash": {
"zoomLevel": 0,
"baseTheme": "vs-dark",
"colorInfo": {
"foreground": "#cccccc",
"background": "#1f1f1f",
"editorBackground": "#1f1f1f",
"titleBarBackground": "#181818",
"titleBarBorder": "#2b2b2b",
"activityBarBackground": "#181818",
"activityBarBorder": "#2b2b2b",
"sideBarBackground": "#181818",
"sideBarBorder": "#2b2b2b",
"statusBarBackground": "#181818",
"statusBarBorder": "#2b2b2b",
"statusBarNoFolderBackground": "#1f1f1f"
},
"layoutInfo": {
"sideBarSide": "left",
"editorPartMinWidth": 220,
"titleBarHeight": 35,
"activityBarWidth": 0,
"sideBarWidth": 300,
"statusBarHeight": 22,
"windowBorder": false
}
},
"windowsState": {
"lastActiveWindow": {
"folder": "file:///d%3A/W/python/001cursro.app/interactive",
"backupPath": "C:\\Users\\huangzhen\\AppData\\Roaming\\Cursor\\Backups\\385f155a4a13070be99ee4e76a057235",
"uiState": {
"mode": 0,
"x": 512,
"y": 192,
"width": 1024,
"height": 768
}
},
"openedWindows": []
}
},
"registry": {
"HKLM_MachineGuid": {
"exists": true,
"value": "948b93c1-ee34-4a48-95d0-a2fce9af92b1"
},
"HKCU_cursor_shell": {
"exists": false,
"values": {}
},
"HKCU_cursor_command": {
"exists": false,
"values": {}
},
"HKCU_cursor_auth": {
"exists": false,
"values": {}
},
"HKCU_cursor_updates": {
"exists": false,
"values": {}
},
"HKCU_cursor_main": {
"exists": false,
"values": {}
}
},
"files": {
"storage": {
"exists": true,
"is_dir": false,
"size": 2214,
"modified_time": "2025-02-12T12:36:27.187387"
},
"storage_backup": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T12:33:10.408749"
},
"user_data": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"global_storage": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T12:37:14.253083"
},
"cache": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"updater": {
"exists": true,
"is_dir": false,
"size": 0,
"modified_time": "2025-02-10T17:19:39.071580"
}
},
"telemetry": {
"machineId": "9eb67b11924f32572a67e6480ce4f1cabf3f61503aa4918af506b259527a4745",
"macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}"
}
}

View File

@@ -22,7 +22,7 @@ a = Analysis(
hookspath=[], hookspath=[],
hooksconfig={}, hooksconfig={},
runtime_hooks=[], runtime_hooks=[],
excludes=[], excludes=['_tkinter', 'tkinter', 'Tkinter'], # 排除 tkinter 相关模块
noarchive=False, noarchive=False,
optimize=0, optimize=0,
) )

View File

@@ -1,59 +0,0 @@
{
"package_json_changes": {},
"registry_changes": {
"HKLM_MachineGuid": {
"before": {
"exists": true,
"value": "d890ab3d-43cd-40c8-a9ef-f5683b5a64e3"
},
"after": {
"exists": true,
"value": "776c6b6c-195f-42dc-94d6-72b70c3aca74"
}
}
},
"file_changes": {
"storage": {
"before": {
"exists": true,
"is_dir": false,
"size": 3427,
"modified_time": "2025-02-12T11:40:57.046415"
},
"after": {
"exists": true,
"is_dir": false,
"size": 1891,
"modified_time": "2025-02-12T11:48:42.627574"
}
},
"storage_backup": {
"before": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:00:01.555876"
},
"after": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:48:26.403770"
}
},
"global_storage": {
"before": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:47:27.627883"
},
"after": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:48:47.490659"
}
}
}
}

View File

@@ -5,8 +5,9 @@ import os
from PIL import Image from PIL import Image
from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QLineEdit, QPushButton, QFrame, QTextEdit, QLabel, QLineEdit, QPushButton, QFrame, QTextEdit,
QMessageBox, QApplication) QMessageBox, QApplication, QSystemTrayIcon, QMenu,
from PyQt5.QtCore import Qt, QTimer QDialog, QProgressBar, QStyle)
from PyQt5.QtCore import Qt, QTimer, QThread, pyqtSignal
from PyQt5.QtGui import QIcon, QPixmap from PyQt5.QtGui import QIcon, QPixmap
sys.path.append(str(Path(__file__).parent.parent)) sys.path.append(str(Path(__file__).parent.parent))
@@ -23,28 +24,111 @@ def get_version():
logging.error(f"读取版本号失败: {str(e)}") logging.error(f"读取版本号失败: {str(e)}")
return "未知版本" return "未知版本"
class LoadingDialog(QDialog):
"""加载对话框"""
def __init__(self, parent=None, message="请稍候..."):
super().__init__(parent)
self.setWindowTitle("处理中")
self.setFixedSize(300, 100)
self.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint)
layout = QVBoxLayout()
# 添加消息标签
self.message_label = QLabel(message)
self.message_label.setAlignment(Qt.AlignCenter)
layout.addWidget(self.message_label)
# 添加进度条
self.progress_bar = QProgressBar()
self.progress_bar.setTextVisible(False)
self.progress_bar.setRange(0, 0) # 设置为循环模式
layout.addWidget(self.progress_bar)
self.setLayout(layout)
# 设置样式
self.setStyleSheet("""
QDialog {
background-color: #f8f9fa;
}
QLabel {
color: #333333;
font-size: 14px;
padding: 10px;
}
QProgressBar {
border: 2px solid #e9ecef;
border-radius: 5px;
text-align: center;
}
QProgressBar::chunk {
background-color: #0d6efd;
width: 10px;
margin: 0.5px;
}
""")
class ApiWorker(QThread):
"""API请求工作线程"""
finished = pyqtSignal(tuple) # 发送结果信号
def __init__(self, func, *args, **kwargs):
super().__init__()
self.func = func
self.args = args
self.kwargs = kwargs
def run(self):
try:
result = self.func(*self.args, **self.kwargs)
self.finished.emit((True, result))
except Exception as e:
self.finished.emit((False, str(e)))
class MainWindow(QMainWindow): class MainWindow(QMainWindow):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.config = Config() self.config = Config()
self.switcher = AccountSwitcher() self.switcher = AccountSwitcher()
# 添加激活状态缓存
self._activation_status = None # 缓存的激活状态
self._status_timer = None # 状态更新定时器
version = get_version() version = get_version()
cursor_version = self.switcher.get_cursor_version() cursor_version = self.switcher.get_cursor_version()
self.setWindowTitle(f"听泉Cursor助手 v{version} (本机Cursor版本: {cursor_version})") self.setWindowTitle(f"听泉Cursor助手 v{version} (本机Cursor版本: {cursor_version})")
self.setMinimumSize(600, 500) self.setMinimumSize(600, 500)
# 设置图标 # 设置窗口图标
try: icon_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "icon", "two.ico")
current_dir = os.path.dirname(os.path.abspath(__file__)) if os.path.exists(icon_path):
icon_path = os.path.join(os.path.dirname(current_dir), "icon", "th.jpg") window_icon = QIcon(icon_path)
if os.path.exists(icon_path): if not window_icon.isNull():
self.setWindowIcon(QIcon(icon_path)) self.setWindowIcon(window_icon)
logging.info(f"成功加载图标: {icon_path}") logging.info(f"成功设置窗口图标: {icon_path}")
else:
logging.error(f"图标文件不存在: {icon_path}") # 创建系统托盘图标
except Exception as e: self.tray_icon = QSystemTrayIcon(self)
logging.error(f"设置图标失败: {str(e)}") self.tray_icon.setIcon(self.windowIcon())
self.tray_icon.setToolTip("听泉Cursor助手")
# 创建托盘菜单
tray_menu = QMenu()
show_action = tray_menu.addAction("显示主窗口")
show_action.triggered.connect(self.show)
quit_action = tray_menu.addAction("退出")
quit_action.triggered.connect(QApplication.instance().quit)
# 设置托盘菜单
self.tray_icon.setContextMenu(tray_menu)
# 连接托盘图标的信号
self.tray_icon.activated.connect(self.on_tray_icon_activated)
# 显示托盘图标
self.tray_icon.show()
# 创建主窗口部件 # 创建主窗口部件
central_widget = QWidget() central_widget = QWidget()
@@ -78,6 +162,23 @@ class MainWindow(QMainWindow):
# 激活区域 # 激活区域
activation_frame = QFrame() activation_frame = QFrame()
activation_layout = QVBoxLayout(activation_frame) activation_layout = QVBoxLayout(activation_frame)
# 使用说明
usage_label = QLabel()
usage_label.setText("使用说明:\n\n1. 输入激活码并点击激活\n2. 激活成功后点击\"刷新Cursor编辑器授权\"即可正常使用\n3. 如果刷新无效,请点击\"突破Cursor0.45.x限制\"\n4. 建议点击\"禁用Cursor版本更新\"保持长期稳定")
usage_label.setStyleSheet("""
QLabel {
color: #6c757d;
font-size: 13px;
padding: 10px;
background-color: #f8f9fa;
border-radius: 4px;
border: 1px solid #dee2e6;
}
""")
activation_layout.addWidget(usage_label)
# 激活码输入区域
activation_layout.addWidget(QLabel("激活(叠加)会员,多个激活码可叠加整体时长")) activation_layout.addWidget(QLabel("激活(叠加)会员,多个激活码可叠加整体时长"))
input_frame = QFrame() input_frame = QFrame()
input_layout = QHBoxLayout(input_frame) input_layout = QHBoxLayout(input_frame)
@@ -93,20 +194,81 @@ class MainWindow(QMainWindow):
# 操作按钮区域 # 操作按钮区域
btn_frame = QFrame() btn_frame = QFrame()
btn_layout = QVBoxLayout(btn_frame) btn_layout = QVBoxLayout(btn_frame)
# 设置按钮样式
button_style = """
QPushButton {
background-color: #0d6efd;
color: white;
border: none;
padding: 15px;
border-radius: 6px;
font-size: 14px;
min-width: 200px;
margin: 5px;
}
QPushButton:hover {
background-color: #0b5ed7;
}
QPushButton:pressed {
background-color: #0a58ca;
}
"""
# 刷新授权按钮
refresh_btn = QPushButton("刷新Cursor编辑器授权") refresh_btn = QPushButton("刷新Cursor编辑器授权")
refresh_btn.setStyleSheet(button_style)
refresh_btn.clicked.connect(self.refresh_cursor_auth) refresh_btn.clicked.connect(self.refresh_cursor_auth)
refresh_btn.setMinimumHeight(50)
btn_layout.addWidget(refresh_btn) btn_layout.addWidget(refresh_btn)
# 突破限制按钮
bypass_btn = QPushButton("突破Cursor0.45.x限制") bypass_btn = QPushButton("突破Cursor0.45.x限制")
bypass_btn.setStyleSheet(button_style.replace("#0d6efd", "#198754").replace("#0b5ed7", "#157347").replace("#0a58ca", "#146c43"))
bypass_btn.clicked.connect(self.dummy_function) bypass_btn.clicked.connect(self.dummy_function)
bypass_btn.setMinimumHeight(50)
btn_layout.addWidget(bypass_btn) btn_layout.addWidget(bypass_btn)
# 禁用更新按钮
disable_update_btn = QPushButton("禁用Cursor版本更新") disable_update_btn = QPushButton("禁用Cursor版本更新")
disable_update_btn.setStyleSheet(button_style.replace("#0d6efd", "#dc3545").replace("#0b5ed7", "#bb2d3b").replace("#0a58ca", "#b02a37"))
disable_update_btn.clicked.connect(self.disable_cursor_update) disable_update_btn.clicked.connect(self.disable_cursor_update)
disable_update_btn.setMinimumHeight(50)
btn_layout.addWidget(disable_update_btn) btn_layout.addWidget(disable_update_btn)
# 设置按钮间距
btn_layout.setSpacing(10)
btn_layout.setContentsMargins(20, 10, 20, 10)
main_layout.addWidget(btn_frame) main_layout.addWidget(btn_frame)
# 启动时检查一次状态 # 启动时检查一次状态
QTimer.singleShot(0, self.check_status) QTimer.singleShot(0, self.check_status)
def on_tray_icon_activated(self, reason):
"""处理托盘图标的点击事件"""
if reason == QSystemTrayIcon.DoubleClick:
self.show()
self.activateWindow()
def closeEvent(self, event):
"""重写关闭事件,最小化到托盘而不是退出"""
if hasattr(self, 'tray_icon') and self.tray_icon.isVisible():
event.ignore()
self.hide()
self.tray_icon.showMessage(
"听泉Cursor助手",
"程序已最小化到系统托盘",
QSystemTrayIcon.Information,
2000
)
else:
event.accept()
if self._status_timer:
self._status_timer.stop()
super().closeEvent(event)
def copy_device_id(self): def copy_device_id(self):
"""复制设备ID到剪贴板""" """复制设备ID到剪贴板"""
if not self.check_status(): if not self.check_status():
@@ -114,32 +276,285 @@ class MainWindow(QMainWindow):
QApplication.clipboard().setText(self.hardware_id_edit.text()) QApplication.clipboard().setText(self.hardware_id_edit.text())
QMessageBox.information(self, "提示", "设备ID已复制到剪贴板") QMessageBox.information(self, "提示", "设备ID已复制到剪贴板")
def show_loading_dialog(self, message="请稍候..."):
"""显示加载对话框"""
self.loading_dialog = LoadingDialog(self, message)
self.loading_dialog.show()
def hide_loading_dialog(self):
"""隐藏加载对话框"""
if hasattr(self, 'loading_dialog'):
self.loading_dialog.hide()
self.loading_dialog.deleteLater()
def activate_account(self): def activate_account(self):
"""激活账号""" """激活账号"""
code = self.activation_edit.text().strip() code = self.activation_edit.text().strip()
if not code: if not code:
QMessageBox.warning(self, "提示", "请输入激活码") # 创建自定义消息框
msg = QDialog(self)
msg.setWindowTitle("提示")
msg.setFixedWidth(400)
msg.setWindowFlags(msg.windowFlags() & ~Qt.WindowContextHelpButtonHint)
# 创建布局
layout = QVBoxLayout()
# 添加图标和文本
icon_label = QLabel()
icon_label.setPixmap(self.style().standardIcon(QStyle.SP_MessageBoxWarning).pixmap(32, 32))
icon_label.setAlignment(Qt.AlignCenter)
layout.addWidget(icon_label)
text_label = QLabel("请输入激活码")
text_label.setAlignment(Qt.AlignCenter)
text_label.setStyleSheet("font-size: 14px; font-weight: bold; color: #333333; padding: 10px;")
layout.addWidget(text_label)
# 添加购买信息
info_text = "获取会员激活码,请通过以下方式:\n\n" \
"• 官方自助网站cursor.nosqli.com\n" \
"• 微信客服behikcigar\n" \
"• 闲鱼店铺xxx\n\n" \
"————————————————————\n" \
"诚招代理商,欢迎加盟合作!"
info_label = QLabel(info_text)
info_label.setAlignment(Qt.AlignLeft)
info_label.setStyleSheet("""
QLabel {
color: #333333;
font-size: 14px;
padding: 15px;
background-color: #f8f9fa;
border-radius: 4px;
border: 1px solid #dee2e6;
margin: 10px;
}
""")
layout.addWidget(info_label)
# 添加复制按钮区域
btn_layout = QHBoxLayout()
# 复制网站按钮
copy_web_btn = QPushButton("复制网站")
copy_web_btn.clicked.connect(lambda: self.copy_and_show_tip(msg, "cursor.nosqli.com", "网站地址已复制到剪贴板"))
copy_web_btn.setStyleSheet("""
QPushButton {
background-color: #0d6efd;
color: white;
border: none;
padding: 8px 15px;
border-radius: 4px;
font-size: 13px;
}
QPushButton:hover {
background-color: #0b5ed7;
}
""")
btn_layout.addWidget(copy_web_btn)
# 复制微信按钮
copy_wx_btn = QPushButton("复制微信")
copy_wx_btn.clicked.connect(lambda: self.copy_and_show_tip(msg, "behikcigar", "微信号已复制到剪贴板"))
copy_wx_btn.setStyleSheet("""
QPushButton {
background-color: #198754;
color: white;
border: none;
padding: 8px 15px;
border-radius: 4px;
font-size: 13px;
}
QPushButton:hover {
background-color: #157347;
}
""")
btn_layout.addWidget(copy_wx_btn)
# 确定按钮
ok_btn = QPushButton("确定")
ok_btn.clicked.connect(msg.accept)
ok_btn.setStyleSheet("""
QPushButton {
background-color: #0d6efd;
color: white;
border: none;
padding: 8px 25px;
border-radius: 4px;
font-size: 13px;
min-width: 100px;
}
QPushButton:hover {
background-color: #0b5ed7;
}
""")
btn_layout.addWidget(ok_btn)
layout.addLayout(btn_layout)
msg.setLayout(layout)
msg.exec_()
return return
try: try:
success, message, account_info = self.switcher.check_activation_code(code) # 显示加载对话框
self.show_loading_dialog("正在验证激活码,请稍候...")
# 创建工作线程
self.worker = ApiWorker(self.switcher.check_activation_code, code)
self.worker.finished.connect(self.on_activation_complete)
self.worker.start()
except Exception as e:
self.hide_loading_dialog()
msg = QMessageBox(self)
msg.setWindowTitle("错误")
msg.setText(f"激活失败: {str(e)}")
msg.setIcon(QMessageBox.Critical)
msg.setStyleSheet("""
QMessageBox {
background-color: #f8f9fa;
min-width: 450px;
padding: 20px;
}
QMessageBox QLabel {
color: #333333;
font-size: 14px;
padding: 10px;
margin: 10px;
}
QMessageBox QLabel:first-child {
font-weight: bold;
color: #dc3545;
}
QPushButton {
background-color: #dc3545;
color: white;
border: none;
padding: 8px 25px;
border-radius: 4px;
font-size: 13px;
min-width: 100px;
margin: 10px;
}
QPushButton:hover {
background-color: #bb2d3b;
}
""")
msg.exec_()
def copy_and_show_tip(self, parent, text, tip):
"""复制文本并显示提示"""
QApplication.clipboard().setText(text)
QMessageBox.information(parent, "提示", tip)
def on_activation_complete(self, result):
"""激活完成回调"""
success, data = result
self.hide_loading_dialog()
if isinstance(data, tuple):
success, message, account_info = data
if success: if success:
# 更新会员信息显示 # 更新会员信息显示
self.update_status_display(account_info) self.update_status_display(account_info)
QMessageBox.information(self, "激活成功", "激活成功!\n" + message) # 更新激活状态缓存
self._activation_status = True
# 更新状态定时器
days_left = account_info.get('days_left', 0)
seconds_left = days_left * 24 * 60 * 60
if self._status_timer:
self._status_timer.stop()
self._status_timer = QTimer(self)
self._status_timer.setSingleShot(True)
self._status_timer.timeout.connect(self.check_status)
update_interval = min(seconds_left - 60, 24 * 60 * 60) # 最长1天更新一次
if update_interval > 0:
self._status_timer.start(update_interval * 1000) # 转换为毫秒
msg = QMessageBox(self)
msg.setWindowTitle("激活成功")
msg.setText("激活成功!")
msg.setInformativeText(message)
msg.setIcon(QMessageBox.Information)
msg.setStyleSheet("""
QMessageBox {
background-color: #f8f9fa;
min-width: 500px;
padding: 20px;
}
QMessageBox QLabel {
color: #333333;
font-size: 14px;
padding: 10px;
margin: 10px;
}
QMessageBox QLabel:first-child {
font-weight: bold;
font-size: 16px;
color: #198754;
}
QPushButton {
background-color: #198754;
color: white;
border: none;
padding: 8px 25px;
border-radius: 4px;
font-size: 13px;
min-width: 100px;
margin: 10px;
}
QPushButton:hover {
background-color: #157347;
}
""")
msg.exec_()
# 清空激活码输入框 # 清空激活码输入框
self.activation_edit.clear() self.activation_edit.clear()
else: else:
QMessageBox.critical(self, "激活失败", message) msg = QMessageBox(self)
msg.setWindowTitle("激活失败")
# 激活后检查一次状态 msg.setText(message)
self.check_status() msg.setIcon(QMessageBox.Critical)
msg.setStyleSheet("""
except Exception as e: QMessageBox {
QMessageBox.critical(self, "错误", f"激活失败: {str(e)}") background-color: #f8f9fa;
# 出错后也检查状态 min-width: 450px;
self.check_status() padding: 20px;
}
QMessageBox QLabel {
color: #333333;
font-size: 14px;
padding: 10px;
margin: 10px;
}
QMessageBox QLabel:first-child {
font-weight: bold;
color: #dc3545;
}
QPushButton {
background-color: #dc3545;
color: white;
border: none;
padding: 8px 25px;
border-radius: 4px;
font-size: 13px;
min-width: 100px;
margin: 10px;
}
QPushButton:hover {
background-color: #bb2d3b;
}
""")
msg.exec_()
else:
QMessageBox.critical(self, "错误", f"激活失败: {data}")
# 激活后检查一次状态
self.check_status()
def update_status_display(self, status_info: dict): def update_status_display(self, status_info: dict):
"""更新状态显示""" """更新状态显示"""
# 打印API返回的原始数据 # 打印API返回的原始数据
@@ -190,51 +605,313 @@ class MainWindow(QMainWindow):
self.status_text.setPlainText("\n".join(status_lines)) self.status_text.setPlainText("\n".join(status_lines))
def check_status(self): def check_status(self):
"""检查会员状态""" """检查会员状态从API获取"""
try: try:
status = self.switcher.get_member_status() # 显示加载对话框
if status: self.show_loading_dialog("正在检查会员状态,请稍候...")
self.update_status_display(status)
return status.get('status') != 'inactive' # 创建工作线程
else: self.worker = ApiWorker(self.switcher.get_member_status)
# 更新为未激活状态 self.worker.finished.connect(self.on_status_check_complete)
inactive_status = { self.worker.start()
"hardware_id": self.switcher.hardware_id,
"expire_time": "",
"days_left": 0,
"total_days": 0,
"status": "inactive",
"activation_records": []
}
self.update_status_display(inactive_status)
return False
except Exception as e: except Exception as e:
self.hide_loading_dialog()
QMessageBox.critical(self, "错误", f"检查状态失败: {str(e)}") QMessageBox.critical(self, "错误", f"检查状态失败: {str(e)}")
self._activation_status = False
return False return False
def on_status_check_complete(self, result):
"""状态检查完成回调"""
success, data = result
self.hide_loading_dialog()
if success and data:
self.update_status_display(data)
# 更新缓存的激活状态
self._activation_status = data.get('status') == 'active'
# 设置状态更新定时器
if self._activation_status:
# 获取剩余时间(秒)
days_left = data.get('days_left', 0)
seconds_left = days_left * 24 * 60 * 60
# 创建定时器在到期前1分钟更新状态
if self._status_timer:
self._status_timer.stop()
self._status_timer = QTimer(self)
self._status_timer.setSingleShot(True)
self._status_timer.timeout.connect(self.check_status)
update_interval = min(seconds_left - 60, 24 * 60 * 60) # 最长1天更新一次
if update_interval > 0:
self._status_timer.start(update_interval * 1000) # 转换为毫秒
return self._activation_status
else:
# 更新为未激活状态
inactive_status = {
"hardware_id": self.switcher.hardware_id,
"expire_time": "",
"days_left": 0,
"total_days": 0,
"status": "inactive",
"activation_records": []
}
self.update_status_display(inactive_status)
self._activation_status = False
return False
def check_activation_status(self) -> bool:
"""检查是否已激活(使用缓存)
Returns:
bool: 是否已激活
"""
if self._activation_status is None:
# 首次检查从API获取
return self.check_status()
if not self._activation_status:
# 创建自定义消息框
msg = QDialog(self)
msg.setWindowTitle("会员未激活")
msg.setFixedWidth(400)
msg.setWindowFlags(msg.windowFlags() & ~Qt.WindowContextHelpButtonHint)
# 创建布局
layout = QVBoxLayout()
# 添加图标和文本
icon_label = QLabel()
icon_label.setPixmap(self.style().standardIcon(QStyle.SP_MessageBoxWarning).pixmap(32, 32))
icon_label.setAlignment(Qt.AlignCenter)
layout.addWidget(icon_label)
text_label = QLabel("您还未激活会员或会员已过期")
text_label.setAlignment(Qt.AlignCenter)
text_label.setStyleSheet("font-size: 14px; font-weight: bold; color: #333333; padding: 10px;")
layout.addWidget(text_label)
# 添加购买信息
info_text = "获取会员激活码,请通过以下方式:\n\n" \
"• 官方自助网站cursor.nosqli.com\n" \
"• 微信客服behikcigar\n" \
"• 闲鱼店铺xxx\n\n" \
"————————————————————\n" \
"诚招代理商,欢迎加盟合作!"
info_label = QLabel(info_text)
info_label.setAlignment(Qt.AlignLeft)
info_label.setStyleSheet("""
QLabel {
color: #333333;
font-size: 14px;
padding: 15px;
background-color: #f8f9fa;
border-radius: 4px;
border: 1px solid #dee2e6;
margin: 10px;
}
""")
layout.addWidget(info_label)
# 添加复制按钮区域
btn_layout = QHBoxLayout()
# 复制网站按钮
copy_web_btn = QPushButton("复制网站")
copy_web_btn.clicked.connect(lambda: self.copy_and_show_tip(msg, "cursor.nosqli.com", "网站地址已复制到剪贴板"))
copy_web_btn.setStyleSheet("""
QPushButton {
background-color: #0d6efd;
color: white;
border: none;
padding: 8px 15px;
border-radius: 4px;
font-size: 13px;
}
QPushButton:hover {
background-color: #0b5ed7;
}
""")
btn_layout.addWidget(copy_web_btn)
# 复制微信按钮
copy_wx_btn = QPushButton("复制微信")
copy_wx_btn.clicked.connect(lambda: self.copy_and_show_tip(msg, "behikcigar", "微信号已复制到剪贴板"))
copy_wx_btn.setStyleSheet("""
QPushButton {
background-color: #198754;
color: white;
border: none;
padding: 8px 15px;
border-radius: 4px;
font-size: 13px;
}
QPushButton:hover {
background-color: #157347;
}
""")
btn_layout.addWidget(copy_wx_btn)
# 确定按钮
ok_btn = QPushButton("确定")
ok_btn.clicked.connect(msg.accept)
ok_btn.setStyleSheet("""
QPushButton {
background-color: #0d6efd;
color: white;
border: none;
padding: 8px 25px;
border-radius: 4px;
font-size: 13px;
min-width: 100px;
}
QPushButton:hover {
background-color: #0b5ed7;
}
""")
btn_layout.addWidget(ok_btn)
layout.addLayout(btn_layout)
msg.setLayout(layout)
msg.exec_()
return self._activation_status
def refresh_cursor_auth(self): def refresh_cursor_auth(self):
"""刷新Cursor授权""" """刷新Cursor授权"""
if not self.check_activation_status():
return
try: try:
success, message = self.switcher.refresh_cursor_auth() # 显示加载对话框
if success: self.show_loading_dialog("正在刷新授权,请稍候...")
QMessageBox.information(self, "成功", message)
else: # 创建工作线程
QMessageBox.critical(self, "失败", message) self.worker = ApiWorker(self.switcher.refresh_cursor_auth)
self.worker.finished.connect(self.on_refresh_auth_complete)
self.worker.start()
except Exception as e: except Exception as e:
QMessageBox.critical(self, "错误", f"刷新授权失败: {str(e)}") self.hide_loading_dialog()
self.show_custom_error("刷新授权失败", str(e))
def on_refresh_auth_complete(self, result):
"""刷新授权完成回调"""
success, data = result
self.hide_loading_dialog()
if isinstance(data, tuple):
success, message = data
if success:
self.show_custom_message("成功", "刷新授权成功", message, QStyle.SP_DialogApplyButton, "#198754")
else:
self.show_custom_error("刷新授权失败", message)
else:
self.show_custom_error("刷新授权失败", str(data))
def disable_cursor_update(self): def disable_cursor_update(self):
"""禁用Cursor更新""" """禁用Cursor更新"""
if not self.check_activation_status():
return
try: try:
success, message = self.switcher.disable_cursor_update() success, message = self.switcher.disable_cursor_update()
if success: if success:
QMessageBox.information(self, "成功", message) self.show_custom_message("成功", "禁用更新成功", message, QStyle.SP_DialogApplyButton, "#198754")
else: else:
QMessageBox.critical(self, "失败", message) self.show_custom_error("禁用更新失败", message)
except Exception as e: except Exception as e:
QMessageBox.critical(self, "错误", f"禁用更新失败: {str(e)}") self.show_custom_error("禁用更新失败", str(e))
def dummy_function(self): def dummy_function(self):
"""占位函数""" """突破版本限制"""
QMessageBox.information(self, "提示", "此功能暂未实现") if not self.check_activation_status():
return
self.show_custom_message(
"提示",
"功能未实现",
"此功能暂未实现,请等待后续更新。",
QStyle.SP_MessageBoxInformation,
"#0d6efd"
)
def show_custom_message(self, title, header, message, icon_type, color):
"""显示自定义消息框"""
msg = QDialog(self)
msg.setWindowTitle(title)
msg.setFixedWidth(400)
msg.setWindowFlags(msg.windowFlags() & ~Qt.WindowContextHelpButtonHint)
layout = QVBoxLayout()
# 添加图标
icon_label = QLabel()
icon_label.setPixmap(self.style().standardIcon(icon_type).pixmap(32, 32))
icon_label.setAlignment(Qt.AlignCenter)
layout.addWidget(icon_label)
# 添加标题
text_label = QLabel(header)
text_label.setAlignment(Qt.AlignCenter)
text_label.setStyleSheet(f"""
font-size: 14px;
font-weight: bold;
color: {color};
padding: 10px;
""")
layout.addWidget(text_label)
# 添加详细信息
info_label = QLabel(message)
info_label.setAlignment(Qt.AlignLeft)
info_label.setWordWrap(True)
info_label.setStyleSheet("""
QLabel {
color: #333333;
font-size: 14px;
padding: 15px;
background-color: #f8f9fa;
border-radius: 4px;
border: 1px solid #dee2e6;
margin: 10px;
}
""")
layout.addWidget(info_label)
# 确定按钮
btn_layout = QHBoxLayout()
ok_btn = QPushButton("确定")
ok_btn.clicked.connect(msg.accept)
ok_btn.setStyleSheet(f"""
QPushButton {{
background-color: {color};
color: white;
border: none;
padding: 8px 25px;
border-radius: 4px;
font-size: 13px;
min-width: 100px;
}}
QPushButton:hover {{
background-color: {color.replace('fd', 'd7') if 'fd' in color else color.replace('54', '47')};
}}
""")
btn_layout.addWidget(ok_btn)
layout.addLayout(btn_layout)
msg.setLayout(layout)
msg.exec_()
def show_custom_error(self, header, message):
"""显示自定义错误消息框"""
self.show_custom_message(
"错误",
header,
message,
QStyle.SP_MessageBoxCritical,
"#dc3545"
)

BIN
icon/logo1.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
icon/logo2.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
icon/logo3.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

29
main.py
View File

@@ -6,7 +6,9 @@ import atexit
import shutil import shutil
import tempfile import tempfile
from pathlib import Path from pathlib import Path
from PyQt5.QtWidgets import QApplication, QMessageBox from PyQt5.QtWidgets import QApplication, QMessageBox, QSystemTrayIcon, QMenu
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt
from gui.main_window import MainWindow from gui.main_window import MainWindow
def cleanup_temp(): def cleanup_temp():
@@ -65,7 +67,32 @@ def main():
logging.info("正在初始化主窗口...") logging.info("正在初始化主窗口...")
app = QApplication(sys.argv) app = QApplication(sys.argv)
# 设置应用程序ID (在设置图标之前)
if sys.platform == "win32":
import ctypes
myappid = u'nezha.cursor.helper.v3'
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
logging.info(f"设置应用程序ID: {myappid}")
# 设置应用程序图标
try:
icon_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "icon", "two.ico")
if os.path.exists(icon_path):
app_icon = QIcon(icon_path)
if not app_icon.isNull():
app.setWindowIcon(app_icon)
logging.info(f"成功设置应用程序图标: {icon_path}")
else:
logging.error("图标文件加载失败")
else:
logging.error(f"图标文件不存在: {icon_path}")
except Exception as e:
logging.error(f"设置应用程序图标失败: {str(e)}")
window = MainWindow() window = MainWindow()
window.setWindowIcon(app.windowIcon()) # 确保窗口使用相同的图标
logging.info("正在启动主窗口...") logging.info("正在启动主窗口...")
window.show() window.show()

View File

@@ -1,4 +1,9 @@
# Use Tsinghua mirror for faster download in China:
# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
requests==2.31.0 requests==2.31.0
pyinstaller==6.3.0 pyinstaller==6.3.0
pillow==10.2.0 # 用于处理图标 pillow==10.2.0 # For icon processing
setuptools==65.5.1 # 解决pkg_resources.extern问题 setuptools==65.5.1 # Fix pkg_resources.extern issue
PyQt5==5.15.10 # GUI framework
pywin32==306 # Windows API support

View File

@@ -1,106 +0,0 @@
{
"github_changes": {
"package_json_changes": {},
"registry_changes": {
"HKLM_MachineGuid": {
"before": {
"exists": true,
"value": "d890ab3d-43cd-40c8-a9ef-f5683b5a64e3"
},
"after": {
"exists": true,
"value": "776c6b6c-195f-42dc-94d6-72b70c3aca74"
}
}
},
"file_changes": {
"storage": {
"before": {
"exists": true,
"is_dir": false,
"size": 3427,
"modified_time": "2025-02-12T11:40:57.046415"
},
"after": {
"exists": true,
"is_dir": false,
"size": 1891,
"modified_time": "2025-02-12T11:48:42.627574"
}
},
"storage_backup": {
"before": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:00:01.555876"
},
"after": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:48:26.403770"
}
},
"global_storage": {
"before": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:47:27.627883"
},
"after": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:48:47.490659"
}
}
}
},
"our_changes": {
"package_json_changes": {},
"registry_changes": {
"HKLM_MachineGuid": {
"before": {
"exists": true,
"value": "948b93c1-ee34-4a48-95d0-a2fce9af92b1"
},
"after": {
"exists": true,
"value": "1deb25e7-cdd4-4367-a347-fba8b33b9b03"
}
}
},
"file_changes": {
"storage_backup": {
"before": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T12:33:10.408749"
},
"after": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T12:37:17.371311"
}
},
"storage": {
"before": {
"exists": true,
"is_dir": false,
"size": 2214,
"modified_time": "2025-02-12T12:36:27.187387"
},
"after": {
"exists": true,
"is_dir": false,
"size": 1980,
"modified_time": "2025-02-12T12:37:17.428609"
}
}
}
}
}

View File

@@ -1 +1 @@
3.2.8 3.3.4