修复前端bug,添加OI比赛排行榜耗时计算

This commit is contained in:
Himit_ZH 2021-07-07 14:25:28 +08:00
parent 112320d424
commit 48259fd38d
26 changed files with 143 additions and 29 deletions

View File

@ -452,7 +452,6 @@ public class ContestController {
// 如果已经开启了封榜模式 // 如果已经开启了封榜模式
.between(isOpenSealRank, "submit_time", contest.getStartTime(), contest.getSealRankTime()) .between(isOpenSealRank, "submit_time", contest.getStartTime(), contest.getSealRankTime())
.between(!isOpenSealRank, "submit_time", contest.getStartTime(), contest.getEndTime()) .between(!isOpenSealRank, "submit_time", contest.getStartTime(), contest.getEndTime())
.ne("uid", "1")
.ne("username", contest.getAuthor()) .ne("username", contest.getAuthor())
.orderByAsc("time"); .orderByAsc("time");

View File

@ -313,7 +313,7 @@ public class JudgeController {
} }
} }
// 超级管理员与管理员有权限查看代码 // 超级管理员与题目管理员有权限查看代码
// 如果不是本人或者并未分享代码则不可查看 // 如果不是本人或者并未分享代码则不可查看
// 当此次提交代码不共享 // 当此次提交代码不共享
// 比赛提交只有比赛创建者和root账号可看代码 // 比赛提交只有比赛创建者和root账号可看代码
@ -332,8 +332,7 @@ public class JudgeController {
judge.setCode(null); judge.setCode(null);
} }
}else { }else {
boolean admin = SecurityUtils.getSubject().hasRole("admin") boolean admin = SecurityUtils.getSubject().hasRole("problem_admin");// 是否为题目管理员
|| SecurityUtils.getSubject().hasRole("problem_admin");// 是否为管理员
if (!judge.getShare() && !root && !admin) { if (!judge.getShare() && !root && !admin) {
if (userRolesVo != null) { // 当前是登陆状态 if (userRolesVo != null) { // 当前是登陆状态
// 需要判断是否为当前登陆用户自己的提交代码 // 需要判断是否为当前登陆用户自己的提交代码

View File

@ -6,6 +6,8 @@ import top.hcode.hoj.pojo.dto.RegisterDto;
import top.hcode.hoj.pojo.entity.UserInfo; import top.hcode.hoj.pojo.entity.UserInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
/** /**
* <p> * <p>
@ -19,4 +21,6 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@Repository @Repository
public interface UserInfoMapper extends BaseMapper<UserInfo> { public interface UserInfoMapper extends BaseMapper<UserInfo> {
int addUser(RegisterDto registerDto); int addUser(RegisterDto registerDto);
List<UserInfo> getSuperAdminList();
} }

View File

@ -31,7 +31,7 @@
SELECT cr.* FROM SELECT cr.* FROM
(SELECT uid,pid,cpid,MAX(time) AS time FROM contest_record (SELECT uid,pid,cpid,MAX(time) AS time FROM contest_record
<where> <where>
cid=#{cid} AND status IS NOT NULL AND uid!='1' cid=#{cid} AND status IS NOT NULL
<if test="contestAuthor!=null"> <if test="contestAuthor!=null">
AND username!=#{contestAuthor} AND username!=#{contestAuthor}
</if> </if>

View File

@ -6,4 +6,7 @@
#{uuid}, #{username},#{password},#{email} #{uuid}, #{username},#{password},#{email}
) )
</insert> </insert>
<select id="getSuperAdminList" resultType="top.hcode.hoj.pojo.entity.UserInfo" useCache="true">
select * from user_info u,user_role ur where u.uuid = ur.uid and ur.role_id = 1000
</select>
</mapper> </mapper>

View File

@ -27,6 +27,12 @@ public class OIContestRankVo {
@ApiModelProperty(value = "提交总得分") @ApiModelProperty(value = "提交总得分")
private Integer totalScore; private Integer totalScore;
@ApiModelProperty(value = "提交总耗时,只有满分的提交才会统计")
private Integer totalTime;
@ApiModelProperty(value = "OI的题对应提交得分") @ApiModelProperty(value = "OI的题对应提交得分")
private HashMap<String, Integer> submissionInfo; private HashMap<String, Integer> submissionInfo;
@ApiModelProperty(value = "OI的题得满分后对应提交最优耗时")
private HashMap<String, Integer> timeInfo;
} }

View File

@ -1,6 +1,7 @@
package top.hcode.hoj.service; package top.hcode.hoj.service;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import top.hcode.hoj.pojo.entity.UserInfo;
import top.hcode.hoj.pojo.vo.ACMContestRankVo; import top.hcode.hoj.pojo.vo.ACMContestRankVo;
import top.hcode.hoj.pojo.entity.ContestRecord; import top.hcode.hoj.pojo.entity.ContestRecord;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
@ -27,4 +28,7 @@ public interface ContestRecordService extends IService<ContestRecord> {
List<ContestRecord> getOIContestRecord(Long cid, String contestAuthor, Boolean isOpenSealRank, Date sealTime, Date startTime, Date endTime); List<ContestRecord> getOIContestRecord(Long cid, String contestAuthor, Boolean isOpenSealRank, Date sealTime, Date startTime, Date endTime);
List<UserInfo> getSuperAdminList();
} }

View File

@ -1,8 +1,11 @@
package top.hcode.hoj.service.impl; package top.hcode.hoj.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import top.hcode.hoj.dao.UserInfoMapper;
import top.hcode.hoj.pojo.entity.UserInfo;
import top.hcode.hoj.pojo.vo.ACMContestRankVo; import top.hcode.hoj.pojo.vo.ACMContestRankVo;
import top.hcode.hoj.pojo.entity.ContestRecord; import top.hcode.hoj.pojo.entity.ContestRecord;
import top.hcode.hoj.dao.ContestRecordMapper; import top.hcode.hoj.dao.ContestRecordMapper;
@ -30,6 +33,9 @@ public class ContestRecordServiceImpl extends ServiceImpl<ContestRecordMapper, C
@Autowired @Autowired
private ContestRecordMapper contestRecordMapper; private ContestRecordMapper contestRecordMapper;
@Autowired
private UserInfoMapper userInfoMapper;
@Override @Override
public IPage<ContestRecord> getACInfo(Integer currentPage, Integer limit, Integer status, Long cid) { public IPage<ContestRecord> getACInfo(Integer currentPage, Integer limit, Integer status, Long cid) {
@ -37,6 +43,11 @@ public class ContestRecordServiceImpl extends ServiceImpl<ContestRecordMapper, C
return page.setRecords(contestRecordMapper.getACInfo(page, status, cid)); return page.setRecords(contestRecordMapper.getACInfo(page, status, cid));
} }
@Override
public List<UserInfo> getSuperAdminList() {
return userInfoMapper.getSuperAdminList();
}
@Override @Override
public IPage<ACMContestRankVo> getContestACMRank(List<ContestRecord> contestRecordList, int currentPage, int limit) { public IPage<ACMContestRankVo> getContestACMRank(List<ContestRecord> contestRecordList, int currentPage, int limit) {
@ -96,7 +107,13 @@ public class ContestRecordServiceImpl extends ServiceImpl<ContestRecordMapper, C
return contestRecordMapper.getOIContestRecord(cid, contestAuthor, isOpenSealRank, sealTime, startTime, endTime); return contestRecordMapper.getOIContestRecord(cid, contestAuthor, isOpenSealRank, sealTime, startTime, endTime);
} }
public List<ACMContestRankVo> calcACMRank(List<ContestRecord> contestRecordList) { public List<ACMContestRankVo> calcACMRank(List<ContestRecord> contestRecordList) {
List<UserInfo> superAdminList = getSuperAdminList();
List<String> superAdminUidList = superAdminList.stream().map(UserInfo::getUuid).collect(Collectors.toList());
List<ACMContestRankVo> result = new ArrayList<>(); List<ACMContestRankVo> result = new ArrayList<>();
HashMap<String, Integer> uidMapIndex = new HashMap<>(); HashMap<String, Integer> uidMapIndex = new HashMap<>();
@ -106,6 +123,11 @@ public class ContestRecordServiceImpl extends ServiceImpl<ContestRecordMapper, C
HashMap<String, Long> firstACMap = new HashMap<>(); HashMap<String, Long> firstACMap = new HashMap<>();
for (ContestRecord contestRecord : contestRecordList) { for (ContestRecord contestRecord : contestRecordList) {
if (superAdminUidList.contains(contestRecord.getUid())) { // 超级管理员的提交不入排行榜
continue;
}
ACMContestRankVo ACMContestRankVo; ACMContestRankVo ACMContestRankVo;
if (!uidMapIndex.containsKey(contestRecord.getUid())) { // 如果该用户信息没还记录 if (!uidMapIndex.containsKey(contestRecord.getUid())) { // 如果该用户信息没还记录
@ -182,15 +204,44 @@ public class ContestRecordServiceImpl extends ServiceImpl<ContestRecordMapper, C
} }
public List<OIContestRankVo> calcOIRank(List<ContestRecord> oiContestRecord) { public List<OIContestRankVo> calcOIRank(List<ContestRecord> oiContestRecord) {
List<UserInfo> superAdminList = getSuperAdminList();
List<String> superAdminUidList = superAdminList.stream().map(UserInfo::getUuid).collect(Collectors.toList());
List<OIContestRankVo> result = new ArrayList<>(); List<OIContestRankVo> result = new ArrayList<>();
HashMap<String, Integer> uidMapIndex = new HashMap<>(); HashMap<String, Integer> uidMapIndex = new HashMap<>();
HashMap<String, HashMap<String, Integer>> uidMapTime = new HashMap<>();
int index = 0; int index = 0;
for (ContestRecord contestRecord : oiContestRecord) { for (ContestRecord contestRecord : oiContestRecord) {
if (superAdminUidList.contains(contestRecord.getUid())) { // 超级管理员的提交不入排行榜
continue;
}
if (contestRecord.getStatus() == 1) { // AC
HashMap<String, Integer> pidMapTime = uidMapTime.get(contestRecord.getUid());
if (pidMapTime != null) {
Integer useTime = pidMapTime.get(contestRecord.getDisplayId());
if (useTime != null) {
if (useTime > contestRecord.getUseTime()) { // 如果时间消耗比原来的少
pidMapTime.put(contestRecord.getDisplayId(), contestRecord.getUseTime());
}
} else {
pidMapTime.put(contestRecord.getDisplayId(), contestRecord.getUseTime());
}
} else {
HashMap<String, Integer> tmp = new HashMap<>();
tmp.put(contestRecord.getDisplayId(), contestRecord.getUseTime());
uidMapTime.put(contestRecord.getUid(), tmp);
}
}
OIContestRankVo oiContestRankVo; OIContestRankVo oiContestRankVo;
if (!uidMapIndex.containsKey(contestRecord.getUid())) { // 如果该用户信息没还记录 if (!uidMapIndex.containsKey(contestRecord.getUid())) { // 如果该用户信息没还记录
// 初始化参数 // 初始化参数
oiContestRankVo = new OIContestRankVo(); oiContestRankVo = new OIContestRankVo();
oiContestRankVo.setRealname(contestRecord.getRealname()) oiContestRankVo.setRealname(contestRecord.getRealname())
@ -218,9 +269,24 @@ public class ContestRecordServiceImpl extends ServiceImpl<ContestRecordMapper, C
} }
// 根据总得分进行降序排序
for (OIContestRankVo oiContestRankVo : result) {
HashMap<String, Integer> pidMapTime = uidMapTime.get(oiContestRankVo.getUid());
int sumTime = 0;
if (pidMapTime != null) {
for (String key : pidMapTime.keySet()) {
Integer time = pidMapTime.get(key);
sumTime += time == null ? 0 : time;
}
}
oiContestRankVo.setTotalTime(sumTime);
oiContestRankVo.setTimeInfo(pidMapTime);
}
// 根据总得分进行降序,再根据总时耗升序排序
List<OIContestRankVo> orderResultList = result.stream() List<OIContestRankVo> orderResultList = result.stream()
.sorted(Comparator.comparing(OIContestRankVo::getTotalScore, Comparator.reverseOrder())) .sorted(Comparator.comparing(OIContestRankVo::getTotalScore, Comparator.reverseOrder())
.thenComparing(OIContestRankVo::getTotalTime,Comparator.naturalOrder()))
.collect(Collectors.toList()); .collect(Collectors.toList());
return orderResultList; return orderResultList;
} }

View File

@ -136,7 +136,8 @@ public class JudgeController {
finalJudge.getCid(), finalJudge.getCid(),
finalJudge.getUid(), finalJudge.getUid(),
finalJudge.getPid(), finalJudge.getPid(),
finalJudge.getScore()); finalJudge.getScore(),
finalJudge.getTime());
} }
@ -165,7 +166,7 @@ public class JudgeController {
public CommonResult remoteJudge(@RequestBody ToJudge toJudge) { public CommonResult remoteJudge(@RequestBody ToJudge toJudge) {
if (!openRemoteJudge) { if (!openRemoteJudge) {
return CommonResult.errorResponse("对不起!该判题服务器未开启远程虚拟判题功能!",CommonResult.STATUS_ACCESS_DENIED); return CommonResult.errorResponse("对不起!该判题服务器未开启远程虚拟判题功能!", CommonResult.STATUS_ACCESS_DENIED);
} }
if (!toJudge.getToken().equals(judgeToken)) { if (!toJudge.getToken().equals(judgeToken)) {

View File

@ -78,13 +78,13 @@ public class RemoteJudgeGetResult {
// 写回数据库 // 写回数据库
judgeService.updateById(judge); judgeService.updateById(judge);
// 同步其它表 // 同步其它表
judgeService.updateOtherTable(submitId, status, cid, uid, pid, score); judgeService.updateOtherTable(submitId, status, cid, uid, pid, score, judge.getTime());
} else { } else {
judgeService.updateById(judge); judgeService.updateById(judge);
// 同步其它表 // 同步其它表
judgeService.updateOtherTable(submitId, status, cid, uid, pid, null); judgeService.updateOtherTable(submitId, status, cid, uid, pid, null, null);
} }
scheduler.shutdown(); scheduler.shutdown();

View File

@ -83,6 +83,7 @@ public class RemoteJudgeToSubmit {
cid, cid,
uid, uid,
pid, pid,
null,
null); null);
log.error("网络错误---------------->获取不到提交ID"); log.error("网络错误---------------->获取不到提交ID");
return; return;

View File

@ -71,6 +71,7 @@ public class POJJudge implements RemoteJudgeStrategy {
TimeUnit.SECONDS.sleep(2); TimeUnit.SECONDS.sleep(2);
maxRunId = getMaxRunId(request, username, problemId); maxRunId = getMaxRunId(request, username, problemId);
} }
return MapUtil.builder(new HashMap<String, Object>()) return MapUtil.builder(new HashMap<String, Object>())
.put("cookies", cookies) .put("cookies", cookies)
.put("runId", maxRunId) .put("runId", maxRunId)
@ -85,6 +86,10 @@ public class POJJudge implements RemoteJudgeStrategy {
.addHeaders(headers); .addHeaders(headers);
HttpResponse response = request.execute(); HttpResponse response = request.execute();
if (response.getStatus() != 200) {
log.error(submitId + " error:{}", response.body());
}
String statusStr = ReUtil.get("<b>Result:</b>(.+?)</td>", response.body(), 1) String statusStr = ReUtil.get("<b>Result:</b>(.+?)</td>", response.body(), 1)
.replaceAll("<.*?>", "") .replaceAll("<.*?>", "")
.trim(); .trim();

View File

@ -13,5 +13,5 @@ import top.hcode.hoj.pojo.entity.Judge;
* @since 2020-10-23 * @since 2020-10-23
*/ */
public interface ContestRecordService extends IService<ContestRecord> { public interface ContestRecordService extends IService<ContestRecord> {
void UpdateContestRecord(String uid, Integer score, Integer status, Long submitId, Long cid); void UpdateContestRecord(String uid, Integer score, Integer status, Long submitId, Long cid, Integer useTime);
} }

View File

@ -21,5 +21,5 @@ public interface JudgeService extends IService<Judge> {
Boolean compileSpj(String code, Long pid, String spjLanguage) throws CompileError, SystemError; Boolean compileSpj(String code, Long pid, String spjLanguage) throws CompileError, SystemError;
void updateOtherTable(Long submitId, Integer status, Long cid, String uid, Long pid, Integer score); void updateOtherTable(Long submitId, Integer status, Long cid, String uid, Long pid, Integer score,Integer useTime);
} }

View File

@ -42,7 +42,7 @@ public class ContestRecordServiceImpl extends ServiceImpl<ContestRecordMapper, C
@Override @Override
@Async @Async
@Transactional @Transactional
public void UpdateContestRecord(String uid, Integer score, Integer status, Long submitId, Long cid) { public void UpdateContestRecord(String uid, Integer score, Integer status, Long submitId, Long cid, Integer useTime) {
UpdateWrapper<ContestRecord> updateWrapper = new UpdateWrapper<>(); UpdateWrapper<ContestRecord> updateWrapper = new UpdateWrapper<>();
// 如果是AC // 如果是AC
if (status.intValue() == Constants.Judge.STATUS_ACCEPTED.getStatus()) { if (status.intValue() == Constants.Judge.STATUS_ACCEPTED.getStatus()) {
@ -64,6 +64,8 @@ public class ContestRecordServiceImpl extends ServiceImpl<ContestRecordMapper, C
updateWrapper.set("score", score); updateWrapper.set("score", score);
} }
updateWrapper.set("use_time", useTime);
updateWrapper.eq("submit_id", submitId) // submit_id一定只有一个 updateWrapper.eq("submit_id", submitId) // submit_id一定只有一个
.eq("uid", uid); .eq("uid", uid);
boolean result = contestRecordMapper.update(null, updateWrapper) > 0; boolean result = contestRecordMapper.update(null, updateWrapper) > 0;

View File

@ -48,7 +48,7 @@ public class JudgeServiceImpl extends ServiceImpl<JudgeMapper, Judge> implements
public Judge Judge(Problem problem, Judge judge) { public Judge Judge(Problem problem, Judge judge) {
// c和c++为一倍时间和空间其它语言为2倍时间和空间 // c和c++为一倍时间和空间其它语言为2倍时间和空间
if (!judge.getLanguage().equals("C++") && !judge.getLanguage().equals("C")&& if (!judge.getLanguage().equals("C++") && !judge.getLanguage().equals("C") &&
!judge.getLanguage().equals("C++ With O2") && !judge.getLanguage().equals("C With O2")) { !judge.getLanguage().equals("C++ With O2") && !judge.getLanguage().equals("C With O2")) {
problem.setTimeLimit(problem.getTimeLimit() * 2); problem.setTimeLimit(problem.getTimeLimit() * 2);
problem.setMemoryLimit(problem.getMemoryLimit() * 2); problem.setMemoryLimit(problem.getMemoryLimit() * 2);
@ -84,7 +84,7 @@ public class JudgeServiceImpl extends ServiceImpl<JudgeMapper, Judge> implements
@Override @Override
@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED) @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
public void updateOtherTable(Long submitId, Integer status, Long cid, String uid, Long pid, Integer score) { public void updateOtherTable(Long submitId, Integer status, Long cid, String uid, Long pid, Integer score, Integer useTime) {
if (cid == 0) { // 非比赛提交 if (cid == 0) { // 非比赛提交
// 如果是AC,就更新user_acproblem表, // 如果是AC,就更新user_acproblem表,
@ -98,7 +98,7 @@ public class JudgeServiceImpl extends ServiceImpl<JudgeMapper, Judge> implements
} else { //如果是比赛提交 } else { //如果是比赛提交
contestRecordService.UpdateContestRecord(uid, score, status, submitId, cid); contestRecordService.UpdateContestRecord(uid, score, status, submitId, cid, useTime);
} }
} }

View File

@ -68,6 +68,9 @@ public class ContestRecord implements Serializable {
@ApiModelProperty(value = "OI比赛的得分") @ApiModelProperty(value = "OI比赛的得分")
private Integer score; private Integer score;
@ApiModelProperty(value = "提交耗时")
private Integer useTime;
@ApiModelProperty(value = "是否为一血AC") @ApiModelProperty(value = "是否为一血AC")
private Boolean firstBlood; private Boolean firstBlood;

View File

@ -304,9 +304,6 @@ a:hover {
margin-top: 80px; margin-top: 80px;
padding: 0 4%; padding: 0 4%;
} }
.vxe-table--body-wrapper {
overflow-x: hidden !important;
}
} }
.markdown-body img { .markdown-body img {
max-width: 100%; max-width: 100%;

View File

@ -85,8 +85,8 @@ export default {
.admin_getContestProblemList(params) .admin_getContestProblemList(params)
.then((res) => { .then((res) => {
this.loading = false; this.loading = false;
this.total = res.data.data.total; this.total = res.data.data.problemList.total;
this.problems = res.data.data.records; this.problems = res.data.data.problemList.records;
}) })
.catch(() => { .catch(() => {
this.loading = false; this.loading = false;

View File

@ -61,6 +61,7 @@
></vxe-table-column> ></vxe-table-column>
<vxe-table-column <vxe-table-column
field="username" field="username"
fixed="left"
min-width="150" min-width="150"
:title="$t('m.User')" :title="$t('m.User')"
> >
@ -76,6 +77,7 @@
</vxe-table-column> </vxe-table-column>
<vxe-table-column <vxe-table-column
field="realname" field="realname"
fixed="left"
min-width="100" min-width="100"
:title="$t('m.RealName')" :title="$t('m.RealName')"
v-if="isContestAdmin" v-if="isContestAdmin"
@ -83,6 +85,7 @@
</vxe-table-column> </vxe-table-column>
<vxe-table-column <vxe-table-column
field="rating" field="rating"
fixed="left"
:title="$t('m.AC') + ' / ' + $t('m.Total')" :title="$t('m.AC') + ' / ' + $t('m.Total')"
min-width="80" min-width="80"
> >
@ -99,6 +102,7 @@
</vxe-table-column> </vxe-table-column>
<vxe-table-column <vxe-table-column
field="totalTime" field="totalTime"
fixed="left"
:title="$t('m.TotalTime')" :title="$t('m.TotalTime')"
min-width="80" min-width="80"
> >

View File

@ -10,7 +10,7 @@
align="center" align="center"
:data="contestProblems" :data="contestProblems"
> >
<vxe-table-column field="pid" min-width="50" :title="$t('m.ID')"> <vxe-table-column field="pid" width="60" :title="$t('m.ID')">
</vxe-table-column> </vxe-table-column>
<vxe-table-column <vxe-table-column
field="displayId" field="displayId"
@ -20,7 +20,8 @@
<vxe-table-column <vxe-table-column
field="displayTitle" field="displayTitle"
:title="$t('m.Title')" :title="$t('m.Title')"
min-width="200" min-width="150"
show-overflow
> >
</vxe-table-column> </vxe-table-column>
<vxe-table-column field="ac" :title="$t('m.AC')" min-width="80"> <vxe-table-column field="ac" :title="$t('m.AC')" min-width="80">

View File

@ -50,6 +50,7 @@
auto-resize auto-resize
size="small" size="small"
align="center" align="center"
ref="OIContestRank"
:data="dataRank" :data="dataRank"
:cell-class-name="cellClassName" :cell-class-name="cellClassName"
:seq-config="{ startIndex: (this.page - 1) * this.limit }" :seq-config="{ startIndex: (this.page - 1) * this.limit }"
@ -63,6 +64,7 @@
<vxe-table-column <vxe-table-column
field="username" field="username"
min-width="150" min-width="150"
fixed="left"
:title="$t('m.User')" :title="$t('m.User')"
> >
<template v-slot="{ row }"> <template v-slot="{ row }">
@ -78,6 +80,7 @@
<vxe-table-column <vxe-table-column
field="realname" field="realname"
min-width="100" min-width="100"
fixed="left"
:title="$t('m.RealName')" :title="$t('m.RealName')"
v-if="isContestAdmin" v-if="isContestAdmin"
> >
@ -85,6 +88,7 @@
<vxe-table-column <vxe-table-column
field="totalScore" field="totalScore"
:title="$t('m.Total_Score')" :title="$t('m.Total_Score')"
fixed="left"
min-width="80" min-width="80"
> >
<template v-slot="{ row }"> <template v-slot="{ row }">
@ -94,6 +98,8 @@
style="color:rgb(87, 163, 243);" style="color:rgb(87, 163, 243);"
>{{ row.totalScore }}</a >{{ row.totalScore }}</a
> >
<br />
<span class="problem-time">({{ row.totalTime }}ms)</span>
</span> </span>
</template> </template>
</vxe-table-column> </vxe-table-column>
@ -112,9 +118,15 @@
> >
</template> </template>
<template v-slot="{ row }"> <template v-slot="{ row }">
<span v-if="row.submissionInfo[problem.displayId]">{{ <div v-if="row.submissionInfo[problem.displayId]">
row.submissionInfo[problem.displayId] <span>{{ row.submissionInfo[problem.displayId] }}</span>
}}</span> <br />
<span
v-if="row.timeInfo && row.timeInfo[problem.displayId]"
style="font-size:12px;"
>({{ row.timeInfo[problem.displayId] }}ms)</span
>
</div>
</template> </template>
</vxe-table-column> </vxe-table-column>
</vxe-table> </vxe-table>
@ -339,4 +351,8 @@ a.emphasis {
a.emphasis:hover { a.emphasis:hover {
color: #2d8cf0; color: #2d8cf0;
} }
.problem-time {
color: rgba(0, 0, 0, 0.45);
font-size: 12px;
}
</style> </style>

View File

@ -150,6 +150,7 @@
field="title" field="title"
:title="$t('m.Problem')" :title="$t('m.Problem')"
min-width="180" min-width="180"
show-overflow
> >
<template v-slot="{ row }"> <template v-slot="{ row }">
<a @click="getProblemUri(row.problemId)" class="title-a">{{ <a @click="getProblemUri(row.problemId)" class="title-a">{{

View File

@ -52,7 +52,7 @@
<vxe-table-column <vxe-table-column
field="submitId" field="submitId"
:title="$t('m.Run_ID')" :title="$t('m.Run_ID')"
min-width="100" width="100"
></vxe-table-column> ></vxe-table-column>
<vxe-table-column :title="$t('m.Submit_Time')" min-width="150"> <vxe-table-column :title="$t('m.Submit_Time')" min-width="150">
<template v-slot="{ row }"> <template v-slot="{ row }">

View File

@ -219,6 +219,7 @@
<vxe-table-column <vxe-table-column
field="language" field="language"
:title="$t('m.Language')" :title="$t('m.Language')"
show-overflow
min-width="130" min-width="130"
> >
<template v-slot="{ row }"> <template v-slot="{ row }">

View File

@ -224,6 +224,7 @@ CREATE TABLE `contest_record` (
`submit_time` datetime NOT NULL COMMENT '具体提交时间', `submit_time` datetime NOT NULL COMMENT '具体提交时间',
`time` bigint(20) unsigned DEFAULT NULL COMMENT '提交时间,为提交时间减去比赛时间', `time` bigint(20) unsigned DEFAULT NULL COMMENT '提交时间,为提交时间减去比赛时间',
`score` int(11) DEFAULT NULL COMMENT 'OI比赛的得分', `score` int(11) DEFAULT NULL COMMENT 'OI比赛的得分',
`use_time` int(11) DEFAULT NULL COMMENT '运行耗时',
`first_blood` tinyint(1) DEFAULT '0' COMMENT '是否为一血AC', `first_blood` tinyint(1) DEFAULT '0' COMMENT '是否为一血AC',
`checked` tinyint(1) DEFAULT '0' COMMENT 'AC是否已校验', `checked` tinyint(1) DEFAULT '0' COMMENT 'AC是否已校验',
`gmt_create` datetime DEFAULT CURRENT_TIMESTAMP, `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP,