From 5b0ca2fb1065cb1c2c82510ba94b55b6bc376a96 Mon Sep 17 00:00:00 2001 From: duanfuxiang Date: Sun, 24 Aug 2025 18:55:14 +0800 Subject: [PATCH] fix pro bug --- CHANGELOG.yaml | 3 + manifest.json | 2 +- package.json | 3 +- pnpm-lock.yaml | 8 + src/hooks/use-infio.ts | 149 ++++++++++++++---- .../components/PluginInfoSettings.tsx | 25 ++- 6 files changed, 148 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.yaml b/CHANGELOG.yaml index 35d1b87..3ee226a 100644 --- a/CHANGELOG.yaml +++ b/CHANGELOG.yaml @@ -1,4 +1,7 @@ releases: + - version: "0.8.3" + features: + - "fix this update pro version error" - version: "0.8.1" fixes: - "fix infio provider api key error" diff --git a/manifest.json b/manifest.json index 6eac4ca..6f0b650 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "infio-copilot", "name": "Infio Copilot", - "version": "0.8.1", + "version": "0.8.0", "minAppVersion": "0.15.0", "description": "A Cursor-inspired AI assistant for notes that offers smart autocomplete and interactive chat with your selected notes", "author": "Felix.D", diff --git a/package.json b/package.json index 18ccdf6..f77ebd7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsidian-infio-copilot", - "version": "0.8.1", + "version": "0.8.3", "description": "A Cursor-inspired AI assistant that offers smart autocomplete and interactive chat with your selected notes", "main": "main.js", "scripts": { @@ -113,6 +113,7 @@ "micromatch": "^4.0.5", "minimatch": "^10.0.1", "neverthrow": "^6.1.0", + "node-machine-id": "^1.1.12", "openai": "^4.73.0", "p-limit": "^6.1.0", "parse5": "^7.1.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8ab4523..138c996 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -189,6 +189,9 @@ importers: neverthrow: specifier: ^6.1.0 version: 6.2.2 + node-machine-id: + specifier: ^1.1.12 + version: 1.1.12 openai: specifier: ^4.73.0 version: 4.104.0(ws@8.18.3)(zod@3.24.2) @@ -5374,6 +5377,9 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + node-machine-id@1.1.12: + resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} + node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} @@ -12668,6 +12674,8 @@ snapshots: node-int64@0.4.0: {} + node-machine-id@1.1.12: {} + node-releases@2.0.19: {} normalize-path@3.0.0: {} diff --git a/src/hooks/use-infio.ts b/src/hooks/use-infio.ts index 796f7ed..2102bc1 100644 --- a/src/hooks/use-infio.ts +++ b/src/hooks/use-infio.ts @@ -1,23 +1,28 @@ /* eslint-disable no-console, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */ import JSZip from "jszip"; -import { App, Notice, Plugin, requestUrl } from "obsidian"; +import { machineId } from 'node-machine-id'; +import { Notice, Platform, Plugin, requestUrl } from "obsidian"; import { INFIO_BASE_URL } from "../constants"; -// 扩展App类型以包含plugins属性 -type AppWithPlugins = App & { - plugins: { - reloadPlugin: (id: string) => void; - }; -}; - -// 类型保护函数 -function hasPluginsProperty(app: App): app is AppWithPlugins { - return 'plugins' in app && - app.plugins !== undefined && - typeof app.plugins === 'object' && - 'reloadPlugin' in app.plugins && - typeof app.plugins.reloadPlugin === 'function'; +function getOperatingSystem(): string { + if (Platform.isWin) { + return 'windows'; + } + if (Platform.isMacOS) { + return 'macos'; + } + if (Platform.isLinux) { + return 'linux'; + } + if (Platform.isAndroidApp) { + return 'android'; + } + if (Platform.isIosApp) { + return 'ios'; + } + // 如果所有已知的平台都不是,则返回未知 + return 'unknown'; } // API响应类型定义 @@ -45,23 +50,89 @@ export const fetchUserPlan = async (apiKey: string): Promise = return response.json; } +// API响应类型定义 +export type CheckGeneralResponse = { + success: boolean; + message: string; + dl_zip?: string; +}; + +export type CheckGeneralParams = { + device_id: string; + device_name: string; +}; + +/** + * 检查设备一般状态 + * @param apiKey API密钥 + * @param deviceId 设备ID + * @param deviceName 设备名称 + * @returns Promise + */ +export const checkGeneral = async ( + apiKey: string +): Promise => { + try { + if (!apiKey) { + throw new Error('API密钥不能为空'); + } + const deviceId = await machineId(); + const deviceName = getOperatingSystem(); + if (!deviceId || !deviceName) { + throw new Error('设备ID和设备名称不能为空'); + } + + const response = await requestUrl({ + url: `${INFIO_BASE_URL}/subscription/check_general`, + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${apiKey}`, + }, + body: JSON.stringify({ + device_id: deviceId, + device_name: deviceName, + }), + }); + + if (response.json.success) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return response.json; + } else { + console.error('检查 gerenal 会员失败:', response.json.message); + return { + success: false, + message: response.json.message || '检查设备一般状态失败', + }; + } + } catch (error) { + console.error('检查 gerenal 会员失败:', error); + + // 返回错误响应格式 + return { + success: false, + message: error instanceof Error ? error.message : '检查设备状态时出现未知错误' + }; + } +}; + /** * 检查用户是否为Pro用户 */ -export const checkIsProUser = async (apiKey: string): Promise => { - try { - if (!apiKey) { - return false; - } +// export const checkIsProUser = async (apiKey: string): Promise => { +// try { +// if (!apiKey) { +// return false; +// } - const userPlan = await fetchUserPlan(apiKey); - return userPlan.plan?.toLowerCase().startsWith('pro') || false; - } catch (error) { - // eslint-disable-next-line no-console - console.error('检查Pro用户状态失败:', error); - return false; - } -} +// const userPlan = await fetchUserPlan(apiKey); +// return userPlan.plan?.toLowerCase().startsWith('pro') || false; +// } catch (error) { +// // eslint-disable-next-line no-console +// console.error('检查Pro用户状态失败:', error); +// return false; +// } +// } /** * 清理临时目录 @@ -82,7 +153,6 @@ const cleanupTempDirectory = async (adapter: Plugin['app']['vault']['adapter'], }; - /** * 下载并解压ZIP文件到临时目录 */ @@ -111,8 +181,6 @@ const downloadAndExtractToTemp = async ( throw new Error("下载的文件格式无效"); } - - console.log("正在解压文件到临时目录..."); console.log(`开始解压文件到临时目录: ${tempDir}`); @@ -264,16 +332,27 @@ export const upgradeToProVersion = async ( await cleanupTempDirectory(adapter, tempDir); - setTimeout(() => { + setTimeout(async () => { console.log(`重载插件: ${plugin.manifest.id}`); - if (hasPluginsProperty(plugin.app)) { - plugin.app.plugins.reloadPlugin(plugin.manifest.id); + try { + // 禁用插件 + await plugin.app.plugins.disablePlugin(plugin.manifest.id); + console.log(`插件已禁用: ${plugin.manifest.id}`); + + // 启用插件 + await plugin.app.plugins.enablePlugin(plugin.manifest.id); + console.log(`插件已重新启用: ${plugin.manifest.id}`); + + new Notice("插件重载完成"); + } catch (error) { + console.error("插件重载失败:", error); + new Notice("插件重载失败,请手动重启插件"); } }, 1000); return { success: true, - message: "加载完成,成功升级为Pro" + message: "加载完成" }; } catch (error) { diff --git a/src/settings/components/PluginInfoSettings.tsx b/src/settings/components/PluginInfoSettings.tsx index 0a95e81..adf5f24 100644 --- a/src/settings/components/PluginInfoSettings.tsx +++ b/src/settings/components/PluginInfoSettings.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import { ApiKeyModal } from '../../components/modals/ApiKeyModal'; import { ProUpgradeModal } from '../../components/modals/ProUpgradeModal'; -import { fetchUserPlan, upgradeToProVersion } from '../../hooks/use-infio'; +import { checkGeneral, fetchUserPlan, upgradeToProVersion } from '../../hooks/use-infio'; import type { InfioSettings } from '../../types/settings'; import { getInfioLogoSvg } from '../../utils/icon'; @@ -46,21 +46,36 @@ export default function PluginInfoSettings({ setIsUpgrading(true); try { - // 检查是否为Pro用户 + // 检查是否为会员(Pro|General) const userPlan = await fetchUserPlan(settings.infioProvider.apiKey); console.log('userPlan', userPlan); const isProUser = userPlan.plan?.toLowerCase().startsWith('pro') || false; - if (!isProUser) { + const isGeneralUser = userPlan.plan?.toLowerCase().startsWith('general') || false; + let dl_zip = userPlan.dl_zip || ''; + if (!isProUser && !isGeneralUser) { if (plugin?.app) { new ProUpgradeModal(plugin.app).open(); } else { - new Notice('您的账户不是Pro用户,无法升级到Pro版本, 请先升级到Pro'); + new Notice('您的账户不是会员用户, 请先购买会员'); } return; } + if (isGeneralUser) { + const result = await checkGeneral(settings.infioProvider.apiKey); + if (!result.success) { + if (plugin?.app) { + new ProUpgradeModal(plugin.app).open(); + } else { + new Notice('您的账户不是会员用户, 请先购买会员'); + } + return; + } + console.log('result', result); + dl_zip = result.dl_zip; + } // 执行升级 - const result = await upgradeToProVersion(plugin, userPlan.dl_zip || ''); + const result = await upgradeToProVersion(plugin, dl_zip); if (result.success) { // 升级成功的提示已经在upgradeToProVersion中处理了