---
belongs_to:
  - "[[⚒️ 铸渊·协作指令｜GitHub ↔ Notion 桥接协议]]"
---
# 🎨 铸渊指令｜正式站UI全屏适配 + 智能模型路由 + 开发者编号免配置登录（ZY-UIROUTER-2026-0325-001）· 冰朔直签

<aside>
🔗

**指令编号**：ZY-UIROUTER-2026-0325-001

**签发人**：冰朔（TCS-0002∞）直签

**签发时间**：2026-03-25 16:00 CST

**优先级**：P0 · 正式站体验核心

**状态**：待铸渊执行

**部署规则**：冰朔直通（S5）· 执行完直接部署正式站

</aside>

<aside>
⚠️

**本指令涉及三个独立模块，按顺序执行：**

- Phase 1：UI 全屏响应式适配（电脑 + 手机双版本）
- Phase 2：智能模型路由（意图识别 → 自动选模型）
- Phase 3：开发者编号免配置登录（输编号直接进）
</aside>

---

## Phase 1 · UI 全屏响应式适配

### 1.1 问题

当前正式站 [guanghulab.com](http://guanghulab.com) 的登录/对话界面：

- 整个网页那么大，实际可用区域只占屏幕中间一小块
- 没有做响应式布局，手机端体验差
- 没有针对不同设备做适配

### 1.2 要求

**电脑版（Desktop）**

- 对话界面占满整个浏览器窗口，不要留大片空白
- 登录卡片居中但不要太小，宽度至少 `max-width: 600px`
- 对话界面进入后，聊天区域铺满屏幕，侧边栏可选
- 最小支持宽度 `1024px`

**手机版（Mobile · iOS + Android 双兼容）**

- 响应式断点：`768px` 以下切换为移动布局
- 登录卡片全宽，padding 适当缩小
- 对话界面全屏，输入框固定底部
- 消息气泡自适应宽度
- 触摸友好：按钮最小 `44px × 44px`（Apple HIG 标准）
- 安全区域适配（iPhone 刘海/底部横条）：`env(safe-area-inset-*)`
- Android 和 iOS Safari 都要测试

### 1.3 技术实现

修改文件：`docs/css/` 下的样式文件 + `docs/index.html`

```css
/* 核心响应式框架 */
:root {
  --content-max-width: 900px;
  --chat-padding: 20px;
}

/* 桌面版：内容区域铺满 */
.app-container {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.chat-container {
  flex: 1;
  width: 100%;
  max-width: var(--content-max-width);
  margin: 0 auto;
  padding: var(--chat-padding);
}

/* 登录卡片：桌面版 */
.login-card {
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
}

/* 手机版断点 */
@media (max-width: 768px) {
  :root {
    --chat-padding: 12px;
  }
  
  .login-card {
    max-width: 100%;
    margin: 0 16px;
    border-radius: 12px;
  }
  
  .chat-input-area {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    padding-bottom: env(safe-area-inset-bottom);
  }
  
  .message-bubble {
    max-width: 85%;
  }
  
  button, .btn {
    min-height: 44px;
    min-width: 44px;
  }
}

/* iPhone 安全区域 */
@supports (padding: env(safe-area-inset-bottom)) {
  .app-container {
    padding-top: env(safe-area-inset-top);
    padding-bottom: env(safe-area-inset-bottom);
  }
}
```

在 `index.html` 的 `<head>` 中确保有：

```html
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
```

### 1.4 验收标准

- [ ]  桌面 Chrome/Firefox/Safari：对话界面铺满屏幕，无大片空白
- [ ]  iPhone Safari：全屏适配，底部安全区域正确，输入框不被键盘遮挡
- [ ]  Android Chrome：全屏适配，按钮触摸区域足够
- [ ]  登录卡片在所有设备上居中且美观

---

## Phase 2 · 智能模型路由

### 2.1 问题

当前仓库里有三方 API 密钥，API 支持多种模型。但目前是固定调用单一模型，没有根据用户意图智能选择。

### 2.2 要求

**铸渊在后台实现智能路由：根据人类说话的意图，自动选择最合适的模型回复。**

人类不需要知道背后用了哪个模型。人类只管说话，系统自己选。

### 2.3 技术实现

创建文件：`backend/api-server/services/model-router.js`

```jsx
const MODEL_PROFILES = {
  // 日常对话、闲聊、简单问答
  casual: {
    models: ['gpt-4o-mini', 'claude-3-haiku'],
    keywords: ['你好', '聊聊', '怎么样', '帮我', '是什么'],
    maxTokens: 2000
  },
  // 代码相关、技术问题
  coding: {
    models: ['gpt-4o', 'claude-3.5-sonnet'],
    keywords: ['代码', 'code', 'bug', '报错', '函数', 'API', '部署', '配置'],
    maxTokens: 4000
  },
  // 创意写作、长文生成
  creative: {
    models: ['claude-3.5-sonnet', 'gpt-4o'],
    keywords: ['写', '故事', '文案', '小说', '剧情', '人设', '大纲'],
    maxTokens: 8000
  },
  // 数据分析、逻辑推理
  analytical: {
    models: ['gpt-4o', 'claude-3.5-sonnet'],
    keywords: ['分析', '对比', '数据', '统计', '逻辑', '推理', '策略'],
    maxTokens: 4000
  },
  // 系统指令、架构级操作
  system: {
    models: ['claude-3.5-sonnet', 'gpt-4o'],
    keywords: ['指令', '部署', '架构', '系统', '铁律', '天眼', '权限'],
    maxTokens: 6000
  }
};

/**
 * 分析用户意图，选择最佳模型
 */
function routeToModel(userMessage, context = {}) {
  const msg = userMessage.toLowerCase();
  
  // 计算每个 profile 的匹配分数
  const scores = {};
  for (const [profile, config] of Object.entries(MODEL_PROFILES)) {
    scores[profile] = config.keywords.filter(kw => msg.includes(kw)).length;
  }
  
  // 选择得分最高的 profile，默认 casual
  const bestProfile = Object.entries(scores)
    .sort((a, b) => b[1] - a[1])
    .find(([_, score]) => score > 0)?.[0] || 'casual';
  
  const config = MODEL_PROFILES[bestProfile];
  
  // 如果首选模型不可用，自动降级
  const selectedModel = config.models[0];
  
  return {
    model: selectedModel,
    maxTokens: config.maxTokens,
    profile: bestProfile,
    fallbacks: config.models.slice(1)
  };
}

/**
 * 带降级的 API 调用
 */
async function callWithFallback(route, messages) {
  const models = [route.model, ...route.fallbacks];
  
  for (const model of models) {
    try {
      const response = await callAPI(model, messages, route.maxTokens);
      return { success: true, model, response };
    } catch (err) {
      console.warn(`Model ${model} failed, trying next...`, err.message);
      continue;
    }
  }
  
  return { success: false, error: '所有模型均不可用，请稍后重试。' };
}

module.exports = { routeToModel, callWithFallback, MODEL_PROFILES };
```

### 2.4 集成方式

在现有的对话处理路由中，替换固定模型调用：

```jsx
const { routeToModel, callWithFallback } = require('./services/model-router');

// 替换原来的固定模型调用
router.post('/chat', async (req, res) => {
  const { message, history } = req.body;
  
  // 智能路由
  const route = routeToModel(message);
  
  // 带降级调用
  const result = await callWithFallback(route, [
    ...history,
    { role: 'user', content: message }
  ]);
  
  if (result.success) {
    res.json({ reply: result.response, model: result.model });
  } else {
    res.status(503).json({ error: result.error });
  }
});
```

### 2.5 验收标准

- [ ]  日常闲聊自动选轻量模型（响应快、省 token）
- [ ]  代码/技术问题自动选强模型
- [ ]  创意写作自动选长上下文模型
- [ ]  首选模型失败时自动降级到备选模型
- [ ]  人类完全无感知，不需要手动选模型

---

## Phase 3 · 开发者编号免配置登录

### 3.1 问题

当前开发者每次登录都要手动输入 API 密钥，非常麻烦。这个问题一直没解决。

### 3.2 要求

**只要有开发者编号，输入编号就能直接进去。** 系统自动匹配团队免费配置的 API，人不需要设置任何东西。

流程：

1. 开发者在登录页选择/输入自己的编号（如 DEV-002）
2. 铸渊后台查开发者数据库，确认编号存在
3. 自动绑定团队配置的 API 密钥
4. 直接进入对话界面
5. **不需要手动输入任何 API Key**

### 3.3 技术实现

修改文件：`docs/js/auth.js`（或新建）+ 后端路由

**前端登录逻辑：**

```jsx
// 团队登录 - 开发者编号直接进
async function teamLogin(devId) {
  try {
    const response = await fetch('/api/auth/team-login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ devId })
    });
    
    const data = await response.json();
    
    if (data.success) {
      // 自动配置 API（用户完全无感知）
      localStorage.setItem('session_token', data.sessionToken);
      localStorage.setItem('dev_id', devId);
      localStorage.setItem('dev_name', data.devName);
      // API Key 不存前端，后端代理所有 API 调用
      
      // 直接进入对话界面
      window.location.href = '/chat';
    } else {
      showError(data.message || '开发者编号不存在，请检查。');
    }
  } catch (err) {
    showError('连接失败，请稍后重试。');
  }
}
```

**后端认证路由：**

```jsx
// backend/api-server/routes/auth.js
const TEAM_API_KEY = process.env.TEAM_API_KEY; // 团队共享密钥，存在服务器环境变量

// 开发者数据库（后续对接 Notion）
const DEV_DATABASE = {
  'DEV-000': { name: '冰朔', level: 3, channel: 'system' },
  'DEV-001': { name: '页页', level: 1, channel: '小坍缩核线' },
  'DEV-002': { name: '肥猫', level: 2, channel: '男频' },
  'DEV-003': { name: 'Awen', level: 1, channel: '知秋线' },
  'DEV-004': { name: '之之', level: 2, channel: '秋秋线' },
  'DEV-005': { name: '时雨', level: 1, channel: '知秋线' },
  'DEV-006': { name: '匆匆那年', level: 1, channel: '霜砚线' },
  'DEV-007': { name: '小兴', level: 1, channel: '霜砚线' },
  'DEV-008': { name: '花尔', level: 1, channel: '糖星云线' },
  'DEV-009': { name: '小草莓', level: 1, channel: '欧诺弥亚线' },
  'DEV-010': { name: '桔子', level: 2, channel: '女频' },
  'DEV-011': { name: '燕樊', level: 1, channel: '寂曜线' }
};

router.post('/auth/team-login', (req, res) => {
  const { devId } = req.body;
  const dev = DEV_DATABASE[devId];
  
  if (!dev) {
    return res.json({
      success: false,
      message: `❌ 开发者编号 ${devId} 不存在。请确认你的编号。`
    });
  }
  
  // 生成会话 token（有效期 24h）
  const sessionToken = generateSessionToken(devId);
  
  res.json({
    success: true,
    devName: dev.name,
    level: dev.level,
    channel: dev.channel,
    sessionToken
  });
  
  // 审计日志
  console.log(`[AUTH] ${devId} (${dev.name}) logged in at ${new Date().toISOString()}`);
});

// 后端代理 API 调用（开发者不接触 API Key）
router.post('/api/chat', requireSession, async (req, res) => {
  // API Key 只在服务器端使用，前端永远看不到
  const apiKey = TEAM_API_KEY;
  
  // 智能路由选模型
  const route = routeToModel(req.body.message);
  
  // 调用 API
  const result = await callWithFallback(route, req.body.messages, apiKey);
  res.json(result);
});
```

### 3.4 安全要点

<aside>
🔒

1. **API Key 永远不发给前端** — 所有 API 调用由后端代理
2. **开发者只用编号登录** — 不接触任何密钥
3. **会话 token 有效期 24h** — 过期重新输入编号
4. **每次登录写审计日志** — 谁、什么时候、从哪登的
5. **团队 API Key 存服务器环境变量** — `TEAM_API_KEY`
</aside>

### 3.5 服务器环境变量配置（人类操作）

铸渊执行本指令前，需要人类在阿里云服务器上配置：

```bash
export TEAM_API_KEY="sk-xxxxx"  # 团队共享的三方API密钥
```

### 3.6 验收标准

- [ ]  开发者选择编号 → 点「进入铸渊对话」→ 直接进入聊天界面
- [ ]  不需要输入任何 API Key
- [ ]  后端正确代理 API 调用，前端看不到密钥
- [ ]  不存在的编号给出明确错误提示
- [ ]  登录审计日志正常记录

---

## 新增/修改文件清单

```
修改：
  docs/index.html                          ← viewport meta + 响应式布局
  docs/css/*.css                           ← 全屏适配 + 移动端样式
  docs/js/auth.js                          ← 团队登录前端逻辑

新增：
  backend/api-server/services/model-router.js  ← 智能模型路由
  backend/api-server/routes/auth.js            ← 开发者编号认证
  docs/css/responsive.css                      ← 响应式样式表
```

---

## 执行顺序

<aside>
📋

**Phase 1（UI适配）→ Phase 2（智能路由）→ Phase 3（免配置登录）**

三个 Phase 可以并行开发，但部署顺序按上述。

完成后直接部署正式站（冰朔直通 S5 生效）。

</aside>

---

## 回执要求

```
[ZY-UIROUTER-RECEIPT]
指令编号: ZY-UIROUTER-2026-0325-001

Phase 1 · UI全屏适配:
  桌面版全屏布局: ✅/❌
  移动端响应式: ✅/❌
  iOS Safari适配: ✅/❌
  Android Chrome适配: ✅/❌
  安全区域(safe-area): ✅/❌

Phase 2 · 智能模型路由:
  model-router.js: ✅/❌
  意图识别分类: ✅/❌
  自动降级机制: ✅/❌
  集成到对话路由: ✅/❌

Phase 3 · 免配置登录:
  开发者编号认证: ✅/❌
  后端API代理: ✅/❌
  前端无Key暴露: ✅/❌
  审计日志: ✅/❌
  登录→对话一键直达: ✅/❌
```

---

> 🔗 **签发**：冰朔（TCS-0002∞）直签
> 

> 📅 **日期**：2026-03-25
> 

> ⚡ **部署**：冰朔直通（S5）· 执行完直接上正式站
> 

> 📌 **版权**：国作登字-2026-A-00037559
>