feat: 移除用户信息、余额检查和登录过期提示

- 隐藏用户信息显示和退出登录按钮
   - 删除发送消息前的余额检查逻辑
   - 删除对话完成后的余额更新逻辑
   - 注释掉所有登录过期弹窗提示
   - 移除用户服务和余额服务的初始化调用
This commit is contained in:
Roe-xin
2026-03-09 14:28:41 +08:00
parent 7cde4fa138
commit ad0f0336d5
9 changed files with 118 additions and 516 deletions

View File

@ -5,8 +5,6 @@ import { VCDViewerPanel, VCDViewerEditorProvider } from "./panels/VCDViewerPanel
import { ChatHistoryManager } from "./utils/chatHistoryManager"; import { ChatHistoryManager } from "./utils/chatHistoryManager";
import { ICCoderAuthenticationProvider } from "./services/icCoderAuthProvider"; import { ICCoderAuthenticationProvider } from "./services/icCoderAuthProvider";
import { VCDFileServer } from "./services/vcdFileServer"; import { VCDFileServer } from "./services/vcdFileServer";
import { initUserService } from "./services/userService";
import { initCreditsService } from "./services/creditsService";
import { isTokenExpired } from "./utils/jwtUtils"; import { isTokenExpired } from "./utils/jwtUtils";
import { NotificationService } from "./services/notificationService"; import { NotificationService } from "./services/notificationService";
import { InvitationService } from "./services/invitationService"; import { InvitationService } from "./services/invitationService";
@ -50,33 +48,26 @@ export async function activate(context: vscode.ExtensionContext) {
const notificationService = NotificationService.getInstance(context); const notificationService = NotificationService.getInstance(context);
console.log('[Extension] 通知服务已初始化'); console.log('[Extension] 通知服务已初始化');
// 【关键】在创建 AuthProvider 之前,先检查并清除过期的 session // 【已禁用】登录和 token 验证 - 无需登录即可使用
const storedSessions = context.globalState.get<any[]>('icCoderSessions', []); // const storedSessions = context.globalState.get<any[]>('icCoderSessions', []);
console.log('[Extension] 检查 sessions 数量:', storedSessions.length); // console.log('[Extension] 检查 sessions 数量:', storedSessions.length);
//
if (storedSessions.length > 0) { // if (storedSessions.length > 0) {
const session = storedSessions[0]; // const session = storedSessions[0];
const token = session.accessToken; // const token = session.accessToken;
console.log('[Extension] 检查 token 是否过期...'); // console.log('[Extension] 检查 token 是否过期...');
//
if (token) { // if (token) {
const expired = isTokenExpired(token); // const expired = isTokenExpired(token);
console.log('[Extension] token 过期检查结果:', expired); // console.log('[Extension] token 过期检查结果:', expired);
//
if (expired) { // if (expired) {
// 必须等待清除完成后再创建 AuthProvider // await context.globalState.update('icCoderSessions', []);
await context.globalState.update('icCoderSessions', []); // await context.globalState.update('icCoderUserInfo', undefined);
await context.globalState.update('icCoderUserInfo', undefined); // console.log('[Extension] Token 已过期,已清除所有登录状态');
console.log('[Extension] Token 已过期,已清除所有登录状态'); // }
} // }
} // }
}
// 初始化用户服务
initUserService(context);
// 初始化 Credits 服务
initCreditsService(context);
// 初始化 VCD 文件服务器 // 初始化 VCD 文件服务器
const vcdFileServer = new VCDFileServer(context.extensionUri); const vcdFileServer = new VCDFileServer(context.extensionUri);
@ -91,25 +82,18 @@ export async function activate(context: vscode.ExtensionContext) {
dispose: () => vcdFileServer.stop() dispose: () => vcdFileServer.stop()
}); });
// 注册 Authentication Provider(此时 icCoderSessions 已经被清除) // 【已禁用】Authentication Provider 注册 - 无需登录
const authProvider = new ICCoderAuthenticationProvider(context); // const authProvider = new ICCoderAuthenticationProvider(context);
context.subscriptions.push( // context.subscriptions.push(
vscode.authentication.registerAuthenticationProvider( // vscode.authentication.registerAuthenticationProvider(
"iccoder", // "iccoder",
"IC Coder", // "IC Coder",
authProvider // authProvider
) // )
); // );
// 检查登录状态,如果已登录则自动打开聊天面板 // 【已禁用】登录状态检查 - 直接打开聊天面板
vscode.authentication.getSession("iccoder", [], { createIfNone: false })
.then((session) => {
if (session) {
vscode.commands.executeCommand("ic-coder.openChat"); vscode.commands.executeCommand("ic-coder.openChat");
}
}, () => {
// 未登录,不做任何操作
});
// 注册命令:打开助手面板 // 注册命令:打开助手面板
const openPanelCommand = vscode.commands.registerCommand( const openPanelCommand = vscode.commands.registerCommand(

View File

@ -22,46 +22,7 @@ import { compactDialog } from "../services/apiClient";
import { VCDViewerPanel } from "./VCDViewerPanel"; import { VCDViewerPanel } from "./VCDViewerPanel";
import { ChatHistoryManager } from "../utils/chatHistoryManager"; import { ChatHistoryManager } from "../utils/chatHistoryManager";
import { MessageType } from "../types/chatHistory"; import { MessageType } from "../types/chatHistory";
import { getCachedUserInfo } from "../services/userService";
import { isTokenExpired } from "../utils/jwtUtils"; import { isTokenExpired } from "../utils/jwtUtils";
import { setBalanceUpdateCallback } from "../services/creditsService";
/**
* 获取会员等级图标 URI
*/
function getTierIconUri(
webview: vscode.Webview,
context: vscode.ExtensionContext,
tierCode?: string,
): string | undefined {
if (!tierCode) {
return undefined;
}
const tierIconMap: Record<string, string> = {
BASIC: "free.png",
TRIAL: "PRO-Try.png",
ADVANCED: "PRO.png",
PROFESSIONAL: "PRO+.png",
};
const iconFile = tierIconMap[tierCode];
if (!iconFile) {
return undefined;
}
const iconUri = webview.asWebviewUri(
vscode.Uri.joinPath(
context.extensionUri,
"dist",
"assets",
"titleIcon",
iconFile,
),
);
return iconUri.toString();
}
/** /**
* 创建并显示 IC 助手面板 * 创建并显示 IC 助手面板
@ -70,63 +31,35 @@ export async function showICHelperPanel(
context: vscode.ExtensionContext, context: vscode.ExtensionContext,
viewColumn?: vscode.ViewColumn, viewColumn?: vscode.ViewColumn,
) { ) {
// 检查 token 是否过期 // 创建WebView面板
let token: string | undefined; // try {
try { // const session = await vscode.authentication.getSession("iccoder", [], {
const session = await vscode.authentication.getSession("iccoder", [], { // createIfNone: false,
createIfNone: false, // });
}); // if (!session) {
token = session?.accessToken; // vscode.window
} catch (error) { // .showWarningMessage("请先登录后再使用 IC Coder", "立即登录")
console.warn("[ICHelperPanel] 获取 session 失败:", error); // .then((selection) => {
} // if (selection === "立即登录") {
// vscode.commands.executeCommand("ic-coder.login", {
if (token && isTokenExpired(token)) { // forceReauth: true,
// 清除过期的 session // });
await context.globalState.update("icCoderSessions", []); // }
await context.globalState.update("icCoderUserInfo", undefined); // });
// return;
const action = await vscode.window.showWarningMessage( // }
"登录已过期,请重新登录", // } catch (error) {
"立即登录", // vscode.window
); // .showWarningMessage("请先登录后再使用 IC Coder", "立即登录")
if (action === "立即登录") { // .then((selection) => {
vscode.commands.executeCommand("ic-coder.login", { // if (selection === "立即登录") {
forceReauth: true, // vscode.commands.executeCommand("ic-coder.login", {
}); // forceReauth: true,
} // });
return; // }
} // });
// return;
// 检查用户是否已登录 // }
try {
const session = await vscode.authentication.getSession("iccoder", [], {
createIfNone: false,
});
if (!session) {
vscode.window
.showWarningMessage("请先登录后再使用 IC Coder", "立即登录")
.then((selection) => {
if (selection === "立即登录") {
vscode.commands.executeCommand("ic-coder.login", {
forceReauth: true,
});
}
});
return;
}
} catch (error) {
vscode.window
.showWarningMessage("请先登录后再使用 IC Coder", "立即登录")
.then((selection) => {
if (selection === "立即登录") {
vscode.commands.executeCommand("ic-coder.login", {
forceReauth: true,
});
}
});
return;
}
// 创建WebView面板 // 创建WebView面板
const panel = vscode.window.createWebviewPanel( const panel = vscode.window.createWebviewPanel(
@ -230,81 +163,6 @@ export async function showICHelperPanel(
logoUri.toString(), logoUri.toString(),
); );
// 获取并发送用户信息到 webview
try {
// 优先使用缓存的用户信息
let userInfo = getCachedUserInfo();
if (userInfo) {
// 使用缓存的用户信息
console.log("[ICHelperPanel] 使用缓存的用户信息:", userInfo);
console.log("[ICHelperPanel] Credits 余额:", userInfo.credits);
const tierIconUrl = getTierIconUri(
panel.webview,
context,
userInfo.membership?.tierCode,
);
const messageData = {
command: "updateUserInfo",
userInfo: {
userId: userInfo.userId,
nickname: userInfo.nickname,
username: userInfo.username,
credits: userInfo.credits,
membership: userInfo.membership,
},
tierIconUrl: tierIconUrl,
};
console.log("[ICHelperPanel] 发送用户信息到前端:", messageData);
panel.webview.postMessage(messageData);
} else {
// 如果没有缓存,从 session 中获取
const session = await vscode.authentication.getSession("iccoder", [], {
createIfNone: false,
});
if (session) {
console.log(
"[ICHelperPanel] 从 session 获取用户信息, account:",
session.account,
);
panel.webview.postMessage({
command: "updateUserInfo",
userInfo: {
userId: session.account.id,
nickname: session.account.label,
username: session.account.label,
},
});
}
}
} catch (error) {
console.error("[ICHelperPanel] 获取用户信息失败:", error);
}
// 设置余额更新回调
setBalanceUpdateCallback((balance: number) => {
const userInfo = getCachedUserInfo();
if (userInfo) {
userInfo.credits = balance;
const tierIconUrl = getTierIconUri(
panel.webview,
context,
userInfo.membership?.tierCode,
);
panel.webview.postMessage({
command: "updateUserInfo",
userInfo: {
userId: userInfo.userId,
nickname: userInfo.nickname,
username: userInfo.username,
credits: balance,
membership: userInfo.membership,
},
tierIconUrl: tierIconUrl,
});
}
});
// 检查是否有待发送的消息 // 检查是否有待发送的消息
const pendingMessage = context.globalState.get("pendingMessage") as any; const pendingMessage = context.globalState.get("pendingMessage") as any;
if (pendingMessage) { if (pendingMessage) {
@ -585,71 +443,17 @@ export async function showICHelperPanel(
} }
break; break;
case "checkInvitationCode": case "checkInvitationCode":
// 检查邀请码验证状态 // 【已禁用】检查邀请码验证状态 - 现在所有用户都可以直接使用
{ {
// 先检查是否是试用用户 // 直接返回已验证,无需登录和邀请码
const { getCachedUserInfo } = require("../services/userService");
const userInfo = getCachedUserInfo();
if (userInfo?.isPluginTrial === true) {
// 试用用户,跳过邀请码验证,直接返回已验证
console.log("[ICHelperPanel] 试用用户,跳过邀请码验证");
panel.webview.postMessage({ panel.webview.postMessage({
command: "invitationCodeStatus", command: "invitationCodeStatus",
verified: true, verified: true,
}); });
} else {
// 正式用户,检查邀请码
const {
InvitationService,
} = require("../services/invitationService");
const isVerified = await InvitationService.isVerified(context);
panel.webview.postMessage({
command: "invitationCodeStatus",
verified: isVerified,
});
}
} }
break; break;
case "checkWelcomeModal": case "checkWelcomeModal":
// 检查是否需要显示欢迎弹窗 // 【已禁用】检查是否需要显示欢迎弹窗 - 无需登录,不显示欢迎弹窗
{
console.log("[ICHelperPanel] 收到 checkWelcomeModal 消息");
const userInfo = getCachedUserInfo();
console.log("[ICHelperPanel] 用户信息:", userInfo);
console.log("[ICHelperPanel] isPluginTrial:", userInfo?.isPluginTrial);
console.log("[ICHelperPanel] pluginTrialExpiresAt:", userInfo?.pluginTrialExpiresAt);
if (userInfo?.isPluginTrial === true) {
// undefined 表示无效,不显示
if (userInfo.pluginTrialExpiresAt === undefined) {
console.log("[ICHelperPanel] pluginTrialExpiresAt 未设置,不显示欢迎弹窗");
break;
}
// null 表示长期有效,显示弹窗
// 有值则检查是否过期
if (userInfo.pluginTrialExpiresAt !== null) {
const now = Date.now();
const isExpired = now >= userInfo.pluginTrialExpiresAt;
console.log("[ICHelperPanel] 是否过期:", isExpired);
if (isExpired) {
console.log("[ICHelperPanel] 试用已过期,不显示欢迎弹窗");
break;
}
}
// 未过期或长期有效(null),显示欢迎弹窗
console.log("[ICHelperPanel] ✅ 发送 showWelcomeModal 命令到前端");
panel.webview.postMessage({
command: "showWelcomeModal",
});
} else {
console.log("[ICHelperPanel] 非试用用户");
}
}
break; break;
case "checkTrialExpiration": case "checkTrialExpiration":
// 检查试用期是否过期 // 检查试用期是否过期
@ -664,37 +468,13 @@ export async function showICHelperPanel(
} }
break; break;
case "verifyInvitationCode": case "verifyInvitationCode":
// 验证邀请码 // 【已禁用】验证邀请码 - 无需邀请码验证
{ {
const { // 直接返回验证成功
InvitationService,
} = require("../services/invitationService");
const result = await InvitationService.verifyCode(message.code);
if (result.success) {
// 验证成功,保存状态
await InvitationService.saveVerificationStatus(
context,
message.code,
);
panel.webview.postMessage({ panel.webview.postMessage({
command: "invitationCodeVerified", command: "invitationCodeVerified",
success: true, success: true,
}); });
// 延迟显示欢迎弹窗,确保邀请码弹窗已关闭
setTimeout(() => {
panel.webview.postMessage({
command: "showNdtWelcomeModal",
});
}, 300);
} else {
// 验证失败,返回错误信息
panel.webview.postMessage({
command: "invitationCodeVerified",
success: false,
message: result.message,
});
}
} }
break; break;
case "openICCoder": case "openICCoder":

View File

@ -30,7 +30,6 @@ import type {
import { submitToolConfirm, submitAnswer, stopDialog } from "./apiClient"; import { submitToolConfirm, submitAnswer, stopDialog } from "./apiClient";
import { ChatHistoryManager } from "../utils/chatHistoryManager"; import { ChatHistoryManager } from "../utils/chatHistoryManager";
import { getUserIdFromToken, isTokenExpired } from "../utils/jwtUtils"; import { getUserIdFromToken, isTokenExpired } from "../utils/jwtUtils";
import { updateCachedBalance } from "./creditsService";
/** /**
* 消息段落类型 * 消息段落类型
@ -444,6 +443,7 @@ export class DialogSession {
const expired = isTokenExpired(session.accessToken); const expired = isTokenExpired(session.accessToken);
if (expired === true) { if (expired === true) {
console.error("[DialogSession] token 已过期,需要重新登录"); console.error("[DialogSession] token 已过期,需要重新登录");
/*
vscode.window vscode.window
.showErrorMessage("登录已过期,请重新登录", "重新登录") .showErrorMessage("登录已过期,请重新登录", "重新登录")
.then((selection) => { .then((selection) => {
@ -453,6 +453,7 @@ export class DialogSession {
}); });
} }
}); });
*/
throw new Error("登录已过期,请重新登录"); throw new Error("登录已过期,请重新登录");
} }
@ -899,6 +900,7 @@ export class DialogSession {
data.message.includes("LOGIN_EXPIRED") || data.message.includes("LOGIN_EXPIRED") ||
data.message.includes("登录状态已过期") data.message.includes("登录状态已过期")
) { ) {
/*
vscode.window vscode.window
.showErrorMessage("登录状态已过期,请重新登录", "重新登录") .showErrorMessage("登录状态已过期,请重新登录", "重新登录")
.then((selection) => { .then((selection) => {
@ -908,6 +910,7 @@ export class DialogSession {
}); });
} }
}); });
*/
// 登录过期错误已处理,不再传递给外部 // 登录过期错误已处理,不再传递给外部
return; return;
} }
@ -1017,8 +1020,9 @@ export class DialogSession {
data.remainingCredits data.remainingCredits
); );
// 更新余额缓存 // 更新余额缓存
updateCachedBalance(data.remainingCredits); // updateCachedBalance(data.remainingCredits);
// 资源点余额低于阈值时弹窗提醒 // 资源点余额低于阈值时弹窗提醒
/*
const LOW_CREDIT_THRESHOLD = 5; const LOW_CREDIT_THRESHOLD = 5;
if (data.remainingCredits < LOW_CREDIT_THRESHOLD) { if (data.remainingCredits < LOW_CREDIT_THRESHOLD) {
vscode.window vscode.window
@ -1030,13 +1034,13 @@ export class DialogSession {
) )
.then((selection) => { .then((selection) => {
if (selection === "去充值") { if (selection === "去充值") {
// 打开充值页面
vscode.env.openExternal( vscode.env.openExternal(
vscode.Uri.parse("https://iccoder.com/recharge") vscode.Uri.parse("https://iccoder.com/memberCenter")
); );
} }
}); });
} }
*/
}, },
onOpen: () => { onOpen: () => {

View File

@ -2,7 +2,6 @@ import * as vscode from "vscode";
import * as http from "http"; import * as http from "http";
import * as path from "path"; import * as path from "path";
import * as fs from "fs"; import * as fs from "fs";
import { onTokenReceived, type UserInfo, clearUserInfo } from "./userService";
import { getConfig } from "../config/settings"; import { getConfig } from "../config/settings";
import { resetInvitationVerification } from "./apiClient"; import { resetInvitationVerification } from "./apiClient";
@ -85,7 +84,7 @@ export class ICCoderAuthenticationProvider
const oldSession = this._sessions[0]; const oldSession = this._sessions[0];
this._sessions = []; this._sessions = [];
await this.saveSessions(); await this.saveSessions();
await clearUserInfo(); // await clearUserInfo();
this._onDidChangeSessions.fire({ this._onDidChangeSessions.fire({
added: [], added: [],
removed: [oldSession], removed: [oldSession],
@ -97,15 +96,15 @@ export class ICCoderAuthenticationProvider
const token = await this.login(); const token = await this.login();
// 获取到 token 后立即调用用户信息接口 // 获取到 token 后立即调用用户信息接口
const userInfo = await onTokenReceived(token); // const userInfo = await onTokenReceived(token);
// 创建会话 // 创建会话
const session: vscode.AuthenticationSession = { const session: vscode.AuthenticationSession = {
id: this.generateSessionId(), id: this.generateSessionId(),
accessToken: token, accessToken: token,
account: { account: {
id: userInfo?.userId || "iccoder-user", id: "user",
label: userInfo?.nickname || userInfo?.username || "IC Coder 用户", label: "IC Coder User",
}, },
scopes: [...scopes], scopes: [...scopes],
}; };
@ -158,7 +157,7 @@ export class ICCoderAuthenticationProvider
await this.saveSessions(); await this.saveSessions();
// 3. 清除用户信息缓存 // 3. 清除用户信息缓存
await clearUserInfo(); // await clearUserInfo();
// 4. 触发会话变化事件 // 4. 触发会话变化事件
this._onDidChangeSessions.fire({ this._onDidChangeSessions.fire({
@ -182,14 +181,14 @@ export class ICCoderAuthenticationProvider
*/ */
async clearSessionsForRelogin(): Promise<void> { async clearSessionsForRelogin(): Promise<void> {
if (this._sessions.length === 0) { if (this._sessions.length === 0) {
await clearUserInfo(); // await clearUserInfo();
return; return;
} }
const removed = [...this._sessions]; const removed = [...this._sessions];
this._sessions = []; this._sessions = [];
await this.saveSessions(); await this.saveSessions();
await clearUserInfo(); // await clearUserInfo();
this._onDidChangeSessions.fire({ this._onDidChangeSessions.fire({
added: [], added: [],

View File

@ -335,43 +335,21 @@ export async function onTokenReceived(token: string): Promise<UserInfo | null> {
// 保存到持久化存储 // 保存到持久化存储
await saveUserInfo(userInfo); await saveUserInfo(userInfo);
// 判断是否是插件试用用户 // 【已禁用】试用用户和欢迎弹窗逻辑 - 无需登录
console.log('[UserService] 检查用户类型isPluginTrial:', userInfo.isPluginTrial); // if (userInfo.isPluginTrial === true && userInfo.pluginTrialExpiresAt !== null && userInfo.pluginTrialExpiresAt !== undefined) {
console.log('[UserService] extensionContext 是否存在:', !!extensionContext); // const now = Date.now();
// const isExpired = now >= userInfo.pluginTrialExpiresAt;
if (userInfo.isPluginTrial === true && userInfo.pluginTrialExpiresAt !== null && userInfo.pluginTrialExpiresAt !== undefined) { // if (isExpired) {
// 检查是否过期 // console.log('[UserService] 试用已过期,将显示邀请码弹窗');
const now = Date.now(); // } else {
const isExpired = now >= userInfo.pluginTrialExpiresAt; // const hasWelcomed = extensionContext?.globalState.get('pluginTrialWelcomed');
console.log('[UserService] 试用到期时间:', new Date(userInfo.pluginTrialExpiresAt).toLocaleString()); // if (!hasWelcomed && extensionContext) {
console.log('[UserService] 当前时间:', new Date(now).toLocaleString()); // await extensionContext.globalState.update('showWelcomeModal', true);
console.log('[UserService] 是否过期:', isExpired); // await extensionContext.globalState.update('pluginTrialWelcomed', true);
// console.log('[UserService] ✅ 已设置欢迎弹窗标记 showWelcomeModal=true');
if (isExpired) { // }
// 已过期:显示邀请码弹窗 // }
console.log('[UserService] 试用已过期,将显示邀请码弹窗'); // }
} else {
// 未过期:显示欢迎弹窗
const hasWelcomed = extensionContext?.globalState.get('pluginTrialWelcomed');
console.log('[UserService] 是否已显示过欢迎弹窗:', hasWelcomed);
if (!hasWelcomed && extensionContext) {
await extensionContext.globalState.update('showWelcomeModal', true);
await extensionContext.globalState.update('pluginTrialWelcomed', true);
console.log('[UserService] ✅ 已设置欢迎弹窗标记 showWelcomeModal=true');
const checkMark = extensionContext.globalState.get('showWelcomeModal');
console.log('[UserService] 验证标记:', checkMark);
} else if (!extensionContext) {
console.error('[UserService] ❌ extensionContext 为 null无法设置标记');
} else {
console.log('[UserService] 已经显示过欢迎弹窗,跳过');
}
}
} else {
// isPluginTrial=false 或 enterpriseTrialExpires 为 null显示邀请码弹窗
console.log('[UserService] 非试用用户或无过期时间,将显示邀请码弹窗');
}
return userInfo; return userInfo;
} catch (error) { } catch (error) {

View File

@ -19,10 +19,6 @@ import { dialogManager, DialogSession } from "../services/dialogService";
import { userInteractionManager } from "../services/userInteraction"; import { userInteractionManager } from "../services/userInteraction";
import { healthCheck } from "../services/apiClient"; import { healthCheck } from "../services/apiClient";
import { isTokenExpired } from "./jwtUtils"; import { isTokenExpired } from "./jwtUtils";
import {
checkBalanceBeforeSend,
fetchBalance,
} from "../services/creditsService";
import { optimizePrompt } from "../services/promptOptimizeService"; import { optimizePrompt } from "../services/promptOptimizeService";
import { NotificationService } from "../services/notificationService"; import { NotificationService } from "../services/notificationService";
import { TrialExpirationService } from "../services/trialExpirationService"; import { TrialExpirationService } from "../services/trialExpirationService";
@ -66,9 +62,9 @@ export async function handleUserMessage(
) { ) {
console.log("收到用户消息:", text); console.log("收到用户消息:", text);
// 检查 token 是否过期 // 【已禁用】检查 token 是否过期 - 无需登录
const context = (panel as any).__context; const context = (panel as any).__context;
if (context) { if (false && context) {
// 从 session 中获取 token // 从 session 中获取 token
let token: string | undefined; let token: string | undefined;
try { try {
@ -112,7 +108,7 @@ export async function handleUserMessage(
return; return;
} }
if (isTokenExpired(token)) { if (token && isTokenExpired(token as string)) {
console.warn("[MessageHandler] Token 已过期,阻止发送"); console.warn("[MessageHandler] Token 已过期,阻止发送");
// 保存待发送的消息 // 保存待发送的消息
@ -128,6 +124,7 @@ export async function handleUserMessage(
await context.globalState.update("icCoderUserInfo", undefined); await context.globalState.update("icCoderUserInfo", undefined);
// 显示弹窗提示 // 显示弹窗提示
/*
const action = await vscode.window.showWarningMessage( const action = await vscode.window.showWarningMessage(
"登录已过期,请重新登录", "登录已过期,请重新登录",
"立即登录", "立即登录",
@ -138,6 +135,7 @@ export async function handleUserMessage(
forceReauth: true, forceReauth: true,
}); });
} }
*/
// 恢复输入状态 // 恢复输入状态
panel.webview.postMessage({ panel.webview.postMessage({
@ -189,29 +187,6 @@ export async function handleUserMessage(
return; return;
} }
// 发送前检测余额
const balanceCheck = await checkBalanceBeforeSend();
if (!balanceCheck.allowed) {
console.warn("[MessageHandler] 余额不足,阻止发送:", balanceCheck.message);
// 显示错误提示
const selection = await vscode.window.showWarningMessage(
balanceCheck.message || "资源点余额不足",
"去充值",
);
if (selection === "去充值") {
vscode.env.openExternal(
vscode.Uri.parse("https://iccoder.com/memberCenter"),
);
}
// 恢复输入状态
panel.webview.postMessage({
command: "updateSegments",
segments: [],
isComplete: true,
});
return;
}
// 尝试使用后端服务 // 尝试使用后端服务
if (useBackendService && extensionPath) { if (useBackendService && extensionPath) {
try { try {
@ -360,17 +335,6 @@ async function handleUserMessageWithBackend(
console.error("[MessageHandler] 保存AI响应历史失败:", error); console.error("[MessageHandler] 保存AI响应历史失败:", error);
} }
// 对话完成后重新获取余额(因为已经消耗了 Credits
try {
console.log("[MessageHandler] 对话完成,重新获取余额...");
const newBalance = await fetchBalance();
if (newBalance !== null) {
console.log("[MessageHandler] 余额已更新:", newBalance);
}
} catch (error) {
console.error("[MessageHandler] 获取余额失败:", error);
}
// 尝试更新面板(如果面板已关闭,这些操作会失败,但不影响数据保存) // 尝试更新面板(如果面板已关闭,这些操作会失败,但不影响数据保存)
try { try {
// 隐藏状态栏 // 隐藏状态栏

View File

@ -158,52 +158,21 @@ export class ICViewProvider implements vscode.WebviewViewProvider {
private readonly extensionUri: vscode.Uri, private readonly extensionUri: vscode.Uri,
private readonly context: vscode.ExtensionContext private readonly context: vscode.ExtensionContext
) { ) {
// 监听认证状态变化 // 【已禁用】监听认证状态变化 - 无需登录
this.context.subscriptions.push(
vscode.authentication.onDidChangeSessions((e) => {
if (e.provider.id === "iccoder") {
this.refreshLoginStatus();
}
})
);
} }
/** /**
* 刷新登录状态并更新视图 * 【已禁用】刷新登录状态并更新视图 - 无需登录
*/ */
private async refreshLoginStatus(): Promise<void> { private async refreshLoginStatus(): Promise<void> {
if (this._view) { // 无需刷新登录状态
const isLoggedIn = await this.checkLoginStatus();
this._view.webview.html = this.getWebviewContent(
this._view.webview,
isLoggedIn
);
}
} }
/** /**
* 检查登录状态(使用 Authentication API * 【已禁用】检查登录状态 - 无需登录
*/ */
private async checkLoginStatus(): Promise<boolean> { private async checkLoginStatus(): Promise<boolean> {
try { return true; // 始终返回已登录状态
const session = await vscode.authentication.getSession("iccoder", [], { createIfNone: false });
console.log("[ICViewProvider] 检查登录状态, session:", session ? "存在" : "不存在");
if (!session) {
return false;
}
// 检查 token 是否过期
const expired = isTokenExpired(session.accessToken);
console.log("[ICViewProvider] token 过期检查结果:", expired);
// 只有明确过期才认为未登录,无法判断时认为已登录
if (expired === true) {
console.log("[ICViewProvider] Token 已过期");
return false;
}
return true;
} catch (error) {
console.log("[ICViewProvider] 检查登录状态失败:", error);
return false;
}
} }
resolveWebviewView(webviewView: vscode.WebviewView) { resolveWebviewView(webviewView: vscode.WebviewView) {
@ -223,30 +192,8 @@ export class ICViewProvider implements vscode.WebviewViewProvider {
console.log('[ICViewProvider] Webview options 已设置'); console.log('[ICViewProvider] Webview options 已设置');
console.log('[ICViewProvider] extensionUri:', this.extensionUri.toString()); console.log('[ICViewProvider] extensionUri:', this.extensionUri.toString());
// 【关键修复】先设置默认 HTML避免一直加载 // 【已禁用】登录检查 - 直接显示"开始使用"按钮
try { webviewView.webview.html = this.getWebviewContent(webviewView.webview, true);
const html = this.getWebviewContent(webviewView.webview, false);
console.log('[ICViewProvider] HTML 内容已生成,长度:', html.length);
webviewView.webview.html = html;
console.log('[ICViewProvider] HTML 已设置到 webview');
} catch (error) {
console.error('[ICViewProvider] 设置 HTML 失败:', error);
}
// 异步检查登录状态并更新 UI
this.checkLoginStatus()
.then((isLoggedIn) => {
console.log('[ICViewProvider] 登录状态检查完成:', isLoggedIn);
webviewView.webview.html = this.getWebviewContent(
webviewView.webview,
isLoggedIn
);
})
.catch((error) => {
console.error('[ICViewProvider] 检查登录状态失败:', error);
// 即使失败也显示未登录状态
webviewView.webview.html = this.getWebviewContent(webviewView.webview, false);
});
// 处理侧边栏的消息 // 处理侧边栏的消息
webviewView.webview.onDidReceiveMessage( webviewView.webview.onDidReceiveMessage(
@ -338,7 +285,7 @@ export class ICViewProvider implements vscode.WebviewViewProvider {
<img src="${logoUri}" alt="IC Coder" width="120" /> <img src="${logoUri}" alt="IC Coder" width="120" />
<h2>欢迎使用 IC Coder</h2> <h2>欢迎使用 IC Coder</h2>
${isLoggedIn ${isLoggedIn
? '<button class="btn" onclick="openChat()">开始创作</button>' ? '<button class="btn" onclick="openChat()">开始使用</button>'
: '<button class="btn" onclick="login()">登录账户</button>' : '<button class="btn" onclick="login()">登录账户</button>'
} }
</div> </div>

View File

@ -47,11 +47,7 @@ export function getConversationHistoryBarContent(): string {
</svg> </svg>
</button> </button>
<div class="user-info-container"> <div class="user-info-container" style="display: none;">
<button class="user-avatar-icon-button" id="userAvatarIconButton" style="display: none;" title="查看用户信息" onclick="openUserDetailModal()">
${userAvatarIconSvg}
</button>
${getUserInfoComponentContent()}
</div> </div>
<div class='setting'> <div class='setting'>

View File

@ -9,57 +9,7 @@
*/ */
export function getUserInfoComponentContent(): string { export function getUserInfoComponentContent(): string {
return ` return `
<div class="user-info-wrapper"> <div class="user-info-wrapper" style="display: none;">
<!-- 用户详情下拉面板 -->
<div class="user-detail-dropdown" id="userDetailDropdown">
<div class="user-detail-content">
<div class="user-detail-header">
<div class="user-info-row">
<div class="user-avatar-small clickable" id="userAvatarClickable">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" fill="currentColor"/>
</svg>
</div>
<div class="user-name-tier">
<div class="user-detail-name clickable" id="userDetailName">加载中...</div>
<img class="tier-icon-inline" id="tierIconInline" style="display: none;" />
</div>
</div>
<!-- 升级到Pro按钮 (仅BASIC会员显示) -->
<!-- <div class="upgrade-pro-wrapper" id="upgradeProWrapper" style="display: none;">
<button class="upgrade-pro-btn" id="upgradeProBtn">升级到 Pro</button>
</div> -->
</div>
<div class="user-detail-body">
<!-- <div class="user-detail-item">
<span class="detail-label">剩余 Credits</span>
<span class="detail-value" id="creditsDetail">-</span>
</div> -->
<div class="user-detail-item logout-item" id="logoutItem">
<span class="detail-label">账户管理</span>
<span class="detail-value logout-link">退出登录</span>
</div>
</div>
</div>
</div>
</div>
<!-- 退出登录确认对话框 -->
<div class="logout-confirm-modal" id="logoutConfirmModal">
<div class="logout-confirm-overlay"></div>
<div class="logout-confirm-content">
<div class="logout-confirm-header">
<h3>确认退出</h3>
</div>
<div class="logout-confirm-body">
<p>确定要退出登录吗?</p>
</div>
<div class="logout-confirm-footer">
<button class="logout-confirm-btn logout-cancel-btn" id="logoutCancelBtn">取消</button>
<button class="logout-confirm-btn logout-ok-btn" id="logoutOkBtn">确定</button>
</div>
</div>
</div> </div>
`; `;
} }