2 Commits

Author SHA1 Message Date
4b2da8244f fix: 修复登录状态相关问题
- 修复登录时VSCode弹出"账户不一致"确认框的问题
- 添加SSE业务错误码401检测,正确触发重新登录流程
- 修复侧边栏登录状态不刷新的问题,添加onDidChangeSessions监听
2026-01-13 14:20:55 +08:00
c571cd9137 feat: 更新 Gateway 路由配置
- dev 环境: localhost:8080/iccoder
- test 环境: 192.168.1.108:2029/iccoder
- prod 环境: api.iccoder.com/iccoder
2026-01-13 12:01:35 +08:00
4 changed files with 73 additions and 22 deletions

View File

@ -8,7 +8,7 @@ import * as vscode from "vscode";
type Environment = "dev" | "test" | "prod"; type Environment = "dev" | "test" | "prod";
/** 当前环境 - 修改这里切换环境 */ /** 当前环境 - 修改这里切换环境 */
const CURRENT_ENV: Environment = "dev"; const CURRENT_ENV: Environment = "test";
/** 服务等级类型 */ /** 服务等级类型 */
export type ServiceTier = "lite" | "syntaxic" | "max" | "auto"; export type ServiceTier = "lite" | "syntaxic" | "max" | "auto";
@ -31,28 +31,28 @@ export interface IccoderConfig {
/** 环境配置 */ /** 环境配置 */
const ENV_CONFIG: Record<Environment, IccoderConfig> = { const ENV_CONFIG: Record<Environment, IccoderConfig> = {
/** 本地开发环境 */ /** 本地开发环境 - 通过 Gateway 路由 */
dev: { dev: {
backendUrl: "http://localhost:2233", backendUrl: "http://localhost:8080/iccoder",
backendUrlStrongeLoop: "http://192.168.1.108:2029", backendUrlStrongeLoop: "http://localhost:8080",
loginUrl: "http://localhost/login", loginUrl: "http://localhost/login",
timeout: 300000, timeout: 300000,
userId: "default-user", userId: "default-user",
serviceTier: "max", // 默认使用 max serviceTier: "max", // 默认使用 max
}, },
/** 测试服务器环境 */ /** 测试服务器环境 - 通过 Gateway 路由 */
test: { test: {
backendUrl: "http://192.168.1.108:2233", backendUrl: "http://192.168.1.108:2029/iccoder",
backendUrlStrongeLoop: "http://192.168.1.108:2029", backendUrlStrongeLoop: "http://192.168.1.108:2029",
loginUrl: "http://192.168.1.108:2005/login", loginUrl: "http://192.168.1.108:2005/login",
timeout: 60000, timeout: 60000,
userId: "default-user", userId: "default-user",
serviceTier: "max", serviceTier: "max",
}, },
/** 生产环境 */ /** 生产环境 - 通过 Gateway 路由 */
prod: { prod: {
backendUrl: "https://api.iccoder.com", backendUrl: "https://api.iccoder.com/iccoder",
backendUrlStrongeLoop: "http://api.iccoder.com:2029", backendUrlStrongeLoop: "https://api.iccoder.com",
loginUrl: "https://iccoder.com/login", loginUrl: "https://iccoder.com/login",
timeout: 60000, timeout: 60000,
userId: "default-user", userId: "default-user",

View File

@ -128,15 +128,18 @@ export function activate(context: vscode.ExtensionContext) {
"ic-coder.login", "ic-coder.login",
async () => { async () => {
try { try {
// 检查是否有现有 session // 先清除 session 偏好,避免 VSCode 弹出"账户不一致"确认框
const existingSession = await vscode.authentication.getSession("iccoder", [], { createIfNone: false }); try {
if (existingSession) { await vscode.authentication.getSession("iccoder", [], {
// 有旧 session使用 forceNewSession 强制创建新 session clearSessionPreference: true,
await vscode.authentication.getSession("iccoder", [], { forceNewSession: true }); createIfNone: false
} else { });
// 没有旧 session使用 createIfNone 创建新 session } catch {
await vscode.authentication.getSession("iccoder", [], { createIfNone: true }); // 忽略错误
} }
// 创建新 session
await vscode.authentication.getSession("iccoder", [], { createIfNone: true });
} catch (error) { } catch (error) {
vscode.window.showErrorMessage(`登录失败: ${error}`); vscode.window.showErrorMessage(`登录失败: ${error}`);
} }

View File

@ -238,6 +238,25 @@ export async function startStreamDialog(
res.on('data', (chunk: string) => { res.on('data', (chunk: string) => {
if (!controller.aborted) { if (!controller.aborted) {
console.log('[SSE] 收到原始数据块:', chunk.substring(0, 200)); console.log('[SSE] 收到原始数据块:', chunk.substring(0, 200));
// 检查是否是业务错误码Gateway 返回 HTTP 200 但响应体是错误 JSON
try {
const trimmed = chunk.trim();
if (trimmed.startsWith('{') && trimmed.includes('"code"')) {
const json = JSON.parse(trimmed);
if (json.code === 401 || json.msg?.includes('登录状态已过期')) {
console.log('[SSE] 检测到登录过期业务错误');
const error = new Error('LOGIN_EXPIRED:登录状态已过期,请重新登录');
callbacks.onError?.({ message: error.message });
controller.abort();
reject(error);
return;
}
}
} catch {
// 不是 JSON 格式,继续正常处理
}
parser.feed(chunk); parser.feed(chunk);
} }
}); });

View File

@ -128,10 +128,34 @@ export function showICHelperPanel(context: vscode.ExtensionContext) {
* 侧边栏视图提供者 * 侧边栏视图提供者
*/ */
export class ICViewProvider implements vscode.WebviewViewProvider { export class ICViewProvider implements vscode.WebviewViewProvider {
private _view?: vscode.WebviewView;
constructor( constructor(
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> {
if (this._view) {
const isLoggedIn = await this.checkLoginStatus();
this._view.webview.html = this.getWebviewContent(
this._view.webview,
isLoggedIn
);
}
}
/** /**
* 检查登录状态(使用 Authentication API * 检查登录状态(使用 Authentication API
@ -139,24 +163,29 @@ export class ICViewProvider implements vscode.WebviewViewProvider {
private async checkLoginStatus(): Promise<boolean> { private async checkLoginStatus(): Promise<boolean> {
try { try {
const session = await vscode.authentication.getSession("iccoder", [], { createIfNone: false }); const session = await vscode.authentication.getSession("iccoder", [], { createIfNone: false });
console.log("[ICViewProvider] 检查登录状态, session:", session ? "存在" : "不存在");
if (!session) { if (!session) {
return false; return false;
} }
// 检查 token 是否过期 // 检查 token 是否过期
const expired = isTokenExpired(session.accessToken); const expired = isTokenExpired(session.accessToken);
// 如果已过期或无法判断null都认为未登录 console.log("[ICViewProvider] token 过期检查结果:", expired);
if (expired === true || expired === null) { // 只有明确过期才认为未登录,无法判断时认为已登录
console.log("Token 已过期或无法判断过期状态"); if (expired === true) {
console.log("[ICViewProvider] Token 已过期");
return false; return false;
} }
return true; return true;
} catch (error) { } catch (error) {
console.log("检查登录状态失败:", error); console.log("[ICViewProvider] 检查登录状态失败:", error);
return false; return false;
} }
} }
resolveWebviewView(webviewView: vscode.WebviewView) { resolveWebviewView(webviewView: vscode.WebviewView) {
// 保存引用以便后续刷新
this._view = webviewView;
webviewView.webview.options = { webviewView.webview.options = {
enableScripts: true, enableScripts: true,
localResourceRoots: [vscode.Uri.joinPath(this.extensionUri, "media")], localResourceRoots: [vscode.Uri.joinPath(this.extensionUri, "media")],