管理后台
管理后台(webadmin)是 Go 服务端内嵌的单页应用,通过浏览器访问 /admin/。它负责管控:账号、部门、模型网关、计量计费、市场与共享内容审批、审计。员工接触不到它——所有管控决策都在这里收口。
会话与安全:管理员登录使用 session + CSRF 防护;登录限流只对失败计数(5 分钟滑动窗口,成功即清空):账号键 10 次,来源 IP 60 次(与客户端登录共用同一份按账号的失败预算);错误统一信封
{"error":{"code":"ERR_CODE","message":"..."}};健康探针/healthz。
侧栏按「管理 / 运维 / 审计」三个分区组织,条目按当前账号的 RBAC 权限点显示
(super_admin 全量;auditor 只有审计日志、用量中心与用户列表的只读视图):
| 分区 | 菜单 | 路径 | 职责 |
|---|---|---|---|
| 管理 | 用户 | /users | 账号、角色、状态、余额、重置密码 / 重置 MFA、登录令牌 |
| 管理 | 部门 | /departments | 部门树、成员(支持多部门) |
| 管理 | 认证 | /auth | 本地 / LDAP / OIDC 登录方式配置 |
| 运维 | 网关 | /gateway | 上游供应商、默认模型、限流、高峰时段、模型定价与用量策略 |
| 运维 | 网关文件 | /gateway-files | 网关 Files API 归属台账:按员工看占用、搜索排序与过期清理 |
| 运维 | 错误监控 | /error-monitoring | 客户端错误上报与 GlitchTip 连接器预填 |
| 运维 | 用量中心 | /usage | 总览、部门、成员、模型、明细、配额与预算、报表订阅 |
| 运维 | 能力中心 | /capabilities | 技能 / 智能体 / 审批三个 Tab(官方/精选标记、授权) |
| 运维 | 应用中心 | /app-center | 员工自建应用(上下架 / 冻结 / 归属 / 更新审批)、运营看板、限制项 |
| 运维 | 连接器 | /connectors | 连接器目录与下发开关 |
| 运维 | 服务器信息 | /server-info | 版本与更新提示、数据库与迁移、模型并发 |
| 审计 | 审计日志 | /audit | 关键操作全程留痕(含保留策略) |
品牌与文案不在管理端编辑:客户端登录页、客户端界面、管理后台侧栏与门户页的名称、标语、 欢迎语、标识与主题色全部来自渠道内容(构建期随镜像注入的只读配置)。 改品牌 = 重新构建对应渠道的镜像,见渠道与白标。 管理员自身的安全设置(修改密码、MFA 设置)在右上角账号菜单,不在上述页面中。
- 创建用户:用户名 + 密码 + 角色(
super_admin/auditor/user);RBAC 角色是唯一真源(is_admin为兼容字段); - 状态:启用 / 禁用——禁用立即吊销该用户全部 API 令牌,客户端需重新登录(与用户更新同事务);
- 删除:双重确认(明示会清除全部 API 令牌、用量记录与组归属,不可恢复);
- 配额(已下线):
quota_tokens/quota_money与部门预算自 2026-09-11 起不再生效 —— 列仍保留在库里,但网关不再读它们,管理端也不下发、不展示,PUT /users/:id里的quota_*字段被直接忽略。余额是唯一闸门; - 余额:
balance_money是存量金额(元),也是员工唯一可花的钱。行内「调整余额 / 充值」支持增加 / 扣减 / 设为并写审计; 页面顶部「月度余额发放」配置闸门开关、每人每月额度与发放方式(增加 / 覆盖),并可立即补发本月—— 开启闸门后余额 ≤ 0 的员工调用 AI 返回 429(管理员豁免);默认关闭,避免升级瞬间全员被拦; - 重置密码 / 重置 MFA:管理员可为本地用户重置密码(重置后强制下次登录改密)与重置动态码;
super_admin不能重置自己的 MFA,需另一位超管操作或运维 CLI 兜底; - 部门与角色:用户归属部门(支持多部门,见「部门管理」);部门归属影响授权可见性(授权给部门覆盖其子部门成员),不影响费用——部门预算已下线(见下)。
- 部门树形结构,成员归属于部门;
- 多部门归属(2026-09):本地账号与 LDAP/OIDC 用户均可属于多个部门——用户页「设置部门」对话框为多选(checkbox 树),提交
group_ids数组;LDAP/OIDC 用户的组来自企业目录(LDAP 每 1 小时全量同步,OIDC/OpenID 按 IdP 的groupsclaim 在登录时同步),管理员手工设置的本地归属可能被企业目录覆盖; - 部门预算已下线(2026-09-11):
groups.budget_money列仍保留在库里,但不再参与任何判定 —— 网关不读、管理端不展示、也不会因此拦截(历史上它曾按「全部所属部门 + 祖先链」生效并返回 429,该行为已随三套并行额度一起收敛)。员工侧的额度只有账户余额一种。 - 授权对象:市场/组织内容可授权给用户或部门(NOCASE 匹配);非部门树内的组(如 LDAP 纯授权组)不参与预算。
登录方式(本地 / LDAP / OIDC / OpenID)在「认证 /auth」页配置:
- 启用方式:复选框勾选出现在客户端登录页的方式(local 恒启用,
hide_local可隐藏客户端本地入口;管理后台恒仅本地账号登录,不受影响); - 配置必填:LDAP = server_url + bind_dn + base_dn;OIDC/OpenID = issuer + client_id + redirect_url(redirect_url 必须 https 或 http 回环);
- 用户名字段(属性,
user_attr):目录中”登录用户名”的属性名——默认uid(OpenLDAP 常用);AD 目录用sAMAccountName;部分企业目录只有cn/mail(部分企业目录登录名即 cn),此时必须填cn,否则批量同步会因取不到 uid 而跳过全部用户(登录单个用户会成功——登录回退输入的用户名——但全量同步不会建人);测试连接的”用户样例”里username为空 = 此字段没配对,请改成目录实际存在的属性; - 测试连接:LDAP 测试返回目录统计——匹配到的用户数、组数、前 5 个用户样例(用户名/显示名/邮箱/组),保存前即可确认过滤器正确性;密码留空或传
***时会用已保存的密码测试(不会因密码未填而失败);OIDC/OpenID 测试拉取/.well-known/openid-configuration验证发现文档; - 密码/密钥保持:已配置的密码不回显(显示「已配置」徽标),留空保存 = 保持原值;如需更换,重新输入即可;显式「清空已保存密码」按钮可清除;
- LDAP 自动同步:保存配置后立即同步一轮,此后每 1 小时全量对账——目录中用户自动创建/更新(显示名/邮箱/组,组全量替换)、目录中消失的用户自动停用并吊销令牌(离职立即失效)、曾被停用不会因回到目录而自动重新启用(目录同步只自动停用、永不自动启用;重新启用一律由管理员显式执行,每轮被跳过的账号记一条
directory_enable_skipped审计);目录扫描为 0 用户时拒绝执行(防过滤器写错误停用全部外部用户); - 配置热生效:LDAP/OIDC 配置保存后无需重启服务端即生效(登录时实时读取配置);
- OIDC/OpenID 差异:组同步仅发生在登录时(IdP 的
groupsclaim),组变更需用户重新登录生效;LDAP 有定时同步,OIDC 无(若需实时离职处理,建议 LDAP)。
- 上游供应商(providers):渠道(channel 选择,如 deepseek)、名称、base URL、API key(SecretInput 显隐切换)、模型列表(保存后自动同步或手填)、启用开关;
- 默认模型:全局选择(下拉);
- 限流:per-user 限流策略;
- 高峰时段:多段高峰窗口(
usage.peak_windows,北京时间),支持每周几选择 + 开始/结束时间;高峰外按模型offpeak_discount折算计价; - 模型定价:每模型 input/output 单价(元/M tokens,
input_price_per_1m/output_price_per_1m),另有缓存命中输入价(cache_input_price_per_1m)与低谷折扣率(offpeak_discount,0-1)——未配置价格的模型在缺省策略下会被拒绝调用(429MODEL_NOT_PRICED,不转发也不产生费用;确实免费/自建时把gateway.unpriced_model_policy设为allow,那时费用才按 0 计);输入价 0/极低但输出价正常的模型照常可用(按输出侧计费);修改价格/折扣只影响之后产生的费用(历史费用按记录时定价留存); - 缓存命中计费:命中缓存的输入 token 按缓存价计费,未配置缓存价时回退输入价(DeepSeek 缓存价);
- 峰谷折算:高峰窗口外(空闲时段)且模型配置了低谷折扣率时,费用 = 标准价 × 折扣率;高峰时段按标准价;DeepSeek 官方当前政策(2026-08 起)= 周一至周五 09:00-12:00、14:00-18:00 为高峰,其余(含周末)为空闲,空闲价 = 高峰价 × 50%。
- 登录模式:不在本页配置;登录方式(local / LDAP / OIDC)见独立的「认证
/auth」页。
- 统计卡:总费用、请求数(chat/embedding 分类)、总 tokens;
- 维度:按用户 / 按模型 / 按日期;费用(money)与 token 两套口径切换;
- 图表:柱状图(费用/tokens 趋势)、饼图(模型分布)、钻取(drill-down:筛选用户 → 看其模型构成);
- 明细:行级费用、prompt/completion tokens、请求数;缓存命中计费在明细中体现(按缓存价);
- 员工自查询:
GET /api/client/v2/auth/usage返回账户余额(balance_money/ 是否开通 / 闸门开关 / 月度额度与发放方式)与今日/昨日/本月/累计 tokens 及费用;配额、剩余额度与部门预算链字段已下线。
市场 · 技能(商城)
Section titled “市场 · 技能(商城)”- 技能 CRUD(上架/编辑/下架/重新上架),技能来源为建议清单(bootstrap 推荐清单)或管理员录入(Git 地址,支持 http/https 远程仓库);
- 授权制:技能市场按用户/部门授权(GrantDialog),未授权一律 404(严格默认拒绝,不泄露存在性),admin 恒全量不落授权表;授权变更写入审计日志;
- 分级语义预留:市场端「免费版 / 专业版」分级词已定名(与组织库「官方/精选」质量标记两套词表隔离),当前版本分级字段随商城分级演进在后续版本落地。
能力中心(统一审批队列)
Section titled “能力中心(统一审批队列)”共享技能(shared_skills)与共享智能体(agent_presets)在此统一审批:
- 只读队列:聚合两域 pending/approved/rejected,列表展示作者、版本、状态;操作走原域端点(
/api/server/admin/shared-skills/...、/api/server/admin/agent-presets/...); - 筛选:状态 Tab(待审核/已通过/已拒绝/全部)+ 类型筛选(技能/智能体);
- 审批动作:approve / reject(reject 必填 reason,员工端展示「未通过原因」) / delete;名称冲突:与市场技能同名时显示警告,approve 将 409 阻断(需先删/改市场技能或驳回共享技能);
- 质量标记:
quality= 官方(official)/ 精选(featured)——仅 approved 可设,reject/pending 自动清空;互斥; - 授权弹窗:复用 GrantDialog——approved 后仍需按用户/部门授权才可见可装(双门制,与市场同构);admin 恒可全量;
- 统计:下载/调用计数(技能含 calls)随审批队列展示;
- 审计动作名如
skill_approve/*_qualify。
历史:早期独立页面
/shared-skills、/agent-presets及其导航已并入「能力中心」(2026-09),路由不再保留。
- 覆盖:用户、部门、配额、网关定价、高峰窗口、商城 CRUD、共享内容审批与授权、quality 标记、密钥变更等关键操作;
- 记录内容:操作者、动作名(如
skill_approve、user_update、usage_peak_update、provider_update)、目标、时间、前后值摘要; - 筛选:按动作类型/目标/时间范围过滤,全程留痕可回溯。
- 展示当前服务端版本、数据库与迁移版本、构建信息;健康检查状态(
/healthz)与运行环境摘要; - 版本更新提示:服务端自动检测本渠道更新目录(默认
release.picoaide.com/<渠道>/latest.json, 可用PICOAI_UPDATE_ENDPOINT覆盖或设off关闭)的最新版本;有新版本时页面顶部显示提示横幅 (含升级目标镜像 tag),管理员按升级流程执行。检查结果有 6 小时缓存, 清单渠道与本部署不一致时按”检查不可用”处理(不显示为”已是最新”); - 模型并发:按模型展示「当前并发 / 90 天峰值 / 目标」,目标在模型
default_params.concurrency_target配置, 展示峰值利用率,达到目标时标红提醒——用于向官方申请扩容的量化依据。当前并发为内存实时快照 (请求发起→结束),峰值每 15s 采样落库(GREATEST 累计永不回退)。
服务端以容器方式部署(一个镜像 = 服务端 + 内置 PostgreSQL + Caddy + 客户端安装包), 也支持单二进制 + 外部 PostgreSQL。部署、升级、备份、渠道与排障见部署章节; 数据库为 PostgreSQL(PG-only)。