#P10001. CodeFun2000二次开发教程(一)会员系列(1)提交权限

CodeFun2000二次开发教程(一)会员系列(1)提交权限

1.B站视频

2.相关文档

1.Hydrooj安装/使用文档

2.Hydrooj代码仓库

3.本节课的代码

index.ts

// 1.导包
import {
    Context, ForbiddenError, RecordModel, Time ,
} from 'hydrooj';

/*
// 2.完成apply函数 -会在初始化时完成调用
    exprot 代表导出,让外部环境可以调用
    async 异步
    ctx : 全局环境,我们需要使用它来挂载事件
*/

// 提交次数
var submittedLimit : number = 3;

export async function apply(ctx: Context) {
    // 3.挂载事件:
    /*
        格式:handler/HookType/HandlerName#FunctionName
     */
    ctx.on('handler/before/ProblemSubmit', async (that) => {
        // 3.1 : 计算时间
        const after = Time.getObjectID(new Date(Date.now() - Time.day));
        // 3.2 : 查询当日提交次数
        const submitted = await RecordModel.count('system', {
            uid: that.user._id,
            input: { $exists: false }, // 不是自测
            _id: { $gt: after },
        });
        // 3.3 : 权限检查
        if (submitted >= submittedLimit && that.user.role !== 'vip') {
            // ts的字符串插值
            throw new ForbiddenError(`非会员每日仅能进行${submittedLimit}次提交。`);
        }
    });
}

/**
Q:我不想写死这些字面常量怎么办?
A:通过系统设置写配置文件。由管理员来定义次数以及角色名.看完后续教程你就明白怎么做了
 */

知识点总结:

1.各种Model都存在Hydro/packages/hydrooj/src/model想用什么功能自己查。

2.各种Handler都存在Hydro/packages/hydrooj/src/handler。想拦截什么事件自己查。

3.拦截事件格式:handler/HookType/HandlerName#FunctionName

HandlerName见handler文件夹。FunctionName见对应Handler类里面的函数

4.mangodb的主键是ObjectId类型,里面存有时间信息。可以通过主键查询某个时间范围的数据

5.record的input字段用来区分自测和非自测