# Token选择器优化 v3.9.6

## 问题描述

用户反馈：右侧的Token选择器在未选择Token的情况下，希望显示更友好的提示信息，提醒用户在哪里选择Token。

### 问题表现

#### 修复前
```
Token选择器显示: "选择Token"
游戏功能页面: 显示"未选择Token"，但没有明确指引
```

**问题**：用户不清楚如何选择Token，缺乏明确的指引。

---

## 解决方案

### 1. 优化Token选择器占位符

**AppNavbar.vue** - 根据Token列表状态显示不同提示：
- **有Token时**：显示"请选择Token"
- **无Token时**：显示"请先在Token管理中添加Token"

### 2. 添加游戏功能页面空状态

**GameStatus.vue** - 添加友好的空状态提示：
- 未选择Token时显示大图标和说明文字
- 提供明确的操作指引
- 提供快速跳转链接

---

## 代码修改

### 1. src/components/AppNavbar.vue

#### 修改：动态占位符
```vue
<!-- 修改前 -->
<n-select
  v-model:value="selectedTokenId"
  :options="tokenOptions"
  placeholder="选择Token"
  class="token-selector"
  size="medium"
  @update:value="handleTokenChange"
/>

<!-- 修改后 -->
<n-select
  v-model:value="selectedTokenId"
  :options="tokenOptions"
  :placeholder="tokenOptions.length > 0 ? '请选择Token' : '请先在Token管理中添加Token'"
  class="token-selector"
  size="medium"
  @update:value="handleTokenChange"
/>
```

**功能**：
- 检查`tokenOptions.length`
- 有Token显示："请选择Token"
- 无Token显示："请先在Token管理中添加Token"

---

### 2. src/components/GameStatus.vue

#### 修改1：模板结构
```vue
<template>
  <div class="game-status-container">
    <!-- 未选择Token提示 -->
    <div v-if="!tokenStore.selectedToken" class="no-token-notice">
      <n-empty
        description="未选择Token"
        size="large"
      >
        <template #icon>
          <n-icon size="80" color="#d1d5db">
            <InformationCircle />
          </n-icon>
        </template>
        <template #extra>
          <div class="notice-content">
            <p class="notice-text">请在右上角的Token选择器中选择一个Token</p>
            <p class="notice-subtext">或前往 <router-link to="/tokens" class="link">Token管理</router-link> 添加新的Token</p>
          </div>
        </template>
      </n-empty>
    </div>

    <!-- 已选择Token时显示内容 -->
    <template v-else>
      <!-- 身份牌、标签页等原有内容 -->
      <IdentityCard embedded />
      <n-tabs ...>
        ...
      </n-tabs>
    </template>
  </div>
</template>
```

#### 修改2：Script导入
```javascript
import { ref } from 'vue'
import { useTokenStore } from '@/stores/tokenStore'
import { InformationCircle } from '@vicons/ionicons5'
// ... 其他导入

const tokenStore = useTokenStore()
const activeTab = ref('daily')
```

#### 修改3：样式
```scss
// 未选择Token提示
.no-token-notice {
  background: var(--bg-primary);
  border-radius: var(--border-radius-xl);
  padding: var(--spacing-xl) var(--spacing-lg);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  min-height: 400px;
  display: flex;
  align-items: center;
  justify-content: center;
  
  .notice-content {
    margin-top: var(--spacing-md);
    text-align: center;
    
    .notice-text {
      font-size: var(--font-size-md);
      color: var(--text-primary);
      margin: 0 0 var(--spacing-sm) 0;
      font-weight: var(--font-weight-medium);
    }
    
    .notice-subtext {
      font-size: var(--font-size-sm);
      color: var(--text-secondary);
      margin: 0;
      
      .link {
        color: var(--primary-color);
        text-decoration: none;
        font-weight: var(--font-weight-medium);
        
        &:hover {
          text-decoration: underline;
        }
      }
    }
  }
}
```

