增加比赛账号限制的额外账号列表

This commit is contained in:
Himit_ZH 2021-11-27 13:15:01 +08:00
parent 5b9dc30b64
commit e400fb05ac
9 changed files with 169 additions and 38 deletions

View File

@ -203,13 +203,9 @@ public class AdminContestController {
public CommonResult getProblemList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "cid", required = false) Long cid,
@RequestParam(value = "cid", required = true) Long cid,
@RequestParam(value = "problemType", required = false) Integer problemType,
@RequestParam(value = "oj", required = false) String oj) {
if (cid == null) {
return CommonResult.errorResponse("参数错误!", CommonResult.STATUS_NOT_FOUND);
}
if (currentPage == null || currentPage < 1) currentPage = 1;
if (limit == null || limit < 1) limit = 10;
IPage<Problem> iPage = new Page<>(currentPage, limit);
@ -225,8 +221,11 @@ public class AdminContestController {
pidList.add(contestProblem.getPid());
});
HashMap<String, Object> contestProblem = new HashMap<>();
if (pidList.size() == 0 && problemType == null) { // 该比赛原本就无题目数据
return CommonResult.successResponse(iPage, "获取成功");
contestProblem.put("problemList", pidList);
contestProblem.put("contestProblemMap", contestProblemMap);
return CommonResult.successResponse(contestProblem, "获取成功");
}
QueryWrapper<Problem> problemQueryWrapper = new QueryWrapper<>();
@ -240,15 +239,14 @@ public class AdminContestController {
}
// 逻辑判断如果是查询已有的就应该是in如果是查询不要重复的使用not in
if (pidList.size() > 0) {
if (problemType != null) {
// 同时需要与比赛相同类型的题目权限需要是公开的隐藏的比赛中不可加入
problemQueryWrapper.notIn("id", pidList);
} else {
problemQueryWrapper.in("id", pidList);
}
if (problemType != null) {
// 同时需要与比赛相同类型的题目权限需要是公开的隐藏的比赛中不可加入
problemQueryWrapper.notIn("id", pidList);
} else {
problemQueryWrapper.in("id", pidList);
}
// 根据oj筛选过滤
if (oj != null && !"All".equals(oj)) {
if (!Constants.RemoteOJ.isRemoteOJ(oj)) {
@ -265,7 +263,6 @@ public class AdminContestController {
}
IPage<Problem> problemList = problemService.page(iPage, problemQueryWrapper);
HashMap<String, Object> contestProblem = new HashMap<>();
contestProblem.put("problemList", problemList);
contestProblem.put("contestProblemMap", contestProblemMap);

View File

@ -7,20 +7,23 @@ import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.TrainingDto;
import top.hcode.hoj.pojo.entity.contest.Contest;
import top.hcode.hoj.pojo.entity.problem.Problem;
import top.hcode.hoj.pojo.entity.training.Training;
import top.hcode.hoj.pojo.vo.TrainingVo;
import top.hcode.hoj.pojo.vo.UserRolesVo;
import top.hcode.hoj.service.problem.impl.ProblemServiceImpl;
import top.hcode.hoj.service.training.impl.TrainingProblemServiceImpl;
import top.hcode.hoj.service.training.impl.TrainingServiceImpl;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
/**
* @Author: Himit_ZH
@ -34,6 +37,12 @@ public class AdminTrainingController {
@Resource
private TrainingServiceImpl trainingService;
@Resource
private TrainingProblemServiceImpl trainingProblemService;
@Resource
private ProblemServiceImpl problemService;
@GetMapping("/list")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
@ -137,5 +146,33 @@ public class AdminTrainingController {
}
}
@GetMapping("/get-problem-list")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
@Transactional(rollbackFor = Exception.class)
public CommonResult getProblemList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "queryExisted", defaultValue = "false") Boolean queryExisted,
@RequestParam(value = "tid", required = true) Long tid) {
if (currentPage == null || currentPage < 1) currentPage = 1;
if (limit == null || limit < 1) limit = 10;
HashMap<String, Object> trainingProblemMap = trainingProblemService.getAdminTrainingProblemList(limit, currentPage, keyword, tid, queryExisted);
return CommonResult.successResponse(trainingProblemMap, "获取成功");
}
@GetMapping("/problem")
@RequiresAuthentication
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
public CommonResult getProblem(@Valid @RequestParam("pid") Long pid) {
Problem problem = problemService.getById(pid);
if (problem != null) { // 查询成功
return CommonResult.successResponse(problem, "查询成功!");
} else {
return CommonResult.errorResponse("查询失败!", CommonResult.STATUS_FAIL);
}
}
}

View File

@ -4,6 +4,7 @@ import cn.hutool.core.util.ReUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.contest.ContestRegister;
import top.hcode.hoj.pojo.vo.ContestVo;
@ -131,6 +132,8 @@ public class ContestServiceImpl extends ServiceImpl<ContestMapper, Contest> impl
accountRule, 1);
String end = ReUtil.get("<end>([\\s\\S]*?)</end>",
accountRule, 1);
String extra = ReUtil.get("<extra>([\\s\\S]*?)</extra>",
accountRule, 1);
int startNum = Integer.parseInt(start);
int endNum = Integer.parseInt(end);
@ -140,6 +143,15 @@ public class ContestServiceImpl extends ServiceImpl<ContestMapper, Contest> impl
return true;
}
}
// 额外账号列表
if (!StringUtils.isEmpty(extra)) {
String[] accountList = extra.trim().split(" ");
for (String account : accountList) {
if (username.equals(account)){
return true;
}
}
}
return false;
}

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import top.hcode.hoj.pojo.entity.training.TrainingProblem;
import top.hcode.hoj.pojo.vo.ProblemVo;
import java.util.HashMap;
import java.util.List;
/**
@ -15,4 +16,7 @@ public interface TrainingProblemService extends IService<TrainingProblem> {
public int getTrainingProblemCount(Long tid);
public List<ProblemVo> getTrainingProblemList(Long tid);
public HashMap<String, Object> getAdminTrainingProblemList(int limit, int currentPage,
String keyword, Long tid, boolean queryExisted);
}

View File

@ -1,13 +1,23 @@
package top.hcode.hoj.service.training.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.dao.TrainingProblemMapper;
import top.hcode.hoj.pojo.entity.problem.Problem;
import top.hcode.hoj.pojo.entity.training.TrainingProblem;
import top.hcode.hoj.pojo.vo.ProblemVo;
import top.hcode.hoj.service.problem.impl.ProblemServiceImpl;
import top.hcode.hoj.service.training.TrainingProblemService;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
/**
@ -21,6 +31,9 @@ public class TrainingProblemServiceImpl extends ServiceImpl<TrainingProblemMappe
@Resource
private TrainingProblemMapper trainingProblemMapper;
@Resource
private ProblemServiceImpl problemService;
@Override
public int getTrainingProblemCount(Long tid) {
return trainingProblemMapper.getTrainingProblemCount(tid);
@ -30,4 +43,51 @@ public class TrainingProblemServiceImpl extends ServiceImpl<TrainingProblemMappe
public List<ProblemVo> getTrainingProblemList(Long tid) {
return trainingProblemMapper.getTrainingProblemList(tid);
}
@Override
public HashMap<String, Object> getAdminTrainingProblemList(int limit, int currentPage, String keyword,
Long tid, boolean queryExisted) {
IPage<Problem> iPage = new Page<>(currentPage, limit);
// 根据tid在TrainingProblem表中查询到对应pid集合
QueryWrapper<TrainingProblem> trainingProblemQueryWrapper = new QueryWrapper<>();
trainingProblemQueryWrapper.eq("tid", tid).orderByAsc("display_id");
List<Long> pidList = new LinkedList<>();
List<TrainingProblem> trainingProblemList = trainingProblemMapper.selectList(trainingProblemQueryWrapper);
HashMap<Long, Object> trainingProblemMap = new HashMap<>();
trainingProblemList.forEach(trainingProblem -> {
trainingProblemMap.put(trainingProblem.getPid(), trainingProblem);
pidList.add(trainingProblem.getPid());
});
HashMap<String, Object> trainingProblem = new HashMap<>();
if (pidList.size() == 0) { // 该训练原本就无题目数据
trainingProblem.put("problemList", pidList);
trainingProblem.put("contestProblemMap", trainingProblemMap);
return trainingProblem;
}
QueryWrapper<Problem> problemQueryWrapper = new QueryWrapper<>();
// 权限需要是公开的隐藏的比赛中不可加入
problemQueryWrapper.eq("auth", 1);
// 逻辑判断如果是查询已有的就应该是in如果是查询不要重复的使用not in
if (queryExisted) {
problemQueryWrapper.in("id", pidList);
} else {
problemQueryWrapper.notIn("id", pidList);
}
if (!StringUtils.isEmpty(keyword)) {
problemQueryWrapper.and(wrapper -> wrapper.like("title", keyword).or()
.like("problem_id", keyword).or()
.like("author", keyword));
}
IPage<Problem> problemList = problemService.page(iPage, problemQueryWrapper);
trainingProblem.put("problemList", problemList);
trainingProblem.put("trainingProblemMap", trainingProblemMap);
return trainingProblem;
}
}

View File

@ -24,7 +24,7 @@ function formatSpecificDuration(startTime, endTime){
if (ms < 0) ms = -ms;
let arr=[86400000,3600000,60000,1000];
let en_time=['day','hour','minute','second'];
let zh_time=['天','小时','分','秒'];
let zh_time=['天','小时','分','秒'];
let res = '';

View File

@ -75,6 +75,8 @@ export const m = {
Suffix:'Suffix',
Start_Number:'Start Number',
End_Number:'End Number',
Extra_Account: 'Extra Accounts Allowed to The Contest',
Extra_Account_Tips:'Please enter the username of the account allowed to enter to the contest, separated by spaces.',
Password_Length:'Password Length',
Generate_and_Export:'Generate & Export',
The_usernames_will_be:'The usernames will be',

View File

@ -75,6 +75,8 @@ export const m = {
Suffix:'后缀',
Start_Number:'开始数字',
End_Number:'结束数字',
Extra_Account: '额外允许参加比赛的账号列表',
Extra_Account_Tips:'请输入允许参加比赛账号的用户名,并用空格隔开。',
Password_Length:'密码长度',
Generate_and_Export:'生成 & 导出',
The_usernames_will_be:'生成的用户名将会是',

View File

@ -207,25 +207,38 @@
></el-input-number>
</el-form-item>
</el-col>
<div
class="userPreview"
v-if="formRule.number_from <= formRule.number_to"
>
{{ $t('m.The_allowed_account_will_be') }}
{{ formRule.prefix + formRule.number_from + formRule.suffix }},
<span v-if="formRule.number_from + 1 < formRule.number_to">
{{
formRule.prefix +
(formRule.number_from + 1) +
formRule.suffix +
'...'
}}
</span>
<span v-if="formRule.number_from + 1 <= formRule.number_to">
{{ formRule.prefix + formRule.number_to + formRule.suffix }}
</span>
</div>
<el-col :md="24" :xs="24">
<el-form-item :label="$t('m.Extra_Account')" prop="prefix">
<el-input
type="textarea"
:placeholder="$t('m.Extra_Account_Tips')"
:rows="8"
v-model="formRule.extra_account"
>
</el-input>
</el-form-item>
</el-col>
</el-form>
<div
class="userPreview"
v-if="formRule.number_from <= formRule.number_to"
>
{{ $t('m.The_allowed_account_will_be') }}
{{ formRule.prefix + formRule.number_from + formRule.suffix }},
<span v-if="formRule.number_from + 1 < formRule.number_to">
{{
formRule.prefix +
(formRule.number_from + 1) +
formRule.suffix +
'...'
}}
</span>
<span v-if="formRule.number_from + 1 <= formRule.number_to">
{{ formRule.prefix + formRule.number_to + formRule.suffix }}
</span>
</div>
</template>
</el-row>
</el-form>
@ -275,6 +288,7 @@ export default {
suffix: '',
number_from: 0,
number_to: 10,
extra_account: '',
},
};
},
@ -435,7 +449,7 @@ export default {
return;
}
if (start != '' && end != '') {
this.durationText = time.duration(start, end);
this.durationText = time.formatSpecificDuration(start, end);
this.contest.duration = durationMS;
}
},
@ -449,12 +463,14 @@ export default {
formRule.number_from +
'</start><end>' +
formRule.number_to +
'</end>';
'</end><extra>' +
formRule.extra_account +
'</extra>';
return result;
},
changeStrToAccountRule(value) {
let reg =
'<prefix>([\\s\\S]*?)</prefix><suffix>([\\s\\S]*?)</suffix><start>([\\s\\S]*?)</start><end>([\\s\\S]*?)</end>';
'<prefix>([\\s\\S]*?)</prefix><suffix>([\\s\\S]*?)</suffix><start>([\\s\\S]*?)</start><end>([\\s\\S]*?)</end><extra>([\\s\\S]*?)</extra>';
let re = RegExp(reg, 'g');
let tmp = re.exec(value);
return {
@ -462,6 +478,7 @@ export default {
suffix: tmp[2],
number_from: tmp[3],
number_to: tmp[4],
extra_account: tmp[5],
};
},
},