Skip to content
页面信息
📝 描述训练计划(课程)模型,用于管理 DAG 结构的训练计划和进度跟踪
📥 导入import { TrainingModel } from 'hydrooj'

TrainingModel

训练计划(课程)模型,用于管理 DAG 结构的训练计划、用户注册和进度跟踪。

TaskModel 不同,TrainingModel 是一个纯模块,导出函数而非类。所有函数直接调用(如 TrainingModel.add(...))。


类型导出

TrainingNode

typescript
interface TrainingNode {
    _id: number;
    title: string;
    requireNids: number[];
    pids: number[];
}

TrainingDoc

typescript
interface TrainingDoc extends Omit<Tdoc, 'docType'> {
    docType: 40; // document.TYPE_TRAINING
    description: string;
    pin?: number;
    dag: TrainingNode[];
}

引用自 packages/hydrooj/src/interface.ts


方法

增删改查

add(domainId: string, title: string, content: string, owner: number, dag?: TrainingNode[], description?: string, pin?: number): Promise<ObjectId>

创建一条新训练计划。默认值:dag=[]description=''pin=0

参数类型默认值说明
domainIdstring域上下文
titlestring训练计划标题
contentstring训练计划内容
ownernumber创建者 UID
dagTrainingNode[][]DAG 节点数组
descriptionstring''描述文本
pinnumber0置顶权重
返回值Promise<ObjectId>新训练计划的 ObjectId

edit(domainId: string, tid: ObjectId, $set: Partial<TrainingDoc>): Promise<TrainingDoc>

更新匹配给定部分文档的训练计划字段。

参数类型默认值说明
domainIdstring域上下文
tidObjectId训练计划 ID
$setPartial<TrainingDoc>要更新的字段
返回值Promise<TrainingDoc>更新后的训练计划文档

del(domainId: string, tid: ObjectId): Promise<[void, void]>

删除训练计划及其所有关联的用户状态。

参数类型默认值说明
domainIdstring域上下文
tidObjectId训练计划 ID
返回值Promise<[void, void]>

get(domainId: string, tid: ObjectId): Promise<TrainingDoc>

通过 ID 获取单条训练计划。未找到则抛出 TrainingNotFoundError。同时将 DAG 中的 pids 值规范化为整数。

参数类型默认值说明
domainIdstring域上下文
tidObjectId训练计划 ID
返回值Promise<TrainingDoc>

getMulti(domainId: string, query?: Filter<TrainingDoc>): FindCursor<TrainingDoc>

返回匹配查询的训练计划游标,按 pin 降序然后 _id 降序排列。

参数类型默认值说明
domainIdstring域上下文
queryFilter<TrainingDoc>查询条件
返回值FindCursor<TrainingDoc>

getList(domainId: string, tids: ObjectId[]): Promise<Record<string, TrainingDoc>>

通过 ID 获取多条训练计划,返回以 docId.toString() 为键的映射。

参数类型默认值说明
domainIdstring域上下文
tidsObjectId[]训练计划 ID 数组
返回值Promise<Record<string, TrainingDoc>>

count(domainId: string, query: Filter<TrainingDoc>): Promise<number>

返回匹配给定查询的训练计划数量。

参数类型默认值说明
domainIdstring域上下文
queryFilter<TrainingDoc>查询条件
返回值Promise<number>

注册与状态

enroll(domainId: string, tid: ObjectId, uid: number): Promise<any>

将用户注册到训练计划中。若已注册则抛出 TrainingAlreadyEnrollError。递增训练计划的 attend 计数器。返回 document.inc 的结果。

参数类型默认值说明
domainIdstring域上下文
tidObjectId训练计划 ID
uidnumber用户 UID
返回值Promise<any>document.inc 的返回值
typescript
// 注册用户到训练计划
const newCount = await TrainingModel.enroll(
    'system',           // domainId
    trainingId,         // tid
    12345,              // uid
);
// 若用户已注册,抛出 TrainingAlreadyEnrollError