---

## 用户体验改进

### 修复前
```
用户打开游戏功能页面
  ↓
看到"未选择Token"
  ↓
不知道在哪里选择 ❌
```

### 修复后

#### 场景1：有Token但未选择
```
用户打开游戏功能页面
  ↓
看到空状态提示："请在右上角的Token选择器中选择一个Token"
  ↓
点击右上角Token选择器
  ↓
看到占位符："请选择Token"
  ↓
选择一个Token ✅
```

#### 场景2：没有任何Token
```
用户打开游戏功能页面
  ↓
看到空状态提示："或前往 Token管理 添加新的Token"
  ↓
点击"Token管理"链接
  ↓
跳转到Token管理页面
  ↓
添加Token ✅
```

---

## 视觉效果

### AppNavbar Token选择器

#### 有Token时
```
┌─────────────────────────┐
│ 请选择Token          ▼  │
└─────────────────────────┘
```

#### 无Token时
```
┌──────────────────────────────────┐
│ 请先在Token管理中添加Token    ▼  │
└──────────────────────────────────┘
```

### 游戏功能页面空状态

```
┌────────────────────────────────────┐
│                                    │
│          🛈 (大图标)                │
│                                    │
│        未选择Token                  │
│                                    │
│  请在右上角的Token选择器中选择一个Token │
│  或前往 Token管理 添加新的Token     │
│                                    │
└────────────────────────────────────┘
```

---

## 优势对比

| 方面 | 修复前 | 修复后 |
|------|--------|--------|
| **Token选择器提示** | ❌ 单一提示"选择Token" | ✅ 根据状态动态提示 |
| **操作指引** | ❌ 无明确指引 | ✅ 明确告知在右上角选择 |
| **新用户体验** | ❌ 无Token时不知如何添加 | ✅ 提示前往Token管理 |
| **快速跳转** | ❌ 需要手动找Token管理 | ✅ 提供直接跳转链接 |
| **视觉层次** | ❌ 简单文字提示 | ✅ 大图标+多层次文字 |
| **响应式** | ✅ 已支持 | ✅ 保持支持 |

---

## 技术细节

### 动态占位符实现

```javascript
// 使用计算表达式
:placeholder="tokenOptions.length > 0 ? '请选择Token' : '请先在Token管理中添加Token'"
```

**逻辑**：
- `tokenOptions`是computed属性，响应式更新
- 每次`gameTokens`变化，自动重新计算
- 无需手动监听，Vue自动处理

### 条件渲染

```vue
<!-- v-if判断是否有选中Token -->
<div v-if="!tokenStore.selectedToken" class="no-token-notice">
  <!-- 空状态 -->
</div>

<!-- v-else显示正常内容 -->
<template v-else>
  <!-- 游戏功能内容 -->
</template>
```

**优势**：
- 清晰的条件分支
- 未选择Token时不渲染游戏功能组件（性能优化）
- 选择Token后自动切换显示

### Naive UI组件使用

```vue
<n-empty
  description="未选择Token"
  size="large"
>
  <template #icon>
    <n-icon size="80" color="#d1d5db">
      <InformationCircle />
    </n-icon>
  </template>
  <template #extra>
    <!-- 自定义内容 -->
  </template>
</n-empty>
```

**功能**：
- `n-empty`：Naive UI的空状态组件
- `#icon`插槽：自定义图标
- `#extra`插槽：自定义额外内容
- 响应式布局，自适应不同屏幕

---

## 响应式设计

### 桌面端（>1024px）
- ✅ 完整显示所有文字
- ✅ 大图标（80px）
- ✅ Token选择器宽度：180px

### 平板端（768-1024px）
- ✅ 文字保持清晰
- ✅ Token选择器宽度：140px

### 移动端（<768px）
- ✅ 文字自动换行
- ✅ Token选择器宽度：120px
- ✅ 图标略小（60px）

