Portal 前端
员工 AI 工作台,部署于 https://app.sayclaw.ai
最后更新:2026-03-05
功能模块
| 模块 | 说明 |
|---|---|
| 登录 | 邮箱密码 + Google OAuth SSO |
| 我的实例 | 查看绑定到自己的 OC 实例,支持认领空闲实例 |
| Telegram 绑定 | 每个实例独立配置 Bot Token + 允许用户 ID |
| AI 对话 | 直连 LiteLLM HTTP(绕过 Gateway),对话记录持久化 |
| 用量统计 | 近 30 天 Token 使用情况 |
| 应用市场 | 浏览和安装配置包 / 技能(一键安装到实例) |
| 配置包详情 | 点击「📄 详情」查看文件列表 + 内容预览 |
| 配置中心 | 查看当前实例的模板配置包 |
页面结构
桌面端(侧边栏导航)
侧边栏
├── 🖥️ 我的实例
├── 📊 用量统计
└── 🏪 应用市场
底部
└── 用户信息 + 退出登录
移动端(底部 Tab Bar)
底部 Tab Bar
├── 🖥️ 我的实例
├── 📊 用量统计
└── 🏪 应用市场
@media (max-width: 768px):侧边栏隐藏,显示底部 Tab Bar;实例卡片单列布局。
应用市场交互
技能卡片
- 「+ 安装」按钮 → 异步队列安装 → 轮询状态 → 「✅ 已安装」
配置包卡片
- 「📄 详情」按钮 → Modal 弹窗
- 左侧:文件列表(带
config/workspace标签) - 右侧:文件内容代码预览(等宽字体,可滚动)
- 左侧:文件列表(带
- 「+ 安装」按钮 → 同技能安装流程
AI 对话架构
Portal 前端(chat.html)
↓ POST /me/chat(带 instance_id)
portal-api (Go)
↓ POST http://35.243.76.69:4000/chat/completions
LiteLLM Proxy
↓ 路由到对应模型(GPT / Claude / Gemini)
AI Provider
- 对话记录持久化到
sayclaw_portal.chat_messages - Token 用量实时更新到
oc_instances.total_tokens(每次对话后UPDATE) - 按实例路由:通过 URL
?instanceId=xxx或默认取用户第一个绑定实例
实例认领规则
- 每人最多认领 1 个实例(
claimInstanceHandler强制校验) - 认领后 < 10s 自动初始化(
init_instanceWorker) - 空闲实例:
GET /instances/available查询(条件:deleted_at IS NULL且未绑定用户)
技术实现
- 框架:Vue 3(CDN 轻量版,无构建步骤,单文件 SPA)
- 样式:纯 CSS 自定义,深色主题,主色
#5B4FE8 - 状态:
reactive+ref,无 Vuex/Pinia - API:
fetch直接调用https://portal-api.sayclaw.ai/api/v1
部署
前端文件:/var/www/sayclaw-app/
├── index.html ← 主应用(登录 + Dashboard + 对话入口)
└── chat.html ← AI 对话页面
Nginx:/etc/nginx/sites-available/sayclaw-app
API:https://portal-api.sayclaw.ai/api/v1
已知限制
- Vue 3 CDN 版无 Tree-shaking,初次加载较慢(< 200KB gzip)
- 对话记录 localStorage 已改为服务端持久化,上限 5000 条/实例
- Google OAuth 回调需
auth-callback.html(非 Vite 构建产物,手动维护)
前端工程治理补充(2026-03-05)
- 若保留单页 SPA 方案,需明确其生命周期(临时/长期)。
- 生产分支禁止保留
.bak历史文件。