fix pro bug

This commit is contained in:
duanfuxiang 2025-08-24 18:55:14 +08:00
parent cfa856fea8
commit 5b0ca2fb10
6 changed files with 148 additions and 42 deletions

View File

@ -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"

View File

@ -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",

View File

@ -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",

8
pnpm-lock.yaml generated
View File

@ -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: {}

View File

@ -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<UserPlanResponse> =
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<CheckGeneralResponse>
*/
export const checkGeneral = async (
apiKey: string
): Promise<CheckGeneralResponse> => {
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<boolean> => {
try {
if (!apiKey) {
return false;
}
// export const checkIsProUser = async (apiKey: string): Promise<boolean> => {
// 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) {

View File

@ -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中处理了