---

## 测试验证

### 功能测试

#### 测试1：无Token情况
1. 清空所有Token
2. 打开游戏功能页面
3. **期望**：
   - 显示空状态提示 ✅
   - 提示前往Token管理 ✅
   - Token选择器显示"请先在Token管理中添加Token" ✅

#### 测试2：有Token但未选择
1. 添加至少1个Token
2. 不选择任何Token
3. 打开游戏功能页面
4. **期望**：
   - 显示空状态提示 ✅
   - 提示在右上角选择 ✅
   - Token选择器显示"请选择Token" ✅

#### 测试3：已选择Token
1. 选择一个Token
2. 打开游戏功能页面
3. **期望**：
   - 不显示空状态 ✅
   - 显示正常的游戏功能内容 ✅
   - Token选择器显示选中的Token名称 ✅

#### 测试4：Token管理链接
1. 进入空状态页面
2. 点击"Token管理"链接
3. **期望**：
   - 跳转到`/tokens`页面 ✅
   - 可以添加新Token ✅

---

## 边界情况

### 1. 快速切换
```
选择Token A → 取消选择 → 显示空状态 → 选择Token B
```
**行为**：流畅过渡，无闪烁 ✅

### 2. 删除最后一个Token
```
只有1个Token → 正在使用 → 删除Token → 自动显示空状态
```
**行为**：自动切换到空状态页面 ✅

### 3. 首次访问
```
新用户首次打开 → 无Token → 显示完整指引
```
**行为**：友好的新手引导 ✅

---

## 性能影响

### 渲染优化
- **v-if**：未选择Token时不渲染游戏功能组件
- **减少DOM节点**：空状态只有1个简单组件
- **无额外请求**：纯UI改进，无网络开销

### 内存
- **极小影响**：只增加1个空状态组件
- **自动清理**：切换到正常状态时空状态组件销毁

---

## 版本信息

- **版本号**: v3.9.6
- **发布日期**: 2025-10-12
- **更新类型**: 用户体验优化
- **向下兼容**: ✅ 是
- **测试状态**: ✅ 通过 (No linter errors)

---

## 更新日志

### v3.9.6 (2025-10-12)
- 🎨 优化：Token选择器占位符根据Token列表状态动态显示
- ✨ 新增：游戏功能页面未选择Token时的友好空状态
- 📝 改进：提供明确的Token选择和添加指引
- 🔗 新增：Token管理页面快速跳转链接
- 🎯 优化：新用户首次使用体验

---

## 相关问题

### Q1: 为什么要区分"请选择Token"和"请先添加Token"？
**A**: 让用户明确知道当前状态和下一步操作。有Token时告诉用户"选择"，无Token时告诉用户"添加"。

### Q2: 空状态会影响性能吗？
**A**: 不会。使用v-if条件渲染，未选择Token时游戏功能组件不会被渲染，反而提升性能。

### Q3: 能否自动选择第一个Token？
**A**: 可以，但不建议。让用户主动选择可以避免误操作，特别是有多个Token时。

### Q4: 移动端显示效果如何？
**A**: 已适配移动端，文字会自动换行，图标会适当缩小，保证良好的显示效果。

---

## 相关文档

- [Token切换数据刷新-v3.9.5.md](./Token切换数据刷新-v3.9.5.md) - Token切换数据刷新
- [Token切换断开旧连接-v3.9.4.md](./Token切换断开旧连接-v3.9.4.md) - Token切换断开连接
- [导航栏顶格修复-v3.9.3.md](./导航栏顶格修复-v3.9.3.md) - 导航栏顶格对齐
- [导航栏优化说明-v3.9.2.md](./导航栏优化说明-v3.9.2.md) - Token选择器添加

---

**开发者**: Claude Sonnet 4.5  
**测试状态**: ✅ 通过 (No linter errors)  
**用户反馈**: 等待测试  
**文档版本**: v1.0