getStatus(domainId: string, tid: ObjectId, uid: number): Promise<TrainingStatusDoc | null>

获取指定用户在特定训练计划中的状态。

参数类型默认值说明
domainIdstring域上下文
tidObjectId训练计划 ID
uidnumber用户 UID
返回值Promise<TrainingStatusDoc | null>

getMultiStatus(domainId: string, query: Filter<TrainingDoc>): FindCursor<TrainingStatusDoc>

返回匹配给定查询的训练计划状态游标。

参数类型默认值说明
domainIdstring域上下文
queryFilter<TrainingDoc>查询条件
返回值FindCursor<TrainingStatusDoc>

getListStatus(domainId: string, uid: number, tids: ObjectId[]): Promise<Record<string, TrainingStatusDoc>>

获取指定用户在多条训练计划中的状态,返回以 docId 为键的映射。

参数类型默认值说明
domainIdstring域上下文
uidnumber用户 UID
tidsObjectId[]训练计划 ID 数组
返回值Promise<Record<string, TrainingStatusDoc>>

setStatus(domainId: string, tid: ObjectId, uid: number, $set: any): Promise<void>

设置(覆盖)用户在特定训练计划中的状态字段。

参数类型默认值说明
domainIdstring域上下文
tidObjectId训练计划 ID
uidnumber用户 UID
$setany要设置的状态字段
返回值Promise<void>

DAG 辅助函数

用于评估训练计划 DAG 中节点完成状态的工具函数。

getPids(dag: TrainingNode[]): number[]

提取 DAG 中所有节点的唯一父 ID(pids)集合。

参数类型默认值说明
dagTrainingNode[]DAG 节点数组
返回值number[]唯一 pids 集合

isDone(node: TrainingNode, doneNids: Set<number>, donePids: Set<number>): boolean

若节点的必需节点 ID 和父题目 ID 均已满足,返回 true

参数类型默认值说明
nodeTrainingNodeDAG 节点
doneNidsSet<number>已完成的节点 ID 集合
donePidsSet<number>已完成的题目 ID 集合
返回值boolean

isProgress(node: TrainingNode, doneNids: Set<number>, donePids: Set<number>, progPids: Set<number>): boolean

若节点的要求已满足但部分父题目未完成,且至少一个父题目已完成或正在进行中,返回 true

参数类型默认值说明
nodeTrainingNodeDAG 节点
doneNidsSet<number>已完成的节点 ID 集合
donePidsSet<number>已完成的题目 ID 集合
progPidsSet<number>进行中的题目 ID 集合
返回值boolean

isOpen(node: TrainingNode, doneNids: Set<number>, donePids: Set<number>, progPids: Set<number>): boolean

若节点的要求已满足,且无父题目已完成或正在进行中,返回 true

参数类型默认值说明
nodeTrainingNodeDAG 节点
doneNidsSet<number>已完成的节点 ID 集合
donePidsSet<number>已完成的题目 ID 集合
progPidsSet<number>进行中的题目 ID 集合
返回值boolean

isInvalid(node: TrainingNode, doneNids: Set<number>): boolean

若节点的必需节点 ID 全部满足(即前置条件未达成),返回 true

参数类型默认值说明
nodeTrainingNodeDAG 节点
doneNidsSet<number>已完成的节点 ID 集合
返回值boolean

备注

  • 训练计划是一种文档类型模型(TYPE_TRAINING = 40)。增删改查和状态操作委托给共享的 document 模块。
  • enroll 是原子操作——使用 setIfNotStatus 防止重复注册,冲突时抛出 TrainingAlreadyEnrollError
  • get 会规范化 DAG 的 pids 值(将数字字符串解析为整数)以保持向后兼容。
  • DAG 辅助函数(isDoneisProgressisOpenisInvalid)接受 Set<number>number[]——内部会自动转换为 Set