feat:用户信息和会员展示到页面上

This commit is contained in:
Roe-xin
2026-01-09 17:21:42 +08:00
parent c58e3603de
commit a85a044a9b
4 changed files with 381 additions and 53 deletions

View File

@ -0,0 +1,287 @@
/**
* 用户信息组件
* 包含用户头像、昵称、会员等级等信息
*/
/**
* 获取用户信息组件的 HTML 内容
* 只包含用户详情下拉面板,不包含触发按钮
*/
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-avatar-small">
<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" id="userDetailName">加载中...</div>
<img class="tier-icon-inline" id="tierIconInline" style="display: none;" />
</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>
</div>
</div>
</div>
`;
}
/**
* 获取用户信息组件的 CSS 样式
*/
export function getUserInfoComponentStyles(): string {
return `
.user-info-wrapper {
position: relative;
}
/* 用户详情下拉面板 */
.user-detail-dropdown {
display: none;
position: absolute;
top: calc(100% + 8px);
right: 0;
z-index: 10000;
min-width: 250px;
max-width: 320px;
}
.user-detail-dropdown.active {
display: block;
animation: dropdownSlideIn 0.2s ease-out;
}
@keyframes dropdownSlideIn {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.user-detail-content {
background: var(--vscode-sideBar-background);
border: 1px solid var(--vscode-widget-border);
border-radius: 8px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
overflow: hidden;
}
.user-detail-header {
padding: 16px;
display: flex;
align-items: center;
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-avatar-small {
width: 26px;
height: 26px;
flex-shrink: 0;
background: linear-gradient(135deg, #007acc 0%, #58a6ff 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 8px rgba(0, 122, 204, 0.3);
}
.user-avatar-small svg {
width: 18px;
height: 18px;
color: #ffffff;
}
.user-name-tier {
flex: 1;
display: flex;
align-items: center;
gap: 8px;
}
.user-detail-name {
font-size: 14px;
font-weight: 600;
color: var(--vscode-foreground);
}
.tier-icon-inline {
height: 26px;
object-fit: contain;
}
.user-detail-body {
padding: 12px;
background: var(--vscode-sideBar-background);
}
.user-detail-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 12px;
margin-bottom: 6px;
background: var(--vscode-editor-background);
border-radius: 6px;
border: 1px solid var(--vscode-widget-border);
transition: all 0.2s ease;
}
.user-detail-item:hover {
background: var(--vscode-list-hoverBackground);
border-color: rgba(0, 122, 204, 0.3);
}
.user-detail-item:last-child {
margin-bottom: 0;
}
.detail-label {
font-size: 12px;
font-weight: 500;
color: var(--vscode-descriptionForeground);
opacity: 0.8;
}
.detail-value {
font-size: 12px;
font-weight: 500;
color: var(--vscode-foreground);
display: flex;
align-items: center;
gap: 6px;
}
.tier-icon-large {
height: 20px;
object-fit: contain;
}
.tier-icon {
width: 110px;
height: 35px;
flex-shrink: 0;
object-fit: contain;
border-radius: 4px;
}
`;
}
/**
* 获取用户信息组件的 JavaScript 脚本
*/
export function getUserInfoComponentScript(): string {
return `
// 用户信息数据
let currentUserInfo = null;
// 切换用户详情下拉面板
function openUserDetailModal() {
const dropdown = document.getElementById('userDetailDropdown');
const userButton = document.getElementById('userAvatarIconButton');
if (dropdown) {
const isActive = dropdown.classList.contains('active');
if (isActive) {
dropdown.classList.remove('active');
if (userButton) {
userButton.classList.remove('active');
}
} else {
dropdown.classList.add('active');
if (userButton) {
userButton.classList.add('active');
}
// 更新下拉面板中的用户信息
updateUserDetailModal();
}
}
}
// 关闭用户详情下拉面板
function closeUserDetailModal() {
const dropdown = document.getElementById('userDetailDropdown');
const userButton = document.getElementById('userAvatarIconButton');
if (dropdown) {
dropdown.classList.remove('active');
}
if (userButton) {
userButton.classList.remove('active');
}
}
// 更新用户详情下拉面板内容
function updateUserDetailModal() {
if (!currentUserInfo) {
return;
}
// 更新用户名
const userDetailName = document.getElementById('userDetailName');
if (userDetailName) {
userDetailName.textContent = currentUserInfo.nickname || '未知用户';
}
// 更新会员等级图标(显示在用户名旁边)
const tierIconInline = document.getElementById('tierIconInline');
if (tierIconInline && currentUserInfo.tierIconUrl) {
tierIconInline.src = currentUserInfo.tierIconUrl;
tierIconInline.style.display = 'block';
} else if (tierIconInline) {
tierIconInline.style.display = 'none';
}
// 更新剩余 Credits
const creditsDetail = document.getElementById('creditsDetail');
if (creditsDetail) {
creditsDetail.textContent = currentUserInfo.credits !== undefined ? currentUserInfo.credits.toString() : '-';
}
}
// 更新用户信息显示
function updateUserInfoDisplay(userInfo) {
currentUserInfo = userInfo;
}
// 绑定下拉面板事件
document.addEventListener('DOMContentLoaded', () => {
// 点击页面其他地方关闭下拉面板
document.addEventListener('click', (e) => {
const dropdown = document.getElementById('userDetailDropdown');
const userButton = document.getElementById('userAvatarIconButton');
if (dropdown && dropdown.classList.contains('active')) {
// 如果点击的不是用户按钮和下拉面板内容,则关闭
if (!userButton?.contains(e.target) && !dropdown.contains(e.target)) {
closeUserDetailModal();
}
}
});
// 阻止下拉面板内容点击事件冒泡
const dropdownContent = document.querySelector('.user-detail-content');
if (dropdownContent) {
dropdownContent.addEventListener('click', (e) => {
e.stopPropagation();
});
}
});
`;
}