DomainModel
域(租户/组织)模型,提供域 CRUD、用户角色成员管理、角色权限管理和加入设置。
DomainModel 是纯静态类。所有方法均通过类本身调用(如 DomainModel.get(...))。
类型导出
DomainDoc
定义在 packages/hydrooj/src/interface.ts:
interface DomainDoc extends Record<string, any> {
_id: string; // 域 ID
owner: number; // 所有者 UID
roles: Dictionary<string>; // 角色名 → 权限 bigint 字符串
avatar: string; // 域头像 URL
bulletin: string; // 域公告文本
_join?: any; // 加入设置(method, role, expire, code)
host?: string[]; // 自定义 host 头
}注意:DomainDoc 继承 Record<string, any>,因此允许任意附加字段。
常量
加入方式
| 常量 | 值 | 说明 |
|---|---|---|
JOIN_METHOD_NONE | 0 | 不允许任何用户加入此域 |
JOIN_METHOD_ALL | 1 | 允许任何用户加入此域 |
JOIN_METHOD_CODE | 2 | 允许任何用户通过邀请码加入 |
加入有效期
| 常量 | 值 | 说明 |
|---|---|---|
JOIN_EXPIRATION_KEEP_CURRENT | 0 | 保持当前有效期 |
JOIN_EXPIRATION_UNLIMITED | -1 | 永不过期 |
| (数字键) | 3, 24, 72, 168, 720 | 3 小时 / 1 天 / 3 天 / 1 周 / 1 个月 |
方法
域 CRUD
add(domainId: string, owner: number, name: string, bulletin: string): Promise<string>
创建新域,指定所有者、名称和公告;将所有者设为 root 角色。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
owner | number | — | 所有者 UID |
name | string | — | 域名称 |
bulletin | string | — | 域公告文本 |
| 返回值 | Promise<string> |
get(domainId: string): Promise<DomainDoc | null>
按 ID 获取域(对 lower 字段不区分大小写查找),带 LRU 缓存。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
| 返回值 | Promise<DomainDoc | null> |
getByHost(host: string): Promise<DomainDoc | null>
按 host 字段获取域,带 LRU 缓存(也缓存 null 未命中)。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
host | string | — | 自定义 host 头值 |
| 返回值 | Promise<DomainDoc | null> |
getMulti(query?: Filter<DomainDoc>): Cursor<DomainDoc>
获取匹配过滤器的域游标。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
query | Filter<DomainDoc> | — | MongoDB 过滤条件 |
| 返回值 | Cursor<DomainDoc> |
getList(domainIds: string[]): Promise<Record<string, DomainDoc | null>>
以域 ID 为键的字典形式获取多个域(内部使用 get,遵循缓存)。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainIds | string[] | — | 域 ID 数组 |
| 返回值 | Promise<Record<string, DomainDoc | null>> |
edit(domainId: string, $set: Partial<DomainDoc>): Promise<DomainDoc | null>
按 ID 更新城字段;广播缓存失效。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
$set | Partial<DomainDoc> | — | 要更新的字段 |
| 返回值 | Promise<DomainDoc | null> |
inc(domainId: string, field: NumberKeys<DomainDoc>, n: number): Promise<number | null>
原子性递增域上的数值字段;广播缓存失效。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
field | NumberKeys<DomainDoc> | — | 要递增的数值字段名 |
n | number | — | 递增量 |
| 返回值 | Promise<number | null> |
getPrefixSearch(prefix: string, limit?: number): Promise<DomainDoc[]>
按 ID 或名称前缀搜索域(正则,不区分大小写);默认限制 50。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
prefix | string | — | 搜索前缀 |
limit | number | 50 | 返回数量上限 |
| 返回值 | Promise<DomainDoc[]> |
del(domainId: string): Promise<void>
删除域及所有用户关联;触发 domain/delete 事件并使缓存失效。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
| 返回值 | Promise<void> |
域用户管理
countUser(domainId: string, role?: string): Promise<number>
统计域中的已加入用户,可选按角色过滤。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
role | string | — | 可选角色过滤 |
| 返回值 | Promise<number> |
getDomainUser(domainId: string, udoc: { _id: number, priv: number }): Promise<any>
获取域用户记录,包含有效角色和计算后的 perm(考虑用户特权如 PRIV_MANAGE_ALL_DOMAIN)。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
udoc | { _id: number, priv: number } | — | 用户文档(至少含 _id 和 priv) |
| 返回值 | Promise<any> |
getDomainUserMulti(domainId: string, uids: number[]): Cursor<any>
按 UID 获取多个域用户记录的游标。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
uids | number[] | — | 用户 ID 数组 |
| 返回值 | Cursor<any> |
getDictUserByDomainId(uid: number): Promise<Record<string, any>>
获取用户的所有已加入域用户记录,以 domainId 为键。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
uid | number | — | 用户 ID |
| 返回值 | Promise<Record<string, any>> |
setUserRole(domainId: string, uid: MaybeArray<number>, role: string, autojoin?: boolean): Promise<any>
设置域中的用户角色;支持单个或批量 UID;可选自动加入。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
uid | MaybeArray<number> | — | 单个或批量用户 ID |
role | string | — | 目标角色名 |
autojoin | boolean | false | 是否自动加入域 |
| 返回值 | Promise<any> |
setJoin(domainId: string, uid: MaybeArray<number>, join: boolean): Promise<void>
设置域中用户的加入状态。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
uid | MaybeArray<number> | — | 单个或批量用户 ID |
join | boolean | — | 加入状态 |
| 返回值 | Promise<void> |
setUserInDomain(domainId: string, uid: number, params: any): Promise<any>
设置域用户记录的指定字段(upsert)。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
uid | number | — | 用户 ID |
params | any | — | 要设置的字段 |
| 返回值 | Promise<any> |
updateUserInDomain(domainId: string, uid: number, update: any): Promise<any>
对域用户记录应用任意 MongoDB 更新(upsert)。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
uid | number | — | 用户 ID |
update | any | — | MongoDB 更新操作 |
| 返回值 | Promise<any> |
setMultiUserInDomain(domainId: string, query: any, params: any): Promise<any>
批量使用 $set 更新匹配查询的域用户(upsert)。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
query | any | — | 匹配条件 |
params | any | — | 要设置的字段 |
| 返回值 | Promise<any> |
getMultiUserInDomain(domainId: string, query?: any): Cursor<any>
获取匹配查询的域用户游标。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
query | any | — | 匹配条件 |
| 返回值 | Cursor<any> |
incUserInDomain(domainId: string, uid: number, field: string, n: number = 1): Promise<any>
对域用户记录执行读-改-写递增数值字段;返回更新后的文档。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
uid | number | — | 用户 ID |
field | string | — | 要递增的字段名 |
n | number | 1 | 递增量 |
| 返回值 | Promise<any> |
角色管理
getRoles(domainId: string | DomainDoc, count?: boolean): Promise<any[]>
获取域的所有角色(内置 + 自定义),可选附带每角色的用户计数。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | DomainDoc | — | 域 ID 或域文档 |
count | boolean | false | 是否附带每角色用户计数 |
| 返回值 | Promise<any[]> |
setRoles(domainId: string, roles: Dictionary<bigint | string>): Promise<any>
设置多个角色及其权限(合并到已有角色中)。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
roles | Dictionary<bigint | string> | — | 角色名 → 权限映射 |
| 返回值 | Promise<any> |
addRole(domainId: string, name: string, permission: bigint): Promise<any>
添加具有指定权限的新自定义角色。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
name | string | — | 角色名 |
permission | bigint | — | 角色权限 |
| 返回值 | Promise<any> |
deleteRoles(domainId: string, roles: string[]): Promise<void>
删除角色并将所有受影响的用户重置为 default 角色。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
domainId | string | — | 域 ID |
roles | string[] | — | 要删除的角色名数组 |
| 返回值 | Promise<void> |
加入设置
getJoinSettings(ddoc: DomainDoc, roles: string[]): any | null
如果域允许加入且角色被允许,则获取加入设置;加入被禁用或已过期时返回 null。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
ddoc | DomainDoc | — | 域文档 |
roles | string[] | — | 允许加入的角色列表 |
| 返回值 | any | null |
属性
| 属性 | 类型 | 说明 |
|---|---|---|
coll | Collection | MongoDB domain 集合 |
collUser | Collection | MongoDB domain.user 集合 |
事件
| 事件 | 参数 | 说明 |
|---|---|---|
domain/create | ddoc: DomainDoc | 域创建时触发(DB 插入前) |
domain/before-get | query: Filter<DomainDoc> | 域查询前触发;允许修改查询条件 |
domain/get | ddoc: DomainDoc | 域成功获取后触发 |
domain/before-update | domainId, $set | 域更新前触发 |
domain/update | domainId, $set, ddoc | 域更新后触发(含更新后的文档) |
domain/delete | domainId | 域删除后触发 |
domain/delete-cache | domainId | 跨集群广播使域缓存失效 |
备注
- 使用
LRUCache,最大 1000 条目,TTL 300000ms(5 分钟)。 - 缓存键:ID 查找使用
id::{lower},host 查找使用host::{host}。 - 缓存通过
domain/delete-cache广播(跨集群)在编辑、递增、角色变更和删除时失效。 getByHost缓存null结果(未找到 host 对应的域)。