diff --git a/src/panels/ICHelperPanel.ts b/src/panels/ICHelperPanel.ts index e2906ca..3574b16 100644 --- a/src/panels/ICHelperPanel.ts +++ b/src/panels/ICHelperPanel.ts @@ -162,7 +162,8 @@ export async function showICHelperPanel( userId: userInfo.userId, nickname: userInfo.nickname, username: userInfo.username, - credits: userInfo.credits + credits: userInfo.credits, + membership: userInfo.membership }, tierIconUrl: tierIconUrl }; @@ -511,6 +512,20 @@ export async function showICHelperPanel( hasWorkspace: hasWorkspace, }); break; + case "openExternalUrl": + // 打开外部链接 + if (message.url) { + vscode.env.openExternal(vscode.Uri.parse(message.url)); + } + break; + case "openICCoder": + // 打开 IC Coder 官网 + vscode.env.openExternal(vscode.Uri.parse('https://www.iccoder.com')); + break; + case "logout": + // 退出登录(前端已有确认对话框) + vscode.commands.executeCommand('iccoder.logout'); + break; } }, undefined, diff --git a/src/views/ICViewProvider.ts b/src/views/ICViewProvider.ts index 894b00c..a451677 100644 --- a/src/views/ICViewProvider.ts +++ b/src/views/ICViewProvider.ts @@ -217,6 +217,17 @@ export class ICViewProvider implements vscode.WebviewViewProvider { vscode.commands.executeCommand("ic-coder.openChat"); } else if (message.command === "login") { vscode.commands.executeCommand("ic-coder.login"); + } else if (message.command === "logout") { + // 退出登录(前端已有确认对话框) + vscode.commands.executeCommand('iccoder.logout'); + } else if (message.command === "openICCoder") { + // 打开 IC Coder 官网 + vscode.env.openExternal(vscode.Uri.parse('https://www.iccoder.com')); + } else if (message.command === "openExternalUrl") { + // 打开外部链接 + if (message.url) { + vscode.env.openExternal(vscode.Uri.parse(message.url)); + } } }, undefined, diff --git a/src/views/userInfoComponent.ts b/src/views/userInfoComponent.ts index 3c699ea..246f146 100644 --- a/src/views/userInfoComponent.ts +++ b/src/views/userInfoComponent.ts @@ -14,14 +14,20 @@ export function getUserInfoComponentContent(): string {
-
- - - + -
-
加载中...
- + +
@@ -30,13 +36,31 @@ export function getUserInfoComponentContent(): string { 剩余 Credits -
-
- +
+ 账户管理 + 退出登录
+ + +
+
+
+
+

确认退出

+
+
+

确定要退出登录吗?

+
+ +
+
`; } @@ -87,12 +111,18 @@ export function getUserInfoComponentStyles(): string { .user-detail-header { padding: 16px; display: flex; - align-items: center; + flex-direction: column; gap: 12px; background: linear-gradient(135deg, rgba(0, 122, 204, 0.1) 0%, rgba(88, 166, 255, 0.05) 100%); border-bottom: 1px solid var(--vscode-widget-border); } + .user-info-row { + display: flex; + align-items: center; + gap: 12px; + } + .user-avatar-small { width: 26px; height: 26px; @@ -175,6 +205,19 @@ export function getUserInfoComponentStyles(): string { margin-bottom: 0; } + .logout-item { + cursor: pointer; + } + + .logout-item:hover { + background: var(--vscode-list-hoverBackground); + border-color: rgba(204, 0, 0, 0.3); + } + + .logout-item:hover .logout-link { + color: #f48771; + } + .detail-label { font-size: 12px; font-weight: 500; @@ -191,6 +234,11 @@ export function getUserInfoComponentStyles(): string { gap: 6px; } + .logout-link { + color: var(--vscode-foreground); + transition: color 0.2s ease; + } + .tier-icon-large { height: 20px; object-fit: contain; @@ -204,28 +252,133 @@ export function getUserInfoComponentStyles(): string { border-radius: 4px; } - .logout { + .upgrade-pro-wrapper { margin-top: 8px; } - .logout-btn { + .upgrade-pro-btn { width: 100%; - padding: 8px 12px; - background: var(--vscode-button-background); - color: var(--vscode-button-foreground); + padding: 6px 12px; + background: linear-gradient(135deg, #007acc 0%, #58a6ff 100%); + color: #ffffff; border: none; - border-radius: 6px; + border-radius: 4px; cursor: pointer; + font-size: 11px; + font-weight: 600; + transition: all 0.2s ease; + box-shadow: 0 1px 4px rgba(0, 122, 204, 0.2); + letter-spacing: 0.3px; + } + + .upgrade-pro-btn:hover { + background: linear-gradient(135deg, #0098ff 0%, #6bb6ff 100%); + box-shadow: 0 2px 8px rgba(0, 122, 204, 0.4); + transform: translateY(-1px); + } + + .upgrade-pro-btn:active { + transform: translateY(0) scale(0.98); + box-shadow: 0 1px 4px rgba(0, 122, 204, 0.3); + } + + /* 退出登录确认对话框 */ + .logout-confirm-modal { + display: none; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 20000; + } + + .logout-confirm-modal.active { + display: block; + } + + .logout-confirm-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + } + + .logout-confirm-content { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: var(--vscode-editor-background); + border: 1px solid var(--vscode-widget-border); + border-radius: 8px; + min-width: 320px; + max-width: 400px; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); + } + + .logout-confirm-header { + padding: 16px 20px; + border-bottom: 1px solid var(--vscode-widget-border); + } + + .logout-confirm-header h3 { + margin: 0; + font-size: 14px; + font-weight: 600; + color: var(--vscode-foreground); + } + + .logout-confirm-body { + padding: 20px; + } + + .logout-confirm-body p { + margin: 0; + font-size: 13px; + color: var(--vscode-foreground); + line-height: 1.5; + } + + .logout-confirm-footer { + padding: 12px 20px; + display: flex; + justify-content: flex-end; + gap: 8px; + border-top: 1px solid var(--vscode-widget-border); + } + + .logout-confirm-btn { + padding: 6px 16px; + border: none; + border-radius: 4px; font-size: 12px; font-weight: 500; + cursor: pointer; transition: all 0.2s ease; } - .logout-btn:hover { - background: var(--vscode-button-hoverBackground); + .logout-cancel-btn { + background: var(--vscode-button-secondaryBackground); + color: var(--vscode-button-secondaryForeground); } - .logout-btn:active { + .logout-cancel-btn:hover { + background: var(--vscode-button-secondaryHoverBackground); + } + + .logout-ok-btn { + background: #f48771; + color: #ffffff; + } + + .logout-ok-btn:hover { + background: #e67361; + } + + .logout-confirm-btn:active { transform: scale(0.98); } `; @@ -264,8 +417,28 @@ export function getUserInfoComponentScript(): string { // 退出登录 function logout() { - console.log("退出登录"); + console.log("显示退出登录确认对话框"); + // 显示确认对话框 + const modal = document.getElementById('logoutConfirmModal'); + if (modal) { + modal.classList.add('active'); + } + } + + // 确认退出登录 + function confirmLogout() { + console.log("确认退出登录"); vscode.postMessage({ command: 'logout' }); + // 关闭确认对话框 + closeLogoutConfirmModal(); + } + + // 关闭退出登录确认对话框 + function closeLogoutConfirmModal() { + const modal = document.getElementById('logoutConfirmModal'); + if (modal) { + modal.classList.remove('active'); + } } // 跳转到 IC Coder 官网 @@ -274,6 +447,12 @@ export function getUserInfoComponentScript(): string { vscode.postMessage({ command: 'openICCoder' }); } + // 升级到Pro + function upgradeToPro() { + console.log("升级到 Pro - 跳转到 IC Coder 官网"); + vscode.postMessage({ command: 'openExternalUrl', url: 'https://www.iccoder.com' }); + } + // 关闭用户详情下拉面板 function closeUserDetailModal() { const dropdown = document.getElementById('userDetailDropdown'); @@ -320,6 +499,19 @@ export function getUserInfoComponentScript(): string { } else { console.warn('[UserInfoComponent] creditsDetail 元素未找到'); } + + // 显示或隐藏升级到Pro按钮 (仅BASIC会员显示) + const upgradeProWrapper = document.getElementById('upgradeProWrapper'); + const tierCode = currentUserInfo.membership?.tierCode; + if (upgradeProWrapper) { + if (tierCode === 'BASIC') { + upgradeProWrapper.style.display = 'block'; + } else { + upgradeProWrapper.style.display = 'none'; + } + } else { + console.warn('[UserInfoComponent] upgradeProWrapper 元素未找到'); + } } // 更新用户信息显示 @@ -335,14 +527,48 @@ export function getUserInfoComponentScript(): string { // 绑定下拉面板事件 document.addEventListener('DOMContentLoaded', () => { - // 绑定退出登录按钮 - const logoutBtn = document.getElementById('logoutBtn'); - if (logoutBtn) { - logoutBtn.addEventListener('click', () => { + // 绑定退出登录卡片点击事件 + const logoutItem = document.getElementById('logoutItem'); + if (logoutItem) { + logoutItem.addEventListener('click', () => { logout(); }); } + // 绑定退出登录确认对话框按钮 + const logoutOkBtn = document.getElementById('logoutOkBtn'); + if (logoutOkBtn) { + logoutOkBtn.addEventListener('click', () => { + confirmLogout(); + }); + } + + const logoutCancelBtn = document.getElementById('logoutCancelBtn'); + if (logoutCancelBtn) { + logoutCancelBtn.addEventListener('click', () => { + closeLogoutConfirmModal(); + }); + } + + // 点击遮罩层关闭对话框 + const logoutConfirmModal = document.getElementById('logoutConfirmModal'); + if (logoutConfirmModal) { + const overlay = logoutConfirmModal.querySelector('.logout-confirm-overlay'); + if (overlay) { + overlay.addEventListener('click', () => { + closeLogoutConfirmModal(); + }); + } + } + + // 绑定升级到Pro按钮 + const upgradeProBtn = document.getElementById('upgradeProBtn'); + if (upgradeProBtn) { + upgradeProBtn.addEventListener('click', () => { + upgradeToPro(); + }); + } + // 绑定头像点击事件 const userAvatar = document.getElementById('userAvatarClickable'); if (userAvatar) { diff --git a/src/views/webviewContent.ts b/src/views/webviewContent.ts index 58eee04..78cf0ea 100644 --- a/src/views/webviewContent.ts +++ b/src/views/webviewContent.ts @@ -607,11 +607,13 @@ export function getWebviewContent( tierName: message.userInfo.tierName, tierIconUrl: message.tierIconUrl, registerTime: message.userInfo.registerTime || message.userInfo.createdAt, - credits: message.userInfo.credits + credits: message.userInfo.credits, + membership: message.userInfo.membership }; console.log('[WebView] 显示用户信息:', userInfoData); console.log('[WebView] userInfoData.credits:', userInfoData.credits); + console.log('[WebView] userInfoData.membership:', userInfoData.membership); // 调用更新用户头像图标按钮的函数 if (typeof updateUserAvatarIconButton === 'function') {