Compare commits
4 Commits
feat/Knowl
...
531d140b99
| Author | SHA1 | Date | |
|---|---|---|---|
| 531d140b99 | |||
| 97b8e8aa7d | |||
| 4ed998e937 | |||
| ad0f0336d5 |
@ -29,6 +29,9 @@ export interface IccoderConfig {
|
||||
serviceTier: ServiceTier;
|
||||
}
|
||||
|
||||
/** 自定义配置缓存 */
|
||||
let customConfig: Partial<IccoderConfig> | null = null;
|
||||
|
||||
/** 环境配置 */
|
||||
const ENV_CONFIG: Record<Environment, IccoderConfig> = {
|
||||
/** 本地开发环境 - 通过 Gateway 路由 */
|
||||
@ -38,7 +41,7 @@ const ENV_CONFIG: Record<Environment, IccoderConfig> = {
|
||||
loginUrl: "http://localhost/login",
|
||||
timeout: 300000,
|
||||
userId: "default-user",
|
||||
serviceTier: "max", // 默认使用 max
|
||||
serviceTier: "max",
|
||||
},
|
||||
/** 测试服务器环境 - 通过 Gateway 路由 */
|
||||
test: {
|
||||
@ -60,6 +63,13 @@ const ENV_CONFIG: Record<Environment, IccoderConfig> = {
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 设置自定义配置
|
||||
*/
|
||||
export function setCustomConfig(config: Partial<IccoderConfig>) {
|
||||
customConfig = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前环境
|
||||
*/
|
||||
@ -71,7 +81,14 @@ export function getCurrentEnv(): Environment {
|
||||
* 获取配置项
|
||||
*/
|
||||
export function getConfig(): IccoderConfig {
|
||||
return { ...ENV_CONFIG[CURRENT_ENV] };
|
||||
const baseConfig = { ...ENV_CONFIG[CURRENT_ENV] };
|
||||
|
||||
// 合并自定义配置(空字符串表示使用默认)
|
||||
if (customConfig?.backendUrl && customConfig.backendUrl !== '') {
|
||||
baseConfig.backendUrl = customConfig.backendUrl;
|
||||
}
|
||||
|
||||
return baseConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -5,16 +5,23 @@ import { VCDViewerPanel, VCDViewerEditorProvider } from "./panels/VCDViewerPanel
|
||||
import { ChatHistoryManager } from "./utils/chatHistoryManager";
|
||||
import { ICCoderAuthenticationProvider } from "./services/icCoderAuthProvider";
|
||||
import { VCDFileServer } from "./services/vcdFileServer";
|
||||
import { initUserService } from "./services/userService";
|
||||
import { initCreditsService } from "./services/creditsService";
|
||||
import { isTokenExpired } from "./utils/jwtUtils";
|
||||
import { NotificationService } from "./services/notificationService";
|
||||
import { InvitationService } from "./services/invitationService";
|
||||
import { ICCoderCodeActionProvider } from "./providers/codeActionProvider";
|
||||
import { setCustomConfig } from "./config/settings";
|
||||
|
||||
export async function activate(context: vscode.ExtensionContext) {
|
||||
console.log("🎉 IC Coder 插件已激活!");
|
||||
|
||||
// 加载保存的配置
|
||||
const savedSettings = context.globalState.get('generalSettings') as any;
|
||||
if (savedSettings?.backendUrl) {
|
||||
setCustomConfig({
|
||||
backendUrl: savedSettings.backendUrl,
|
||||
});
|
||||
}
|
||||
|
||||
// 创建装饰类型(代码旁边的提示)
|
||||
const decorationType = vscode.window.createTextEditorDecorationType({
|
||||
after: {
|
||||
@ -50,33 +57,26 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
const notificationService = NotificationService.getInstance(context);
|
||||
console.log('[Extension] 通知服务已初始化');
|
||||
|
||||
// 【关键】在创建 AuthProvider 之前,先检查并清除过期的 session
|
||||
const storedSessions = context.globalState.get<any[]>('icCoderSessions', []);
|
||||
console.log('[Extension] 检查 sessions 数量:', storedSessions.length);
|
||||
|
||||
if (storedSessions.length > 0) {
|
||||
const session = storedSessions[0];
|
||||
const token = session.accessToken;
|
||||
console.log('[Extension] 检查 token 是否过期...');
|
||||
|
||||
if (token) {
|
||||
const expired = isTokenExpired(token);
|
||||
console.log('[Extension] token 过期检查结果:', expired);
|
||||
|
||||
if (expired) {
|
||||
// 必须等待清除完成后再创建 AuthProvider
|
||||
await context.globalState.update('icCoderSessions', []);
|
||||
await context.globalState.update('icCoderUserInfo', undefined);
|
||||
console.log('[Extension] Token 已过期,已清除所有登录状态');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化用户服务
|
||||
initUserService(context);
|
||||
|
||||
// 初始化 Credits 服务
|
||||
initCreditsService(context);
|
||||
// 【已禁用】登录和 token 验证 - 无需登录即可使用
|
||||
// const storedSessions = context.globalState.get<any[]>('icCoderSessions', []);
|
||||
// console.log('[Extension] 检查 sessions 数量:', storedSessions.length);
|
||||
//
|
||||
// if (storedSessions.length > 0) {
|
||||
// const session = storedSessions[0];
|
||||
// const token = session.accessToken;
|
||||
// console.log('[Extension] 检查 token 是否过期...');
|
||||
//
|
||||
// if (token) {
|
||||
// const expired = isTokenExpired(token);
|
||||
// console.log('[Extension] token 过期检查结果:', expired);
|
||||
//
|
||||
// if (expired) {
|
||||
// await context.globalState.update('icCoderSessions', []);
|
||||
// await context.globalState.update('icCoderUserInfo', undefined);
|
||||
// console.log('[Extension] Token 已过期,已清除所有登录状态');
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// 初始化 VCD 文件服务器
|
||||
const vcdFileServer = new VCDFileServer(context.extensionUri);
|
||||
@ -91,25 +91,18 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
dispose: () => vcdFileServer.stop()
|
||||
});
|
||||
|
||||
// 注册 Authentication Provider(此时 icCoderSessions 已经被清除)
|
||||
// 【已禁用】Authentication Provider 注册 - 无需登录
|
||||
const authProvider = new ICCoderAuthenticationProvider(context);
|
||||
context.subscriptions.push(
|
||||
vscode.authentication.registerAuthenticationProvider(
|
||||
"iccoder",
|
||||
"IC Coder",
|
||||
authProvider
|
||||
)
|
||||
);
|
||||
// context.subscriptions.push(
|
||||
// vscode.authentication.registerAuthenticationProvider(
|
||||
// "iccoder",
|
||||
// "IC Coder",
|
||||
// authProvider
|
||||
// )
|
||||
// );
|
||||
|
||||
// 检查登录状态,如果已登录则自动打开聊天面板
|
||||
vscode.authentication.getSession("iccoder", [], { createIfNone: false })
|
||||
.then((session) => {
|
||||
if (session) {
|
||||
// 【已禁用】登录状态检查 - 直接打开聊天面板
|
||||
vscode.commands.executeCommand("ic-coder.openChat");
|
||||
}
|
||||
}, () => {
|
||||
// 未登录,不做任何操作
|
||||
});
|
||||
|
||||
// 注册命令:打开助手面板
|
||||
const openPanelCommand = vscode.commands.registerCommand(
|
||||
|
||||
@ -18,50 +18,12 @@ import {
|
||||
startChangeSession,
|
||||
handleOpenFileDiff,
|
||||
} from "../utils/messageHandler";
|
||||
import { setCustomConfig } from "../config/settings";
|
||||
import { compactDialog } from "../services/apiClient";
|
||||
import { VCDViewerPanel } from "./VCDViewerPanel";
|
||||
import { ChatHistoryManager } from "../utils/chatHistoryManager";
|
||||
import { MessageType } from "../types/chatHistory";
|
||||
import { getCachedUserInfo } from "../services/userService";
|
||||
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 助手面板
|
||||
@ -70,63 +32,35 @@ export async function showICHelperPanel(
|
||||
context: vscode.ExtensionContext,
|
||||
viewColumn?: vscode.ViewColumn,
|
||||
) {
|
||||
// 检查 token 是否过期
|
||||
let token: string | undefined;
|
||||
try {
|
||||
const session = await vscode.authentication.getSession("iccoder", [], {
|
||||
createIfNone: false,
|
||||
});
|
||||
token = session?.accessToken;
|
||||
} catch (error) {
|
||||
console.warn("[ICHelperPanel] 获取 session 失败:", error);
|
||||
}
|
||||
|
||||
if (token && isTokenExpired(token)) {
|
||||
// 清除过期的 session
|
||||
await context.globalState.update("icCoderSessions", []);
|
||||
await context.globalState.update("icCoderUserInfo", undefined);
|
||||
|
||||
const action = await vscode.window.showWarningMessage(
|
||||
"登录已过期,请重新登录",
|
||||
"立即登录",
|
||||
);
|
||||
if (action === "立即登录") {
|
||||
vscode.commands.executeCommand("ic-coder.login", {
|
||||
forceReauth: true,
|
||||
});
|
||||
}
|
||||
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面板
|
||||
// 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面板
|
||||
const panel = vscode.window.createWebviewPanel(
|
||||
@ -230,81 +164,6 @@ export async function showICHelperPanel(
|
||||
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;
|
||||
if (pendingMessage) {
|
||||
@ -585,71 +444,17 @@ export async function showICHelperPanel(
|
||||
}
|
||||
break;
|
||||
case "checkInvitationCode":
|
||||
// 检查邀请码验证状态
|
||||
// 【已禁用】检查邀请码验证状态 - 现在所有用户都可以直接使用
|
||||
{
|
||||
// 先检查是否是试用用户
|
||||
const { getCachedUserInfo } = require("../services/userService");
|
||||
const userInfo = getCachedUserInfo();
|
||||
|
||||
if (userInfo?.isPluginTrial === true) {
|
||||
// 试用用户,跳过邀请码验证,直接返回已验证
|
||||
console.log("[ICHelperPanel] 试用用户,跳过邀请码验证");
|
||||
// 直接返回已验证,无需登录和邀请码
|
||||
panel.webview.postMessage({
|
||||
command: "invitationCodeStatus",
|
||||
verified: true,
|
||||
});
|
||||
} else {
|
||||
// 正式用户,检查邀请码
|
||||
const {
|
||||
InvitationService,
|
||||
} = require("../services/invitationService");
|
||||
const isVerified = await InvitationService.isVerified(context);
|
||||
panel.webview.postMessage({
|
||||
command: "invitationCodeStatus",
|
||||
verified: isVerified,
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
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;
|
||||
case "checkTrialExpiration":
|
||||
// 检查试用期是否过期
|
||||
@ -664,37 +469,13 @@ export async function showICHelperPanel(
|
||||
}
|
||||
break;
|
||||
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({
|
||||
command: "invitationCodeVerified",
|
||||
success: true,
|
||||
});
|
||||
// 延迟显示欢迎弹窗,确保邀请码弹窗已关闭
|
||||
setTimeout(() => {
|
||||
panel.webview.postMessage({
|
||||
command: "showNdtWelcomeModal",
|
||||
});
|
||||
}, 300);
|
||||
} else {
|
||||
// 验证失败,返回错误信息
|
||||
panel.webview.postMessage({
|
||||
command: "invitationCodeVerified",
|
||||
success: false,
|
||||
message: result.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "openICCoder":
|
||||
@ -904,6 +685,21 @@ export async function showICHelperPanel(
|
||||
// 退出登录(前端已有确认对话框)
|
||||
vscode.commands.executeCommand("ic-coder.logout");
|
||||
break;
|
||||
case "saveGeneralSettings":
|
||||
// 保存通用设置
|
||||
context.globalState.update('generalSettings', message.settings);
|
||||
// 更新运行时配置(包括清空)
|
||||
setCustomConfig({ backendUrl: message.settings.backendUrl || '' });
|
||||
vscode.window.showInformationMessage('设置已保存');
|
||||
break;
|
||||
case "loadGeneralSettings":
|
||||
// 加载通用设置
|
||||
const settings = context.globalState.get('generalSettings');
|
||||
panel.webview.postMessage({
|
||||
command: 'loadedGeneralSettings',
|
||||
settings: settings
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
undefined,
|
||||
|
||||
@ -30,7 +30,6 @@ import type {
|
||||
import { submitToolConfirm, submitAnswer, stopDialog } from "./apiClient";
|
||||
import { ChatHistoryManager } from "../utils/chatHistoryManager";
|
||||
import { getUserIdFromToken, isTokenExpired } from "../utils/jwtUtils";
|
||||
import { updateCachedBalance } from "./creditsService";
|
||||
|
||||
/**
|
||||
* 消息段落类型
|
||||
@ -444,6 +443,7 @@ export class DialogSession {
|
||||
const expired = isTokenExpired(session.accessToken);
|
||||
if (expired === true) {
|
||||
console.error("[DialogSession] token 已过期,需要重新登录");
|
||||
/*
|
||||
vscode.window
|
||||
.showErrorMessage("登录已过期,请重新登录", "重新登录")
|
||||
.then((selection) => {
|
||||
@ -453,6 +453,7 @@ export class DialogSession {
|
||||
});
|
||||
}
|
||||
});
|
||||
*/
|
||||
throw new Error("登录已过期,请重新登录");
|
||||
}
|
||||
|
||||
@ -899,6 +900,7 @@ export class DialogSession {
|
||||
data.message.includes("LOGIN_EXPIRED") ||
|
||||
data.message.includes("登录状态已过期")
|
||||
) {
|
||||
/*
|
||||
vscode.window
|
||||
.showErrorMessage("登录状态已过期,请重新登录", "重新登录")
|
||||
.then((selection) => {
|
||||
@ -908,6 +910,7 @@ export class DialogSession {
|
||||
});
|
||||
}
|
||||
});
|
||||
*/
|
||||
// 登录过期错误已处理,不再传递给外部
|
||||
return;
|
||||
}
|
||||
@ -1017,8 +1020,9 @@ export class DialogSession {
|
||||
data.remainingCredits
|
||||
);
|
||||
// 更新余额缓存
|
||||
updateCachedBalance(data.remainingCredits);
|
||||
// updateCachedBalance(data.remainingCredits);
|
||||
// 资源点余额低于阈值时弹窗提醒
|
||||
/*
|
||||
const LOW_CREDIT_THRESHOLD = 5;
|
||||
if (data.remainingCredits < LOW_CREDIT_THRESHOLD) {
|
||||
vscode.window
|
||||
@ -1030,13 +1034,13 @@ export class DialogSession {
|
||||
)
|
||||
.then((selection) => {
|
||||
if (selection === "去充值") {
|
||||
// 打开充值页面
|
||||
vscode.env.openExternal(
|
||||
vscode.Uri.parse("https://iccoder.com/recharge")
|
||||
vscode.Uri.parse("https://iccoder.com/memberCenter")
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
onOpen: () => {
|
||||
|
||||
@ -2,7 +2,6 @@ import * as vscode from "vscode";
|
||||
import * as http from "http";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import { onTokenReceived, type UserInfo, clearUserInfo } from "./userService";
|
||||
import { getConfig } from "../config/settings";
|
||||
import { resetInvitationVerification } from "./apiClient";
|
||||
|
||||
@ -85,7 +84,7 @@ export class ICCoderAuthenticationProvider
|
||||
const oldSession = this._sessions[0];
|
||||
this._sessions = [];
|
||||
await this.saveSessions();
|
||||
await clearUserInfo();
|
||||
// await clearUserInfo();
|
||||
this._onDidChangeSessions.fire({
|
||||
added: [],
|
||||
removed: [oldSession],
|
||||
@ -97,15 +96,15 @@ export class ICCoderAuthenticationProvider
|
||||
const token = await this.login();
|
||||
|
||||
// 获取到 token 后立即调用用户信息接口
|
||||
const userInfo = await onTokenReceived(token);
|
||||
// const userInfo = await onTokenReceived(token);
|
||||
|
||||
// 创建会话
|
||||
const session: vscode.AuthenticationSession = {
|
||||
id: this.generateSessionId(),
|
||||
accessToken: token,
|
||||
account: {
|
||||
id: userInfo?.userId || "iccoder-user",
|
||||
label: userInfo?.nickname || userInfo?.username || "IC Coder 用户",
|
||||
id: "user",
|
||||
label: "IC Coder User",
|
||||
},
|
||||
scopes: [...scopes],
|
||||
};
|
||||
@ -158,7 +157,7 @@ export class ICCoderAuthenticationProvider
|
||||
await this.saveSessions();
|
||||
|
||||
// 3. 清除用户信息缓存
|
||||
await clearUserInfo();
|
||||
// await clearUserInfo();
|
||||
|
||||
// 4. 触发会话变化事件
|
||||
this._onDidChangeSessions.fire({
|
||||
@ -182,14 +181,14 @@ export class ICCoderAuthenticationProvider
|
||||
*/
|
||||
async clearSessionsForRelogin(): Promise<void> {
|
||||
if (this._sessions.length === 0) {
|
||||
await clearUserInfo();
|
||||
// await clearUserInfo();
|
||||
return;
|
||||
}
|
||||
|
||||
const removed = [...this._sessions];
|
||||
this._sessions = [];
|
||||
await this.saveSessions();
|
||||
await clearUserInfo();
|
||||
// await clearUserInfo();
|
||||
|
||||
this._onDidChangeSessions.fire({
|
||||
added: [],
|
||||
|
||||
@ -161,7 +161,16 @@ export async function startStreamDialog(
|
||||
|
||||
const body = JSON.stringify(request);
|
||||
|
||||
console.log(`[SSE] 开始流式对话: taskId=${request.taskId}, mode=${request.mode}, url=${urlString}`);
|
||||
console.log('[SSE] 请求详情:', {
|
||||
url: urlString,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'text/event-stream',
|
||||
hasToken: !!request.token,
|
||||
},
|
||||
body: request
|
||||
});
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const options: http.RequestOptions = {
|
||||
|
||||
@ -335,43 +335,21 @@ export async function onTokenReceived(token: string): Promise<UserInfo | null> {
|
||||
// 保存到持久化存储
|
||||
await saveUserInfo(userInfo);
|
||||
|
||||
// 判断是否是插件试用用户
|
||||
console.log('[UserService] 检查用户类型,isPluginTrial:', userInfo.isPluginTrial);
|
||||
console.log('[UserService] extensionContext 是否存在:', !!extensionContext);
|
||||
|
||||
if (userInfo.isPluginTrial === true && userInfo.pluginTrialExpiresAt !== null && userInfo.pluginTrialExpiresAt !== undefined) {
|
||||
// 检查是否过期
|
||||
const now = Date.now();
|
||||
const isExpired = now >= userInfo.pluginTrialExpiresAt;
|
||||
console.log('[UserService] 试用到期时间:', new Date(userInfo.pluginTrialExpiresAt).toLocaleString());
|
||||
console.log('[UserService] 当前时间:', new Date(now).toLocaleString());
|
||||
console.log('[UserService] 是否过期:', isExpired);
|
||||
|
||||
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] 非试用用户或无过期时间,将显示邀请码弹窗');
|
||||
}
|
||||
// 【已禁用】试用用户和欢迎弹窗逻辑 - 无需登录
|
||||
// if (userInfo.isPluginTrial === true && userInfo.pluginTrialExpiresAt !== null && userInfo.pluginTrialExpiresAt !== undefined) {
|
||||
// const now = Date.now();
|
||||
// const isExpired = now >= userInfo.pluginTrialExpiresAt;
|
||||
// if (isExpired) {
|
||||
// console.log('[UserService] 试用已过期,将显示邀请码弹窗');
|
||||
// } else {
|
||||
// const hasWelcomed = extensionContext?.globalState.get('pluginTrialWelcomed');
|
||||
// if (!hasWelcomed && extensionContext) {
|
||||
// await extensionContext.globalState.update('showWelcomeModal', true);
|
||||
// await extensionContext.globalState.update('pluginTrialWelcomed', true);
|
||||
// console.log('[UserService] ✅ 已设置欢迎弹窗标记 showWelcomeModal=true');
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
return userInfo;
|
||||
} catch (error) {
|
||||
|
||||
@ -19,10 +19,6 @@ import { dialogManager, DialogSession } from "../services/dialogService";
|
||||
import { userInteractionManager } from "../services/userInteraction";
|
||||
import { healthCheck } from "../services/apiClient";
|
||||
import { isTokenExpired } from "./jwtUtils";
|
||||
import {
|
||||
checkBalanceBeforeSend,
|
||||
fetchBalance,
|
||||
} from "../services/creditsService";
|
||||
import { optimizePrompt } from "../services/promptOptimizeService";
|
||||
import { NotificationService } from "../services/notificationService";
|
||||
import { TrialExpirationService } from "../services/trialExpirationService";
|
||||
@ -66,9 +62,9 @@ export async function handleUserMessage(
|
||||
) {
|
||||
console.log("收到用户消息:", text);
|
||||
|
||||
// 检查 token 是否过期
|
||||
// 【已禁用】检查 token 是否过期 - 无需登录
|
||||
const context = (panel as any).__context;
|
||||
if (context) {
|
||||
if (false && context) {
|
||||
// 从 session 中获取 token
|
||||
let token: string | undefined;
|
||||
try {
|
||||
@ -112,7 +108,7 @@ export async function handleUserMessage(
|
||||
return;
|
||||
}
|
||||
|
||||
if (isTokenExpired(token)) {
|
||||
if (token && isTokenExpired(token as string)) {
|
||||
console.warn("[MessageHandler] Token 已过期,阻止发送");
|
||||
|
||||
// 保存待发送的消息
|
||||
@ -128,6 +124,7 @@ export async function handleUserMessage(
|
||||
await context.globalState.update("icCoderUserInfo", undefined);
|
||||
|
||||
// 显示弹窗提示
|
||||
/*
|
||||
const action = await vscode.window.showWarningMessage(
|
||||
"登录已过期,请重新登录",
|
||||
"立即登录",
|
||||
@ -138,6 +135,7 @@ export async function handleUserMessage(
|
||||
forceReauth: true,
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
// 恢复输入状态
|
||||
panel.webview.postMessage({
|
||||
@ -189,29 +187,6 @@ export async function handleUserMessage(
|
||||
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) {
|
||||
try {
|
||||
@ -226,10 +201,10 @@ export async function handleUserMessage(
|
||||
);
|
||||
return;
|
||||
} catch (error) {
|
||||
console.error("当前访问人数过多,请稍后重试:", error);
|
||||
console.error("处理用户消息失败:", error);
|
||||
panel.webview.postMessage({
|
||||
command: "updateStatus",
|
||||
text: "当前访问人数过多,请稍后重试",
|
||||
text: "处理用户消息失败,请稍后重试",
|
||||
type: "error",
|
||||
});
|
||||
// 恢复输入状态
|
||||
@ -360,17 +335,6 @@ async function handleUserMessageWithBackend(
|
||||
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 {
|
||||
// 隐藏状态栏
|
||||
@ -414,7 +378,7 @@ async function handleUserMessageWithBackend(
|
||||
});
|
||||
panel.webview.postMessage({
|
||||
command: "receiveMessage",
|
||||
text: `❌ 错误: ${message}`,
|
||||
text: `错误: ${message}`,
|
||||
});
|
||||
// 恢复输入状态
|
||||
panel.webview.postMessage({
|
||||
|
||||
@ -13,6 +13,7 @@ import {
|
||||
abortCurrentDialog,
|
||||
handleOptimizePrompt,
|
||||
} from "../utils/messageHandler";
|
||||
import { setCustomConfig } from "../config/settings";
|
||||
|
||||
/**
|
||||
* 创建并显示IC 侧边栏视图
|
||||
@ -141,6 +142,21 @@ export function showICHelperPanel(context: vscode.ExtensionContext) {
|
||||
case "optimizePrompt":
|
||||
handleOptimizePrompt(panel, message.prompt);
|
||||
break;
|
||||
// 保存通用设置
|
||||
case "saveGeneralSettings":
|
||||
context.globalState.update('generalSettings', message.settings);
|
||||
// 更新运行时配置(包括清空)
|
||||
setCustomConfig({ backendUrl: message.settings.backendUrl || '' });
|
||||
vscode.window.showInformationMessage('设置已保存');
|
||||
break;
|
||||
// 加载通用设置
|
||||
case "loadGeneralSettings":
|
||||
const settings = context.globalState.get('generalSettings');
|
||||
panel.webview.postMessage({
|
||||
command: 'loadedGeneralSettings',
|
||||
settings: settings
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
undefined,
|
||||
@ -158,52 +174,21 @@ export class ICViewProvider implements vscode.WebviewViewProvider {
|
||||
private readonly extensionUri: vscode.Uri,
|
||||
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)
|
||||
* 【已禁用】检查登录状态 - 无需登录
|
||||
*/
|
||||
private async checkLoginStatus(): Promise<boolean> {
|
||||
try {
|
||||
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;
|
||||
}
|
||||
return true; // 始终返回已登录状态
|
||||
}
|
||||
|
||||
resolveWebviewView(webviewView: vscode.WebviewView) {
|
||||
@ -223,30 +208,8 @@ export class ICViewProvider implements vscode.WebviewViewProvider {
|
||||
console.log('[ICViewProvider] Webview options 已设置');
|
||||
console.log('[ICViewProvider] extensionUri:', this.extensionUri.toString());
|
||||
|
||||
// 【关键修复】先设置默认 HTML,避免一直加载
|
||||
try {
|
||||
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.html = this.getWebviewContent(webviewView.webview, true);
|
||||
|
||||
// 处理侧边栏的消息
|
||||
webviewView.webview.onDidReceiveMessage(
|
||||
@ -266,6 +229,20 @@ export class ICViewProvider implements vscode.WebviewViewProvider {
|
||||
if (message.url) {
|
||||
vscode.env.openExternal(vscode.Uri.parse(message.url));
|
||||
}
|
||||
} else if (message.command === "saveGeneralSettings") {
|
||||
// 保存通用设置
|
||||
this.context.globalState.update('generalSettings', message.settings);
|
||||
if (message.settings.backendUrl) {
|
||||
setCustomConfig({ backendUrl: message.settings.backendUrl });
|
||||
}
|
||||
vscode.window.showInformationMessage('设置已保存');
|
||||
} else if (message.command === "loadGeneralSettings") {
|
||||
// 加载通用设置
|
||||
const settings = this.context.globalState.get('generalSettings');
|
||||
webviewView.webview.postMessage({
|
||||
command: 'loadedGeneralSettings',
|
||||
settings: settings
|
||||
});
|
||||
}
|
||||
},
|
||||
undefined,
|
||||
@ -338,7 +315,7 @@ export class ICViewProvider implements vscode.WebviewViewProvider {
|
||||
<img src="${logoUri}" alt="IC Coder" width="120" />
|
||||
<h2>欢迎使用 IC Coder</h2>
|
||||
${isLoggedIn
|
||||
? '<button class="btn" onclick="openChat()">开始创作</button>'
|
||||
? '<button class="btn" onclick="openChat()">开始使用</button>'
|
||||
: '<button class="btn" onclick="login()">登录账户</button>'
|
||||
}
|
||||
</div>
|
||||
|
||||
@ -47,11 +47,7 @@ export function getConversationHistoryBarContent(): string {
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<div class="user-info-container">
|
||||
<button class="user-avatar-icon-button" id="userAvatarIconButton" style="display: none;" title="查看用户信息" onclick="openUserDetailModal()">
|
||||
${userAvatarIconSvg}
|
||||
</button>
|
||||
${getUserInfoComponentContent()}
|
||||
<div class="user-info-container" style="display: none;">
|
||||
</div>
|
||||
|
||||
<div class='setting'>
|
||||
|
||||
@ -4,75 +4,15 @@
|
||||
export function getGeneralSettingsComponentContent(): string {
|
||||
return `
|
||||
<div class="general-settings">
|
||||
<h3 class="settings-section-title">通用设置</h3>
|
||||
<h3 class="settings-section-title">后端服务配置</h3>
|
||||
|
||||
<div class="settings-section">
|
||||
<div class="settings-item">
|
||||
<div class="settings-item-header">
|
||||
<label class="settings-item-label">主题</label>
|
||||
<span class="settings-item-description">选择界面主题</span>
|
||||
<label class="settings-item-label">后端服务地址</label>
|
||||
<span class="settings-item-description">自定义后端 API 地址</span>
|
||||
</div>
|
||||
<select class="settings-select" id="themeSelect">
|
||||
<option value="auto">跟随系统</option>
|
||||
<option value="light">浅色</option>
|
||||
<option value="dark">深色</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="settings-item">
|
||||
<div class="settings-item-header">
|
||||
<label class="settings-item-label">语言</label>
|
||||
<span class="settings-item-description">选择界面语言</span>
|
||||
</div>
|
||||
<select class="settings-select" id="languageSelect">
|
||||
<option value="zh-CN">简体中文</option>
|
||||
<option value="en-US">English</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="settings-item">
|
||||
<div class="settings-item-header">
|
||||
<label class="settings-item-label">自动保存</label>
|
||||
<span class="settings-item-description">自动保存会话历史</span>
|
||||
</div>
|
||||
<label class="settings-switch">
|
||||
<input type="checkbox" id="autoSaveCheckbox" checked>
|
||||
<span class="settings-switch-slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="settings-item">
|
||||
<div class="settings-item-header">
|
||||
<label class="settings-item-label">显示时间戳</label>
|
||||
<span class="settings-item-description">在消息中显示时间戳</span>
|
||||
</div>
|
||||
<label class="settings-switch">
|
||||
<input type="checkbox" id="showTimestampCheckbox">
|
||||
<span class="settings-switch-slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-section">
|
||||
<h4 class="settings-subsection-title">编辑器设置</h4>
|
||||
|
||||
<div class="settings-item">
|
||||
<div class="settings-item-header">
|
||||
<label class="settings-item-label">字体大小</label>
|
||||
<span class="settings-item-description">设置编辑器字体大小</span>
|
||||
</div>
|
||||
<input type="number" class="settings-input" id="fontSizeInput" value="14" min="10" max="24">
|
||||
</div>
|
||||
|
||||
<div class="settings-item">
|
||||
<div class="settings-item-header">
|
||||
<label class="settings-item-label">代码高亮</label>
|
||||
<span class="settings-item-description">启用代码语法高亮</span>
|
||||
</div>
|
||||
<label class="settings-switch">
|
||||
<input type="checkbox" id="syntaxHighlightCheckbox" checked>
|
||||
<span class="settings-switch-slider"></span>
|
||||
</label>
|
||||
<input type="text" class="settings-input-text" id="backendUrlInput" placeholder="https://iccoder.com">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -176,6 +116,21 @@ export function getGeneralSettingsComponentStyles(): string {
|
||||
border-color: var(--vscode-focusBorder);
|
||||
}
|
||||
|
||||
.settings-input-text {
|
||||
width: 300px;
|
||||
padding: 6px 12px;
|
||||
background: var(--vscode-input-background);
|
||||
color: var(--vscode-input-foreground);
|
||||
border: 1px solid var(--vscode-input-border);
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.settings-input-text:focus {
|
||||
border-color: var(--vscode-focusBorder);
|
||||
}
|
||||
|
||||
.settings-switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
@ -270,57 +225,37 @@ export function getGeneralSettingsComponentScript(): string {
|
||||
// 保存通用设置
|
||||
function saveGeneralSettings() {
|
||||
const settings = {
|
||||
theme: document.getElementById('themeSelect').value,
|
||||
language: document.getElementById('languageSelect').value,
|
||||
autoSave: document.getElementById('autoSaveCheckbox').checked,
|
||||
showTimestamp: document.getElementById('showTimestampCheckbox').checked,
|
||||
fontSize: document.getElementById('fontSizeInput').value,
|
||||
syntaxHighlight: document.getElementById('syntaxHighlightCheckbox').checked,
|
||||
backendUrl: document.getElementById('backendUrlInput').value,
|
||||
};
|
||||
|
||||
// 发送消息到扩展
|
||||
vscode.postMessage({
|
||||
command: 'saveGeneralSettings',
|
||||
settings: settings
|
||||
});
|
||||
|
||||
// 显示保存成功提示
|
||||
console.log('通用设置已保存', settings);
|
||||
closeSettingsModal();
|
||||
}
|
||||
|
||||
// 重置通用设置
|
||||
function resetGeneralSettings() {
|
||||
document.getElementById('themeSelect').value = 'auto';
|
||||
document.getElementById('languageSelect').value = 'zh-CN';
|
||||
document.getElementById('autoSaveCheckbox').checked = true;
|
||||
document.getElementById('showTimestampCheckbox').checked = false;
|
||||
document.getElementById('fontSizeInput').value = '14';
|
||||
document.getElementById('syntaxHighlightCheckbox').checked = true;
|
||||
document.getElementById('backendUrlInput').value = '';
|
||||
|
||||
// 清空保存的配置
|
||||
vscode.postMessage({
|
||||
command: 'saveGeneralSettings',
|
||||
settings: { backendUrl: '' }
|
||||
});
|
||||
|
||||
console.log('通用设置已重置为默认值');
|
||||
closeSettingsModal();
|
||||
}
|
||||
|
||||
// 加载通用设置
|
||||
function loadGeneralSettings(settings) {
|
||||
if (!settings) return;
|
||||
|
||||
if (settings.theme) {
|
||||
document.getElementById('themeSelect').value = settings.theme;
|
||||
}
|
||||
if (settings.language) {
|
||||
document.getElementById('languageSelect').value = settings.language;
|
||||
}
|
||||
if (settings.autoSave !== undefined) {
|
||||
document.getElementById('autoSaveCheckbox').checked = settings.autoSave;
|
||||
}
|
||||
if (settings.showTimestamp !== undefined) {
|
||||
document.getElementById('showTimestampCheckbox').checked = settings.showTimestamp;
|
||||
}
|
||||
if (settings.fontSize) {
|
||||
document.getElementById('fontSizeInput').value = settings.fontSize;
|
||||
}
|
||||
if (settings.syntaxHighlight !== undefined) {
|
||||
document.getElementById('syntaxHighlightCheckbox').checked = settings.syntaxHighlight;
|
||||
if (settings.backendUrl) {
|
||||
document.getElementById('backendUrlInput').value = settings.backendUrl;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@ -203,6 +203,8 @@ export function getSettingsComponentScript(): string {
|
||||
const modal = document.getElementById('settingsModal');
|
||||
if (modal) {
|
||||
modal.classList.add('active');
|
||||
// 请求加载设置
|
||||
vscode.postMessage({ command: 'loadGeneralSettings' });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -9,57 +9,7 @@
|
||||
*/
|
||||
export function getUserInfoComponentContent(): string {
|
||||
return `
|
||||
<div class="user-info-wrapper">
|
||||
<!-- 用户详情下拉面板 -->
|
||||
<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 class="user-info-wrapper" style="display: none;">
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -903,6 +903,13 @@ export function getWebviewContent(
|
||||
}
|
||||
break;
|
||||
|
||||
case 'loadedGeneralSettings':
|
||||
// 加载通用设置
|
||||
if (typeof loadGeneralSettings === 'function') {
|
||||
loadGeneralSettings(message.settings);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
console.log('[WebView] 未处理的消息类型:', message.command);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user