1.增加比赛(训练)题目难度、标签显示

hoj在训练和比赛模式添加题目的时候界面如下:

这个界面可能会有一个小问题,管理员在添加题目时,只能看到题目的标题,没有标签和难度显示,这样可能无法直接从标题本身看到题目的内容以及是不是适合某次考试内容,所以想增加一个标签和难度显示。

增加后效果如下:

找到对应的后台接口进行修改。原作者使用的查询是:

IPage<Problem> problemListPage = problemEntityService.page(iPage, problemQueryWrapper);

problemQueryWrapper前面进行了很多查询语句,我们直接把对应的sql写上。

这里需要说明的是,如果要返回每个题目对应的标签,要注意的是看下原来的返回数据的写法:

另外一点就是原作者这个地方有两个是实体类:problem和problemVO,这两个实体类都是描述,problemVO中有关于标签的描述,problem没有关于标签的描述,所以直接用problemVO即可。

重新编写查询语句:

 Page<ProblemVO> problemListPage =problemEntityService.getContestProblemList(limit,currentPage,keyword,pidList, problemType,contest.getGid());

对应的sql参考如下:

   SELECT DISTINCT
        p.id AS pid,
        p.id,
        p.problem_id,
        p.title,
        p.difficulty,
        p.type
        FROM problem p
        <where>
            <choose>
                <when test="pids.size()==0 and problemType == null">
                    and id =null
                </when>
                <otherwise>
                    <if test="problemType!=null" >
                        and p.is_group =false
                        and p.type = #{problemType}
                        and auth !=2
                    </if>
                    <if test="problemType!=null and pids.size()>0">
                        and p.id not in
                        <foreach collection="pids" item="id" index="index" open="(" close=")" separator=",">
                            #{id}
                        </foreach>
                    </if>
                    <if test="problemType==null and pids.size()>0">
                        and p.id  in
                        <foreach collection="pids" item="id" index="index" open="(" close=")" separator=",">
                            #{id}
                        </foreach>
                    </if>
                    <if test="problemType!=null and gid!=null">
                        and auth!=3
                    </if>
                    <if test="keyword != null and keyword != '' ">
                        and (
                        p.title like concat('%',#{keyword},'%') or p.problem_id like concat('%',#{keyword},'%')
                        )
                    </if>
                </otherwise>
            </choose>
            and p.is_remote=false
        </where>
        order by length(p.problem_id) asc,p.problem_id asc

其余的接口参考上面的写法即可。

2.修改题目显示bug

有一个现象:如果将一个题目变成比赛题目(auth=3),这时训练的时候看不到这个题目。如果将这个题目从比赛中删除,那么我们在比赛中应该能看到这个题目,但是操作下来发现并不能看到这个题目了。于是在移除比赛题目的接口位置出增加下面这样的一段代码:

 /**
     * 查询题目有没有在公共比赛和团队比赛中存在,如果都不存在,则将auth重置为1
     * @param pid
     * @return
     */
    public void findContestProblem(Long pid) throws StatusFailException, StatusForbiddenException {
        //查看公共比赛(团队比赛)是否存在这个题目
        QueryWrapper<ContestProblem> ContestProblemQueryWrapper = new QueryWrapper<>();
        ContestProblemQueryWrapper.eq("pid", pid);
        ContestProblem existedContestProblem = contestProblemEntityService.getOne(ContestProblemQueryWrapper);
        //如果是空,说明没有任何比赛有这个题目,那么应该更新题目的auth=1 (公开状态)
        if(existedContestProblem==null){
            UpdateWrapper<Problem> problemUpdateWrapper = new UpdateWrapper<>();
            problemUpdateWrapper.eq("id", pid)
                    .set("auth",1);
            boolean isOk = problemEntityService.update(problemUpdateWrapper);
            if (!isOk) {
                throw new StatusFailException("更新失败");
            }
        }
    }

这样我们在移除比赛题目时就能更新题目状态了。