跳到主要内容

员工账号(Portal 用户管理)

管理使用 SayClaw 的员工账号。员工通过 Portal 登录后使用 AI 实例,Admin 后台可创建/停用员工、分配实例、设置配额。

最后更新:2026-03-09


1. 数据模型

员工账号存储在 sayclaw_portal.users 表,与 Admin 账号(sayclaw_admin.admin_users)是独立体系。

字段说明
idUUID
email登录邮箱(唯一)
name姓名
department部门
statusactive / revoked
quota_daily日配额(token 数)
password_hashSHA256 密码哈希

关联关系

users (Portal)
└── user_instances (多对多)
└── oc_instances (Admin)

一个员工可以绑定多个 OC 实例。


2. API

员工列表

GET /api/v1/users

返回所有员工,自动 JOIN 关联实例信息:

{
"list": [{
"id": "xxx",
"email": "[email protected]",
"name": "张三",
"department": "技术部",
"status": "active",
"quota_daily": 100000,
"instance_id": "oc-ai-jp-2-01",
"instance_name": "实例01",
"instance_model": "gpt-4o",
"total_tokens": 52340,
"total_requests": 128,
"est_cost_usd": 0.15
}]
}

注意:est_cost_usd 是根据 total_tokens × 模型单价 估算的近似值。

创建员工

POST /api/v1/users
Body: { email, name, department, password }
  • password 使用 SHA256 存储
  • 创建后状态为 active

更新员工

PATCH /api/v1/users/:id
Body: { name?, department?, status?, quota_daily? }
  • status 设为 revoked 即停用
  • quota_daily 单位为 token 数

删除员工

DELETE /api/v1/users/:id

软删除(设 revoked_at)。

分配实例

POST /api/v1/users/:id/assign-instance
Body: { instance_id }

将指定 OC 实例分配给该员工。写入 user_instances 表(ON DUPLICATE KEY 幂等)。


3. 费用估算逻辑

代码中 estimateCostUSD 按模型和 token 数估算费用:

tokenPricesPer1K = map[string]float64{
"gpt-4o": 0.0025,
"gpt-4o-mini": 0.00015,
"claude-opus-4-6": 0.015,
"claude-sonnet-4-6": 0.003,
"default": 0.002,
}
cost = totalTokens / 1000 × pricePerK

4. 数据库

-- sayclaw_portal.users
CREATE TABLE users (
id VARCHAR(64) PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(100),
department VARCHAR(100),
status VARCHAR(20) DEFAULT 'active',
quota_daily BIGINT DEFAULT 0,
password_hash VARCHAR(255),
google_id VARCHAR(255),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
revoked_at DATETIME
);

-- sayclaw_portal.user_instances
CREATE TABLE user_instances (
user_id VARCHAR(64) NOT NULL,
instance_id VARCHAR(128) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (user_id, instance_id)
);