修正特殊判题,增加前台i18n
This commit is contained in:
parent
b1ed8ca13c
commit
8668f34d64
|
@ -66,6 +66,7 @@ Password: 开启SMTP服务后生成的随机授权码
|
|||
| 2021-05-24 | 判题调度乐观锁改为悲观锁 | Himit_ZH |
|
||||
| 2021-05-28 | 增加导入导出题目,增加用户页面的最近登录,开发正式结束,进入维护摸鱼 | Himit_ZH |
|
||||
| 2021-06-02 | 大更新,完善补充前端页面,修正判题等待超时时间,修补一系列bug | Himit_ZH |
|
||||
| 2021-06-07 | 修正特殊判题,增加前台i18n | Himit_ZH |
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ public class AdminJudgeController {
|
|||
// 如果该题已经是AC通过状态,更新该题目的用户ac做题表 user_acproblem
|
||||
if (judge.getStatus().intValue() == Constants.Judge.STATUS_ACCEPTED.getStatus().intValue()) {
|
||||
QueryWrapper<UserAcproblem> userAcproblemQueryWrapper = new QueryWrapper<>();
|
||||
userAcproblemQueryWrapper.eq("pid", judge.getPid()).eq("uid", judge.getUid());
|
||||
userAcproblemQueryWrapper.eq("submit_id", judge.getSubmitId());
|
||||
userAcproblemService.remove(userAcproblemQueryWrapper);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import com.alibaba.excel.EasyExcel;
|
|||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||
|
@ -26,10 +25,6 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.Constructor;
|
||||
import org.yaml.snakeyaml.error.YAMLException;
|
||||
import top.hcode.hoj.common.result.CommonResult;
|
||||
import top.hcode.hoj.pojo.dto.ProblemDto;
|
||||
import top.hcode.hoj.pojo.dto.QDOJProblemDto;
|
||||
|
@ -271,6 +266,13 @@ public class FileController {
|
|||
problemCaseQueryWrapper.eq("pid", pid);
|
||||
List<ProblemCase> problemCaseList = problemCaseService.list(problemCaseQueryWrapper);
|
||||
Assert.notEmpty(problemCaseList, "对不起,该题目的评测数据为空!");
|
||||
boolean hasTestCase = true;
|
||||
if (problemCaseList.get(0).getInput().endsWith(".in") && (problemCaseList.get(0).getOutput().endsWith(".out") ||
|
||||
problemCaseList.get(0).getOutput().endsWith(".ans"))) {
|
||||
hasTestCase = false;
|
||||
}
|
||||
Assert.isTrue(hasTestCase, "对不起,该题目的评测数据为空!");
|
||||
|
||||
workDir = Constants.File.FILE_DOWNLOAD_TMP_FOLDER.getPath() + File.separator + IdUtil.simpleUUID();
|
||||
FileUtil.mkdir(workDir);
|
||||
// 写入本地
|
||||
|
|
|
@ -169,7 +169,10 @@ public class AccountController {
|
|||
}
|
||||
QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<>();
|
||||
userInfoQueryWrapper.eq("email", email.trim());
|
||||
UserInfo userInfo = userInfoDao.getOne(userInfoQueryWrapper);
|
||||
UserInfo userInfo = userInfoDao.getOne(userInfoQueryWrapper, false);
|
||||
if (userInfo == null) {
|
||||
return CommonResult.errorResponse("对不起,该邮箱无注册用户,请重新检查!");
|
||||
}
|
||||
String code = IdUtil.simpleUUID().substring(0, 21); // 随机生成20位数字与字母的组合
|
||||
redisUtils.set(Constants.Email.RESET_PASSWORD_KEY_PREFIX.getValue() + userInfo.getUsername(), code, 10 * 60);//默认链接有效10分钟
|
||||
// 发送邮件
|
||||
|
@ -454,11 +457,10 @@ public class AccountController {
|
|||
public CommonResult changeEmail(@RequestBody Map params, HttpServletRequest request) {
|
||||
|
||||
String password = (String) params.get("password");
|
||||
String oldEmail = (String) params.get("oldEmail");
|
||||
String newEmail = (String) params.get("newEmail");
|
||||
// 数据可用性判断
|
||||
if (StringUtils.isEmpty(password) || StringUtils.isEmpty(newEmail) || StringUtils.isEmpty(oldEmail)) {
|
||||
return CommonResult.errorResponse("请求参数不能为空!");
|
||||
if (StringUtils.isEmpty(password) || StringUtils.isEmpty(newEmail)) {
|
||||
return CommonResult.errorResponse("密码或新邮箱不能为空!");
|
||||
}
|
||||
if (!Validator.isEmail(newEmail)) {
|
||||
return CommonResult.errorResponse("邮箱格式错误!");
|
||||
|
|
|
@ -239,7 +239,7 @@ public class JudgeController {
|
|||
// 如果该题已经是AC通过状态,更新该题目的用户ac做题表 user_acproblem
|
||||
if (judge.getStatus().intValue() == Constants.Judge.STATUS_ACCEPTED.getStatus().intValue()) {
|
||||
QueryWrapper<UserAcproblem> userAcproblemQueryWrapper = new QueryWrapper<>();
|
||||
userAcproblemQueryWrapper.eq("pid", judge.getPid()).eq("uid", judge.getUid());
|
||||
userAcproblemQueryWrapper.eq("submit_id", judge.getSubmitId());
|
||||
userAcproblemService.remove(userAcproblemQueryWrapper);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<mapper namespace="top.hcode.hoj.dao.JudgeMapper">
|
||||
<select id="getCommonJudgeList" resultType="top.hcode.hoj.pojo.vo.JudgeVo" useCache="false">
|
||||
select j.uid,j.submit_id,j.submit_time,j.uid,j.username,j.uid,j.pid,j.status,j.share,
|
||||
j.time,j.memory,j.length,j.language,j.cid,j.cpid,j.judger,p.problem_id as display_pid,p.title
|
||||
j.time,j.memory,j.score,j.length,j.language,j.cid,j.cpid,j.judger,p.problem_id as display_pid,p.title
|
||||
from judge j,problem p
|
||||
<where>
|
||||
p.id = j.pid AND j.cid = 0 AND j.cpid = 0
|
||||
|
@ -30,7 +30,7 @@
|
|||
|
||||
<select id="getContestJudgeList" resultType="top.hcode.hoj.pojo.vo.JudgeVo" useCache="false">
|
||||
select j.uid,j.submit_id,j.submit_time,j.uid,j.username,j.uid,cp.display_id,cp.display_title as title,
|
||||
j.status,j.share,j.time,j.memory,j.length,j.language,j.cid,j.cpid,j.judger
|
||||
j.status,j.share,j.time,j.memory,j.score,j.length,j.language,j.cid,j.cpid,j.judger
|
||||
from judge j,contest_problem cp
|
||||
<where>
|
||||
j.pid=cp.pid AND j.cid = cp.cid
|
||||
|
@ -88,6 +88,6 @@
|
|||
COUNT(IF(status=4,status,NULL)) AS se,
|
||||
COUNT(IF(status=8,status,NULL)) AS pa,
|
||||
COUNT(*) AS total
|
||||
FROM judge where pid=#{pid}
|
||||
FROM judge where pid=#{pid} AND cid=0
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
, COUNT(IF(j.status = 8, STATUS, NULL)) AS pa
|
||||
, COUNT(*) AS total
|
||||
FROM judge j
|
||||
WHERE j.pid
|
||||
WHERE j.cid=0
|
||||
GROUP BY j.pid
|
||||
) j
|
||||
ON j.pid = p.id
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
SELECT u.uuid as uid,u.nickname,u.username,u.signature,u.avatar,
|
||||
(SELECT COUNT( DISTINCT pid ) FROM user_acproblem WHERE uid =u.uuid) AS solved,
|
||||
(SELECT COUNT(pid) FROM user_acproblem WHERE uid =u.uuid) AS ac,
|
||||
(SELECT COUNT(uid) FROM judge WHERE uid=u.uuid) AS total
|
||||
(SELECT COUNT(uid) FROM judge WHERE uid=u.uuid AND cid=0) AS total
|
||||
FROM user_info u WHERE u.status = 0
|
||||
ORDER BY solved DESC,ac DESC
|
||||
</select>
|
||||
|
@ -17,7 +17,7 @@
|
|||
and DATE(gmt_create) >= DATE_SUB(CURDATE(),INTERVAL 7 DAY) ) AS solved,
|
||||
(SELECT COUNT(pid) FROM user_acproblem WHERE uid =u.uuid
|
||||
and DATE(gmt_create) >= DATE_SUB(CURDATE(),INTERVAL 7 DAY)) AS ac,
|
||||
(SELECT COUNT(uid) FROM judge WHERE uid=u.uuid) AS total
|
||||
(SELECT COUNT(uid) FROM judge WHERE uid=u.uuid AND cid=0) AS total
|
||||
FROM user_info u WHERE u.status = 0
|
||||
ORDER BY solved DESC,ac DESC LIMIT 10
|
||||
</select>
|
||||
|
@ -43,7 +43,7 @@
|
|||
FROM user_info u, (
|
||||
SELECT MAX(score) AS score, uid, pid
|
||||
FROM judge
|
||||
WHERE score IS NOT NULL
|
||||
WHERE cid=0 AND score IS NOT NULL
|
||||
GROUP BY pid, uid
|
||||
) s
|
||||
WHERE u.status = 0
|
||||
|
@ -70,14 +70,14 @@
|
|||
|
||||
<select id="getUserHomeInfo" resultMap="map_UserHomeVo">
|
||||
SELECT u.uuid as uid,u.username,u.signature,u.school,u.github,u.blog,u.avatar,ur.rating,
|
||||
(SELECT COUNT(uid) FROM judge WHERE uid=u.uuid) AS total
|
||||
(SELECT COUNT(uid) FROM judge WHERE uid=u.uuid AND cid=0) AS total
|
||||
FROM user_info u,user_record ur WHERE u.uuid = ur.uid AND u.status = 0 AND u.uuid = #{uid}
|
||||
</select>
|
||||
|
||||
<!-- 子查询-->
|
||||
<select id="getProblemScore" resultType="java.lang.Integer">
|
||||
SELECT MAX(score) AS sum_score FROM judge
|
||||
WHERE uid=#{uid} AND score IS NOT NULL GROUP BY pid
|
||||
WHERE uid=#{uid} AND cid=0 AND score IS NOT NULL GROUP BY pid
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
|
@ -54,6 +54,9 @@ public class JudgeVo {
|
|||
@ApiModelProperty(value = "运行内存(b)")
|
||||
private Integer memory;
|
||||
|
||||
@ApiModelProperty(value = "题目得分,ACM题目默认为null")
|
||||
private Integer score;
|
||||
|
||||
@ApiModelProperty(value = "代码长度")
|
||||
private Integer length;
|
||||
|
||||
|
|
|
@ -118,8 +118,8 @@ public class ProblemTestCaseUtils {
|
|||
throw new SystemError("problemID:[" + problemId + "] test case has not found.", null, null);
|
||||
}
|
||||
// 可能zip上传记录的是文件名,这是也是说明文件丢失了
|
||||
if (problemCases.get(0).getInput().endsWith(".in") && (problemCases.get(0).getInput().endsWith(".out") ||
|
||||
problemCases.get(0).getInput().endsWith(".ans"))) {
|
||||
if (problemCases.get(0).getInput().endsWith(".in") && (problemCases.get(0).getOutput().endsWith(".out") ||
|
||||
problemCases.get(0).getOutput().endsWith(".ans"))) {
|
||||
throw new SystemError("problemID:[" + problemId + "] test case has not found.", null, null);
|
||||
}
|
||||
|
||||
|
|
|
@ -10873,6 +10873,11 @@
|
|||
"integrity": "sha1-UylVzB6yCKPZkLOp+acFdGV+CPI=",
|
||||
"dev": true
|
||||
},
|
||||
"vue-i18n": {
|
||||
"version": "8.24.4",
|
||||
"resolved": "https://registry.nlark.com/vue-i18n/download/vue-i18n-8.24.4.tgz",
|
||||
"integrity": "sha1-sVhhTB332xg9nK3du3Ph1UAmlJI="
|
||||
},
|
||||
"vue-loader": {
|
||||
"version": "15.9.4",
|
||||
"resolved": "https://registry.npm.taobao.org/vue-loader/download/vue-loader-15.9.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-loader%2Fdownload%2Fvue-loader-15.9.4.tgz",
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"vue-codemirror-lite": "^1.0.4",
|
||||
"vue-cropper": "^0.5.5",
|
||||
"vue-echarts": "^5.0.0-beta.0",
|
||||
"vue-i18n": "^8.24.4",
|
||||
"vue-m-message": "^3.0.0",
|
||||
"vue-monoplasty-slide-verify": "^1.1.3",
|
||||
"vue-particles": "^1.0.9",
|
||||
|
|
|
@ -21,19 +21,23 @@
|
|||
<el-divider></el-divider>
|
||||
</el-col>
|
||||
<el-col :md="6" :xs="24">
|
||||
<h1>Service</h1>
|
||||
<p><a @click="goRoute('/status')">Judging Queue</a></p>
|
||||
<p><a @click="goRoute('/developer')">System Info</a></p>
|
||||
<h1>{{ $t('m.Service') }}</h1>
|
||||
<p>
|
||||
<a @click="goRoute('/status')">{{ $t('m.Judging_Queue') }}</a>
|
||||
</p>
|
||||
<p>
|
||||
<a @click="goRoute('/developer')">{{ $t('m.System_Info') }}</a>
|
||||
</p>
|
||||
</el-col>
|
||||
<el-col class="hr-none">
|
||||
<el-divider></el-divider>
|
||||
</el-col>
|
||||
<el-col :md="6" :xs="24">
|
||||
<h1>Development</h1>
|
||||
<h1>{{ $t('m.Development') }}</h1>
|
||||
<p class="mb-1">
|
||||
<a :href="websiteConfig.projectUrl" target="_blank"
|
||||
>Open Source</a
|
||||
>
|
||||
<a :href="websiteConfig.projectUrl" target="_blank">{{
|
||||
$t('m.Open_Source')
|
||||
}}</a>
|
||||
</p>
|
||||
<p class="mb-1"><a @click="goRoute('/#')">API</a></p>
|
||||
</el-col>
|
||||
|
@ -41,10 +45,10 @@
|
|||
<el-divider></el-divider>
|
||||
</el-col>
|
||||
<el-col :md="6" :xs="24">
|
||||
<h1>Support</h1>
|
||||
<h1>{{ $t('m.Support') }}</h1>
|
||||
<p>
|
||||
<i class="fa fa-info-circle" aria-hidden="true"></i
|
||||
><a @click="goRoute('/introduction')"> Help</a>
|
||||
><a @click="goRoute('/introduction')"> {{ $t('m.Help') }}</a>
|
||||
</p>
|
||||
<p>
|
||||
<i class="fa fa-envelope" aria-hidden="true"></i>
|
||||
|
@ -64,6 +68,19 @@
|
|||
target="_blank"
|
||||
>{{ websiteConfig.projectName }}</a
|
||||
>
|
||||
<span style="margin-left:10px">
|
||||
<el-dropdown @command="changeLanguage" placement="top">
|
||||
<span class="el-dropdown-link">
|
||||
<i class="fa fa-globe" aria-hidden="true">
|
||||
{{ this.webLanguage == 'zh-CN' ? '简体中文' : 'English' }}</i
|
||||
><i class="el-icon-arrow-up el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="zh-CN">简体中文</el-dropdown-item>
|
||||
<el-dropdown-item command="en-US">English</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</span>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
@ -79,7 +96,7 @@
|
|||
|
||||
<script>
|
||||
import NavBar from '@/components/oj/common/NavBar';
|
||||
import { mapActions, mapState } from 'vuex';
|
||||
import { mapActions, mapState, mapGetters } from 'vuex';
|
||||
export default {
|
||||
name: 'app-content',
|
||||
components: {
|
||||
|
@ -102,6 +119,9 @@ export default {
|
|||
return str.toUpperCase();
|
||||
}
|
||||
},
|
||||
changeLanguage(language) {
|
||||
this.$store.commit('changeWebLanguage', { language: language });
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
$route(newVal, oldVal) {
|
||||
|
@ -118,6 +138,7 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
...mapState(['websiteConfig']),
|
||||
...mapGetters(['webLanguage']),
|
||||
},
|
||||
created: function() {
|
||||
this.$nextTick(function() {
|
||||
|
|
|
@ -175,21 +175,21 @@ export const CONTEST_TYPE_REVERSE = {
|
|||
'0': {
|
||||
name:'Public',
|
||||
color:'success',
|
||||
tips:'公开赛,每个用户都可查看与提交',
|
||||
tips:'Public_Tips',
|
||||
submit:true, // 公开赛可看可提交
|
||||
look:true,
|
||||
},
|
||||
'1':{
|
||||
name:'Private',
|
||||
color:'danger',
|
||||
tips:'私有赛,需要密码才可查看与提交',
|
||||
tips:'Private_Tips',
|
||||
submit:false, // 私有赛 必须要密码才能看和提交
|
||||
look:false,
|
||||
},
|
||||
'2':{
|
||||
name:'Protect',
|
||||
name:'Protected',
|
||||
color:'warning',
|
||||
tips:'保护赛,每个用户都可查看,提交需要密码',
|
||||
tips:'Protected_Tips',
|
||||
submit:false, //保护赛,可以看但是不能提交,提交需要附带比赛密码
|
||||
look:true,
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ export const CONTEST_TYPE_REVERSE = {
|
|||
export const CONTEST_TYPE = {
|
||||
PUBLIC: 0,
|
||||
PRIVATE: 1,
|
||||
PROTECT: 2
|
||||
PROTECTED: 2
|
||||
}
|
||||
|
||||
export const USER_TYPE = {
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import moment from 'moment'
|
||||
import i18n from '@/i18n'
|
||||
// 全局设定语言
|
||||
moment.locale(i18n.locale);
|
||||
|
||||
|
||||
// convert utc time to localtime
|
||||
function utcToLocal (utcDt, format = 'YYYY-MM-DD HH:mm:ss') {
|
||||
|
|
|
@ -4,11 +4,17 @@ import { STORAGE_KEY } from '@/common/constants'
|
|||
import myMessage from '@/common/message'
|
||||
import api from "@/common/api";
|
||||
|
||||
function submissionMemoryFormat (memory) {
|
||||
if (memory === undefined || memory ===null || memory === '') return '--'
|
||||
// 1048576 = 1024 * 1024
|
||||
let t = parseInt(memory)
|
||||
return String(t.toFixed(0)) + 'KB'
|
||||
// function submissionMemoryFormat (memory) {
|
||||
// if (memory === undefined || memory ===null || memory === '') return '--'
|
||||
// // 1048576 = 1024 * 1024
|
||||
// let t = parseInt(memory)
|
||||
// return String(t.toFixed(0)) + 'KB'
|
||||
// }
|
||||
function submissionMemoryFormat(a,b){
|
||||
if(0===a || a ===null || a === ''||a=== undefined)return"--";
|
||||
var c=1024,d=b||1,e=["KB","MB","GB","TB","PB","EB","ZB","YB"],
|
||||
f=Math.floor(Math.log(a)/Math.log(c));
|
||||
return parseFloat((a/Math.pow(c,f)).toFixed(d))+" "+e[f]
|
||||
}
|
||||
|
||||
function submissionTimeFormat (time) {
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
type="textarea"
|
||||
:rows="8"
|
||||
id="own-textarea"
|
||||
placeholder="快来写下你的评论吧~😘"
|
||||
:placeholder="$t('m.Come_and_write_down_your_comments') + '~😘'"
|
||||
>
|
||||
</el-input>
|
||||
<div class="input-bottom">
|
||||
<span title="emoji表情">
|
||||
<span title="emoji">
|
||||
<el-popover
|
||||
placement="top-start"
|
||||
width="300"
|
||||
|
@ -34,7 +34,7 @@
|
|||
</span>
|
||||
<span
|
||||
class="markdown-key"
|
||||
title="行内代码"
|
||||
:title="$t('m.Inline_Code')"
|
||||
@click="addContentTips(0, false)"
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -53,7 +53,7 @@
|
|||
</span>
|
||||
<span
|
||||
class="markdown-key"
|
||||
title="代码块"
|
||||
:title="$t('m.Code_Block')"
|
||||
@click="addContentTips(1, false)"
|
||||
>
|
||||
<svg
|
||||
|
@ -73,7 +73,7 @@
|
|||
</span>
|
||||
<span
|
||||
class="markdown-key"
|
||||
title="链接"
|
||||
:title="$t('m.Link')"
|
||||
@click="addContentTips(2, false)"
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -91,7 +91,7 @@
|
|||
></span>
|
||||
<span
|
||||
class="markdown-key"
|
||||
title="无序列表"
|
||||
:title="$t('m.Unordered_list')"
|
||||
@click="addContentTips(3, false)"
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -109,7 +109,7 @@
|
|||
></span>
|
||||
<span
|
||||
class="markdown-key"
|
||||
title="有序列表"
|
||||
:title="$t('m.Ordered_List')"
|
||||
@click="addContentTips(4, false)"
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -127,14 +127,17 @@
|
|||
></span>
|
||||
<span class="own-btn-comment">
|
||||
<el-button class="btn" type="primary" round @click="commitComment"
|
||||
><i class="el-icon-edit"> 提交评论</i></el-button
|
||||
><i class="el-icon-edit">
|
||||
{{ $t('m.Submit_Comment') }}</i
|
||||
></el-button
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="comment-total">
|
||||
<div class="text">
|
||||
<span>全部评论</span><span class="number">{{ totalComment }}</span>
|
||||
<span>{{ $t('m.All_Comment') }}</span
|
||||
><span class="number">{{ totalComment }}</span>
|
||||
</div>
|
||||
</h3>
|
||||
<div
|
||||
|
@ -201,7 +204,7 @@
|
|||
>
|
||||
<i class="iconfont fa fa-thumbs-o-up"></i>
|
||||
<span class="like-num">{{
|
||||
item.likeNum > 0 ? item.likeNum + '人赞' : '赞'
|
||||
item.likeNum > 0 ? item.likeNum + $t('m.Like') : $t('m.Like')
|
||||
}}</span>
|
||||
</span>
|
||||
<span
|
||||
|
@ -209,7 +212,7 @@
|
|||
@click="showCommentInput(item)"
|
||||
>
|
||||
<i class="iconfont el-icon-chat-square"></i>
|
||||
<span>回复</span>
|
||||
<span>{{ $t('m.Reply') }}</span>
|
||||
</span>
|
||||
<span
|
||||
v-if="item.fromUid == userInfo.uid || isAdminRole"
|
||||
|
@ -217,7 +220,7 @@
|
|||
@click="deleteComment(item, commentIndex)"
|
||||
>
|
||||
<i class="iconfont el-icon-delete"></i>
|
||||
<span>删除</span>
|
||||
<span>{{ $t('m.Delete') }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="reply">
|
||||
|
@ -254,7 +257,7 @@
|
|||
v-if="reply.fromRole == 'admin'"
|
||||
>ADM</span
|
||||
>
|
||||
<span class="reply-text">回复</span>
|
||||
<span class="reply-text">{{ $t('m.Reply') }}</span>
|
||||
<span
|
||||
class="to-name"
|
||||
:title="reply.toName"
|
||||
|
@ -283,7 +286,7 @@
|
|||
@click="showCommentInput(item, reply)"
|
||||
>
|
||||
<i class="iconfont el-icon-chat-square"></i>
|
||||
<span>回复</span>
|
||||
<span>{{ $t('m.Reply') }}</span>
|
||||
</span>
|
||||
<span
|
||||
class="reply-opt reply-delete"
|
||||
|
@ -291,20 +294,22 @@
|
|||
@click="deleteReply(reply, commentIndex, replyIndex)"
|
||||
>
|
||||
<i class="iconfont el-icon-delete"></i>
|
||||
<span>删除</span>
|
||||
<span>{{ $t('m.Delete') }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="view-more item" v-if="item.totalReplyNum > 3">
|
||||
共<b>{{ item.totalReplyNum }}</b
|
||||
>条回复,
|
||||
{{ $t('m.Reply_Total') }}<b>{{ item.totalReplyNum }}</b
|
||||
>{{ $t('m.Replies') }},
|
||||
<a
|
||||
class="btn-more"
|
||||
@click="showAllReply(item)"
|
||||
v-if="!item.hadOpen"
|
||||
>点击查看全部</a
|
||||
>{{ $t('m.Click_Show_All') }}</a
|
||||
>
|
||||
<a class="btn-more" @click="pickWayReply(item)" v-else>收起</a>
|
||||
<a class="btn-more" @click="pickWayReply(item)" v-else>{{
|
||||
$t('m.Pick_up')
|
||||
}}</a>
|
||||
</div>
|
||||
<transition name="fade">
|
||||
<div class="input-wrapper" v-if="showItemId === item.id">
|
||||
|
@ -318,7 +323,7 @@
|
|||
>
|
||||
</el-input>
|
||||
<div class="input-bottom">
|
||||
<span title="emoji表情">
|
||||
<span title="emoji">
|
||||
<el-popover
|
||||
placement="top-start"
|
||||
width="300"
|
||||
|
@ -343,7 +348,7 @@
|
|||
</span>
|
||||
<span
|
||||
class="markdown-key"
|
||||
title="行内代码"
|
||||
:title="$t('m.Inline_Code')"
|
||||
@click="addContentTips(0, true)"
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -362,7 +367,7 @@
|
|||
</span>
|
||||
<span
|
||||
class="markdown-key"
|
||||
title="代码块"
|
||||
:title="$t('m.Code_Block')"
|
||||
@click="addContentTips(1, true)"
|
||||
>
|
||||
<svg
|
||||
|
@ -382,7 +387,7 @@
|
|||
</span>
|
||||
<span
|
||||
class="markdown-key"
|
||||
title="链接"
|
||||
:title="$t('m.Link')"
|
||||
@click="addContentTips(2, true)"
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -400,7 +405,7 @@
|
|||
></span>
|
||||
<span
|
||||
class="markdown-key"
|
||||
title="无序列表"
|
||||
:title="$t('m.Unordered_list')"
|
||||
@click="addContentTips(3, true)"
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -418,7 +423,7 @@
|
|||
></span>
|
||||
<span
|
||||
class="markdown-key"
|
||||
title="有序列表"
|
||||
:title="$t('m.Ordered_List')"
|
||||
@click="addContentTips(4, true)"
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -441,7 +446,7 @@
|
|||
round
|
||||
@click="cancel"
|
||||
size="small"
|
||||
>取消</el-button
|
||||
>{{ $t('m.Cancel') }}</el-button
|
||||
>
|
||||
<el-button
|
||||
class="btn"
|
||||
|
@ -449,7 +454,7 @@
|
|||
round
|
||||
@click="commitReply(item.id)"
|
||||
size="small"
|
||||
>发送</el-button
|
||||
>{{ $t('m.OK') }}</el-button
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -461,7 +466,7 @@
|
|||
</div>
|
||||
<div class="container loading-text" v-if="showloading">
|
||||
<a style="background: #fff;padding:10px;" @click="loadMoreComment"
|
||||
><span>加载更多...</span></a
|
||||
><span>{{ $t('m.Load_More') }}...</span></a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -497,7 +502,7 @@ export default {
|
|||
commentLikeMap: {},
|
||||
facelistVisiable: false,
|
||||
replyFacelistVisiable: false,
|
||||
replyPlaceholder: '写下你的评论吧~',
|
||||
replyPlaceholder: '',
|
||||
query: {
|
||||
limit: 10,
|
||||
currentPage: 1,
|
||||
|
@ -537,6 +542,9 @@ export default {
|
|||
methods: {
|
||||
init() {
|
||||
let queryParams = Object.assign({}, this.query);
|
||||
this.replyPlaceholder = this.$i18n.t(
|
||||
'm.Come_and_write_down_your_comments'
|
||||
);
|
||||
api.getCommentList(queryParams).then((res) => {
|
||||
let moreCommentList = res.data.data.commentList.records;
|
||||
for (let i = 0; i < moreCommentList.length; i++) {
|
||||
|
@ -582,7 +590,7 @@ export default {
|
|||
*/
|
||||
commitComment() {
|
||||
if (!this.isAuthenticated) {
|
||||
myMessage.warning('请先登录');
|
||||
myMessage.warning(this.$i18n.t('m.Please_login_first'));
|
||||
this.$store.dispatch('changeModalStatus', { visible: true });
|
||||
return;
|
||||
}
|
||||
|
@ -609,7 +617,7 @@ export default {
|
|||
|
||||
commitReply() {
|
||||
if (!this.isAuthenticated) {
|
||||
myMessage.warning('请先登录');
|
||||
myMessage.warning(this.$i18n.t('m.Please_login_first'));
|
||||
this.$store.dispatch('changeModalStatus', { visible: true });
|
||||
return;
|
||||
}
|
||||
|
@ -657,7 +665,9 @@ export default {
|
|||
this.replyObj.toName = reply.fromName;
|
||||
this.replyObj.toAvatar = reply.fromAvatar;
|
||||
} else {
|
||||
this.replyPlaceholder = '快来写下你的评论吧~';
|
||||
this.replyPlaceholder = this.$i18n.t(
|
||||
'm.Come_and_write_down_your_comments'
|
||||
);
|
||||
this.replyObj.commentId = item.id;
|
||||
this.replyObj.toUid = item.fromUid;
|
||||
this.replyObj.toName = item.fromName;
|
||||
|
@ -671,9 +681,9 @@ export default {
|
|||
*/
|
||||
|
||||
deleteComment(comment, commentIndex) {
|
||||
this.$confirm('此操作将删除该评论及其所有回复, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
this.$confirm(this.$i18n.t('m.Delete_Comment_Tips'), 'Tips', {
|
||||
confirmButtonText: this.$i18n.t('m.OK'),
|
||||
cancelButtonText: this.$i18n.t('m.Cancel'),
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
|
@ -697,9 +707,9 @@ export default {
|
|||
*/
|
||||
|
||||
deleteReply(reply, commentIndex, replyIndex) {
|
||||
this.$confirm('此操作将删除该回复, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
this.$confirm(this.$i18n.t('m.Delete_Reply_Tips'), 'Tips', {
|
||||
confirmButtonText: this.$i18n.t('m.OK'),
|
||||
cancelButtonText: this.$i18n.t('m.Cancel'),
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
|
@ -794,10 +804,10 @@ export default {
|
|||
tips = '[HOJ](https://hcode.top)';
|
||||
break;
|
||||
case 3:
|
||||
tips = '\n- 无序列表';
|
||||
tips = '\n- ...';
|
||||
break;
|
||||
case 4:
|
||||
tips = '\n1. 有序列表';
|
||||
tips = '\n1. ...';
|
||||
break;
|
||||
}
|
||||
if (isReply) {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
size="small"
|
||||
icon="el-icon-refresh"
|
||||
:loading="btnLoading"
|
||||
>Refresh</el-button
|
||||
>{{ $t('m.Refresh') }}</el-button
|
||||
>
|
||||
<el-button
|
||||
v-else
|
||||
|
@ -19,7 +19,7 @@
|
|||
icon="el-icon-back"
|
||||
@click="goBack"
|
||||
size="small"
|
||||
>Back</el-button
|
||||
>{{ $t('m.Back') }}</el-button
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -29,7 +29,7 @@
|
|||
v-if="!announcements.length"
|
||||
key="no-announcement"
|
||||
>
|
||||
<p>暂无公告</p>
|
||||
<p>{{ $t('m.No_Announcements') }}</p>
|
||||
</div>
|
||||
<template v-if="listVisible">
|
||||
<ul class="announcements-container" key="list">
|
||||
|
@ -155,7 +155,9 @@ export default {
|
|||
computed: {
|
||||
title() {
|
||||
if (this.listVisible) {
|
||||
return this.isContest ? 'Contest Announcements' : 'Announcements';
|
||||
return this.isContest
|
||||
? this.$i18n.t('m.Contest_Announcement')
|
||||
: this.$i18n.t('m.Announcement');
|
||||
} else {
|
||||
return this.announcement.title;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<el-row class="header">
|
||||
<el-col :xs="24" :sm="14" :md="14" :lg="14">
|
||||
<div class="select-row">
|
||||
<span>Lang:</span>
|
||||
<span>{{ $t('m.Lang') }}:</span>
|
||||
<span>
|
||||
<el-select
|
||||
:value="this.language"
|
||||
|
@ -17,7 +17,7 @@
|
|||
</el-select>
|
||||
</span>
|
||||
<span>
|
||||
<el-tooltip content="重置代码" placement="top" style="">
|
||||
<el-tooltip :content="$t('m.Reset_Code')" placement="top">
|
||||
<el-button
|
||||
icon="el-icon-refresh"
|
||||
@click="onResetClick"
|
||||
|
@ -26,7 +26,7 @@
|
|||
</el-tooltip>
|
||||
</span>
|
||||
<span>
|
||||
<el-tooltip content="上传文件" placement="top" style="">
|
||||
<el-tooltip :content="$t('m.Upload_file')" placement="top">
|
||||
<el-button
|
||||
icon="el-icon-upload"
|
||||
@click="onUploadFile"
|
||||
|
@ -46,7 +46,7 @@
|
|||
</el-col>
|
||||
<el-col :xs="24" :sm="10" :md="10" :lg="10">
|
||||
<div class="select-row fl-right">
|
||||
<span>Theme:</span>
|
||||
<span>{{ $t('m.Theme') }}:</span>
|
||||
<el-select
|
||||
:value="this.theme"
|
||||
@change="onThemeChange"
|
||||
|
@ -56,8 +56,9 @@
|
|||
<el-option
|
||||
v-for="item in themes"
|
||||
:key="item.label"
|
||||
:label="$t('m.' + item.label)"
|
||||
:value="item.value"
|
||||
>{{ item.label }}
|
||||
>{{ $t('m.' + item.label) }}
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<el-input
|
||||
v-model="formLogin.username"
|
||||
prefix-icon="el-icon-user-solid"
|
||||
placeholder="Username"
|
||||
:placeholder="$t('m.Login_Username')"
|
||||
width="100%"
|
||||
@keyup.enter.native="enterHandleLogin"
|
||||
></el-input>
|
||||
|
@ -19,7 +19,7 @@
|
|||
<el-input
|
||||
v-model="formLogin.password"
|
||||
prefix-icon="el-icon-lock"
|
||||
placeholder="Password"
|
||||
:placeholder="$t('m.Login_Password')"
|
||||
type="password"
|
||||
@keyup.enter.native="enterHandleLogin"
|
||||
></el-input>
|
||||
|
@ -31,7 +31,7 @@
|
|||
v-if="!needVerify"
|
||||
@click="handleLogin"
|
||||
:loading="btnLoginLoading"
|
||||
>登录</el-button
|
||||
>{{ $t('m.Login_Btn') }}</el-button
|
||||
>
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
|
@ -40,9 +40,9 @@
|
|||
trigger="click"
|
||||
v-else
|
||||
>
|
||||
<el-button type="primary" :loading="btnLoginLoading" slot="reference"
|
||||
>登录</el-button
|
||||
>
|
||||
<el-button type="primary" :loading="btnLoginLoading" slot="reference">{{
|
||||
$t('m.Login_Btn')
|
||||
}}</el-button>
|
||||
<slide-verify
|
||||
:l="42"
|
||||
:r="10"
|
||||
|
@ -50,13 +50,13 @@
|
|||
:h="100"
|
||||
:accuracy="3"
|
||||
@success="handleLogin"
|
||||
slider-text="请向右滑动验证"
|
||||
:slider-text="$t('m.Login_Verify')"
|
||||
ref="slideBlock"
|
||||
v-if="!verify.loginSuccess"
|
||||
>
|
||||
</slide-verify>
|
||||
<el-alert
|
||||
title="验证成功"
|
||||
:title="$t('m.Login_Verify_Success')"
|
||||
type="success"
|
||||
:description="verify.loginMsg"
|
||||
v-show="verify.loginSuccess"
|
||||
|
@ -70,13 +70,13 @@
|
|||
v-if="allow_register"
|
||||
type="primary"
|
||||
@click="switchMode('Register')"
|
||||
>没有账户? 现在注册!</el-link
|
||||
>{{ $t('m.Login_No_Account') }}</el-link
|
||||
>
|
||||
<el-link
|
||||
type="primary"
|
||||
@click="switchMode('ResetPwd')"
|
||||
style="float: right"
|
||||
>忘记密码</el-link
|
||||
>{{ $t('m.Login_Forget_Password') }}</el-link
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -104,25 +104,25 @@ export default {
|
|||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: 'The username is required',
|
||||
message: this.$i18n.t('m.Username_Check'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
max: 255,
|
||||
message: 'The longest length of a username is 255',
|
||||
message: this.$i18n.t('m.Username_Check_Max'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: 'The password is required',
|
||||
message: this.$i18n.t('m.Password_Check_Required'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 20,
|
||||
message: 'The length of the password is between 6 and 20',
|
||||
message: this.$i18n.t('m.Password_Check_Between'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
|
@ -148,7 +148,7 @@ export default {
|
|||
if (this.needVerify) {
|
||||
this.verify.loginSuccess = true;
|
||||
let time = (times / 1000).toFixed(1);
|
||||
this.verify.loginMsg = '本次耗时' + time + 's';
|
||||
this.verify.loginMsg = 'Total time ' + time + 's';
|
||||
setTimeout(() => {
|
||||
this.loginSlideBlockVisible = false;
|
||||
this.verify.loginSuccess = false;
|
||||
|
@ -167,7 +167,7 @@ export default {
|
|||
this.$store.commit('changeUserToken', jwt);
|
||||
this.$store.dispatch('setUserInfo', res.data.data);
|
||||
this.$store.dispatch('incrLoginFailNum', true);
|
||||
mMessage.success('欢迎回来~');
|
||||
mMessage.success(this.$i18n.t('m.Welcome_Back'));
|
||||
},
|
||||
(_) => {
|
||||
this.$store.dispatch('incrLoginFailNum', false);
|
||||
|
|
|
@ -16,37 +16,53 @@
|
|||
></el-image>
|
||||
</div>
|
||||
<el-menu-item index="/home"
|
||||
><i class="el-icon-s-home"></i>Home</el-menu-item
|
||||
><i class="el-icon-s-home"></i>{{ $t('m.NavBar_Home') }}</el-menu-item
|
||||
>
|
||||
<el-menu-item index="/problem"
|
||||
><i class="el-icon-s-grid"></i>Problem</el-menu-item
|
||||
><i class="el-icon-s-grid"></i
|
||||
>{{ $t('m.NavBar_Problem') }}</el-menu-item
|
||||
>
|
||||
<el-menu-item index="/contest"
|
||||
><i class="el-icon-trophy"></i>Contest</el-menu-item
|
||||
><i class="el-icon-trophy"></i
|
||||
>{{ $t('m.NavBar_Contest') }}</el-menu-item
|
||||
>
|
||||
<el-menu-item index="/status"
|
||||
><i class="el-icon-s-marketing"></i>Status</el-menu-item
|
||||
><i class="el-icon-s-marketing"></i
|
||||
>{{ $t('m.NavBar_Status') }}</el-menu-item
|
||||
>
|
||||
<el-submenu index="rank">
|
||||
<template slot="title"><i class="el-icon-s-data"></i>Rank</template>
|
||||
<el-menu-item index="/acm-rank">ACM Rank</el-menu-item>
|
||||
<el-menu-item index="/oi-rank">OI Rank</el-menu-item>
|
||||
<template slot="title"
|
||||
><i class="el-icon-s-data"></i>{{ $t('m.NavBar_Rank') }}</template
|
||||
>
|
||||
<el-menu-item index="/acm-rank">{{
|
||||
$t('m.NavBar_ACM_Rank')
|
||||
}}</el-menu-item>
|
||||
<el-menu-item index="/oi-rank">{{
|
||||
$t('m.NavBar_OI_Rank')
|
||||
}}</el-menu-item>
|
||||
</el-submenu>
|
||||
|
||||
<el-menu-item index="/discussion"
|
||||
><i class="el-icon-s-comment"></i>Discussion</el-menu-item
|
||||
><i class="el-icon-s-comment"></i
|
||||
>{{ $t('m.NavBar_Discussion') }}</el-menu-item
|
||||
>
|
||||
|
||||
<el-submenu index="about">
|
||||
<template slot="title"><i class="el-icon-info"></i>About</template>
|
||||
<el-menu-item index="/introduction">Introduction</el-menu-item>
|
||||
<el-menu-item index="/developer">Developer</el-menu-item>
|
||||
<template slot="title"
|
||||
><i class="el-icon-info"></i>{{ $t('m.NavBar_About') }}</template
|
||||
>
|
||||
<el-menu-item index="/introduction">{{
|
||||
$t('m.NavBar_Introduction')
|
||||
}}</el-menu-item>
|
||||
<el-menu-item index="/developer">{{
|
||||
$t('m.NavBar_Developer')
|
||||
}}</el-menu-item>
|
||||
</el-submenu>
|
||||
|
||||
<template v-if="!isAuthenticated">
|
||||
<div class="btn-menu">
|
||||
<el-button type="primary" round @click="handleBtnClick('Login')"
|
||||
>Login
|
||||
>{{ $t('m.NavBar_Login') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="websiteConfig.register"
|
||||
|
@ -54,7 +70,7 @@
|
|||
type="danger"
|
||||
@click="handleBtnClick('Register')"
|
||||
style="margin-left: 5px"
|
||||
>Register
|
||||
>{{ $t('m.NavBar_Register') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -70,17 +86,21 @@
|
|||
</span>
|
||||
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="/user-home">Home</el-dropdown-item>
|
||||
<el-dropdown-item command="/status?onlyMine=true"
|
||||
>Submissions</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item command="/setting">Setting</el-dropdown-item>
|
||||
<el-dropdown-item v-if="isAdminRole" command="/admin"
|
||||
>Management</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item divided command="/logout"
|
||||
>Logout</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item command="/user-home">{{
|
||||
$t('m.NavBar_UserHome')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item command="/status?onlyMine=true">{{
|
||||
$t('m.NavBar_Submissions')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item command="/setting">{{
|
||||
$t('m.NavBar_Setting')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item v-if="isAdminRole" command="/admin">{{
|
||||
$t('m.NavBar_Management')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item divided command="/logout">{{
|
||||
$t('m.NavBar_Logout')
|
||||
}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<avatar
|
||||
|
@ -108,14 +128,14 @@
|
|||
slot="right"
|
||||
@click="handleBtnClick('Login')"
|
||||
v-show="!isAuthenticated"
|
||||
>Login</mu-button
|
||||
>{{ $t('m.NavBar_Login') }}</mu-button
|
||||
>
|
||||
<mu-button
|
||||
flat
|
||||
slot="right"
|
||||
@click="handleBtnClick('Register')"
|
||||
v-show="!isAuthenticated && websiteConfig.register"
|
||||
>Register</mu-button
|
||||
>{{ $t('m.NavBar_Register') }}</mu-button
|
||||
>
|
||||
|
||||
<mu-menu
|
||||
|
@ -129,31 +149,41 @@
|
|||
<mu-list slot="content" @change="handleCommand">
|
||||
<mu-list-item button value="/user-home">
|
||||
<mu-list-item-content>
|
||||
<mu-list-item-title>Home</mu-list-item-title>
|
||||
<mu-list-item-title>{{
|
||||
$t('m.NavBar_UserHome')
|
||||
}}</mu-list-item-title>
|
||||
</mu-list-item-content>
|
||||
</mu-list-item>
|
||||
|
||||
<mu-list-item button value="/status?onlyMine=true">
|
||||
<mu-list-item-content>
|
||||
<mu-list-item-title>Submissions</mu-list-item-title>
|
||||
<mu-list-item-title>{{
|
||||
$t('m.NavBar_Submissions')
|
||||
}}</mu-list-item-title>
|
||||
</mu-list-item-content>
|
||||
</mu-list-item>
|
||||
<mu-list-item button value="/setting">
|
||||
<mu-list-item-content>
|
||||
<mu-list-item-title>Setting</mu-list-item-title>
|
||||
<mu-list-item-title>{{
|
||||
$t('m.NavBar_Setting')
|
||||
}}</mu-list-item-title>
|
||||
</mu-list-item-content>
|
||||
</mu-list-item>
|
||||
|
||||
<mu-list-item button value="/admin" v-show="isAdminRole">
|
||||
<mu-list-item-content>
|
||||
<mu-list-item-title>Management</mu-list-item-title>
|
||||
<mu-list-item-title>{{
|
||||
$t('m.NavBar_Management')
|
||||
}}</mu-list-item-title>
|
||||
</mu-list-item-content>
|
||||
</mu-list-item>
|
||||
<mu-divider></mu-divider>
|
||||
|
||||
<mu-list-item button value="/logout">
|
||||
<mu-list-item-content>
|
||||
<mu-list-item-title>Logout</mu-list-item-title>
|
||||
<mu-list-item-title>{{
|
||||
$t('m.NavBar_Logout')
|
||||
}}</mu-list-item-title>
|
||||
</mu-list-item-content>
|
||||
</mu-list-item>
|
||||
</mu-list>
|
||||
|
@ -175,7 +205,7 @@
|
|||
<mu-list-item-action>
|
||||
<mu-icon value="home" size="24"></mu-icon>
|
||||
</mu-list-item-action>
|
||||
<mu-list-item-title>Home</mu-list-item-title>
|
||||
<mu-list-item-title>{{ $t('m.NavBar_Home') }}</mu-list-item-title>
|
||||
</mu-list-item>
|
||||
|
||||
<mu-list-item
|
||||
|
@ -187,7 +217,9 @@
|
|||
<mu-list-item-action>
|
||||
<mu-icon value=":el-icon-s-grid" size="24"></mu-icon>
|
||||
</mu-list-item-action>
|
||||
<mu-list-item-title>Problem</mu-list-item-title>
|
||||
<mu-list-item-title>{{
|
||||
$t('m.NavBar_Problem')
|
||||
}}</mu-list-item-title>
|
||||
</mu-list-item>
|
||||
|
||||
<mu-list-item
|
||||
|
@ -199,7 +231,9 @@
|
|||
<mu-list-item-action>
|
||||
<mu-icon value=":el-icon-trophy" size="24"></mu-icon>
|
||||
</mu-list-item-action>
|
||||
<mu-list-item-title>Contest</mu-list-item-title>
|
||||
<mu-list-item-title>{{
|
||||
$t('m.NavBar_Contest')
|
||||
}}</mu-list-item-title>
|
||||
</mu-list-item>
|
||||
|
||||
<mu-list-item
|
||||
|
@ -211,7 +245,7 @@
|
|||
<mu-list-item-action>
|
||||
<mu-icon value=":el-icon-s-marketing" size="24"></mu-icon>
|
||||
</mu-list-item-action>
|
||||
<mu-list-item-title>Status</mu-list-item-title>
|
||||
<mu-list-item-title>{{ $t('m.NavBar_Status') }}</mu-list-item-title>
|
||||
</mu-list-item>
|
||||
|
||||
<mu-list-item
|
||||
|
@ -224,7 +258,7 @@
|
|||
<mu-list-item-action>
|
||||
<mu-icon value=":el-icon-s-data" size="24"></mu-icon>
|
||||
</mu-list-item-action>
|
||||
<mu-list-item-title>Rank</mu-list-item-title>
|
||||
<mu-list-item-title>{{ $t('m.NavBar_Rank') }}</mu-list-item-title>
|
||||
<mu-list-item-action>
|
||||
<mu-icon
|
||||
class="toggle-icon"
|
||||
|
@ -240,7 +274,7 @@
|
|||
@click="opendrawer = !opendrawer"
|
||||
active-class="mobile-menu-active"
|
||||
>
|
||||
<mu-list-item-title>ACM Rank</mu-list-item-title>
|
||||
<mu-list-item-title>{{ $t('m.NavBar_Rank') }}</mu-list-item-title>
|
||||
</mu-list-item>
|
||||
<mu-list-item
|
||||
button
|
||||
|
@ -250,7 +284,9 @@
|
|||
@click="opendrawer = !opendrawer"
|
||||
active-class="mobile-menu-active"
|
||||
>
|
||||
<mu-list-item-title>OI Rank</mu-list-item-title>
|
||||
<mu-list-item-title>{{
|
||||
$t('m.NavBar_OI_Rank')
|
||||
}}</mu-list-item-title>
|
||||
</mu-list-item>
|
||||
</mu-list-item>
|
||||
|
||||
|
@ -263,7 +299,9 @@
|
|||
<mu-list-item-action>
|
||||
<mu-icon value=":fa fa-comments" size="24"></mu-icon>
|
||||
</mu-list-item-action>
|
||||
<mu-list-item-title>Discussion</mu-list-item-title>
|
||||
<mu-list-item-title>{{
|
||||
$t('m.NavBar_Discussion')
|
||||
}}</mu-list-item-title>
|
||||
</mu-list-item>
|
||||
|
||||
<mu-list-item
|
||||
|
@ -276,7 +314,7 @@
|
|||
<mu-list-item-action>
|
||||
<mu-icon value=":el-icon-info" size="24"></mu-icon>
|
||||
</mu-list-item-action>
|
||||
<mu-list-item-title>About</mu-list-item-title>
|
||||
<mu-list-item-title>{{ $t('m.NavBar_About') }}</mu-list-item-title>
|
||||
<mu-list-item-action>
|
||||
<mu-icon
|
||||
class="toggle-icon"
|
||||
|
@ -292,7 +330,9 @@
|
|||
@click="opendrawer = !opendrawer"
|
||||
active-class="mobile-menu-active"
|
||||
>
|
||||
<mu-list-item-title>Introduction</mu-list-item-title>
|
||||
<mu-list-item-title>{{
|
||||
$t('m.NavBar_Introduction')
|
||||
}}</mu-list-item-title>
|
||||
</mu-list-item>
|
||||
<mu-list-item
|
||||
button
|
||||
|
@ -302,7 +342,9 @@
|
|||
@click="opendrawer = !opendrawer"
|
||||
active-class="mobile-menu-active"
|
||||
>
|
||||
<mu-list-item-title>Developer</mu-list-item-title>
|
||||
<mu-list-item-title>{{
|
||||
$t('m.NavBar_Developer')
|
||||
}}</mu-list-item-title>
|
||||
</mu-list-item>
|
||||
</mu-list-item>
|
||||
</mu-list>
|
||||
|
@ -415,10 +457,15 @@ export default {
|
|||
},
|
||||
title: {
|
||||
get() {
|
||||
let ojName = this.websiteConfig.shortName
|
||||
? this.websiteConfig.shortName.toUpperCase()
|
||||
: 'OJ';
|
||||
if (this.modalStatus.mode == 'ResetPwd') {
|
||||
return 'Reset Password - HOJ';
|
||||
return this.$i18n.t('m.Dialog_Reset_Password') + ' - ' + ojName;
|
||||
} else {
|
||||
return this.modalStatus.mode + ' - HOJ';
|
||||
return (
|
||||
this.$i18n.t('m.Dialog_' + this.modalStatus.mode) + ' - ' + ojName
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<el-input
|
||||
v-model="registerForm.username"
|
||||
prefix-icon="el-icon-user-solid"
|
||||
placeholder="Please Enter Username"
|
||||
:placeholder="$t('m.Register_Username')"
|
||||
@keyup.enter.native="handleRegister"
|
||||
width="100%"
|
||||
></el-input>
|
||||
|
@ -15,7 +15,7 @@
|
|||
<el-input
|
||||
v-model="registerForm.password"
|
||||
prefix-icon="el-icon-lock"
|
||||
placeholder="Please Enter Password"
|
||||
:placeholder="$t('m.Register_Password')"
|
||||
@keyup.enter.native="handleRegister"
|
||||
type="password"
|
||||
></el-input>
|
||||
|
@ -24,7 +24,7 @@
|
|||
<el-input
|
||||
v-model="registerForm.passwordAgain"
|
||||
prefix-icon="el-icon-lock"
|
||||
placeholder="Please Enter Password Again"
|
||||
:placeholder="$t('m.Register_Password_Again')"
|
||||
@keyup.enter.native="handleRegister"
|
||||
type="password"
|
||||
></el-input>
|
||||
|
@ -33,7 +33,7 @@
|
|||
<el-input
|
||||
v-model="registerForm.email"
|
||||
prefix-icon="el-icon-message"
|
||||
placeholder="Please Enter Email"
|
||||
:placeholder="$t('m.Register_Email')"
|
||||
@keyup.enter.native="handleRegister"
|
||||
>
|
||||
<el-button
|
||||
|
@ -51,7 +51,7 @@
|
|||
<el-input
|
||||
v-model="registerForm.code"
|
||||
prefix-icon="el-icon-s-check"
|
||||
placeholder="Please enter the captcha from the email"
|
||||
:placeholder="$t('m.Register_Email_Captcha')"
|
||||
@keyup.enter.native="handleRegister"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
@ -62,11 +62,11 @@
|
|||
@click="handleRegister()"
|
||||
:loading="btnRegisterLoading"
|
||||
>
|
||||
注册
|
||||
{{ $t('m.Register_Btn') }}
|
||||
</el-button>
|
||||
<el-link type="primary" @click="switchMode('Login')"
|
||||
>已有账户? 返回登录!</el-link
|
||||
>
|
||||
<el-link type="primary" @click="switchMode('Login')">{{
|
||||
$t('m.Register_Already_Registed')
|
||||
}}</el-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -80,7 +80,7 @@ export default {
|
|||
api.checkUsernameOrEmail(value, undefined).then(
|
||||
(res) => {
|
||||
if (res.data.data.username === true) {
|
||||
callback(new Error('The username already exists'));
|
||||
callback(new Error(this.$i18n.t('m.The_username_already_exists')));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ export default {
|
|||
api.checkUsernameOrEmail(undefined, value).then(
|
||||
(res) => {
|
||||
if (res.data.data.email === true) {
|
||||
callback(new Error('The email already exists'));
|
||||
callback(new Error(this.$i18n.t('m.The_email_already_exists')));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ export default {
|
|||
|
||||
const CheckAgainPassword = (rule, value, callback) => {
|
||||
if (value !== this.registerForm.password) {
|
||||
callback(new Error('Password does not match'));
|
||||
callback(new Error(this.$i18n.t('m.Password_does_not_match')));
|
||||
}
|
||||
callback();
|
||||
};
|
||||
|
@ -128,15 +128,19 @@ export default {
|
|||
sendEmailError: false,
|
||||
rules: {
|
||||
username: [
|
||||
{ required: true, message: 'Username is required', trigger: 'blur' },
|
||||
{
|
||||
required: true,
|
||||
message: this.$i18n.t('m.Username_Check_Required'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
validator: CheckUsernameNotExist,
|
||||
trigger: 'blur',
|
||||
message: 'The username already exists',
|
||||
message: this.$i18n.t('m.The_username_already_exists'),
|
||||
},
|
||||
{
|
||||
max: 255,
|
||||
message: 'The longest length of a username is 255',
|
||||
message: this.$i18n.t('m.Username_Check_Max'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
|
@ -144,30 +148,30 @@ export default {
|
|||
email: [
|
||||
{
|
||||
required: true,
|
||||
message: 'The email is required',
|
||||
message: this.$i18n.t('m.Email_Check_Required'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
type: 'email',
|
||||
message: 'The email format is incorrect',
|
||||
message: this.$i18n.t('m.Email_Check_Format'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
validator: CheckEmailNotExist,
|
||||
message: 'The email already exists',
|
||||
message: this.$i18n.t('m.The_email_already_exists'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: 'The password is required',
|
||||
message: this.$i18n.t('m.Password_Check_Required'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 20,
|
||||
message: 'The length of the password is between 6 and 20',
|
||||
message: this.$i18n.t('m.Password_Check_Between'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
{ validator: CheckPassword, trigger: 'blur' },
|
||||
|
@ -175,7 +179,7 @@ export default {
|
|||
passwordAgain: [
|
||||
{
|
||||
required: true,
|
||||
message: 'The password again is required',
|
||||
message: this.$i18n.t('m.Password_Again_Check_Required'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
{ validator: CheckAgainPassword, trigger: 'change' },
|
||||
|
@ -183,13 +187,13 @@ export default {
|
|||
code: [
|
||||
{
|
||||
required: true,
|
||||
message: 'The captcha must be six digits',
|
||||
message: this.$i18n.t('m.Code_Check_Required'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 6,
|
||||
message: 'The captcha must be six digits',
|
||||
message: this.$i18n.t('m.Code_Check_Length'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
|
@ -222,13 +226,13 @@ export default {
|
|||
sendRegisterEmail() {
|
||||
var emailReg = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/;
|
||||
if (!emailReg.test(this.registerForm.email)) {
|
||||
mMessage.error('请检查邮箱格式!');
|
||||
mMessage.error(this.$i18n.t('m.Email_Check_Format'));
|
||||
return;
|
||||
}
|
||||
this.btnEmailLoading = true;
|
||||
this.countdownNum = '正在处理...';
|
||||
this.countdownNum = 'Waiting...';
|
||||
if (this.registerForm.email) {
|
||||
mMessage.info('请稍后...系统正在处理中...');
|
||||
mMessage.info(this.$i18n.t('m.The_system_is_processing'));
|
||||
api.getRegisterEmail(this.registerForm.email).then(
|
||||
(res) => {
|
||||
if (res.data.msg != null) {
|
||||
|
@ -253,7 +257,7 @@ export default {
|
|||
this.btnRegisterLoading = true;
|
||||
api.register(formData).then(
|
||||
(res) => {
|
||||
mMessage.success(res.data.msg);
|
||||
mMessage.success(this.$i18n.t('m.Thanks_for_registering'));
|
||||
this.switchMode('Login');
|
||||
this.btnRegisterLoading = false;
|
||||
},
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<el-input
|
||||
v-model="formResetPassword.email"
|
||||
prefix-icon="el-icon-message"
|
||||
placeholder="Please Enter Your Email"
|
||||
:placeholder="$t('m.Reset_Password_Email')"
|
||||
>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
@ -15,7 +15,7 @@
|
|||
<el-input
|
||||
v-model="formResetPassword.captcha"
|
||||
prefix-icon="el-icon-s-check"
|
||||
placeholder="Please Enter the captcha"
|
||||
:placeholder="$t('m.Reset_Password_Captcha')"
|
||||
></el-input>
|
||||
</div>
|
||||
<div id="captchaImg">
|
||||
|
@ -35,9 +35,9 @@
|
|||
>
|
||||
{{ resetText }}
|
||||
</el-button>
|
||||
<el-link type="primary" @click="switchMode('Login')"
|
||||
>想起密码? 返回登录!</el-link
|
||||
>
|
||||
<el-link type="primary" @click="switchMode('Login')">{{
|
||||
$t('m.Remember_Passowrd_To_Login')
|
||||
}}</el-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -60,7 +60,7 @@ export default {
|
|||
);
|
||||
};
|
||||
return {
|
||||
resetText: '发送重置密码的邮件',
|
||||
resetText: 'Send Password Reset Email',
|
||||
btnResetPwdLoading: false,
|
||||
btnResetPwdDisabled: false,
|
||||
captchaSrc: '',
|
||||
|
@ -92,6 +92,7 @@ export default {
|
|||
};
|
||||
},
|
||||
mounted() {
|
||||
this.resetText = this.$i18n.t('m.Send_Password_Reset_Email');
|
||||
this.getCaptcha();
|
||||
},
|
||||
methods: {
|
||||
|
@ -110,10 +111,10 @@ export default {
|
|||
},
|
||||
countDown() {
|
||||
let i = this.time;
|
||||
this.resetText = i + '秒后,可重新发送重置密码的邮件...';
|
||||
this.resetText = i + 's, ' + this.$i18n.t('m.Watting_Can_Resend_Email');
|
||||
if (i == 0) {
|
||||
this.btnResetPwdDisabled = false;
|
||||
this.resetText = '发送重置密码的邮件';
|
||||
this.resetText = this.$i18n.t('m.Send_Password_Reset_Email');
|
||||
return;
|
||||
}
|
||||
setTimeout(() => {
|
||||
|
@ -123,8 +124,8 @@ export default {
|
|||
handleResetPwd() {
|
||||
this.$refs['formResetPassword'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.resetText = '正在处理...';
|
||||
mMessage.info('请稍后...系统正在处理中...');
|
||||
this.resetText = 'Waiting...';
|
||||
mMessage.info(this.$i18n.t('m.The_system_is_processing'));
|
||||
this.btnResetPwdLoading = true;
|
||||
this.btnResetPwdDisabled = true;
|
||||
api.applyResetPassword(this.formResetPassword).then(
|
||||
|
@ -142,7 +143,7 @@ export default {
|
|||
this.formResetPassword.captchaKey = '';
|
||||
this.btnResetPwdLoading = false;
|
||||
this.btnResetPwdDisabled = false;
|
||||
this.resetText = '重新发送';
|
||||
this.resetText = this.$i18n.t('m.Send_Password_Reset_Email');
|
||||
this.getCaptcha();
|
||||
}
|
||||
);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<el-row :gutter="20">
|
||||
<el-col :sm="24" :md="10" :lg="10">
|
||||
<div class="left">
|
||||
<p class="section-title">Change Password</p>
|
||||
<p class="section-title">{{ $t('m.Change_Password') }}</p>
|
||||
<el-form
|
||||
class="setting-content"
|
||||
ref="formPassword"
|
||||
|
@ -31,7 +31,7 @@
|
|||
slot="reference"
|
||||
:loading="loading.btnPassword"
|
||||
:disabled="disabled.btnPassword"
|
||||
>Update Password</el-button
|
||||
>{{ $t('m.Update_Password') }}</el-button
|
||||
>
|
||||
<slide-verify
|
||||
:l="42"
|
||||
|
@ -41,13 +41,13 @@
|
|||
:accuracy="3"
|
||||
@success="changePassword"
|
||||
@again="onAgain('password')"
|
||||
slider-text="请向右滑动验证"
|
||||
:slider-text="$t('m.Slide_Verify')"
|
||||
ref="passwordSlideBlock"
|
||||
v-show="!verify.passwordSuccess"
|
||||
>
|
||||
</slide-verify>
|
||||
<el-alert
|
||||
title="验证成功"
|
||||
:title="$t('m.Slide_Verify_Success')"
|
||||
type="success"
|
||||
:description="verify.passwordMsg"
|
||||
v-show="verify.passwordSuccess"
|
||||
|
@ -76,7 +76,7 @@
|
|||
</el-col>
|
||||
<el-col :sm="24" :md="10" :lg="10">
|
||||
<div class="right">
|
||||
<p class="section-title">Change Email</p>
|
||||
<p class="section-title">{{ $t('m.Change_Email') }}</p>
|
||||
<el-form
|
||||
class="setting-content"
|
||||
ref="formEmail"
|
||||
|
@ -104,7 +104,7 @@
|
|||
slot="reference"
|
||||
:loading="loading.btnEmailLoading"
|
||||
:disabled="disabled.btnEmail"
|
||||
>Update Email</el-button
|
||||
>{{ $t('m.Update_Email') }}</el-button
|
||||
>
|
||||
<slide-verify
|
||||
:l="42"
|
||||
|
@ -114,13 +114,13 @@
|
|||
:accuracy="3"
|
||||
@success="changeEmail"
|
||||
@again="onAgain('email')"
|
||||
slider-text="请向右滑动验证"
|
||||
:slider-text="$t('m.Slide_Verify')"
|
||||
ref="emailSlideBlock"
|
||||
v-show="!verify.emailSuccess"
|
||||
>
|
||||
</slide-verify>
|
||||
<el-alert
|
||||
title="验证成功"
|
||||
:title="$t('m.Slide_Verify_Success')"
|
||||
type="success"
|
||||
:description="verify.emailMsg"
|
||||
v-show="verify.emailSuccess"
|
||||
|
@ -157,25 +157,26 @@ export default {
|
|||
{
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
message: 'The old password is required',
|
||||
},
|
||||
{
|
||||
trigger: 'blur',
|
||||
min: 6,
|
||||
max: 20,
|
||||
message: 'The length of the password is between 6 and 20',
|
||||
message: this.$i18n.t('m.Password_Check_Between'),
|
||||
},
|
||||
];
|
||||
const CheckAgainPassword = (rule, value, callback) => {
|
||||
if (value !== this.formPassword.newPassword) {
|
||||
callback(new Error('Password does not match'));
|
||||
callback(new Error(this.$i18n.t('m.Password_does_not_match')));
|
||||
}
|
||||
callback();
|
||||
};
|
||||
const CheckNewPassword = (rule, value, callback) => {
|
||||
if (this.formPassword.oldPassword !== '') {
|
||||
if (this.formPassword.oldPassword === this.formPassword.newPassword) {
|
||||
callback(new Error("The new password doesn't change"));
|
||||
callback(
|
||||
new Error(this.$i18n.t('m.The_new_password_does_not_change'))
|
||||
);
|
||||
} else {
|
||||
// 对第二个密码框再次验证
|
||||
this.$refs.formPassword.validateField('again_password');
|
||||
|
@ -186,7 +187,7 @@ export default {
|
|||
const CheckEmail = (rule, value, callback) => {
|
||||
if (this.formEmail.oldEmail !== '') {
|
||||
if (this.formEmail.oldEmail === this.formEmail.newEmail) {
|
||||
callback(new Error("The new email doesn't change"));
|
||||
callback(new Error(this.$i18n.t('m.The_new_email_does_not_change')));
|
||||
}
|
||||
}
|
||||
callback();
|
||||
|
@ -238,13 +239,12 @@ export default {
|
|||
{
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
message: 'The new password is required',
|
||||
},
|
||||
{
|
||||
trigger: 'blur',
|
||||
min: 6,
|
||||
max: 20,
|
||||
message: 'The length of the password is between 6 and 20',
|
||||
message: this.$i18n.t('m.Password_Check_Between'),
|
||||
},
|
||||
{ validator: CheckNewPassword, trigger: 'blur' },
|
||||
],
|
||||
|
@ -252,7 +252,7 @@ export default {
|
|||
{
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
message: 'The again password is required',
|
||||
message: this.$i18n.t('m.Password_Again_Check_Required'),
|
||||
},
|
||||
{ validator: CheckAgainPassword, trigger: 'blur' },
|
||||
],
|
||||
|
@ -262,13 +262,13 @@ export default {
|
|||
newEmail: [
|
||||
{
|
||||
required: true,
|
||||
message: 'The new email is required',
|
||||
message: this.$i18n.t('m.Email_Check_Required'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
type: 'email',
|
||||
trigger: 'change',
|
||||
message: 'The email format is incorrect',
|
||||
message: this.$i18n.t('m.Email_Check_Format'),
|
||||
},
|
||||
{ validator: CheckEmail, trigger: 'blur' },
|
||||
],
|
||||
|
@ -282,7 +282,7 @@ export default {
|
|||
changePassword(times) {
|
||||
this.verify.passwordSuccess = true;
|
||||
let time = (times / 1000).toFixed(1);
|
||||
this.verify.passwordMsg = '本次耗时' + time + 's';
|
||||
this.verify.passwordMsg = 'Total time ' + time + 's';
|
||||
setTimeout(() => {
|
||||
this.visible.passwordSlideBlock = false;
|
||||
this.verify.passwordSuccess = false;
|
||||
|
@ -299,10 +299,10 @@ export default {
|
|||
(res) => {
|
||||
this.loading.btnPassword = false;
|
||||
if (res.data.data.code == 200) {
|
||||
myMessage.success(res.data.msg);
|
||||
myMessage.success(this.$i18n.t('m.Update_Successfully'));
|
||||
this.visible.passwordAlert = {
|
||||
show: true,
|
||||
title: '修改成功',
|
||||
title: this.$i18n.t('m.Update_Successfully'),
|
||||
type: 'success',
|
||||
description: res.data.data.msg,
|
||||
};
|
||||
|
@ -314,7 +314,7 @@ export default {
|
|||
myMessage.error(res.data.msg);
|
||||
this.visible.passwordAlert = {
|
||||
show: true,
|
||||
title: '修改失败',
|
||||
title: this.$i18n.t('m.Update_Failed'),
|
||||
type: 'warning',
|
||||
description: res.data.data.msg,
|
||||
};
|
||||
|
@ -334,7 +334,7 @@ export default {
|
|||
changeEmail(times) {
|
||||
this.verify.emailSuccess = true;
|
||||
let time = (times / 1000).toFixed(1);
|
||||
this.verify.emailMsg = '本次耗时' + time + 's';
|
||||
this.verify.emailMsg = 'Total time ' + time + 's';
|
||||
setTimeout(() => {
|
||||
this.visible.emailSlideBlock = false;
|
||||
this.verify.emailSuccess = false;
|
||||
|
@ -349,10 +349,10 @@ export default {
|
|||
(res) => {
|
||||
this.loading.btnEmail = false;
|
||||
if (res.data.data.code == 200) {
|
||||
myMessage.success(res.data.msg);
|
||||
myMessage.success(this.$i18n.t('m.Update_Successfully'));
|
||||
this.visible.emailAlert = {
|
||||
show: true,
|
||||
title: '修改成功',
|
||||
title: this.$i18n.t('m.Update_Successfully'),
|
||||
type: 'success',
|
||||
description: res.data.data.msg,
|
||||
};
|
||||
|
@ -364,7 +364,7 @@ export default {
|
|||
myMessage.error(res.data.msg);
|
||||
this.visible.emailAlert = {
|
||||
show: true,
|
||||
title: '修改失败',
|
||||
title: this.$i18n.t('m.Update_Failed'),
|
||||
type: 'warning',
|
||||
description: res.data.data.msg,
|
||||
};
|
||||
|
@ -387,7 +387,7 @@ export default {
|
|||
} else {
|
||||
this.$refs.emailSlideBlock.reset();
|
||||
}
|
||||
myMessage.warning('速度过快,可能为机器操作!请重新验证!');
|
||||
myMessage.warning(this.$i18n.t('m.Guess_robot'));
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="section-title">Avatar Setting</div>
|
||||
<div class="section-title">{{ $t('m.Avatar_Setting') }}</div>
|
||||
<div class="section-main">
|
||||
<avatar
|
||||
:username="formProfile.username"
|
||||
|
@ -19,7 +19,7 @@
|
|||
>
|
||||
<div style="padding: 20px 0">
|
||||
<i class="el-icon-upload" style="color: #3399ff;font-size:52px"></i>
|
||||
<p>将头像图片拖放到此处,或者单击手动选择。</p>
|
||||
<p>{{ $t('m.Upload_avatar_hint') }}</p>
|
||||
</div>
|
||||
</el-upload>
|
||||
</template>
|
||||
|
@ -108,11 +108,11 @@
|
|||
</template>
|
||||
<el-dialog
|
||||
:visible.sync="uploadModalVisible"
|
||||
title="上传头像"
|
||||
:title="$t('m.Upload')"
|
||||
width="350px"
|
||||
>
|
||||
<div class="upload-modal">
|
||||
<p class="notice">你的头像将被设置为如下:</p>
|
||||
<p class="notice">{{ $t('m.Your_new_avatar') + ':' }}</p>
|
||||
<img :src="uploadImgSrc" />
|
||||
</div>
|
||||
<div slot="footer">
|
||||
|
@ -120,13 +120,13 @@
|
|||
@click="uploadAvatar"
|
||||
:loading="loadingUploadBtn"
|
||||
type="primary"
|
||||
>Upload</el-button
|
||||
>{{ $t('m.Upload') }}</el-button
|
||||
>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
<div class="section-title">UserInfo Setting</div>
|
||||
<div class="section-title">{{ $t('m.UserInfo_Setting') }}</div>
|
||||
<el-form ref="formProfile" :model="formProfile">
|
||||
<el-row :gutter="30" justify="space-around">
|
||||
<el-col :md="10" :xs="24">
|
||||
|
@ -168,7 +168,7 @@
|
|||
type="primary"
|
||||
@click="updateUserInfo"
|
||||
:loading="loadingSaveBtn"
|
||||
>Save All</el-button
|
||||
>{{ $t('m.Save') }}</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
import Vue from 'vue'
|
||||
import store from "@/store"
|
||||
import VueI18n from 'vue-i18n'
|
||||
import elenUS from 'element-ui/lib/locale/lang/en'
|
||||
import elzhCN from 'element-ui/lib/locale/lang/zh-CN'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
const languages = [
|
||||
{value: 'en-US', label: 'English', el: elenUS},
|
||||
{value: 'zh-CN', label: '简体中文', el: elzhCN},
|
||||
]
|
||||
const messages = {}
|
||||
|
||||
// combine admin and oj
|
||||
for (let lang of languages) {
|
||||
let locale = lang.value
|
||||
let m = require(`./oj/${locale}`).m
|
||||
// Object.assign(m, require(`./admin/${locale}`).m)
|
||||
messages[locale] = Object.assign({m: m}, lang.el);
|
||||
}
|
||||
|
||||
|
||||
// load language packages
|
||||
export default new VueI18n({
|
||||
locale: store.getters.webLanguage,
|
||||
messages: messages
|
||||
})
|
||||
|
||||
export {languages}
|
|
@ -0,0 +1,391 @@
|
|||
export const m = {
|
||||
// /components/oj/common/NavBar.vue 导航栏
|
||||
NavBar_Home: 'Home',
|
||||
NavBar_Problem: 'Problem',
|
||||
NavBar_Contest: 'Contest',
|
||||
NavBar_Status: 'Status',
|
||||
NavBar_Rank: 'Rank',
|
||||
NavBar_ACM_Rank: 'ACM Rank',
|
||||
NavBar_OI_Rank: 'OI Rank',
|
||||
NavBar_Discussion: 'Discussion',
|
||||
NavBar_About: 'About',
|
||||
NavBar_Introduction: 'Introduction',
|
||||
NavBar_Developer:'Developer',
|
||||
NavBar_Login: 'Login',
|
||||
NavBar_Register: 'Register',
|
||||
NavBar_UserHome: 'Home',
|
||||
NavBar_Submissions: 'Submissions',
|
||||
NavBar_Setting:'Setting',
|
||||
NavBar_Management: 'Management',
|
||||
NavBar_Logout: 'Logout',
|
||||
Dialog_Login: 'Login',
|
||||
Dialog_Register:'Register',
|
||||
Dialog_Reset_Password:'Reset Password',
|
||||
|
||||
// /components/oj/common/Login.vue 登录弹窗
|
||||
Login_Username: 'Username',
|
||||
Login_Password: 'Password',
|
||||
Login_Btn:'Login',
|
||||
Slide_Verify:'Please slide right to verify',
|
||||
Slide_Verify_Success:'Success',
|
||||
Login_No_Account: 'No account? Register now!',
|
||||
Login_Forget_Password: 'Forget Password',
|
||||
Username_Check_Required:'The username is required.',
|
||||
Username_Check_Max:'The longest length of a username is 255.',
|
||||
Password_Check_Required:'The password is required.',
|
||||
Password_Check_Between:'The length of the password is between 6 and 20.',
|
||||
Welcome_Back: 'Welcome back~',
|
||||
|
||||
// /components/oj/common/Register.vue 注册弹窗
|
||||
Register_Username: 'Please Enter Username',
|
||||
Register_Password: 'Please Enter Password',
|
||||
Register_Password_Again: 'Please Enter Password Again',
|
||||
Register_Email: 'Please Enter Email',
|
||||
Register_Email_Captcha: 'Please enter the captcha from the email',
|
||||
Register_Btn: 'Register',
|
||||
Register_Already_Registed: 'Already registed? Login now!',
|
||||
The_username_already_exists: 'The username already exists.',
|
||||
The_email_already_exists: 'The email already exists.',
|
||||
Password_does_not_match: 'Password does not match.',
|
||||
Email_Check_Required:'The email is required.',
|
||||
Email_Check_Format:'The email format is incorrect.',
|
||||
Password_Again_Check_Required:'The password again is required.',
|
||||
Code_Check_Required:'The captcha is required.',
|
||||
Code_Check_Length:'The captcha must be six digits.',
|
||||
The_system_is_processing:'Please Waiting... The system is processing...',
|
||||
Thanks_for_registering: 'Thanks for your registering, you can login now.',
|
||||
|
||||
// /components/oj/common/ResetPassword.vue 重置密码弹窗
|
||||
// /views/oj/user/SetNeWPassword.vue 设置新密码页
|
||||
Reset_Password_Email: 'Please Enter Your Email',
|
||||
Reset_Password_Captcha: 'Please Enter the captcha',
|
||||
Send_Password_Reset_Email: 'Send Password Reset Email',
|
||||
Waiting_Can_Resend_Email:'resend the Reset Email...',
|
||||
Remember_Passowrd_To_Login:'Remember password? To login!',
|
||||
Set_New_Password:'Set New Password',
|
||||
Set_New_Password_Msg: 'Please Enter New Password',
|
||||
Set_New_Password_Again_Msg: 'Please Enter New Password Again',
|
||||
The_username_does_not_exists:'The username does not exists.',
|
||||
Your_password_has_been_reset: 'Your password has been reset.',
|
||||
|
||||
// /components/oj/setting/Account.vue 账号信息管理页面
|
||||
Change_Password: 'Change Password',
|
||||
Change_Email: 'Change Email',
|
||||
Update_Password: 'Update Password',
|
||||
Update_Email: 'Update Email',
|
||||
The_new_password_does_not_change:"The new password doesn't change.",
|
||||
The_new_email_does_not_change:"The new email doesn't change.",
|
||||
Update_Successfully:'Update successfully',
|
||||
Update_Failed:'Update Failed',
|
||||
Guess_robot:'Speed too fast, may be machine operation! Please verify again!',
|
||||
|
||||
|
||||
// /components/oj/setting/UserInfo.vue
|
||||
Avatar_Setting: 'Avatar Setting',
|
||||
UserInfo_Setting: 'UserInfo Setting',
|
||||
Upload_avatar_hint:'Drag and drop the avatar here, or click here.',
|
||||
Save:'Save',
|
||||
Upload:'Upload',
|
||||
Your_new_avatar:'Your new avatar',
|
||||
|
||||
// /views/oj/user/UserHome.vue
|
||||
Recent_login_time:'Recently launched:',
|
||||
Not_set_yet:'Not set yet',
|
||||
UserHome_Solved: 'Solved',
|
||||
UserHome_Submissions: 'Submissions',
|
||||
UserHome_Score: 'Score',
|
||||
UserHome_Rating:'Rating',
|
||||
List_Solved_Problems: 'List of solved problems',
|
||||
UserHome_Not_Data: 'The guy is so lazy that has not solved any problem yet.',
|
||||
|
||||
// /views/oj/user/Setting.vue
|
||||
Account_Setting:'Account Setting',
|
||||
UserInfo_Setting:'UserInfo Setting',
|
||||
|
||||
// App.vue 底部文案
|
||||
Service:'Service',
|
||||
Judging_Queue:'Judging Queue',
|
||||
System_Info:'System Info',
|
||||
Development:'Development',
|
||||
Open_Source:'Open Source',
|
||||
Support:'Support',
|
||||
Help:'Help',
|
||||
|
||||
// /views/oj/Home.vue
|
||||
Welcome_to:'Welcome to ',
|
||||
Recent_7_Days_AC_Rank:'Recent 7 Days AC Top 10 Rank',
|
||||
Other_OJ_Contest:'Other Online Judge Contest',
|
||||
|
||||
|
||||
// 表格通用列名,按钮,搜索框等
|
||||
Enter_keyword:'Enter keyword',
|
||||
Reset:'Reset',
|
||||
Username:'Username',
|
||||
Solved:'Solved',
|
||||
AC:'AC',
|
||||
OJ:'OJ',
|
||||
Title:'Title',
|
||||
Begin_Time:'Begin Time',
|
||||
End_Time:'End Time',
|
||||
Problem_ID:'Problem ID',
|
||||
Total:'Total',
|
||||
AC_Rate:'AC Rate',
|
||||
Score: 'Score',
|
||||
|
||||
// /views/oj/problem/problemList.vue
|
||||
Problem_List:'Problem List',
|
||||
All:'All',
|
||||
Mine:'Mine',
|
||||
Level:'Level',
|
||||
Tags:'Tags',
|
||||
Pick_a_random_question:'Pick a random question',
|
||||
Touch_Get_Status:'Please touch or hover the mouse to the designated problem line to view the submission status',
|
||||
Good_luck_to_you:'Good luck to you!',
|
||||
|
||||
// /views/oj/problem/Problem.vue
|
||||
Contest_Problem:'Contest Problem',
|
||||
Show_Tags:'Show tags',
|
||||
No_tag:'No tag',
|
||||
Statistic: 'Statistic',
|
||||
Solution:'Solution',
|
||||
Description: 'Description',
|
||||
Input: 'Input',
|
||||
Output: 'Output',
|
||||
Sample_Input: 'Sample Input',
|
||||
Sample_Output: 'Sample Output',
|
||||
Hint: 'Hint',
|
||||
Source: 'Source',
|
||||
Status: 'Status',
|
||||
Information: 'Information',
|
||||
Time_Limit: 'Time Limit',
|
||||
Memory_Limit: 'Memory Limit',
|
||||
Other:'Other',
|
||||
Created: 'Created By',
|
||||
Please_login_first:'Please login first',
|
||||
Submit: 'Submit',
|
||||
Submitting: 'Submitting',
|
||||
Judging: 'Judging',
|
||||
Wrong_Answer: 'Wrong Answer',
|
||||
View_Contest: 'View Contest',
|
||||
Are_you_sure_you_want_to_reset_your_code: 'Are you sure you want to reset your code?',
|
||||
Code_can_not_be_empty: 'Code can not be empty',
|
||||
Submit_code_successfully: 'Submit code successfully',
|
||||
You_have_solved_the_problem: 'You have solved the problem',
|
||||
Submitted_successfully: 'Submitted successfully',
|
||||
You_have_submitted_a_solution: 'You have submitted a solution.',
|
||||
Contest_has_ended: 'Contest has ended',
|
||||
You_have_submission_in_this_problem_sure_to_cover_it: 'You have submission in this problem, sure to cover it?',
|
||||
Close:'Close',
|
||||
Cancel:'Cancel',
|
||||
OK:'OK',
|
||||
Copied_successfully:'Copied successfully',
|
||||
Copied_failed:'Copied failed',
|
||||
|
||||
|
||||
// 状态码表示的结果
|
||||
|
||||
Accepted: 'Accepted',
|
||||
Time_Limit_Exceeded: 'Time Limit Exceeded',
|
||||
Memory_Limit_Exceeded: 'Memory Limit Exceeded',
|
||||
Runtime_Error: 'Runtime Error',
|
||||
System_Error: 'System Error',
|
||||
Pending: 'Pending',
|
||||
Partial_Accepted: 'Partial Accepted',
|
||||
Compile_Error: 'Compile Error',
|
||||
|
||||
|
||||
// /views/oj/status/SubmissionList.vue
|
||||
When: 'When',
|
||||
Time: 'Time',
|
||||
Memory: 'Memory',
|
||||
Length:'Length',
|
||||
Language:'Language',
|
||||
View_submission_details:'View submission details',
|
||||
Judger:'Judger',
|
||||
Author: 'Author',
|
||||
Submit_Time:'Submit Time',
|
||||
Option: 'Option',
|
||||
Rejudge: 'Rejudge',
|
||||
Refresh:'Refresh',
|
||||
Enter_Problem_ID:'Enter Problem ID',
|
||||
Enter_Author:'Enter Author',
|
||||
Run_ID:'Run ID',
|
||||
Problem:'Problem',
|
||||
|
||||
// /views/oj/status/SubmissionDetails.vue
|
||||
Test_point_details:'Test point details',
|
||||
Copy:'Copy',
|
||||
Shared:'Shared',
|
||||
Unshared:'Unshared',
|
||||
Shared_successfully:'Shared successfully',
|
||||
|
||||
// /views/oj/rank/ACMRank.vue
|
||||
ACM_Ranklist: 'ACM Ranklist',
|
||||
User:'User',
|
||||
Nickname:'Nickname',
|
||||
Mood: 'Mood',
|
||||
Rating: 'Rating',
|
||||
|
||||
// /views/oj/rank/OIRank.vue
|
||||
OI_Ranklist: 'OI Ranklist',
|
||||
|
||||
// /views/oj/discussion/discussionList.vue
|
||||
Created_Time:'Created Time',
|
||||
Likes:'Likes',
|
||||
Views:'Views',
|
||||
Edit:'Edit',
|
||||
Delete:'Delete',
|
||||
Post_discussion:'Post Discussion',
|
||||
Post_problem_discussion:'Post Problem Discussion',
|
||||
General_discussion:'General Discussion',
|
||||
Return:'Return',
|
||||
Category:'Category',
|
||||
Discussion_title:'Title',
|
||||
Discussion_Desc:'Description',
|
||||
Discussion_Category:'Category',
|
||||
Discussion_top:'Top',
|
||||
Discussion_content:'Content',
|
||||
Create_Discussion:'Create Discussion',
|
||||
Edit_Discussion:'Edit Discussion',
|
||||
Delete_Discussion_Tips:'This operation will delete the discussion, including the associated comments and replies. Do you want to continue?',
|
||||
Delete_successfully:'Delete successfully',
|
||||
Post_successfully:'Post successfully',
|
||||
|
||||
// /views/oj/discussion/discussionList.vue
|
||||
Report:'Report',
|
||||
Like:'Like',
|
||||
Liked:'Liked',
|
||||
Report_Reason:'Report Reason',
|
||||
|
||||
// 404.vue
|
||||
Page_Not_Found:"Sorry, the page can't be found",
|
||||
Go_Home:'Go Home',
|
||||
Back:'Back',
|
||||
|
||||
// /views/oj/contest/ContestList.vue
|
||||
Rule: 'Rule',
|
||||
Running: 'Running',
|
||||
Scheduled: 'Scheduled',
|
||||
Ended: 'Ended',
|
||||
No_contest: 'No contest',
|
||||
Contests:'Contests',
|
||||
Public:'Public',
|
||||
Private:'Private',
|
||||
Protected:'Protected',
|
||||
Public_Tips:'Public - Any one can see and submit.',
|
||||
Private_Tips:'Private - Only users knowing contest password can see and submit.',
|
||||
Protected_Tips:'Protected - Any one can see, but only users knowing contest password can submit.',
|
||||
|
||||
// /views/oj/contest/ContestDetail.vue
|
||||
StartAt: 'StartAt',
|
||||
EndAt: 'EndAt',
|
||||
Password_Required: 'Password Required',
|
||||
To_Enter_Need_Password:'To enter the Private contest,please input the password!',
|
||||
Enter_the_contest_password:'Enter the contest password',
|
||||
Enter:'Enter',
|
||||
Overview: 'Overview',
|
||||
Announcement: 'Announcement',
|
||||
Submissions: 'Submissions',
|
||||
Rankings: 'Rankings',
|
||||
Comment:'Comment',
|
||||
Admin_Helper: 'AC Info',
|
||||
Register_contest_successfully:'Register contest successfully',
|
||||
|
||||
// /views/oj/contest/children/ACMContestRank.vue
|
||||
Contest_Rank:'Contest Rank',
|
||||
Menu: 'Menu',
|
||||
Chart: 'Chart',
|
||||
Table:'Table',
|
||||
Auto_Refresh: 'Auto Refresh',
|
||||
RealName: 'RealName',
|
||||
Force_Update: 'Force Update',
|
||||
Download_as_CSV: 'Download as CSV',
|
||||
TotalTime: 'TotalTime',
|
||||
Top_10_Teams: 'Top 10 Teams',
|
||||
save_as_image: 'save as image',
|
||||
|
||||
// /views/oj/contest/children/ACMInfo.vue
|
||||
AC_Time: 'AC Time',
|
||||
First_Blood: 'First Blood',
|
||||
Checked: 'Checked',
|
||||
Not_Checked: 'Not Checked',
|
||||
Check_It: 'Check It',
|
||||
Accepted:'Accepted',
|
||||
|
||||
// /views/oj/contest/children/ContestRejudgeAdmin.vue
|
||||
Contest_Rejudge:'Contest Rejudge',
|
||||
ID: 'ID',
|
||||
Contest_Rejudge_Tips:'Are you sure you want to rejudge all submissions of the questions?',
|
||||
Rejudge_All:'Rejudge All',
|
||||
Rejudge_successfully:'Rejudge successfully',
|
||||
|
||||
// /views/oj/contest/children/OIContestRank.vue
|
||||
Total_Score: 'Total Score',
|
||||
|
||||
// /views/oj/about/Introduction.vue
|
||||
Compiler: 'Compiler',
|
||||
Example:'Example',
|
||||
Result_Explanation: 'Result Explanation',
|
||||
Pending_Description: 'Your solution is waiting be judged, please wait for the result...',
|
||||
Submitted_Faild_Description:'Your submission failed this time, please click the button to submit again.',
|
||||
Compiling_Description:'Your source code is being compiled, please wait for the result...',
|
||||
Judging_Description:'Your program is running with test data. Please wait for the result...',
|
||||
Compile_Error_Description: "Failed to compile your source code. Click on the link to see compiler's output.",
|
||||
Persentation_Error_Description:'The code you submitted is very close to the correct answer. Please check whether there are extra spaces, newlines and other blanks in the code format output.',
|
||||
Accepted_Description: 'Congratulations! Your solution is correct.',
|
||||
Wrong_Answer_Description: "Your program's output doesn't match judger's answer.",
|
||||
Runtime_Error_Description: 'Your program terminated abnormally. Possible reasons are: segment fault, divided by zero or exited with code other than 0.',
|
||||
Time_Limit_Exceeded_Description: 'The time your program used has exceeded limit.',
|
||||
Memory_Limit_Exceeded_Description: 'The memory your program actually used has exceeded limit.',
|
||||
System_Error_Description: 'Oops, something has gone wrong with the judger. Please report this to administrator.',
|
||||
Compile_Explanation:'Compile Explanation',
|
||||
Compile_Tips1:"`__int64` is not defined by ANSI standard and can only be used in `VC`. It should be written as `long long` type in `GNU C++`. For `scanf` and `printf`, please use `%lld` as the format.",
|
||||
Compile_Tips2:"The return value of `main()` must be defined as `int`, not `void`",
|
||||
Compile_Tips3:"`i` lost definition outside the loop,\"for(int i=0...){...}\"",
|
||||
Compile_Tips4:"`itoa` is not an ANSI standard function (not available in standard `C/C++`)",
|
||||
|
||||
// /views/oj/about/Developer.vue
|
||||
Leader_BackEnd_FrontEnd_Engineer:'Leader & BackEnd | FrontEnd Engineer',
|
||||
Distributed:'Distributed',
|
||||
Distributed_Desc:'It is divided into frontend and backend separation, and supports the micro service cluster',
|
||||
Customization:'Customization',
|
||||
Customization_Desc:'The website configuration is highly integrated and supports customized modification',
|
||||
Security:'Security',
|
||||
Security_Desc:'The Sandbox is isolated by CGroup, and the website authority control is perfect',
|
||||
Diversity:'Diversity',
|
||||
Diversity_Desc:'Support codefoces, HDU remote judge',
|
||||
Available:'Available',
|
||||
Faulty:'Faulty',
|
||||
|
||||
// /components/oj/common/Announcements.vue
|
||||
Contest_Announcement: 'Contest Announcement',
|
||||
No_Announcements: 'No Announcements',
|
||||
|
||||
// /components/oj/common/CodeMirror.vue
|
||||
Lang: 'Lang',
|
||||
Theme: 'Theme',
|
||||
Reset_Code: 'Reset Code',
|
||||
Upload_file: 'Upload file',
|
||||
monokai: 'Mnokai',
|
||||
solarized: 'Molarized Light',
|
||||
material: 'Material',
|
||||
|
||||
// /components/oj/comment/CodeMirror.vue
|
||||
Come_and_write_down_your_comments:'Come and write down your comments',
|
||||
Inline_Code:'Inline Code',
|
||||
Code_Block:'Code Block',
|
||||
Link:'Link',
|
||||
Unordered_list:'Unordered List',
|
||||
Ordered_List:'Ordered List',
|
||||
Submit_Comment:'Submit',
|
||||
All_Comment:'All Comment',
|
||||
Reply:'Reply',
|
||||
Reply_Total:'Total',
|
||||
Replies:'replies',
|
||||
Click_Show_All:'Click to Show All',
|
||||
Pick_up:"Pick up",
|
||||
Load_More:'Load More',
|
||||
Delete_Comment_Tips:'This operation will delete the comment and all its replies. Do you want to continue?',
|
||||
Delete_Reply_Tips:'This operation will delete the reply. Do you want to continue?',
|
||||
|
||||
}
|
|
@ -0,0 +1,381 @@
|
|||
export const m = {
|
||||
// /components/oj/common/NavBar.vue 导航栏
|
||||
NavBar_Home: '首页',
|
||||
NavBar_Problem: '题目',
|
||||
NavBar_Contest: '比赛',
|
||||
NavBar_Status: '状态',
|
||||
NavBar_Rank: '排名',
|
||||
NavBar_ACM_Rank: 'ACM 排名',
|
||||
NavBar_OI_Rank: 'OI 排名',
|
||||
NavBar_Discussion: '讨论',
|
||||
NavBar_About: '关于',
|
||||
NavBar_Introduction: '简介',
|
||||
NavBar_Developer:'开发者',
|
||||
NavBar_Login: '登录',
|
||||
NavBar_Register: '注册',
|
||||
NavBar_UserHome: '我的首页',
|
||||
NavBar_Submissions: '我的提交',
|
||||
NavBar_Setting:'我的设置',
|
||||
NavBar_Management: '后台管理',
|
||||
NavBar_Logout: '退出登录',
|
||||
Dialog_Login: '登录',
|
||||
Dialog_Register:'注册',
|
||||
Dialog_Reset_Password:'重置密码',
|
||||
|
||||
// /components/oj/common/Login.vue 登录弹窗
|
||||
Login_Username: '用户名',
|
||||
Login_Password: '密码',
|
||||
Login_Btn:'登录',
|
||||
Slide_Verify:'请向右滑动验证',
|
||||
Slide_Verify_Success:'验证成功',
|
||||
Login_No_Account: '没有账号?立即注册!',
|
||||
Login_Forget_Password: '忘记密码',
|
||||
Username_Check_Required:'The username is required.',
|
||||
Username_Check_Max:'The longest length of a username is 255.',
|
||||
Password_Check_Required:'The password is required.',
|
||||
Password_Check_Between:'The length of the password is between 6 and 20.',
|
||||
Welcome_Back: '欢迎回来~',
|
||||
|
||||
// /components/oj/common/Register.vue 注册弹窗
|
||||
Register_Username: 'Please Enter Username',
|
||||
Register_Password: 'Please Enter Password',
|
||||
Register_Password_Again: 'Please Enter Password Again',
|
||||
Register_Email: 'Please Enter Email',
|
||||
Register_Email_Captcha: 'Please enter the captcha from the email',
|
||||
Register_Btn: '注册',
|
||||
Register_Already_Registed: '已有账号?立即登录!',
|
||||
The_username_already_exists: 'The username already exists.',
|
||||
The_email_already_exists: 'The email already exists.',
|
||||
Password_does_not_match: 'Password does not match.',
|
||||
Email_Check_Required:'The email is required.',
|
||||
Email_Check_Format:'The email format is incorrect.',
|
||||
Password_Again_Check_Required:'The password again is required.',
|
||||
Code_Check_Required:'The captcha is required.',
|
||||
Code_Check_Length:'The captcha must be six digits.',
|
||||
The_system_is_processing:'Please Waiting... The system is processing...',
|
||||
Thanks_for_registering: 'Thanks for your registering, you can login now.',
|
||||
|
||||
// /components/oj/common/ResetPassword.vue 重置密码弹窗
|
||||
// /views/oj/user/SetNeWPassword.vue 设置新密码页
|
||||
Reset_Password_Email: 'Please Enter Your Email',
|
||||
Reset_Password_Captcha: 'Please Enter the captcha',
|
||||
Send_Password_Reset_Email: 'Send Password Reset Email',
|
||||
Waiting_Can_Resend_Email:'resend the Reset Email...',
|
||||
Remember_Passowrd_To_Login:'Remember password? To login!',
|
||||
Set_New_Password:'Set New Password',
|
||||
Set_New_Password_Msg: 'Please Enter New Password',
|
||||
Set_New_Password_Again_Msg: 'Please Enter New Password Again',
|
||||
The_username_does_not_exists:'The username does not exists.',
|
||||
Your_password_has_been_reset: 'Your password has been reset.',
|
||||
|
||||
// /components/oj/setting/Account.vue 账号信息管理页面
|
||||
Change_Password: 'Change Password',
|
||||
Change_Email: 'Change Email',
|
||||
Update_Password: 'Update Password',
|
||||
Update_Email: 'Update Email',
|
||||
The_new_password_does_not_change:"The new password doesn't change.",
|
||||
The_new_email_does_not_change:"The new email doesn't change.",
|
||||
Update_Successfully:'Update successfully',
|
||||
Update_Failed:'Update Failed',
|
||||
Guess_robot:'Speed too fast, may be machine operation! Please verify again!',
|
||||
|
||||
|
||||
// /components/oj/setting/UserInfo.vue
|
||||
Avatar_Setting: 'Avatar Setting',
|
||||
UserInfo_Setting: 'UserInfo Setting',
|
||||
Upload_avatar_hint:'Drag and drop the avatar here, or click here.',
|
||||
Save:'保存',
|
||||
Upload:'上传',
|
||||
Your_new_avatar:'你的新头像',
|
||||
|
||||
// /views/oj/user/UserHome.vue
|
||||
Recent_login_time:'Recently launched:',
|
||||
Not_set_yet:'Not set yet',
|
||||
UserHome_Solved: 'Solved',
|
||||
UserHome_Submissions: 'Submissions',
|
||||
UserHome_Score: 'Score',
|
||||
UserHome_Rating:'Rating',
|
||||
List_Solved_Problems: 'List of solved problems',
|
||||
UserHome_Not_Data: 'The guy is so lazy that has not solved any problem yet.',
|
||||
|
||||
// /views/oj/user/Setting.vue
|
||||
Account_Setting:'Account Setting',
|
||||
UserInfo_Setting:'UserInfo Setting',
|
||||
|
||||
// App.vue 底部文案
|
||||
Service:'服务',
|
||||
Judging_Queue:'评测队列',
|
||||
System_Info:'系统信息',
|
||||
Development:'开发',
|
||||
Open_Source:'开源',
|
||||
Support:'支持',
|
||||
Help:'帮助',
|
||||
|
||||
// /views/oj/Home.vue
|
||||
Welcome_to:'欢迎使用 ',
|
||||
Recent_7_Days_AC_Rank:'7天内做题数排名前10',
|
||||
Other_OJ_Contest:'其它在线评测平台的近期比赛',
|
||||
|
||||
|
||||
// 表格通用列名,按钮,搜索框等
|
||||
Enter_keyword:'输入关键词',
|
||||
Reset:'Reset',
|
||||
Username:'Username',
|
||||
Solved:'Solved',
|
||||
AC:'AC',
|
||||
OJ:'OJ',
|
||||
Title:'Title',
|
||||
Begin_Time:'Begin Time',
|
||||
End_Time:'End Time',
|
||||
Problem_ID:'Problem ID',
|
||||
Total:'Total',
|
||||
AC_Rate:'AC Rate',
|
||||
Score: 'Score',
|
||||
|
||||
// /views/oj/problem/problemList.vue
|
||||
Problem_List:'Problem List',
|
||||
All:'All',
|
||||
Mine:'Mine',
|
||||
Level:'Level',
|
||||
Tags:'Tags',
|
||||
Pick_a_random_question:'Pick a random question',
|
||||
Touch_Get_Status:'Please touch or hover the mouse to the designated problem line to view the submission status',
|
||||
Good_luck_to_you:'Good luck to you!',
|
||||
|
||||
// /views/oj/problem/Problem.vue
|
||||
Contest_Problem:'Contest Problem',
|
||||
Show_Tags:'Show tags',
|
||||
No_tag:'No tag',
|
||||
Statistic: 'Statistic',
|
||||
Solution:'Solution',
|
||||
Description: 'Description',
|
||||
Input: 'Input',
|
||||
Output: 'Output',
|
||||
Sample_Input: 'Sample Input',
|
||||
Sample_Output: 'Sample Output',
|
||||
Hint: 'Hint',
|
||||
Source: 'Source',
|
||||
Status: 'Status',
|
||||
Information: 'Information',
|
||||
Time_Limit: 'Time Limit',
|
||||
Memory_Limit: 'Memory Limit',
|
||||
Other:'Other',
|
||||
Created: 'Created By',
|
||||
Please_login_first:'Please login first',
|
||||
Submit: 'Submit',
|
||||
Submitting: 'Submitting',
|
||||
Judging: 'Judging',
|
||||
Wrong_Answer: 'Wrong Answer',
|
||||
View_Contest: 'View Contest',
|
||||
Are_you_sure_you_want_to_reset_your_code: 'Are you sure you want to reset your code?',
|
||||
Code_can_not_be_empty: 'Code can not be empty',
|
||||
Submit_code_successfully: 'Submit code successfully',
|
||||
You_have_solved_the_problem: 'You have solved the problem',
|
||||
Submitted_successfully: 'Submitted successfully',
|
||||
You_have_submitted_a_solution: 'You have submitted a solution.',
|
||||
Contest_has_ended: 'Contest has ended',
|
||||
You_have_submission_in_this_problem_sure_to_cover_it: 'You have submission in this problem, sure to cover it?',
|
||||
Close:'Close',
|
||||
Cancel:'Cancel',
|
||||
OK:'OK',
|
||||
Copied_successfully:'Copied successfully',
|
||||
Copied_failed:'Copied failed',
|
||||
|
||||
|
||||
// /views/oj/status/SubmissionList.vue
|
||||
When: 'When',
|
||||
ID: 'ID',
|
||||
Time: 'Time',
|
||||
Memory: 'Memory',
|
||||
Length:'Length',
|
||||
Language:'Language',
|
||||
View_submission_details:'View submission details',
|
||||
Judger:'Judger',
|
||||
Author: 'Author',
|
||||
Submit_Time:'Submit Time',
|
||||
Option: 'Option',
|
||||
Rejudge: 'Rejudge',
|
||||
Refresh:'Refresh',
|
||||
Enter_Problem_ID:'Enter Problem ID',
|
||||
Enter_Author:'Enter Author',
|
||||
Run_ID:'Run ID',
|
||||
Problem:'Problem',
|
||||
|
||||
// /views/oj/status/SubmissionDetails.vue
|
||||
Test_point_details:'Test point details',
|
||||
Copy:'Copy',
|
||||
Shared:'Shared',
|
||||
Unshared:'Unshared',
|
||||
Shared_successfully:'Shared successfully',
|
||||
|
||||
// /views/oj/rank/ACMRank.vue
|
||||
ACM_Ranklist: 'ACM Ranklist',
|
||||
User:'User',
|
||||
Nickname:'Nickname',
|
||||
Mood: 'Mood',
|
||||
Rating: 'Rating',
|
||||
|
||||
// /views/oj/rank/OIRank.vue
|
||||
OI_Ranklist: 'OI Ranklist',
|
||||
|
||||
// /views/oj/discussion/discussionList.vue
|
||||
Created_Time:'Created Time',
|
||||
Likes:'Likes',
|
||||
Views:'Views',
|
||||
Edit:'Edit',
|
||||
Delete:'Delete',
|
||||
Post_discussion:'Post Discussion',
|
||||
Post_problem_discussion:'Post Problem Discussion',
|
||||
General_discussion:'General Discussion',
|
||||
Return:'Return',
|
||||
Category:'Category',
|
||||
Discussion_title:'Title',
|
||||
Discussion_Desc:'Description',
|
||||
Discussion_Category:'Category',
|
||||
Discussion_top:'Top',
|
||||
Discussion_content:'Content',
|
||||
Create_Discussion:'Create Discussion',
|
||||
Edit_Discussion:'Edit Discussion',
|
||||
Delete_Discussion_Tips:'This operation will delete the discussion, including the associated comments and replies. Do you want to continue?',
|
||||
Delete_successfully:'Delete successfully',
|
||||
Post_successfully:'Post successfully',
|
||||
|
||||
// /views/oj/discussion/discussionList.vue
|
||||
Report:'Report',
|
||||
Like:'Like',
|
||||
Liked:'Liked',
|
||||
Report_Reason:'Report Reason',
|
||||
|
||||
// 404.vue
|
||||
Page_Not_Found:"Sorry, the page can't be found",
|
||||
Go_Home:'Go Home',
|
||||
Back:'Back',
|
||||
|
||||
// /views/oj/contest/ContestList.vue
|
||||
Rule: 'Rule',
|
||||
Running: 'Running',
|
||||
Scheduled: 'Scheduled',
|
||||
Ended: 'Ended',
|
||||
No_contest: 'No contest',
|
||||
Contests:'Contests',
|
||||
Public:'公开赛',
|
||||
Private:'私有赛',
|
||||
Protected:'保护赛',
|
||||
Public_Tips:'公开赛 - 每个用户都可查看与提交',
|
||||
Private_Tips:'私有赛 - 用户需要密码才可查看与提交',
|
||||
Protected_Tips:'保护赛 - 每个用户都可查看,但是提交需要密码',
|
||||
|
||||
// /views/oj/contest/ContestDetail.vue
|
||||
StartAt: 'StartAt',
|
||||
EndAt: 'EndAt',
|
||||
Password_Required: 'Password Required',
|
||||
To_Enter_Need_Password:'To enter the Private contest,please input the password!',
|
||||
Enter_the_contest_password:'Enter the contest password',
|
||||
Enter:'Enter',
|
||||
Overview: 'Overview',
|
||||
Announcement: '公告',
|
||||
Submissions: 'Submissions',
|
||||
Rankings: 'Rankings',
|
||||
Comment:'Comment',
|
||||
Admin_Helper: 'AC Info',
|
||||
Register_contest_successfully:'Register contest successfully',
|
||||
|
||||
// /views/oj/contest/children/ACMContestRank.vue
|
||||
Contest_Rank:'Contest Rank',
|
||||
Menu: 'Menu',
|
||||
Chart: 'Chart',
|
||||
Table:'Table',
|
||||
Auto_Refresh: 'Auto Refresh',
|
||||
RealName: 'RealName',
|
||||
Force_Update: 'Force Update',
|
||||
Download_as_CSV: 'Download as CSV',
|
||||
TotalTime: 'TotalTime',
|
||||
Top_10_Teams: 'Top 10 Teams',
|
||||
save_as_image: 'save as image',
|
||||
|
||||
// /views/oj/contest/children/ACMInfo.vue
|
||||
AC_Time: 'AC Time',
|
||||
First_Blood: 'First Blood',
|
||||
Checked: 'Checked',
|
||||
Not_Checked: 'Not Checked',
|
||||
Check_It: 'Check It',
|
||||
Accepted:'Accepted',
|
||||
|
||||
// /views/oj/contest/children/ContestRejudgeAdmin.vue
|
||||
Contest_Rejudge:'Contest Rejudge',
|
||||
ID: 'ID',
|
||||
Rejudge_All:'Rejudge All',
|
||||
Contest_Rejudge_Tips:'Are you sure you want to rejudge all submissions of the questions?',
|
||||
Rejudge_successfully:'Rejudge successfully',
|
||||
|
||||
// /views/oj/contest/children/OIContestRank.vue
|
||||
Total_Score: 'Total Score',
|
||||
|
||||
// /views/oj/about/Introduction.vue
|
||||
Compiler: '编译器',
|
||||
Example:'例题',
|
||||
Result_Explanation: '结果说明',
|
||||
Pending_Description: '您的解答正在排队等待测评中,请等待结果...',
|
||||
Submitted_Faild_Description:'您的此次提交失败,请点击按钮重新提交...',
|
||||
Compiling_Description:'正在对您的源代码进行编译中,请等待结果...',
|
||||
Judging_Description:'正在使用测试数据运行您的程序中,请等待结果...',
|
||||
Compile_Error_Description: "无法编译您的源代码,点击链接查看编译器的输出。",
|
||||
Persentation_Error_Description:'您提交的代码已经很接近正确答案,请检查代码格式输出是否有多余空格,换行等空白符。',
|
||||
Accepted_Description: '恭喜! 您的解题方法是正确的。',
|
||||
Wrong_Answer_Description: "您的程序输出结果与判题程序的答案不符。",
|
||||
Runtime_Error_Description: '您的程序异常终止,可能的原因是:段错误,被零除或用非0的代码退出程序。',
|
||||
Time_Limit_Exceeded_Description: '您的程序运行时间已超出题目限制。',
|
||||
Memory_Limit_Exceeded_Description: '您的程序实际使用的内存已超出题目限制。',
|
||||
System_Error_Description: '糟糕,判题机系统出了问题。请报告给管理员。',
|
||||
Compile_Explanation:'编译说明',
|
||||
Compile_Tips1:"__int64不是ANSI标准定义,只能在VC使用,在 GNU C++ 中应写成 long long 类型, scanf和printf 请使用%lld作为格式",
|
||||
Compile_Tips2:"main() 返回值必须定义为 int ,而不是 void",
|
||||
Compile_Tips3:"i 在循环外失去定义 \"for(int i=0...){...}\"",
|
||||
Compile_Tips4:"itoa 不是ansi标准函数(标准 C/C++ 中无此函数)",
|
||||
|
||||
// /views/oj/about/Developer.vue
|
||||
Leader_BackEnd_FrontEnd_Engineer:'主导 & 后端 | 前端 开发者',
|
||||
Distributed:'分布式',
|
||||
Distributed_Desc:'前后端分离,支持判题微服务集群',
|
||||
Customization:'定制化',
|
||||
Customization_Desc:'网站配置高度集成,支持定制化修改',
|
||||
Security:'安全性',
|
||||
Security_Desc:'判题沙盒使用cgroup隔离,网站权限控制完善',
|
||||
Diversity:'多样性',
|
||||
Diversity_Desc:'支持Codefoces,HDU的远程判题',
|
||||
Available:'有效',
|
||||
Faulty:'不完善',
|
||||
|
||||
// /components/oj/common/Announcements.vue
|
||||
Contest_Announcement: '比赛公告',
|
||||
No_Announcements: '暂无公告',
|
||||
|
||||
// /components/oj/common/CodeMirror.vue
|
||||
Lang: '语言',
|
||||
Theme: '风格',
|
||||
Reset_Code: '重置密码',
|
||||
Upload_file: '上传文件',
|
||||
monokai: 'Mnokai',
|
||||
solarized: 'Molarized Light',
|
||||
material: 'Material',
|
||||
|
||||
// /components/oj/comment/CodeMirror.vue
|
||||
Come_and_write_down_your_comments:'快来写下你的评论吧',
|
||||
Inline_Code:'行内代码',
|
||||
Code_Block:'代码块',
|
||||
Link:'链接',
|
||||
Unordered_list:'无序列表',
|
||||
Ordered_List:'有序列表',
|
||||
Submit_Comment:'提交评论',
|
||||
All_Comment:'全部评论',
|
||||
Reply:'回复',
|
||||
Reply_Total:'总共',
|
||||
Replies:'条回复',
|
||||
Click_Show_All:'点击查看全部',
|
||||
Pick_up:'收起',
|
||||
Load_More:'加载更多',
|
||||
Delete_Comment_Tips:'此操作将删除该评论及其所有回复, 是否继续?',
|
||||
Delete_Reply_Tips:'此操作将删除该回复, 是否继续?',
|
||||
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ import Vue from 'vue'
|
|||
import App from './App.vue'
|
||||
import store from './store'
|
||||
import Element from 'element-ui'
|
||||
import i18n from '@/i18n'
|
||||
|
||||
// import "element-ui/lib/theme-chalk/index.css"
|
||||
import 'font-awesome/css/font-awesome.min.css'
|
||||
|
@ -84,5 +85,6 @@ Vue.config.productionTip = false
|
|||
new Vue({
|
||||
router,
|
||||
store,
|
||||
i18n,
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
|
|
|
@ -3,6 +3,9 @@ import Vuex from 'vuex'
|
|||
import user from '@/store/user'
|
||||
import contest from "@/store/contest"
|
||||
import api from '@/common/api'
|
||||
import i18n from '@/i18n'
|
||||
import storage from '@/common/storage'
|
||||
import moment from 'moment'
|
||||
Vue.use(Vuex)
|
||||
const rootState = {
|
||||
modalStatus: {
|
||||
|
@ -18,6 +21,7 @@ const rootState = {
|
|||
},
|
||||
registerTimeOut: 60,
|
||||
resetTimeOut: 90,
|
||||
language:storage.get('Web_Language') || 'zh-CN',
|
||||
}
|
||||
|
||||
const rootGetters = {
|
||||
|
@ -33,6 +37,9 @@ const rootGetters = {
|
|||
'websiteConfig' (state) {
|
||||
return state.websiteConfig
|
||||
},
|
||||
'webLanguage'(state){
|
||||
return state.language
|
||||
}
|
||||
}
|
||||
|
||||
const rootMutations = {
|
||||
|
@ -74,6 +81,14 @@ const rootMutations = {
|
|||
changeWebsiteConfig(state, payload) {
|
||||
state.websiteConfig = payload.websiteConfig
|
||||
},
|
||||
changeWebLanguage (state, {language}) {
|
||||
if (language) {
|
||||
state.language = language
|
||||
i18n.locale = language
|
||||
moment.locale(language);
|
||||
}
|
||||
storage.set('Web_Language', language)
|
||||
}
|
||||
}
|
||||
const rootActions = {
|
||||
changeModalStatus({ commit }, payload) {
|
||||
|
|
|
@ -1,53 +1,58 @@
|
|||
<template>
|
||||
<el-card shadow>
|
||||
<div class="error">
|
||||
<div class="container-floud">
|
||||
<div style="text-align: center">
|
||||
<div class="container-error-404">
|
||||
<div class="clip">
|
||||
<div class="shadow">
|
||||
<span class="digit thirdDigit">{{thirdDigit}}</span>
|
||||
<el-card shadow>
|
||||
<div class="error">
|
||||
<div class="container-floud">
|
||||
<div style="text-align: center">
|
||||
<div class="container-error-404">
|
||||
<div class="clip">
|
||||
<div class="shadow">
|
||||
<span class="digit thirdDigit">{{ thirdDigit }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clip">
|
||||
<div class="shadow">
|
||||
<span class="digit secondDigit">{{ secondDigit }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clip">
|
||||
<div class="shadow">
|
||||
<span class="digit firstDigit">{{ firstDigit }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="msg">
|
||||
OH!
|
||||
<span class="triangle"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clip">
|
||||
<div class="shadow">
|
||||
<span class="digit secondDigit">{{secondDigit}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clip">
|
||||
<div class="shadow">
|
||||
<span class="digit firstDigit">{{firstDigit}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="msg">
|
||||
OH!
|
||||
<span class="triangle"></span>
|
||||
</div>
|
||||
<h2 class="h1">{{ $t('m.Page_Not_Found') }}</h2>
|
||||
<el-button @click="goHome" size="large" style="width: 150px;">
|
||||
<i class="el-icon-s-home"></i> {{ $t('m.Go_Home') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
@click="backPage"
|
||||
size="large"
|
||||
style="width: 150px;margin-left: 40px;"
|
||||
type="primary"
|
||||
>
|
||||
<i class="el-icon-back"></i> {{ $t('m.Back') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<h2 class="h1">很抱歉,你访问的页面找不到了</h2>
|
||||
<el-button @click="goHome" size="large" style="width: 150px;">
|
||||
<i class="el-icon-s-home"></i> Go Home
|
||||
</el-button>
|
||||
<el-button @click="backPage" size="large" style="width: 150px;margin-left: 40px;" type="primary">
|
||||
<i class="el-icon-back"></i> Back
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-card>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "NotFound404",
|
||||
data(){
|
||||
return{
|
||||
firstDigit:null,
|
||||
secondDigit:null,
|
||||
thirdDigit:null
|
||||
}
|
||||
name: 'NotFound404',
|
||||
data() {
|
||||
return {
|
||||
firstDigit: null,
|
||||
secondDigit: null,
|
||||
thirdDigit: null,
|
||||
};
|
||||
},
|
||||
mounted(){
|
||||
this.init()
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
backPage() {
|
||||
|
@ -55,9 +60,8 @@ export default {
|
|||
},
|
||||
goHome() {
|
||||
this.$router.push({
|
||||
name: "Home",
|
||||
name: 'Home',
|
||||
});
|
||||
|
||||
},
|
||||
init() {
|
||||
var loop1,
|
||||
|
@ -66,7 +70,7 @@ export default {
|
|||
time = 30,
|
||||
i = 0,
|
||||
number;
|
||||
loop3 = setInterval(()=> {
|
||||
loop3 = setInterval(() => {
|
||||
if (i > 40) {
|
||||
clearInterval(loop3);
|
||||
this.thirdDigit = 4;
|
||||
|
@ -75,16 +79,16 @@ export default {
|
|||
i++;
|
||||
}
|
||||
}, time);
|
||||
loop2 = setInterval(()=> {
|
||||
loop2 = setInterval(() => {
|
||||
if (i > 80) {
|
||||
clearInterval(loop2);
|
||||
this.secondDigit = 0;
|
||||
} else {
|
||||
this.secondDigit= Math.floor(Math.random() * 9) + 1;
|
||||
this.secondDigit = Math.floor(Math.random() * 9) + 1;
|
||||
i++;
|
||||
}
|
||||
}, time);
|
||||
loop1 = setInterval(()=> {
|
||||
loop1 = setInterval(() => {
|
||||
if (i > 100) {
|
||||
clearInterval(loop1);
|
||||
this.firstDigit = 4;
|
||||
|
@ -98,7 +102,6 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
.error .clip .shadow {
|
||||
height: 180px;
|
||||
}
|
||||
|
@ -135,7 +138,7 @@ export default {
|
|||
border-bottom: 15px solid transparent;
|
||||
}
|
||||
.error .container-error-404 {
|
||||
margin:0 auto;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
height: 250px;
|
||||
padding-top: 40px;
|
||||
|
@ -155,7 +158,7 @@ export default {
|
|||
}
|
||||
.error .clip:nth-of-type(3) .shadow:after,
|
||||
.error .clip:nth-of-type(1) .shadow:after {
|
||||
content: "";
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: -8px;
|
||||
bottom: 0px;
|
||||
|
@ -214,7 +217,7 @@ export default {
|
|||
position: absolute;
|
||||
z-index: 999;
|
||||
transform: rotate(45deg);
|
||||
content: "";
|
||||
content: '';
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
@ -257,4 +260,4 @@ export default {
|
|||
height: 150px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
@ -68,7 +68,8 @@
|
|||
<el-card v-else>
|
||||
<div slot="header" class="content-center">
|
||||
<span class="panel-title home-title welcome-title"
|
||||
>Welcome to {{ toUpper(websiteConfig.shortName) }}</span
|
||||
>{{ $t('m.Welcome_to')
|
||||
}}{{ toUpper(websiteConfig.shortName) }}</span
|
||||
>
|
||||
</div>
|
||||
<el-carousel
|
||||
|
@ -87,9 +88,9 @@
|
|||
<el-col :md="10" :sm="24" class="phone-margin">
|
||||
<el-card>
|
||||
<div slot="header" class="clearfix">
|
||||
<span class="panel-title home-title"
|
||||
>Recent 7 Days AC Top 10 Rank</span
|
||||
>
|
||||
<span class="panel-title home-title">{{
|
||||
$t('m.Recent_7_Days_AC_Rank')
|
||||
}}</span>
|
||||
</div>
|
||||
<vxe-table
|
||||
border="inner"
|
||||
|
@ -110,7 +111,7 @@
|
|||
</vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="username"
|
||||
title="Username"
|
||||
:title="$t('m.Username')"
|
||||
min-width="130"
|
||||
align="left"
|
||||
>
|
||||
|
@ -130,11 +131,16 @@
|
|||
>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="ac" title="AC" min-width="30" align="left">
|
||||
<vxe-table-column
|
||||
field="ac"
|
||||
:title="$t('m.AC')"
|
||||
min-width="30"
|
||||
align="left"
|
||||
>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="solved"
|
||||
title="Solved"
|
||||
:title="$t('m.Solved')"
|
||||
min-width="50"
|
||||
align="left"
|
||||
>
|
||||
|
@ -147,9 +153,9 @@
|
|||
<el-col :md="14" :sm="24" style="margin-top: 20px;">
|
||||
<el-card>
|
||||
<div slot="header" class="clearfix">
|
||||
<span class="panel-title home-title"
|
||||
>Other Online Judge Contest</span
|
||||
>
|
||||
<span class="panel-title home-title">{{
|
||||
$t('m.Other_OJ_Contest')
|
||||
}}</span>
|
||||
</div>
|
||||
<vxe-table
|
||||
border="inner"
|
||||
|
@ -162,24 +168,28 @@
|
|||
>
|
||||
<vxe-table-column
|
||||
field="oj"
|
||||
title="OJ"
|
||||
:title="$t('m.OJ')"
|
||||
min-width="100"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="title"
|
||||
title="Title"
|
||||
:title="$t('m.Title')"
|
||||
min-width="200"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="beginTime"
|
||||
title="Begin Time"
|
||||
:title="$t('m.Begin_Time')"
|
||||
min-width="150"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ row.beginTime | localtime }}</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="endTime" title="End Time" min-width="150">
|
||||
<vxe-table-column
|
||||
field="endTime"
|
||||
:title="$t('m.End_Time')"
|
||||
min-width="150"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ row.endTime | localtime }}</span>
|
||||
</template>
|
||||
|
|
|
@ -9,60 +9,58 @@
|
|||
>
|
||||
</h1>
|
||||
<p>
|
||||
Leader & BackEnd | FrontEnd Engineer / Himit_ZH
|
||||
{{ $t('m.Leader_BackEnd_FrontEnd_Engineer') }} / Himit_ZH
|
||||
<a href="https://github.com/HimitZH" class="icon" target="_blank"
|
||||
><i class="fa fa-github"></i>
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
BackEnd Engineer / Howie
|
||||
<a href="https://github.com/Huangyan0804" class="icon" target="_blank"
|
||||
><i class="fa fa-github"></i>
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
Maintainer Engineer / Alteria
|
||||
<a href="https://github.com/HackerMac" class="icon" target="_blank"
|
||||
><i class="fa fa-github"></i>
|
||||
</a>
|
||||
</p>
|
||||
<p class="teal-text">
|
||||
<i class="el-icon-circle-check"></i> Open Source
|
||||
<i class="el-icon-circle-check"></i> {{ $t('m.Open_Source') }}
|
||||
</p>
|
||||
</paper-card>
|
||||
</div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :xs="24" :md="12">
|
||||
<paper-card type="server">
|
||||
<h1>分布式</h1>
|
||||
<p><small>前后端分离,支持判题微服务集群</small></p>
|
||||
<h1>{{ $t('m.Distributed') }}</h1>
|
||||
<p>
|
||||
<small>{{ $t('m.Distributed_Desc') }}</small>
|
||||
</p>
|
||||
<p class="teal-text">
|
||||
<i class="el-icon-circle-check"></i> Distributed
|
||||
<i class="el-icon-circle-check"></i> {{ $t('m.Available') }}
|
||||
</p>
|
||||
</paper-card>
|
||||
</el-col>
|
||||
<el-col :xs="24" :md="12">
|
||||
<paper-card type="server">
|
||||
<h1>定制化</h1>
|
||||
<p><small>网站配置高度集成,支持定制化修改</small></p>
|
||||
<h1>{{ $t('m.Customization') }}</h1>
|
||||
<p>
|
||||
<small>{{ $t('m.Customization_Desc') }}</small>
|
||||
</p>
|
||||
<p class="teal-text">
|
||||
<i class="el-icon-circle-check"></i> Customization
|
||||
<i class="el-icon-circle-check"></i> {{ $t('m.Available') }}
|
||||
</p>
|
||||
</paper-card>
|
||||
</el-col>
|
||||
<el-col :xs="24" :md="12">
|
||||
<paper-card type="server">
|
||||
<h1>安全性</h1>
|
||||
<p><small>判题沙盒使用cgroup隔离,网站权限控制完善</small></p>
|
||||
<p class="teal-text"><i class="el-icon-circle-check"></i> Security</p>
|
||||
<h1>{{ $t('m.Security') }}</h1>
|
||||
<p>
|
||||
<small>{{ $t('m.Security_Desc') }}</small>
|
||||
</p>
|
||||
<p class="teal-text">
|
||||
<i class="el-icon-circle-check"></i> {{ $t('m.Available') }}
|
||||
</p>
|
||||
</paper-card>
|
||||
</el-col>
|
||||
<el-col :xs="24" :md="12">
|
||||
<paper-card type="server">
|
||||
<h1>多样性</h1>
|
||||
<p><small>支持Codefoces,HDU的远程判题</small></p>
|
||||
<h1>{{ $t('m.Diversity') }}</h1>
|
||||
<p>
|
||||
<small>{{ $t('m.Diversity_Desc') }}</small>
|
||||
</p>
|
||||
<p class="teal-text">
|
||||
<i class="el-icon-circle-check"></i> Diversity
|
||||
<i class="el-icon-circle-check"></i> {{ $t('m.Faulty') }}
|
||||
</p>
|
||||
</paper-card>
|
||||
</el-col>
|
||||
|
|
|
@ -4,15 +4,21 @@
|
|||
<el-col :md="12" :sm="24">
|
||||
<el-card class="container">
|
||||
<div slot="header">
|
||||
<span class="panel-title home-title">Compiler & Example</span>
|
||||
<span class="panel-title home-title">{{
|
||||
$t('m.Compiler') + ' & ' + $t('m.Example')
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="content">
|
||||
<ul>
|
||||
<li v-for="lang in languages" :key="lang.name">
|
||||
{{ lang.name }} ( {{ lang.description }} )
|
||||
<p style="color: #409EFF;font-size:16px">Compiler</p>
|
||||
<p style="color: #409EFF;font-size:16px">
|
||||
{{ $t('m.Compiler') }}
|
||||
</p>
|
||||
<pre>{{ lang.compileCommand }}</pre>
|
||||
<p style="color: #409EFF;font-size:16px">A+B Problem</p>
|
||||
<p style="color: #409EFF;font-size:16px">
|
||||
A+B {{ $t('m.Problem') }}
|
||||
</p>
|
||||
<Highlight
|
||||
:code="lang.template"
|
||||
:language="lang.name"
|
||||
|
@ -25,77 +31,72 @@
|
|||
<el-col :md="12" :sm="24">
|
||||
<el-card class="container">
|
||||
<div slot="header">
|
||||
<span class="panel-title home-title">Result Explanation</span>
|
||||
<span class="panel-title home-title">{{
|
||||
$t('m.Result_Explanation')
|
||||
}}</span>
|
||||
</div>
|
||||
<ul class="result">
|
||||
<li>
|
||||
<span :class="getStatusColor(5)">Pending</span>
|
||||
:您的解答正在排队等待测评中,请等待结果...
|
||||
:{{ $t('m.Pending_Description') }}
|
||||
</li>
|
||||
<li>
|
||||
<span :class="getStatusColor(10)">Submitted Failed</span>
|
||||
:您的此次提交失败,请点击按钮重新提交...
|
||||
:{{ $t('m.Submitted_Faild_Description') }}
|
||||
</li>
|
||||
<li>
|
||||
<span :class="getStatusColor(6)">Compiling</span>
|
||||
:正在对您的源代码进行编译中,请等待结果...
|
||||
:{{ $t('m.Compiling_Description') }}
|
||||
</li>
|
||||
<li>
|
||||
<span :class="getStatusColor(7)">Judging</span>
|
||||
:正在使用测试数据运行您的程序中,请等待结果...
|
||||
:{{ $t('m.Judging_Description') }}
|
||||
</li>
|
||||
<li>
|
||||
<span :class="getStatusColor(-2)">Compile Error</span> :
|
||||
无法编译您的源代码,点击链接查看编译器的输出。
|
||||
{{ $t('m.Compile_Error_Description') }}
|
||||
</li>
|
||||
<li>
|
||||
<span :class="getStatusColor(-3)">Presentation Error</span> :
|
||||
您提交的代码已经很接近正确答案,请检查代码格式输出是否有多余空格,换行等空白符。
|
||||
{{ $t('m.Persentation_Error_Description') }}
|
||||
</li>
|
||||
<li>
|
||||
<span :class="getStatusColor(0)">Accepted</span> :
|
||||
您的解题方法是正确的。
|
||||
{{ $t('m.Accepted_Description') }}
|
||||
</li>
|
||||
<li>
|
||||
<span :class="getStatusColor(-1)">Wrong Answer</span> :
|
||||
您的程序输出结果与判题程序的答案不符。
|
||||
{{ $t('m.Wrong_Answer_Description') }}
|
||||
</li>
|
||||
<li>
|
||||
<span :class="getStatusColor(3)">Runtime Error</span> :
|
||||
您的程序异常终止,可能的原因是:段错误,被零除或用非0的代码退出程序。
|
||||
{{ $t('m.Runtime_Error_Description') }}
|
||||
</li>
|
||||
<li>
|
||||
<span :class="getStatusColor(1)">Time Limit Exceeded</span> :
|
||||
您的程序使用的 CPU 时间已超出题目限制。
|
||||
{{ $t('m.Time_Limit_Exceeded_Description') }}
|
||||
</li>
|
||||
<li>
|
||||
<span :class="getStatusColor(2)">Memory Limit Exceeded</span> :
|
||||
您的程序实际使用的内存已超出题目限制。
|
||||
{{ $t('m.Memory_Limit_Exceeded_Description') }}
|
||||
</li>
|
||||
<li>
|
||||
<span :class="getStatusColor(4)">System Error</span> :
|
||||
糟糕,判题机系统出了问题。请报告给管理员。
|
||||
{{ $t('m.System_Error_Description') }}
|
||||
</li>
|
||||
</ul>
|
||||
</el-card>
|
||||
<el-card class="container">
|
||||
<div slot="header">
|
||||
<span class="panel-title home-title">Compile Explanation</span>
|
||||
<span class="panel-title home-title">{{
|
||||
$t('m.Compile_Explanation')
|
||||
}}</span>
|
||||
</div>
|
||||
<ul class="result">
|
||||
<li>
|
||||
1. __int64不是ANSI标准定义,只能在VC使用,在 GNU C++ 中应写成 long
|
||||
long 类型, scanf和printf 请使用%lld作为格式
|
||||
</li>
|
||||
<li>
|
||||
2. main() 返回值必须定义为 int ,而不是 void
|
||||
</li>
|
||||
<li>
|
||||
3. i 在循环外失去定义 "for(int i=0...){...}"
|
||||
</li>
|
||||
<li>
|
||||
4. itoa 不是ansi标准函数(标准 C/C++ 中无此函数)
|
||||
</li>
|
||||
<li>1. {{ $t('m.Compile_Tips1') }}</li>
|
||||
<li>2. {{ $t('m.Compile_Tips2') }}</li>
|
||||
<li>3. {{ $t('m.Compile_Tips2') }}</li>
|
||||
<li>4. {{ $t('m.Compile_Tips4') }}</li>
|
||||
</ul>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
|
|
@ -12,14 +12,14 @@
|
|||
<el-col :span="12" class="text-align:left">
|
||||
<el-tooltip
|
||||
v-if="contest.auth != null && contest.auth != undefined"
|
||||
:content.sync="CONTEST_TYPE_REVERSE[contest.auth]['tips']"
|
||||
:content="$t('m.' + CONTEST_TYPE_REVERSE[contest.auth]['tips'])"
|
||||
placement="top"
|
||||
>
|
||||
<el-tag
|
||||
:type.sync="CONTEST_TYPE_REVERSE[contest.auth]['color']"
|
||||
effect="plain"
|
||||
>
|
||||
{{ CONTEST_TYPE_REVERSE[contest.auth]['name'] }}
|
||||
{{ $t('m.' + CONTEST_TYPE_REVERSE[contest.auth]['name']) }}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
</el-col>
|
||||
|
@ -34,13 +34,13 @@
|
|||
<el-col :xs="24" :md="12" class="left">
|
||||
<p>
|
||||
<i class="fa fa-hourglass-start" aria-hidden="true"></i>
|
||||
StartAt:{{ contest.startTime | localtime }}
|
||||
{{ $t('m.StartAt') }}:{{ contest.startTime | localtime }}
|
||||
</p>
|
||||
</el-col>
|
||||
<el-col :xs="24" :md="12" class="right">
|
||||
<p>
|
||||
<i class="fa fa-hourglass-end" aria-hidden="true"></i>
|
||||
EndAt:{{ contest.endTime | localtime }}
|
||||
{{ $t('m.EndAt') }}:{{ contest.endTime | localtime }}
|
||||
</p>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@ -71,30 +71,32 @@
|
|||
style="text-align:center"
|
||||
>
|
||||
<div slot="header">
|
||||
<span class="panel-title">Password required</span>
|
||||
<span class="panel-title">{{ $t('m.Password_Required') }}</span>
|
||||
</div>
|
||||
<p class="password-form-tips">
|
||||
To enter the Private contest,please input the password!
|
||||
{{ $t('m.To_Enter_Need_Password') }}
|
||||
</p>
|
||||
<el-form>
|
||||
<el-input
|
||||
v-model="contestPassword"
|
||||
type="password"
|
||||
placeholder="Enter the contest password"
|
||||
:placeholder="$t('m.Enter_the_contest_password')"
|
||||
@keydown.enter.native="checkPassword"
|
||||
/>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="checkPassword"
|
||||
style="float:right;margin:5px"
|
||||
>Enter</el-button
|
||||
>{{ $t('m.Enter') }}</el-button
|
||||
>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-tabs v-else @tab-click="tabClick" v-model="route_name">
|
||||
<el-tab-pane name="ContestDetails" lazy>
|
||||
<span slot="label"><i class="el-icon-s-home"></i> Overview</span>
|
||||
<span slot="label"
|
||||
><i class="el-icon-s-home"></i> {{ $t('m.Overview') }}</span
|
||||
>
|
||||
<el-card class="box-card">
|
||||
<div
|
||||
v-html="descriptionHtml"
|
||||
|
@ -111,7 +113,9 @@
|
|||
:disabled="contestMenuDisabled"
|
||||
>
|
||||
<span slot="label"
|
||||
><i class="fa fa-list" aria-hidden="true"></i> Problem</span
|
||||
><i class="fa fa-list" aria-hidden="true"></i> {{
|
||||
$t('m.Problem')
|
||||
}}</span
|
||||
>
|
||||
<transition name="el-zoom-in-bottom">
|
||||
<router-view
|
||||
|
@ -125,7 +129,9 @@
|
|||
lazy
|
||||
:disabled="contestMenuDisabled"
|
||||
>
|
||||
<span slot="label"><i class="el-icon-menu"></i> Status</span>
|
||||
<span slot="label"
|
||||
><i class="el-icon-menu"></i> {{ $t('m.Status') }}</span
|
||||
>
|
||||
<transition name="el-zoom-in-bottom">
|
||||
<router-view
|
||||
v-if="route_name === 'ContestSubmissionList'"
|
||||
|
@ -135,7 +141,9 @@
|
|||
|
||||
<el-tab-pane name="ContestRank" lazy :disabled="contestMenuDisabled">
|
||||
<span slot="label"
|
||||
><i class="fa fa-bar-chart" aria-hidden="true"></i> Rank</span
|
||||
><i class="fa fa-bar-chart" aria-hidden="true"></i> {{
|
||||
$t('m.NavBar_Rank')
|
||||
}}</span
|
||||
>
|
||||
<transition name="el-zoom-in-bottom">
|
||||
<router-view v-if="route_name === 'ContestRank'"></router-view>
|
||||
|
@ -148,8 +156,9 @@
|
|||
:disabled="contestMenuDisabled"
|
||||
>
|
||||
<span slot="label"
|
||||
><i class="fa fa-bullhorn" aria-hidden="true"></i
|
||||
> Announcement</span
|
||||
><i class="fa fa-bullhorn" aria-hidden="true"></i> {{
|
||||
$t('m.Announcement')
|
||||
}}</span
|
||||
>
|
||||
<transition name="el-zoom-in-bottom">
|
||||
<router-view
|
||||
|
@ -160,8 +169,9 @@
|
|||
|
||||
<el-tab-pane name="ContestComment" lazy :disabled="contestMenuDisabled">
|
||||
<span slot="label"
|
||||
><i class="fa fa-commenting" aria-hidden="true"></i
|
||||
> Comment</span
|
||||
><i class="fa fa-commenting" aria-hidden="true"></i> {{
|
||||
$t('m.Comment')
|
||||
}}</span
|
||||
>
|
||||
<transition name="el-zoom-in-bottom">
|
||||
<router-view v-if="route_name === 'ContestComment'"></router-view>
|
||||
|
@ -175,8 +185,9 @@
|
|||
v-if="showAdminHelper"
|
||||
>
|
||||
<span slot="label"
|
||||
><i class="el-icon-s-help" aria-hidden="true"></i> AC
|
||||
Info</span
|
||||
><i class="el-icon-s-help" aria-hidden="true"></i> {{
|
||||
$t('m.Admin_Helper')
|
||||
}}</span
|
||||
>
|
||||
<transition name="el-zoom-in-bottom">
|
||||
<router-view v-if="route_name === 'ContestACInfo'"></router-view>
|
||||
|
@ -190,8 +201,9 @@
|
|||
v-if="isSuperAdmin"
|
||||
>
|
||||
<span slot="label"
|
||||
><i class="el-icon-refresh" aria-hidden="true"></i
|
||||
> Rejudge</span
|
||||
><i class="el-icon-refresh" aria-hidden="true"></i> {{
|
||||
$t('m.Rejudge')
|
||||
}}</span
|
||||
>
|
||||
<transition name="el-zoom-in-bottom">
|
||||
<router-view
|
||||
|
@ -273,13 +285,13 @@ export default {
|
|||
},
|
||||
checkPassword() {
|
||||
if (this.contestPassword === '') {
|
||||
myMessage.warning('请输入该比赛的密码!');
|
||||
myMessage.warning(this.$i18n.t('m.Enter_the_contest_password'));
|
||||
return;
|
||||
}
|
||||
this.btnLoading = true;
|
||||
api.registerContest(this.contestID + '', this.contestPassword).then(
|
||||
(res) => {
|
||||
myMessage.success(res.data.msg);
|
||||
myMessage.success(this.$i18n.t('m.Register_contest_successfully'));
|
||||
this.$store.commit('contestIntoAccess', { intoAccess: true });
|
||||
this.btnLoading = false;
|
||||
},
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
<div slot="header">
|
||||
<span class="panel-title"
|
||||
>{{
|
||||
query.type === '' ? 'All' : parseContestType(query.type)
|
||||
query.type === '' ? $t('m.All') : parseContestType(query.type)
|
||||
}}
|
||||
Contests</span
|
||||
{{ $t('m.Contests') }}</span
|
||||
>
|
||||
<div class="filter-row">
|
||||
<span>
|
||||
|
@ -18,11 +18,17 @@
|
|||
class="drop-menu"
|
||||
>
|
||||
<span class="el-dropdown-link">
|
||||
{{ query.type == '' ? 'Rule' : parseContestType(query.type) }}
|
||||
{{
|
||||
query.type == ''
|
||||
? $t('m.Rule')
|
||||
: parseContestType(query.type)
|
||||
}}
|
||||
<i class="el-icon-caret-bottom"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="">All</el-dropdown-item>
|
||||
<el-dropdown-item command="">{{
|
||||
$t('m.All')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item command="0">ACM</el-dropdown-item>
|
||||
<el-dropdown-item command="1">OI</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
|
@ -39,16 +45,24 @@
|
|||
<span class="el-dropdown-link">
|
||||
{{
|
||||
query.status === ''
|
||||
? 'Status'
|
||||
? $t('m.Status')
|
||||
: CONTEST_STATUS_REVERSE[query.status]['name']
|
||||
}}
|
||||
<i class="el-icon-caret-bottom"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="">All</el-dropdown-item>
|
||||
<el-dropdown-item command="-1">Scheduled</el-dropdown-item>
|
||||
<el-dropdown-item command="0">Running</el-dropdown-item>
|
||||
<el-dropdown-item command="1">Ended</el-dropdown-item>
|
||||
<el-dropdown-item command="">{{
|
||||
$t('m.All')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item command="-1">{{
|
||||
$t('m.Scheduled')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item command="0">{{
|
||||
$t('m.Running')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item command="1">{{
|
||||
$t('m.Ended')
|
||||
}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</span>
|
||||
|
@ -56,7 +70,7 @@
|
|||
<span>
|
||||
<vxe-input
|
||||
v-model="query.keyword"
|
||||
placeholder="Enter keyword"
|
||||
:placeholder="$t('m.Enter_keyword')"
|
||||
type="search"
|
||||
size="medium"
|
||||
@keyup.enter.native="filterByChange"
|
||||
|
@ -65,7 +79,9 @@
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<p id="no-contest" v-show="contests.length == 0">暂无比赛</p>
|
||||
<p id="no-contest" v-show="contests.length == 0">
|
||||
{{ $t('m.No_contest') }}
|
||||
</p>
|
||||
<ol id="contest-list">
|
||||
<li
|
||||
v-for="contest in contests"
|
||||
|
@ -127,7 +143,9 @@
|
|||
</li>
|
||||
<li>
|
||||
<el-tooltip
|
||||
:content="CONTEST_TYPE_REVERSE[contest.auth].tips"
|
||||
:content="
|
||||
$t('m.' + CONTEST_TYPE_REVERSE[contest.auth].tips)
|
||||
"
|
||||
placement="top"
|
||||
effect="light"
|
||||
>
|
||||
|
@ -135,7 +153,9 @@
|
|||
:type="CONTEST_TYPE_REVERSE[contest.auth]['color']"
|
||||
effect="plain"
|
||||
>
|
||||
{{ CONTEST_TYPE_REVERSE[contest.auth]['name'] }}
|
||||
{{
|
||||
$t('m.' + CONTEST_TYPE_REVERSE[contest.auth]['name'])
|
||||
}}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
</li>
|
||||
|
@ -154,7 +174,9 @@
|
|||
size="medium"
|
||||
>
|
||||
<i class="fa fa-circle" aria-hidden="true"></i>
|
||||
{{ CONTEST_STATUS_REVERSE[contest.status]['name'] }}
|
||||
{{
|
||||
$t('m.' + CONTEST_STATUS_REVERSE[contest.status]['name'])
|
||||
}}
|
||||
</el-tag>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@ -257,7 +279,7 @@ export default {
|
|||
},
|
||||
toContest(contest) {
|
||||
if (contest.type !== CONTEST_TYPE.PUBLIC && !this.isAuthenticated) {
|
||||
myMessage.warning('请先登录');
|
||||
myMessage.warning(this.$i18n.t('m.Please_login_first'));
|
||||
this.$store.dispatch('changeModalStatus', { visible: true });
|
||||
} else {
|
||||
this.$router.push({
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
<template>
|
||||
<el-card shadow>
|
||||
<div slot="header">
|
||||
<span class="panel-title">Contest Rank</span>
|
||||
<span class="panel-title">{{ $t('m.Contest_Rank') }}</span>
|
||||
<span style="float:right;font-size: 20px;">
|
||||
<el-popover trigger="hover" placement="left-start">
|
||||
<i class="el-icon-s-tools" slot="reference"></i>
|
||||
<div id="switches">
|
||||
<p>
|
||||
<span>Chart</span>
|
||||
<span>{{ $t('m.Chart') }}</span>
|
||||
<el-switch v-model="showChart"></el-switch>
|
||||
</p>
|
||||
<p>
|
||||
<span>Table</span>
|
||||
<span>{{ $t('m.Table') }}</span>
|
||||
<el-switch v-model="showTable"></el-switch>
|
||||
</p>
|
||||
<p>
|
||||
<span>Auto Refresh(10s)</span>
|
||||
<span>{{ $t('m.Auto_Refresh') }}(10s)</span>
|
||||
<el-switch
|
||||
:disabled="refreshDisabled"
|
||||
v-model="autoRefresh"
|
||||
|
@ -24,7 +24,7 @@
|
|||
</p>
|
||||
<template v-if="isContestAdmin">
|
||||
<p>
|
||||
<span>Force Update</span>
|
||||
<span>{{ $t('m.Force_Update') }}</span>
|
||||
<el-switch
|
||||
:disabled="refreshDisabled"
|
||||
v-model="forceUpdate"
|
||||
|
@ -32,9 +32,9 @@
|
|||
</p>
|
||||
</template>
|
||||
<template>
|
||||
<el-button type="primary" size="small" @click="downloadRankCSV"
|
||||
>Download as CSV</el-button
|
||||
>
|
||||
<el-button type="primary" size="small" @click="downloadRankCSV">{{
|
||||
$t('m.Download_as_CSV')
|
||||
}}</el-button>
|
||||
</template>
|
||||
</div>
|
||||
</el-popover>
|
||||
|
@ -59,7 +59,11 @@
|
|||
min-width="50"
|
||||
fixed="left"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column field="username" min-width="150" title="User">
|
||||
<vxe-table-column
|
||||
field="username"
|
||||
min-width="150"
|
||||
:title="$t('m.User')"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span
|
||||
><a
|
||||
|
@ -73,11 +77,15 @@
|
|||
<vxe-table-column
|
||||
field="realname"
|
||||
min-width="100"
|
||||
title="RealName"
|
||||
:title="$t('m.RealName')"
|
||||
v-if="isContestAdmin"
|
||||
>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="rating" title="AC / Total" min-width="80">
|
||||
<vxe-table-column
|
||||
field="rating"
|
||||
:title="$t('m.AC') + ' / ' + $t('m.Total')"
|
||||
min-width="80"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span
|
||||
>{{ row.ac }} /
|
||||
|
@ -89,7 +97,11 @@
|
|||
</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="totalTime" title="TotalTime" min-width="80">
|
||||
<vxe-table-column
|
||||
field="totalTime"
|
||||
:title="$t('m.TotalTime')"
|
||||
min-width="80"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ parseTotalTime(row.totalTime) }}</span>
|
||||
</template>
|
||||
|
@ -155,7 +167,7 @@ export default {
|
|||
dataRank: [],
|
||||
options: {
|
||||
title: {
|
||||
text: 'Top 10 Teams',
|
||||
text: this.$i18n.t('m.Top_10_Teams'),
|
||||
left: 'center',
|
||||
top: 0,
|
||||
},
|
||||
|
@ -171,7 +183,7 @@ export default {
|
|||
toolbox: {
|
||||
show: true,
|
||||
feature: {
|
||||
saveAsImage: { show: true, title: 'save as image' },
|
||||
saveAsImage: { show: true, title: this.$i18n.t('m.save_as_image') },
|
||||
},
|
||||
right: '0',
|
||||
},
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<template>
|
||||
<el-card shadow="always">
|
||||
<div slot="header">
|
||||
<span class="panel-title">AC Info</span>
|
||||
<span class="panel-title">{{ $t('m.Admin_Helper') }}</span>
|
||||
<div class="filter-row">
|
||||
<span>
|
||||
Auto Refresh(10s)
|
||||
{{ $t('m.Auto_Refresh') }}(10s)
|
||||
<el-switch
|
||||
@change="handleAutoRefresh"
|
||||
v-model="autoRefresh"
|
||||
|
@ -17,7 +17,7 @@
|
|||
size="small"
|
||||
icon="el-icon-refresh"
|
||||
:loading="btnLoading"
|
||||
>Refresh</el-button
|
||||
>{{ $t('m.Refresh') }}</el-button
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -29,25 +29,35 @@
|
|||
align="center"
|
||||
:data="acInfoList"
|
||||
>
|
||||
<vxe-table-column field="submitTime" min-width="150" title="AC Time">
|
||||
<vxe-table-column
|
||||
field="submitTime"
|
||||
min-width="150"
|
||||
:title="$t('m.AC_Time')"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ row.submitTime | localtime }}</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="displayId"
|
||||
title="Problem ID"
|
||||
:title="$t('m.Problem_ID')"
|
||||
min-width="100"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column field="first_blood" title="AC Status" min-width="80">
|
||||
<template v-slot="{ row }">
|
||||
<el-tag effect="dark" color="#ed3f14" v-if="row.firstBlood"
|
||||
>First Blood</el-tag
|
||||
>
|
||||
<el-tag effect="dark" color="#19be6b" v-else>Accepet</el-tag>
|
||||
<el-tag effect="dark" color="#ed3f14" v-if="row.firstBlood">{{
|
||||
$t('m.First_Blood')
|
||||
}}</el-tag>
|
||||
<el-tag effect="dark" color="#19be6b" v-else>{{
|
||||
$t('m.Accepted')
|
||||
}}</el-tag>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="username" title="Username" min-width="150">
|
||||
<vxe-table-column
|
||||
field="username"
|
||||
:title="$t('m.Username')"
|
||||
min-width="150"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span
|
||||
><a
|
||||
|
@ -60,15 +70,17 @@
|
|||
</vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="realname"
|
||||
title="RealName"
|
||||
:title="$t('m.RealName')"
|
||||
min-width="150"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column field="checked" title="Status" min-width="150">
|
||||
<vxe-table-column field="checked" :title="$t('m.Status')" min-width="150">
|
||||
<template v-slot="{ row }">
|
||||
<el-tag effect="dark" color="#19be6b" v-if="row.checked"
|
||||
>Checked</el-tag
|
||||
>
|
||||
<el-tag effect="dark" color="#f90" v-else>Not Checked</el-tag>
|
||||
<el-tag effect="dark" color="#19be6b" v-if="row.checked">{{
|
||||
$t('m.Checked')
|
||||
}}</el-tag>
|
||||
<el-tag effect="dark" color="#f90" v-else>{{
|
||||
$t('m.Not_Checked')
|
||||
}}</el-tag>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="option" title="Option" min-width="150">
|
||||
|
@ -79,7 +91,7 @@
|
|||
icon="el-icon-circle-check"
|
||||
@click="updateCheckedStatus(row)"
|
||||
round
|
||||
>Check It</el-button
|
||||
>{{ $t('m.Check_It') }}</el-button
|
||||
>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
|
@ -93,8 +105,7 @@
|
|||
</el-card>
|
||||
</template>
|
||||
<script>
|
||||
import { mapState, mapActions } from 'vuex';
|
||||
import moment from 'moment';
|
||||
import { mapState } from 'vuex';
|
||||
import Pagination from '@/components/oj/common/Pagination.vue';
|
||||
import api from '@/common/api';
|
||||
import myMessage from '@/common/message';
|
||||
|
@ -152,7 +163,7 @@ export default {
|
|||
api
|
||||
.updateACInfoCheckedStatus(data)
|
||||
.then((res) => {
|
||||
myMessage.success(res.data.msg);
|
||||
myMessage.success(this.$i18n.t('m.Update_Successfully'));
|
||||
this.getACInfo();
|
||||
})
|
||||
.catch(() => {});
|
||||
|
|
|
@ -69,26 +69,26 @@
|
|||
></vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="displayTitle"
|
||||
title="Title"
|
||||
:title="$t('m.Title')"
|
||||
min-width="200"
|
||||
></vxe-table-column>
|
||||
|
||||
<!-- 以下列只有在实时刷新榜单的情况下才显示 -->
|
||||
<vxe-table-column
|
||||
field="ac"
|
||||
title="AC"
|
||||
:title="$t('m.AC')"
|
||||
min-width="80"
|
||||
v-if="ContestRealTimePermission"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="total"
|
||||
title="Total"
|
||||
:title="$t('m.Total')"
|
||||
min-width="80"
|
||||
v-if="ContestRealTimePermission"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="ACRating"
|
||||
title="AC Rate"
|
||||
:title="$t('m.AC_Rate')"
|
||||
min-width="80"
|
||||
v-if="ContestRealTimePermission"
|
||||
>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<el-card shadow="always">
|
||||
<div slot="header">
|
||||
<span class="panel-title">Admin Contest Rejudge</span>
|
||||
<span class="panel-title">{{ $t('m.Contest_Rejudge') }}</span>
|
||||
</div>
|
||||
<vxe-table
|
||||
border="inner"
|
||||
|
@ -10,23 +10,27 @@
|
|||
align="center"
|
||||
:data="contestProblems"
|
||||
>
|
||||
<vxe-table-column field="pid" min-width="50" title="Problem ID">
|
||||
<vxe-table-column field="pid" min-width="50" :title="$t('m.ID')">
|
||||
</vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="displayId"
|
||||
title="Display ID"
|
||||
:title="$t('m.Problem_ID')"
|
||||
min-width="100"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column field="displayTitle" title="Title" min-width="200">
|
||||
<vxe-table-column
|
||||
field="displayTitle"
|
||||
:title="$t('m.Title')"
|
||||
min-width="200"
|
||||
>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="ac" title="AC" min-width="80">
|
||||
<vxe-table-column field="ac" :title="$t('m.AC')" min-width="80">
|
||||
</vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="total"
|
||||
title="Total"
|
||||
:title="$t('m.Total')"
|
||||
min-width="80"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column field="option" title="Option" min-width="150">
|
||||
<vxe-table-column field="option" :title="$t('m.Option')" min-width="150">
|
||||
<template v-slot="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
|
@ -35,7 +39,7 @@
|
|||
icon="el-icon-refresh-right"
|
||||
@click="rejudgeProblem(row)"
|
||||
round
|
||||
>Rejudge All</el-button
|
||||
>{{ $t('m.Rejudge_All') }}</el-button
|
||||
>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
|
@ -63,26 +67,29 @@ export default {
|
|||
methods: {
|
||||
...mapActions(['getContestProblems']),
|
||||
rejudgeProblem(row) {
|
||||
this.$confirm('你是否确定将该题的所有提交全部重判?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
this.$confirm(this.$i18n.t('m.Contest_Rejudge_Tips'), 'Tips', {
|
||||
confirmButtonText: this.$i18n.t('m.OK'),
|
||||
cancelButtonText: this.$i18n.t('m.Cancel'),
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
let params = {
|
||||
pid: row.pid,
|
||||
cid: row.cid,
|
||||
};
|
||||
this.btnLoading = true;
|
||||
api
|
||||
.ContestRejudgeProblem(params)
|
||||
.then((res) => {
|
||||
myMessage.success(res.data.msg);
|
||||
this.btnLoading = false;
|
||||
})
|
||||
.catch(() => {
|
||||
this.btnLoading = false;
|
||||
});
|
||||
});
|
||||
}).then(
|
||||
() => {
|
||||
let params = {
|
||||
pid: row.pid,
|
||||
cid: row.cid,
|
||||
};
|
||||
this.btnLoading = true;
|
||||
api
|
||||
.ContestRejudgeProblem(params)
|
||||
.then((res) => {
|
||||
myMessage.success(this.$i18n.t('m.Rejudge_successfully'));
|
||||
this.btnLoading = false;
|
||||
})
|
||||
.catch(() => {
|
||||
this.btnLoading = false;
|
||||
});
|
||||
},
|
||||
() => {}
|
||||
);
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
<template>
|
||||
<el-card shadow>
|
||||
<div slot="header">
|
||||
<span class="panel-title">Contest Rank</span>
|
||||
<span class="panel-title">{{ $t('m.Contest_Rank') }}</span>
|
||||
<span style="float:right;font-size: 20px;">
|
||||
<el-popover trigger="hover" placement="left-start">
|
||||
<i class="el-icon-s-tools" slot="reference"></i>
|
||||
<div id="switches">
|
||||
<p>
|
||||
<span>Chart</span>
|
||||
<span>{{ $t('m.Chart') }}</span>
|
||||
<el-switch v-model="showChart"></el-switch>
|
||||
</p>
|
||||
<p>
|
||||
<span>Table</span>
|
||||
<span>{{ $t('m.Table') }}</span>
|
||||
<el-switch v-model="showTable"></el-switch>
|
||||
</p>
|
||||
<p>
|
||||
<span>Auto Refresh(10s)</span>
|
||||
<span>{{ $t('m.Auto_Refresh') }}(10s)</span>
|
||||
<el-switch
|
||||
:disabled="refreshDisabled"
|
||||
@change="handleAutoRefresh"
|
||||
|
@ -24,7 +24,7 @@
|
|||
</p>
|
||||
<template v-if="isContestAdmin">
|
||||
<p>
|
||||
<span>Force Update</span>
|
||||
<span>{{ $t('m.Force_Update') }}</span>
|
||||
<el-switch
|
||||
:disabled="refreshDisabled"
|
||||
v-model="forceUpdate"
|
||||
|
@ -32,9 +32,9 @@
|
|||
</p>
|
||||
</template>
|
||||
<template>
|
||||
<el-button type="primary" size="small" @click="downloadRankCSV"
|
||||
>Download as CSV</el-button
|
||||
>
|
||||
<el-button type="primary" size="small" @click="downloadRankCSV">{{
|
||||
$t('m.Download_as_CSV')
|
||||
}}</el-button>
|
||||
</template>
|
||||
</div>
|
||||
</el-popover>
|
||||
|
@ -60,7 +60,11 @@
|
|||
min-width="50"
|
||||
fixed="left"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column field="username" min-width="150" title="User">
|
||||
<vxe-table-column
|
||||
field="username"
|
||||
min-width="150"
|
||||
:title="$t('m.User')"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span
|
||||
><a
|
||||
|
@ -74,11 +78,15 @@
|
|||
<vxe-table-column
|
||||
field="realname"
|
||||
min-width="100"
|
||||
title="RealName"
|
||||
:title="$t('m.RealName')"
|
||||
v-if="isContestAdmin"
|
||||
>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="totalScore" title="TotalScore" min-width="80">
|
||||
<vxe-table-column
|
||||
field="totalScore"
|
||||
:title="$t('m.Total_Score')"
|
||||
min-width="80"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span
|
||||
><a
|
||||
|
@ -141,7 +149,7 @@ export default {
|
|||
autoRefresh: false,
|
||||
options: {
|
||||
title: {
|
||||
text: 'Top 10 Teams',
|
||||
text: this.$i18n.t('m.Top_10_Teams'),
|
||||
left: 'center',
|
||||
},
|
||||
tooltip: {
|
||||
|
@ -152,7 +160,7 @@ export default {
|
|||
feature: {
|
||||
dataView: { show: true, readOnly: true },
|
||||
magicType: { show: true, type: ['line', 'bar'] },
|
||||
saveAsImage: { show: true },
|
||||
saveAsImage: { show: true, title: this.$i18n.t('m.save_as_image') },
|
||||
},
|
||||
right: '10%',
|
||||
top: '5%',
|
||||
|
@ -187,7 +195,7 @@ export default {
|
|||
},
|
||||
series: [
|
||||
{
|
||||
name: 'Score',
|
||||
name: this.$i18n.t('m.Score'),
|
||||
type: 'bar',
|
||||
barMaxWidth: '80',
|
||||
data: [0],
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
>ADM</span
|
||||
>
|
||||
<span class="c999" style="padding:0 6px;"
|
||||
><i class="el-icon-folder-opened"> 分类:</i
|
||||
><i class="el-icon-folder-opened"> {{ $t('m.Category') }}:</i
|
||||
><a
|
||||
class="c999"
|
||||
@click="toAllDiscussionByCid(discussion.categoryId)"
|
||||
|
@ -45,35 +45,39 @@
|
|||
>
|
||||
<span class="c999"
|
||||
><i class="fa fa-thumbs-o-up"></i
|
||||
><span> 点赞:{{ discussion.likeNum }}</span></span
|
||||
><span> {{ $t('m.Likes') }}:{{ discussion.likeNum }}</span></span
|
||||
>
|
||||
<span class="c999"
|
||||
><i class="fa fa-eye"></i
|
||||
><span> 浏览:{{ discussion.viewNum }}</span></span
|
||||
><span> {{ $t('m.Views') }}:{{ discussion.viewNum }}</span></span
|
||||
>
|
||||
|
||||
<a @click="showReportDialog = true" class="report" title="举报"
|
||||
><i class="fa fa-envira"></i><span>举报</span></a
|
||||
<a
|
||||
@click="showReportDialog = true"
|
||||
class="report"
|
||||
:title="$t('m.Report')"
|
||||
><i class="fa fa-envira"></i><span>{{ $t('m.Report') }}</span></a
|
||||
>
|
||||
<a
|
||||
@click="toLikeDiscussion(discussion.id, true)"
|
||||
class="like"
|
||||
title="点赞"
|
||||
:title="$t('m.Like')"
|
||||
v-if="!discussion.hasLike"
|
||||
>
|
||||
<i class="fa fa-thumbs-o-up"></i> <span>点赞</span></a
|
||||
<i class="fa fa-thumbs-o-up"></i>
|
||||
<span>{{ $t('m.Like') }}</span></a
|
||||
>
|
||||
<a
|
||||
@click="toLikeDiscussion(discussion.id, false)"
|
||||
class="like"
|
||||
title="已点赞"
|
||||
:title="$t('m.Liked')"
|
||||
v-else
|
||||
>
|
||||
<i class="fa fa-thumbs-up"></i> <span>已点赞</span></a
|
||||
<i class="fa fa-thumbs-up"></i> <span>{{ $t('m.Liked') }}</span></a
|
||||
>
|
||||
|
||||
<span>
|
||||
<i class="fa fa-clock-o"> 创建时间:</i>
|
||||
<i class="fa fa-clock-o"> {{ $t('m.Created_Time') }}:</i>
|
||||
<span>
|
||||
<el-tooltip
|
||||
:content="discussion.gmtCreate | localtime"
|
||||
|
@ -86,7 +90,7 @@
|
|||
|
||||
<span style="padding:0 6px;" v-show="userInfo.uid == discussion.uid"
|
||||
><a style="color:#8fb0c9" @click="showEditDiscussionDialog = true"
|
||||
><i class="el-icon-edit-outline"> 编辑</i></a
|
||||
><i class="el-icon-edit-outline"> {{ $t('m.Edit') }}</i></a
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
|
@ -100,9 +104,13 @@
|
|||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog title="举报" :visible.sync="showReportDialog" width="350px">
|
||||
<el-dialog
|
||||
:title="$t('m.Report')"
|
||||
:visible.sync="showReportDialog"
|
||||
width="350px"
|
||||
>
|
||||
<el-form label-position="top" :model="report">
|
||||
<el-form-item label="标签" required>
|
||||
<el-form-item :label="$t('m.Tags')" required>
|
||||
<el-checkbox-group v-model="report.tagList">
|
||||
<el-checkbox label="垃圾广告"></el-checkbox>
|
||||
<el-checkbox label="违法违规"></el-checkbox>
|
||||
|
@ -112,11 +120,11 @@
|
|||
<el-checkbox label="恶意抄袭"></el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="理由" required>
|
||||
<el-form-item :label="$t('m.Report_Reason')" required>
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="report.content"
|
||||
placeholder="请写下举报的理由"
|
||||
:placeholder="$t('m.Report_Reason')"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
:rows="4"
|
||||
|
@ -125,10 +133,12 @@
|
|||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="danger" @click.native="showReportDialog = false"
|
||||
>取消</el-button
|
||||
>
|
||||
<el-button type="primary" @click.native="submitReport">提交</el-button>
|
||||
<el-button type="danger" @click.native="showReportDialog = false">{{
|
||||
$t('m.Cancel')
|
||||
}}</el-button>
|
||||
<el-button type="primary" @click.native="submitReport">{{
|
||||
$t('m.OK')
|
||||
}}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
|
@ -140,28 +150,24 @@
|
|||
@open="onOpenEditDialog"
|
||||
>
|
||||
<el-form label-position="top" :model="discussion">
|
||||
<el-form-item label="讨论标题" required>
|
||||
<el-form-item :label="$t('m.Discussion_title')" required>
|
||||
<el-input
|
||||
v-model="discussion.title"
|
||||
placeholder="请输入讨论标题"
|
||||
:placeholder="$t('m.Discussion_title')"
|
||||
class="title-input"
|
||||
>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="讨论简介" required>
|
||||
<el-form-item :label="$t('m.Discussion_Desc')" required>
|
||||
<el-input
|
||||
v-model="discussion.description"
|
||||
placeholder="请输入讨论简介"
|
||||
:placeholder="$t('m.Discussion_Desc')"
|
||||
class="title-input"
|
||||
>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="讨论分类" required>
|
||||
<el-select
|
||||
v-model="discussion.categoryId"
|
||||
placeholder="请选择"
|
||||
disabled
|
||||
>
|
||||
<el-form-item :label="$t('m.Discussion_Category')" required>
|
||||
<el-select v-model="discussion.categoryId" placeholder="---" disabled>
|
||||
<el-option
|
||||
:label="discussion.categoryName"
|
||||
:value="discussion.categoryId"
|
||||
|
@ -169,10 +175,14 @@
|
|||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否置顶" required v-if="isAdminRole">
|
||||
<el-form-item
|
||||
:label="$t('m.Discussion_top')"
|
||||
required
|
||||
v-if="isAdminRole"
|
||||
>
|
||||
<el-switch v-model="discussion.topPriority"> </el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="讨论内容" required>
|
||||
<el-form-item :label="$t('m.Discussion_content')" required>
|
||||
<Editor :value.sync="discussion.content"></Editor>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -180,11 +190,11 @@
|
|||
<el-button
|
||||
type="danger"
|
||||
@click.native="showEditDiscussionDialog = false"
|
||||
>取消</el-button
|
||||
>
|
||||
<el-button type="primary" @click.native="submitDiscussion"
|
||||
>发布</el-button
|
||||
>{{ $t('m.Cancel') }}</el-button
|
||||
>
|
||||
<el-button type="primary" @click.native="submitDiscussion">{{
|
||||
$t('m.OK')
|
||||
}}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<comment :did="$route.params.discussionID"></comment>
|
||||
|
@ -260,7 +270,7 @@ export default {
|
|||
|
||||
toLikeDiscussion(did, toLike) {
|
||||
if (!this.isAuthenticated) {
|
||||
myMessage.warning('请先登录');
|
||||
myMessage.warning(this.$i18n.t('m.Please_login_first'));
|
||||
return;
|
||||
}
|
||||
api.toLikeDiscussion(did, toLike).then((res) => {
|
||||
|
@ -281,14 +291,14 @@ export default {
|
|||
delete discussion.viewNum;
|
||||
delete discussion.likeNum;
|
||||
api.updateDiscussion(discussion).then((res) => {
|
||||
myMessage.success(res.data.msg);
|
||||
myMessage.success(this.$i18n.t('m.Update_Successfully'));
|
||||
this.showEditDiscussionDialog = false;
|
||||
this.init();
|
||||
});
|
||||
},
|
||||
submitReport() {
|
||||
if (!this.isAuthenticated) {
|
||||
myMessage.warning('请先登录');
|
||||
myMessage.warning(this.$i18n.t('m.Please_login_first'));
|
||||
return;
|
||||
}
|
||||
if (this.report.tagList.length == 0 && !this.report.content) {
|
||||
|
@ -306,7 +316,7 @@ export default {
|
|||
did: this.discussionID,
|
||||
};
|
||||
api.toReportDiscussion(discussionReport).then((res) => {
|
||||
myMessage.success(res.data.msg);
|
||||
myMessage.success(this.$i18n.t('m.Post_successfully'));
|
||||
this.showReportDialog = false;
|
||||
});
|
||||
},
|
||||
|
@ -388,7 +398,7 @@ export default {
|
|||
.title-article .title-msg a.like {
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
right: 60px;
|
||||
right: 68px;
|
||||
color: #ff6700 !important;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
<el-breadcrumb separator-class="el-icon-arrow-right">
|
||||
<template v-if="currentCategory">
|
||||
<el-breadcrumb-item :to="{ name: routeName, query: null }">
|
||||
{{ query.onlyMine ? '我的' : '' }}全部</el-breadcrumb-item
|
||||
{{ query.onlyMine ? $t('m.Mine') : ''
|
||||
}}{{ $t('m.All') }}</el-breadcrumb-item
|
||||
>
|
||||
<el-breadcrumb-item
|
||||
>{{ currentCategory }} ( {{ total }} )</el-breadcrumb-item
|
||||
|
@ -15,7 +16,7 @@
|
|||
</template>
|
||||
<template v-else>
|
||||
<el-breadcrumb-item :to="{ name: routeName }"
|
||||
>{{ query.onlyMine ? '我的' : '' }}全部 (
|
||||
>{{ query.onlyMine ? $t('m.Mine') : '' }}{{ $t('m.All') }} (
|
||||
{{ total }} )</el-breadcrumb-item
|
||||
>
|
||||
</template>
|
||||
|
@ -24,7 +25,7 @@
|
|||
<span class="search"
|
||||
><vxe-input
|
||||
v-model="query.keyword"
|
||||
placeholder="Enter the keyword"
|
||||
:placeholder="$t('m.Enter_keyword')"
|
||||
type="search"
|
||||
@keyup.enter.native="handleQueryChange"
|
||||
@search-click="handleQueryChange"
|
||||
|
@ -103,7 +104,7 @@
|
|||
<span class="pr pl hidden-xs-only"
|
||||
><label class="fw"><i class="fa fa-clock-o"></i></label
|
||||
><span>
|
||||
创建时间:<el-tooltip
|
||||
{{ $t('m.Created_Time') }}:<el-tooltip
|
||||
:content="discussion.gmtCreate | localtime"
|
||||
placement="top"
|
||||
>
|
||||
|
@ -113,11 +114,15 @@
|
|||
>
|
||||
<span class="pr"
|
||||
><label class="fw"><i class="fa fa-thumbs-o-up"></i></label
|
||||
><span> 点赞:{{ discussion.likeNum }}</span></span
|
||||
><span>
|
||||
{{ $t('m.Likes') }}:{{ discussion.likeNum }}</span
|
||||
></span
|
||||
>
|
||||
<span class="pr"
|
||||
><label class="fw"><i class="fa fa-eye"></i></label
|
||||
><span> 浏览:{{ discussion.viewNum }}</span></span
|
||||
><span>
|
||||
{{ $t('m.Views') }}:{{ discussion.viewNum }}</span
|
||||
></span
|
||||
>
|
||||
<span
|
||||
><label class="fw"><i class="el-icon-folder-opened"></i></label>
|
||||
|
@ -148,13 +153,13 @@
|
|||
icon="el-icon-edit-outline"
|
||||
:command="'edit:' + index"
|
||||
v-show="discussion.uid === userInfo.uid"
|
||||
>编辑</el-dropdown-item
|
||||
>{{ $t('m.Edit') }}</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item
|
||||
icon="el-icon-delete"
|
||||
:command="'delete:' + index"
|
||||
v-show="discussion.uid === userInfo.uid || isAdminRole"
|
||||
>删除</el-dropdown-item
|
||||
>{{ $t('m.Delete') }}</el-dropdown-item
|
||||
>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
@ -173,13 +178,13 @@
|
|||
icon="el-icon-edit-outline"
|
||||
:command="'edit:' + index"
|
||||
v-show="discussion.uid === userInfo.uid"
|
||||
>编辑</el-dropdown-item
|
||||
>{{ $t('m.Edit') }}</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item
|
||||
icon="el-icon-delete"
|
||||
:command="'delete:' + index"
|
||||
v-show="discussion.uid === userInfo.uid || isAdminRole"
|
||||
>删除</el-dropdown-item
|
||||
>{{ $t('m.Delete') }}</el-dropdown-item
|
||||
>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
@ -206,7 +211,11 @@
|
|||
@click="toEditDiscussion"
|
||||
style="width: 100%;"
|
||||
><i class="el-icon-edit">
|
||||
{{ this.query.pid == '' ? '发布讨论' : '发布题目讨论' }}</i
|
||||
{{
|
||||
this.query.pid == ''
|
||||
? $t('m.Post_discussion')
|
||||
: $t('m.Post_problem_discussion')
|
||||
}}</i
|
||||
>
|
||||
</el-button>
|
||||
<el-button
|
||||
|
@ -216,7 +225,7 @@
|
|||
@click="toOnlyMyDiscussion(!query.onlyMine)"
|
||||
style="width: 100%;margin-left:0;margin-top:10px"
|
||||
><i class="el-icon-search">
|
||||
{{ query.onlyMine ? '查看所有讨论' : '只看自己' }}</i
|
||||
{{ query.onlyMine ? $t('m.All') : $t('m.Mine') }}</i
|
||||
>
|
||||
</el-button>
|
||||
<template v-if="this.query.pid">
|
||||
|
@ -225,7 +234,7 @@
|
|||
type="success"
|
||||
@click="toAllDiscussion"
|
||||
style="width: 100%;margin-left:0;margin-top:10px"
|
||||
><i class="el-icon-s-home"> 综合讨论区</i>
|
||||
><i class="el-icon-s-home"> {{ $t('m.General_discussion') }}</i>
|
||||
</el-button>
|
||||
|
||||
<el-button
|
||||
|
@ -239,7 +248,7 @@
|
|||
)
|
||||
"
|
||||
style="width: 100%;margin-left:0;margin-top:10px"
|
||||
><i class="el-icon-back"> 返回 ({{ query.pid }}) 题目</i>
|
||||
><i class="el-icon-back"> {{ $t('m.Return') }} ({{ query.pid }})</i>
|
||||
</el-button>
|
||||
</template>
|
||||
<div class="category-body">
|
||||
|
@ -252,7 +261,7 @@
|
|||
routeName
|
||||
)
|
||||
"
|
||||
><i class="el-icon-folder-opened"></i> 讨论分类</a
|
||||
><i class="el-icon-folder-opened"></i> {{ $t('m.Category') }}</a
|
||||
>
|
||||
</h3>
|
||||
<el-row>
|
||||
|
@ -292,24 +301,24 @@
|
|||
@open="onOpenEditDialog"
|
||||
>
|
||||
<el-form label-position="top" :model="discussion">
|
||||
<el-form-item label="讨论标题" required>
|
||||
<el-form-item :label="$t('m.Discussion_title')" required>
|
||||
<el-input
|
||||
v-model="discussion.title"
|
||||
placeholder="请输入讨论标题"
|
||||
:placeholder="$t('m.Discussion_title')"
|
||||
class="title-input"
|
||||
>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="讨论简介" required>
|
||||
<el-form-item :label="$t('m.Discussion_Desc')" required>
|
||||
<el-input
|
||||
v-model="discussion.description"
|
||||
placeholder="请输入讨论简介"
|
||||
:placeholder="$t('m.Discussion_Desc')"
|
||||
class="title-input"
|
||||
>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="讨论分类" required>
|
||||
<el-select v-model="discussion.categoryId" placeholder="请选择">
|
||||
<el-form-item :label="$t('m.Discussion_Category')" required>
|
||||
<el-select v-model="discussion.categoryId" placeholder="---">
|
||||
<el-option
|
||||
v-for="category in categoryList"
|
||||
:key="category.id"
|
||||
|
@ -319,10 +328,14 @@
|
|||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否置顶" required v-if="isAdminRole">
|
||||
<el-form-item
|
||||
:label="$t('m.Discussion_top')"
|
||||
required
|
||||
v-if="isAdminRole"
|
||||
>
|
||||
<el-switch v-model="discussion.topPriority"> </el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="讨论内容" required>
|
||||
<el-form-item :label="$t('m.Discussion_content')" required>
|
||||
<Editor :value.sync="discussion.content"></Editor>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -330,11 +343,11 @@
|
|||
<el-button
|
||||
type="danger"
|
||||
@click.native="showEditDiscussionDialog = false"
|
||||
>取消</el-button
|
||||
>
|
||||
<el-button type="primary" @click.native="submitDiscussion"
|
||||
>发布</el-button
|
||||
>{{ $t('m.Cancel') }}</el-button
|
||||
>
|
||||
<el-button type="primary" @click.native="submitDiscussion">{{
|
||||
$t('m.OK')
|
||||
}}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
@ -372,7 +385,7 @@ export default {
|
|||
},
|
||||
backupDiscussion: {}, // 临时记录
|
||||
// 对话框标题
|
||||
discussionDialogTitle: 'Edit Discussion',
|
||||
discussionDialogTitle: '',
|
||||
discussionList: [],
|
||||
categoryList: [],
|
||||
cidMapName: {},
|
||||
|
@ -389,6 +402,7 @@ export default {
|
|||
};
|
||||
},
|
||||
mounted() {
|
||||
this.discussionDialogTitle = this.$i18n.t('m.Edit_Discussion');
|
||||
api.getCategoryList().then((res) => {
|
||||
this.categoryList = res.data.data;
|
||||
for (let i = 0; i < this.categoryList.length; i++) {
|
||||
|
@ -443,10 +457,10 @@ export default {
|
|||
|
||||
toEditDiscussion() {
|
||||
if (!this.isAuthenticated) {
|
||||
myMessage.warning('请先登录');
|
||||
myMessage.warning(this.$i18n.t('m.Please_login_first'));
|
||||
this.$store.dispatch('changeModalStatus', { visible: true });
|
||||
} else {
|
||||
this.discussionDialogTitle = 'Create Discussion';
|
||||
this.discussionDialogTitle = this.$i18n.t('m.Create_Discussion');
|
||||
if (this.backupDiscussion) {
|
||||
this.discussion = this.backupDiscussion;
|
||||
// 避免监听覆盖
|
||||
|
@ -524,18 +538,18 @@ export default {
|
|||
submitDiscussion() {
|
||||
// 默认为题目的讨论添加题号格式
|
||||
let discussion = Object.assign({}, this.discussion);
|
||||
if (this.discussionDialogTitle == 'Create Discussion') {
|
||||
if (this.discussionDialogTitle == this.$i18n.t('m.Create_Discussion')) {
|
||||
if (discussion.pid) {
|
||||
discussion.title = '[' + discussion.pid + '] ' + discussion.title;
|
||||
}
|
||||
api.addDiscussion(discussion).then((res) => {
|
||||
myMessage.success(res.data.msg);
|
||||
myMessage.success(this.$i18n.t('m.Post_successfully'));
|
||||
this.showEditDiscussionDialog = false;
|
||||
this.init();
|
||||
});
|
||||
} else {
|
||||
api.updateDiscussion(discussion).then((res) => {
|
||||
myMessage.success(res.data.msg);
|
||||
myMessage.success(this.$i18n.t('m.Update_Successfully'));
|
||||
this.showEditDiscussionDialog = false;
|
||||
this.init();
|
||||
});
|
||||
|
@ -545,7 +559,7 @@ export default {
|
|||
let tmpArr = command.split(':');
|
||||
switch (tmpArr[0]) {
|
||||
case 'edit':
|
||||
this.discussionDialogTitle = 'Edit Discussion';
|
||||
this.discussionDialogTitle = this.$i18n.t('m.Edit_Discussion');
|
||||
this.discussion = Object.assign(
|
||||
{},
|
||||
this.discussionList[parseInt(tmpArr[1])]
|
||||
|
@ -553,19 +567,15 @@ export default {
|
|||
this.showEditDiscussionDialog = true;
|
||||
break;
|
||||
case 'delete':
|
||||
this.$confirm(
|
||||
'此操作将删除该讨论包括关联的评论与回复, 是否继续?',
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
).then(() => {
|
||||
this.$confirm(this.$i18n.t('m.Delete_Discussion_Tips'), 'Tips', {
|
||||
confirmButtonText: this.$i18n.t('m.OK'),
|
||||
cancelButtonText: this.$i18n.t('m.Cancel'),
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
api
|
||||
.deleteDiscussion(this.discussionList[parseInt(tmpArr[1])].id)
|
||||
.then((res) => {
|
||||
myMessage.success(res.data.msg);
|
||||
myMessage.success(this.$i18n.t('m.Delete_successfully'));
|
||||
this.init();
|
||||
});
|
||||
});
|
||||
|
@ -582,7 +592,7 @@ export default {
|
|||
},
|
||||
discussion(newVal, oldVal) {
|
||||
if (
|
||||
this.discussionDialogTitle == 'Create Discussion' &&
|
||||
this.discussionDialogTitle == this.$i18n.t('m.Create_Discussion') &&
|
||||
newVal != oldVal
|
||||
) {
|
||||
this.backupDiscussion = this.discussion;
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
<span>{{ problemData.problem.title }}</span
|
||||
><br />
|
||||
<span v-if="contestID && !contestEnded"
|
||||
><el-tag effect="plain" size="small">比赛题目</el-tag></span
|
||||
><el-tag effect="plain" size="small">{{
|
||||
$t('m.Contest_Problem')
|
||||
}}</el-tag></span
|
||||
>
|
||||
<div v-else-if="problemData.tags.length > 0" class="problem-tag">
|
||||
<el-popover placement="right-start" width="60" trigger="hover">
|
||||
|
@ -19,7 +21,7 @@
|
|||
type="primary"
|
||||
style="cursor: pointer;"
|
||||
effect="plain"
|
||||
>Show Tags</el-tag
|
||||
>{{ $t('m.Show_Tags') }}</el-tag
|
||||
>
|
||||
<el-tag
|
||||
v-for="tag in problemData.tags"
|
||||
|
@ -32,7 +34,9 @@
|
|||
</el-popover>
|
||||
</div>
|
||||
<div v-else-if="problemData.tags.length == 0" class="problem-tag">
|
||||
<el-tag effect="plain" size="small">暂无标签</el-tag>
|
||||
<el-tag effect="plain" size="small">{{
|
||||
$t('m.No_tag')
|
||||
}}</el-tag>
|
||||
</div>
|
||||
<div class="problem-menu">
|
||||
<span v-if="!contestID">
|
||||
|
@ -41,7 +45,7 @@
|
|||
:underline="false"
|
||||
@click="goProblemDiscussion"
|
||||
><i class="fa fa-comments" aria-hidden="true"></i>
|
||||
Discussion</el-link
|
||||
{{ $t('m.NavBar_Discussion') }}</el-link
|
||||
></span
|
||||
>
|
||||
<span>
|
||||
|
@ -50,7 +54,7 @@
|
|||
:underline="false"
|
||||
@click="graphVisible = !graphVisible"
|
||||
><i class="fa fa-pie-chart" aria-hidden="true"></i>
|
||||
Statistic</el-link
|
||||
{{ $t('m.Statistic') }}</el-link
|
||||
></span
|
||||
>
|
||||
<span>
|
||||
|
@ -59,45 +63,45 @@
|
|||
:underline="false"
|
||||
@click="goProblemSubmission"
|
||||
><i class="fa fa-bars" aria-hidden="true"></i>
|
||||
Solution</el-link
|
||||
{{ $t('m.Solution') }}</el-link
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
<div class="question-intr">
|
||||
<span
|
||||
>Time Limit:C/C++
|
||||
{{ problemData.problem.timeLimit }}MS,Other
|
||||
>{{ $t('m.Time_Limit') }}:C/C++
|
||||
{{ problemData.problem.timeLimit }}MS,{{ $t('m.Other') }}
|
||||
{{ problemData.problem.timeLimit * 2 }}MS</span
|
||||
><br />
|
||||
<span
|
||||
>Memory Limit:C/C++
|
||||
{{ problemData.problem.memoryLimit }}MB,Other
|
||||
>{{ $t('m.Memory_Limit') }}:C/C++
|
||||
{{ problemData.problem.memoryLimit }}MB,{{ $t('m.Other') }}
|
||||
{{ problemData.problem.memoryLimit * 2 }}MB</span
|
||||
><br />
|
||||
<span
|
||||
>Level:{{
|
||||
>{{ $t('m.Level') }}:{{
|
||||
PROBLEM_LEVEL[problemData.problem.difficulty]['name']
|
||||
}}</span
|
||||
><span
|
||||
v-if="problemData.problem.type == 1"
|
||||
style="margin-left: 10px;"
|
||||
>Score:{{ problemData.problem.ioScore }}</span
|
||||
>{{ $t('m.Score') }}:{{ problemData.problem.ioScore }}</span
|
||||
><br />
|
||||
<span v-show="problemData.problem.author"
|
||||
>Create By:{{ problemData.problem.author }}</span
|
||||
>{{ $t('m.Created') }}:{{ problemData.problem.author }}</span
|
||||
><br />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="problem-content">
|
||||
<p class="title">Description</p>
|
||||
<p class="title">{{ $t('m.Description') }}</p>
|
||||
<p
|
||||
class="content markdown-body"
|
||||
v-html="problemData.problem.description"
|
||||
v-katex
|
||||
v-highlight
|
||||
></p>
|
||||
<p class="title">Input</p>
|
||||
<p class="title">{{ $t('m.Input') }}</p>
|
||||
<p
|
||||
class="content markdown-body"
|
||||
v-html="problemData.problem.input"
|
||||
|
@ -105,7 +109,7 @@
|
|||
v-highlight
|
||||
></p>
|
||||
|
||||
<p class="title">Output</p>
|
||||
<p class="title">{{ $t('m.Output') }}</p>
|
||||
<p
|
||||
class="content markdown-body"
|
||||
v-html="problemData.problem.output"
|
||||
|
@ -120,7 +124,7 @@
|
|||
<div class="flex-container example">
|
||||
<div class="example-input">
|
||||
<p class="title">
|
||||
Sample Input {{ index + 1 }}
|
||||
{{ $t('m.Sample_Input') }} {{ index + 1 }}
|
||||
<a
|
||||
class="copy"
|
||||
v-clipboard:copy="example.input"
|
||||
|
@ -134,7 +138,7 @@
|
|||
</div>
|
||||
<div class="example-output">
|
||||
<p class="title">
|
||||
Sample Output {{ index + 1 }}
|
||||
{{ $t('m.Sample_Output') }} {{ index + 1 }}
|
||||
<a
|
||||
class="copy"
|
||||
v-clipboard:copy="example.output"
|
||||
|
@ -149,22 +153,22 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="problemData.problem.hint">
|
||||
<p class="title">Hint</p>
|
||||
<template v-if="problemData.problem.hint">
|
||||
<p class="title">{{ $t('m.Hint') }}</p>
|
||||
<el-card dis-hover>
|
||||
<div
|
||||
<p
|
||||
class="hint-content markdown-body"
|
||||
v-html="problemData.problem.hint"
|
||||
v-katex
|
||||
v-highlight
|
||||
></div>
|
||||
></p>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div v-if="problemData.problem.source && !contestID">
|
||||
<p class="title">Source</p>
|
||||
<template v-if="problemData.problem.source && !contestID">
|
||||
<p class="title">{{ $t('m.Source') }}</p>
|
||||
<p class="content" v-html="problemData.problem.source"></p>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
@ -192,12 +196,12 @@
|
|||
show-icon
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
>Please login first</el-alert
|
||||
>{{ $t('m.Please_login_first') }}</el-alert
|
||||
>
|
||||
</div>
|
||||
<div class="status" v-if="statusVisible">
|
||||
<template v-if="result.status == JUDGE_STATUS_RESERVE['sf']">
|
||||
<span>Status:</span>
|
||||
<span>{{ $t('m.Status') }}:</span>
|
||||
<el-tag
|
||||
effect="dark"
|
||||
:color="submissionStatus.color"
|
||||
|
@ -217,7 +221,7 @@
|
|||
this.contestRuleType == RULE_TYPE.ACM)
|
||||
"
|
||||
>
|
||||
<span>Status:</span>
|
||||
<span>{{ $t('m.Status') }}:</span>
|
||||
<el-tag
|
||||
effect="dark"
|
||||
:color="submissionStatus.color"
|
||||
|
@ -239,7 +243,7 @@
|
|||
show-icon
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
>Submitted successfully</el-alert
|
||||
>{{ $t('m.Submitted_successfully') }}</el-alert
|
||||
>
|
||||
</template>
|
||||
</div>
|
||||
|
@ -254,7 +258,7 @@
|
|||
show-icon
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
>You have solved the problem</el-alert
|
||||
>{{ $t('m.You_have_solved_the_problem') }}</el-alert
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
|
@ -270,7 +274,7 @@
|
|||
show-icon
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
>You have submitted a solution</el-alert
|
||||
>{{ $t('m.You_have_submitted_a_solution') }}</el-alert
|
||||
>
|
||||
</div>
|
||||
<div v-if="contestEnded">
|
||||
|
@ -279,7 +283,7 @@
|
|||
show-icon
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
>Contest has ended</el-alert
|
||||
>{{ $t('m.Contest_has_ended') }}</el-alert
|
||||
>
|
||||
</div>
|
||||
</el-col>
|
||||
|
@ -306,8 +310,8 @@
|
|||
:disabled="problemSubmitDisabled || submitted"
|
||||
class="fl-right"
|
||||
>
|
||||
<span v-if="submitting">Submitting</span>
|
||||
<span v-else>Submit</span>
|
||||
<span v-if="submitting">{{ $t('m.Submitting') }}</span>
|
||||
<span v-else>{{ $t('m.Submit') }}</span>
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@ -321,9 +325,9 @@
|
|||
<ECharts :options="largePie" :initOptions="largePieInitOpts"></ECharts>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<el-button type="ghost" @click="graphVisible = false" size="small"
|
||||
>Close</el-button
|
||||
>
|
||||
<el-button type="ghost" @click="graphVisible = false" size="small">{{
|
||||
$t('m.Close')
|
||||
}}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
|
@ -342,7 +346,7 @@
|
|||
style="margin-left:130px"
|
||||
@click="submitCode"
|
||||
>
|
||||
OK
|
||||
{{ $t('m.Submit') }}
|
||||
</el-button>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
|
@ -367,7 +371,7 @@ import api from '@/common/api';
|
|||
import myMessage from '@/common/message';
|
||||
import { addCodeBtn } from '@/common/codeblock';
|
||||
// 只显示这些状态的图形占用
|
||||
const filtedStatus = ['wa', 'ce', 'ac', 'tle', 'mle', 're', 'pe'];
|
||||
const filtedStatus = ['wa', 'ce', 'ac', 'pa', 'tle', 'mle', 're', 'pe'];
|
||||
|
||||
export default {
|
||||
name: 'ProblemDetails',
|
||||
|
@ -601,11 +605,15 @@ export default {
|
|||
this.theme = newTheme;
|
||||
},
|
||||
onResetToTemplate() {
|
||||
this.$confirm('是否确定要重置代码模板?', '提示', {
|
||||
cancelButtonText: '取消',
|
||||
confirmButtonText: '确定',
|
||||
type: 'warning',
|
||||
})
|
||||
this.$confirm(
|
||||
this.$i18n.t('m.Are_you_sure_you_want_to_reset_your_code'),
|
||||
'Tips',
|
||||
{
|
||||
cancelButtonText: this.$i18n.t('m.Cancel'),
|
||||
confirmButtonText: this.$i18n.t('m.OK'),
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
let codeTemplate = this.problemData.codeTemplate;
|
||||
if (codeTemplate && codeTemplate[this.language]) {
|
||||
|
@ -659,7 +667,7 @@ export default {
|
|||
},
|
||||
submitCode() {
|
||||
if (this.code.trim() === '') {
|
||||
myMessage.error('提交的代码不能为空!');
|
||||
myMessage.error(this.$i18n.t('m.Code_can_not_be_empty'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -699,7 +707,7 @@ export default {
|
|||
if (!detailsVisible) {
|
||||
this.$Modal.success({
|
||||
title: 'Success',
|
||||
content: '代码提交成功!',
|
||||
content: this.$i18n.t('m.Submit_code_successfully'),
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
|
@ -729,11 +737,13 @@ export default {
|
|||
) {
|
||||
if (this.submissionExists) {
|
||||
this.$confirm(
|
||||
'你已经有该题目的提交了,确定要再一次提交覆盖之前的提交记录?',
|
||||
'警告',
|
||||
this.$i18n.t(
|
||||
'm.You_have_submission_in_this_problem_sure_to_cover_it'
|
||||
),
|
||||
'Warning',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
confirmButtonText: this.$i18n.t('m.OK'),
|
||||
cancelButtonText: this.$i18n.t('m.Cancel'),
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
|
@ -771,10 +781,10 @@ export default {
|
|||
},
|
||||
|
||||
onCopy(event) {
|
||||
myMessage.success('Sample copied successfully');
|
||||
myMessage.success(this.$i18n.t('m.Copied_successfully'));
|
||||
},
|
||||
onCopyError(e) {
|
||||
myMessage.success('Sample copy failed');
|
||||
myMessage.success(this.$i18n.t('m.Copied_failed'));
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
|
@ -845,6 +855,11 @@ export default {
|
|||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.katex .katex-mathml {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
#problem-main {
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
<div slot="header">
|
||||
<el-row :gutter="18">
|
||||
<el-col :sm="5" :md="5" :lg="7">
|
||||
<span class="panel-title hidden-xs-only">Problem List</span>
|
||||
<span class="panel-title hidden-xs-only">{{
|
||||
$t('m.Problem_List')
|
||||
}}</span>
|
||||
</el-col>
|
||||
<el-col :xs="8" :sm="3" :md="3" :lg="3" style="padding-top: 6px;">
|
||||
<el-dropdown
|
||||
|
@ -16,7 +18,9 @@
|
|||
>
|
||||
<span class="el-dropdown-link">
|
||||
{{
|
||||
query.oj === 'Mine' || query.oj === '' ? 'Mine' : query.oj
|
||||
query.oj === 'Mine' || query.oj === ''
|
||||
? $t('m.Mine')
|
||||
: query.oj
|
||||
}}
|
||||
<i class="el-icon-caret-bottom"></i>
|
||||
</span>
|
||||
|
@ -42,13 +46,15 @@
|
|||
<span class="el-dropdown-link">
|
||||
{{
|
||||
query.difficulty === 'All' || query.difficulty === ''
|
||||
? 'Level'
|
||||
? $t('m.Level')
|
||||
: query.difficulty
|
||||
}}
|
||||
<i class="el-icon-caret-bottom"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="All">All</el-dropdown-item>
|
||||
<el-dropdown-item command="All">{{
|
||||
$t('m.All')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
:command="key"
|
||||
v-for="(value, key, index) in PROBLEM_LEVEL_RESERVE"
|
||||
|
@ -62,13 +68,13 @@
|
|||
<vxe-checkbox
|
||||
v-model="tagVisible"
|
||||
@change="changeTagVisible(tagVisible)"
|
||||
>Tag</vxe-checkbox
|
||||
>{{ $t('m.Tags') }}</vxe-checkbox
|
||||
>
|
||||
</el-col>
|
||||
<el-col :xs="18" :sm="7" :md="7" :lg="5" class="top-pt">
|
||||
<vxe-input
|
||||
v-model="query.keyword"
|
||||
placeholder="Enter keyword"
|
||||
:placeholder="$t('m.Enter_keyword')"
|
||||
type="search"
|
||||
size="medium"
|
||||
@search-click="filterByKeyword"
|
||||
|
@ -82,7 +88,7 @@
|
|||
icon="el-icon-refresh"
|
||||
round
|
||||
@click="onReset"
|
||||
>Reset</el-button
|
||||
>{{ $t('m.Reset') }}</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :xs="6" class="hidden-sm-and-up top-pt">
|
||||
|
@ -130,11 +136,15 @@
|
|||
</vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="problemId"
|
||||
title="Problem ID"
|
||||
:title="$t('m.Problem_ID')"
|
||||
min-width="100"
|
||||
></vxe-table-column>
|
||||
|
||||
<vxe-table-column field="title" title="Title" min-width="180">
|
||||
<vxe-table-column
|
||||
field="title"
|
||||
:title="$t('m.Title')"
|
||||
min-width="180"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<a @click="getProblemUri(row.problemId)" class="title-a">{{
|
||||
row.title
|
||||
|
@ -142,7 +152,11 @@
|
|||
</template>
|
||||
</vxe-table-column>
|
||||
|
||||
<vxe-table-column field="difficulty" title="Level" min-width="100">
|
||||
<vxe-table-column
|
||||
field="difficulty"
|
||||
:title="$t('m.Level')"
|
||||
min-width="100"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span :class="getLevelColor(row.difficulty)">{{
|
||||
PROBLEM_LEVEL[row.difficulty].name
|
||||
|
@ -152,7 +166,7 @@
|
|||
|
||||
<vxe-table-column
|
||||
field="tag"
|
||||
title="Tag"
|
||||
:title="$t('m.Tags')"
|
||||
min-width="250"
|
||||
visible="false"
|
||||
>
|
||||
|
@ -168,10 +182,10 @@
|
|||
</vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="total"
|
||||
title="Total"
|
||||
:title="$t('m.Total')"
|
||||
min-width="80"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column title="AC Rate" min-width="80">
|
||||
<vxe-table-column :title="$t('m.AC_Rate')" min-width="80">
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ getPercentage(row.ac, row.total) }}%</span>
|
||||
</template>
|
||||
|
@ -209,7 +223,9 @@
|
|||
</el-row>
|
||||
</el-card>
|
||||
<el-card :padding="10" style="margin-top:20px">
|
||||
<div slot="header"><span class="taglist-title">Tags</span></div>
|
||||
<div slot="header">
|
||||
<span class="taglist-title">{{ $t('m.Tags') }}</span>
|
||||
</div>
|
||||
<el-button
|
||||
v-for="tag in tagList"
|
||||
:key="tag.id"
|
||||
|
@ -223,7 +239,7 @@
|
|||
|
||||
<el-button long id="pick-one" @click="pickone">
|
||||
<i class="fa fa-random"></i>
|
||||
Pick a random question
|
||||
{{ $t('m.Pick_a_random_question') }}
|
||||
</el-button>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
@ -257,7 +273,7 @@ export default {
|
|||
REMOTE_OJ: {},
|
||||
tagList: [],
|
||||
tagVisible: false,
|
||||
currentProblemTitle: '请触碰或鼠标悬浮到指定题目行即可查看提交情况',
|
||||
currentProblemTitle: '',
|
||||
problemRecord: [],
|
||||
problemList: [],
|
||||
limit: 20,
|
||||
|
@ -290,6 +306,7 @@ export default {
|
|||
this.JUDGE_STATUS_RESERVE = Object.assign({}, JUDGE_STATUS_RESERVE);
|
||||
this.JUDGE_STATUS = Object.assign({}, JUDGE_STATUS);
|
||||
this.REMOTE_OJ = Object.assign({}, REMOTE_OJ);
|
||||
this.currentProblemTitle = this.$i18n.t('m.Touch_Get_Status');
|
||||
// 初始化
|
||||
this.problemRecord = [
|
||||
{ status: 0, count: 100 },
|
||||
|
@ -464,7 +481,7 @@ export default {
|
|||
},
|
||||
pickone() {
|
||||
api.pickone().then((res) => {
|
||||
myMessage.success('随机题目获取成功,祝你好运');
|
||||
myMessage.success(this.$i18n.t('m.Good_luck_to_you'));
|
||||
this.$router.push({
|
||||
name: 'ProblemDetails',
|
||||
params: { problemID: res.data.data.problemId },
|
||||
|
|
|
@ -4,8 +4,8 @@ const pieColorMap = {
|
|||
'TLE': {color: '#ff9300'},
|
||||
'MLE': {color: '#f7de00'},
|
||||
'RE': {color: '#ff6104'},
|
||||
'CE': {color: '#80848f'},
|
||||
'PAC': {color: '#2d8cf0'},
|
||||
'CE': {color: '#f90'},
|
||||
'PA': {color: '#2d8cf0'},
|
||||
'PE':{color:'#f90'}
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ const largePie = {
|
|||
itemGap:
|
||||
10,
|
||||
data:
|
||||
['AC', 'RE', 'WA', 'TLE', 'PAC', 'MLE','PE']
|
||||
['AC','PA','PE','CE','RE', 'WA', 'TLE', 'MLE']
|
||||
},
|
||||
series: [
|
||||
{
|
||||
|
@ -80,9 +80,10 @@ const largePie = {
|
|||
{value: 0, name: 'WA'},
|
||||
{value: 0, name: 'TLE'},
|
||||
{value: 0, name: 'AC'},
|
||||
{value: 0, name: 'PA'},
|
||||
{value: 0, name: 'MLE'},
|
||||
{value: 0, name: 'PAC'},
|
||||
{value: 0, name: 'PE'}
|
||||
{value: 0, name: 'PE'},
|
||||
{value: 0, name: 'CE'}
|
||||
],
|
||||
label: {
|
||||
normal: {
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
<el-row type="flex" justify="space-around">
|
||||
<el-col :span="24">
|
||||
<el-card :padding="10">
|
||||
<div slot="header"><span class="panel-title">ACM Ranklist</span></div>
|
||||
<div slot="header">
|
||||
<span class="panel-title">{{ $t('m.ACM_Ranklist') }}</span>
|
||||
</div>
|
||||
<div class="echarts">
|
||||
<ECharts :options="options" ref="chart" :autoresize="true"></ECharts>
|
||||
</div>
|
||||
|
@ -16,7 +18,11 @@
|
|||
style="font-weight: 500;"
|
||||
>
|
||||
<vxe-table-column type="seq" min-width="50"></vxe-table-column>
|
||||
<vxe-table-column field="username" title="User" min-width="150">
|
||||
<vxe-table-column
|
||||
field="username"
|
||||
:title="$t('m.User')"
|
||||
min-width="150"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<a
|
||||
@click="getInfoByUsername(row.uid, row.username)"
|
||||
|
@ -27,20 +33,20 @@
|
|||
</vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="nickname"
|
||||
title="Nickname"
|
||||
:title="$t('m.Nickname')"
|
||||
min-width="180"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="signature"
|
||||
title="Mood"
|
||||
:title="$t('m.Mood')"
|
||||
min-width="180"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="solved"
|
||||
title="Solved"
|
||||
:title="$t('m.Solved')"
|
||||
min-width="80"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column title="AC" min-width="80">
|
||||
<vxe-table-column :title="$t('m.AC')" min-width="80">
|
||||
<template v-slot="{ row }">
|
||||
<a
|
||||
@click="goUserACStatus(row.username)"
|
||||
|
@ -51,10 +57,10 @@
|
|||
</vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="total"
|
||||
title="Total"
|
||||
:title="$t('m.Total')"
|
||||
min-width="80"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column title="Rating" min-width="80">
|
||||
<vxe-table-column :title="$t('m.Rating')" min-width="80">
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ getACRate(row.ac, row.total) }}</span>
|
||||
</template>
|
||||
|
@ -153,7 +159,7 @@ export default {
|
|||
],
|
||||
series: [
|
||||
{
|
||||
name: 'AC',
|
||||
name: this.$i18n.t('m.AC'),
|
||||
type: 'bar',
|
||||
data: [0],
|
||||
itemStyle: {
|
||||
|
@ -164,7 +170,7 @@ export default {
|
|||
},
|
||||
},
|
||||
{
|
||||
name: 'Total',
|
||||
name: this.$i18n.t('m.Total'),
|
||||
type: 'bar',
|
||||
data: [0],
|
||||
itemStyle: {
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
<el-row type="flex" justify="space-around">
|
||||
<el-col :span="24">
|
||||
<el-card :padding="10">
|
||||
<div slot="header"><span class="panel-title">OI Ranklist</span></div>
|
||||
<div slot="header">
|
||||
<span class="panel-title">{{ $t('m.OI_Ranklist') }}</span>
|
||||
</div>
|
||||
<div class="echarts">
|
||||
<ECharts :options="options" ref="chart" auto-resize></ECharts>
|
||||
</div>
|
||||
|
@ -16,7 +18,11 @@
|
|||
style="font-weight: 500;"
|
||||
>
|
||||
<vxe-table-column type="seq" min-width="50"></vxe-table-column>
|
||||
<vxe-table-column field="username" title="User" min-width="150">
|
||||
<vxe-table-column
|
||||
field="username"
|
||||
:title="$t('m.User')"
|
||||
min-width="150"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<a
|
||||
@click="getInfoByUsername(row.uid, row.username)"
|
||||
|
@ -27,20 +33,20 @@
|
|||
</vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="nickname"
|
||||
title="Nickname"
|
||||
:title="$t('m.Nickname')"
|
||||
min-width="180"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="signature"
|
||||
title="Mood"
|
||||
:title="$t('m.Mood')"
|
||||
min-width="180"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column title="Score" min-width="80">
|
||||
<vxe-table-column :title="$t('m.Score')" min-width="80">
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ row.score }}</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column title="AC" min-width="80">
|
||||
<vxe-table-column :title="$t('m.AC')" min-width="80">
|
||||
<template v-slot="{ row }">
|
||||
<a
|
||||
@click="goUserACStatus(row.username)"
|
||||
|
@ -51,10 +57,10 @@
|
|||
</vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="total"
|
||||
title="Total"
|
||||
:title="$t('m.Total')"
|
||||
min-width="80"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column title="Rating" min-width="80">
|
||||
<vxe-table-column :title="$t('m.Rating')" min-width="80">
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ getACRate(row.ac, row.total) }}</span>
|
||||
</template>
|
||||
|
@ -156,7 +162,7 @@ export default {
|
|||
],
|
||||
series: [
|
||||
{
|
||||
name: 'Score',
|
||||
name: this.$i18n.t('m.Score'),
|
||||
type: 'bar',
|
||||
data: [0],
|
||||
barMaxWidth: '80',
|
||||
|
|
|
@ -18,16 +18,23 @@
|
|||
</div>
|
||||
<div v-else class="content">
|
||||
<span class="span-row"
|
||||
>Time: {{ submissionTimeFormat(submission.time) }}</span
|
||||
>{{ $t('m.Time') }}:
|
||||
{{ submissionTimeFormat(submission.time) }}</span
|
||||
>
|
||||
<span class="span-row"
|
||||
>Memory: {{ submissionMemoryFormat(submission.memory) }}</span
|
||||
>{{ $t('m.Memory') }}:
|
||||
{{ submissionMemoryFormat(submission.memory) }}</span
|
||||
>
|
||||
<span class="span-row"
|
||||
>Length: {{ submissionLengthFormat(submission.length) }}</span
|
||||
>{{ $t('m.Length') }}:
|
||||
{{ submissionLengthFormat(submission.length) }}</span
|
||||
>
|
||||
<span class="span-row"
|
||||
>{{ $t('m.Language') }}: {{ submission.language }}</span
|
||||
>
|
||||
<span class="span-row"
|
||||
>{{ $t('m.Author') }}: {{ submission.username }}</span
|
||||
>
|
||||
<span class="span-row">Language: {{ submission.language }}</span>
|
||||
<span class="span-row">Author: {{ submission.username }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-alert>
|
||||
|
@ -44,44 +51,52 @@
|
|||
>
|
||||
<vxe-table-column
|
||||
field="submitId"
|
||||
title="ID"
|
||||
:title="$t('m.Run_ID')"
|
||||
min-width="100"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column title="Submit time" min-width="150">
|
||||
<vxe-table-column :title="$t('m.Submit_Time')" min-width="150">
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ row.submitTime | localtime }}</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="pid" title="Problem ID" min-width="100">
|
||||
<vxe-table-column
|
||||
field="pid"
|
||||
:title="$t('m.Problem_ID')"
|
||||
min-width="100"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<a @click="getProblemUri(row)" style="color: rgb(87, 163, 243)">{{
|
||||
row.displayPid
|
||||
}}</a>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="status" title="Status" min-width="170">
|
||||
<vxe-table-column field="status" :title="$t('m.Staus')" min-width="170">
|
||||
<template v-slot="{ row }">
|
||||
<span :class="getStatusColor(row.status)">{{
|
||||
JUDGE_STATUS[row.status].name
|
||||
}}</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column title="Time" min-width="96">
|
||||
<vxe-table-column :title="$t('m.Time')" min-width="96">
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ submissionTimeFormat(row.time) }}</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column title="Memory" min-width="96">
|
||||
<vxe-table-column :title="$t('m.Memory')" min-width="96">
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ submissionMemoryFormat(row.memory) }}</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column title="Score" min-width="64" v-if="isIOProblem">
|
||||
<vxe-table-column
|
||||
:title="$t('m.Score')"
|
||||
min-width="64"
|
||||
v-if="isIOProblem"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ row.score }}</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column title="Length" min-width="80">
|
||||
<vxe-table-column :title="$t('m.Length')" min-width="80">
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ submissionLengthFormat(row.length) }}</span>
|
||||
</template>
|
||||
|
@ -91,7 +106,9 @@
|
|||
<el-col :span="24" v-if="testCaseResult">
|
||||
<el-card style="margin-top: 13px;" shadow="hover">
|
||||
<div slot="header">
|
||||
<span class="panel-title home-title">测试点详情</span>
|
||||
<span class="panel-title home-title">{{
|
||||
$t('m.Test_point_details')
|
||||
}}</span>
|
||||
</div>
|
||||
<el-row :gutter="10">
|
||||
<el-col
|
||||
|
@ -114,7 +131,7 @@
|
|||
</div>
|
||||
<div class="test-run-static">
|
||||
<span v-if="item.score != null">
|
||||
{{ item.score }}分 <i class="el-icon-success"></i>
|
||||
{{ item.score }} <i class="el-icon-success"></i>
|
||||
</span>
|
||||
<span v-else>
|
||||
<i class="el-icon-success"></i>
|
||||
|
@ -134,7 +151,7 @@
|
|||
</div>
|
||||
<div class="test-run-static">
|
||||
<span v-if="item.score != null">
|
||||
{{ item.score }}分 <i class="el-icon-error"></i>
|
||||
{{ item.score }} <i class="el-icon-error"></i>
|
||||
</span>
|
||||
<span v-else>
|
||||
<i class="el-icon-error"></i>
|
||||
|
@ -160,7 +177,7 @@
|
|||
size="large"
|
||||
@click="doCopy"
|
||||
v-if="submission.code"
|
||||
>Copy</el-button
|
||||
>{{ $t('m.Copy') }}</el-button
|
||||
>
|
||||
<template v-if="codeShare">
|
||||
<el-button
|
||||
|
@ -170,7 +187,7 @@
|
|||
icon="el-icon-circle-close"
|
||||
@click="shareSubmission(false)"
|
||||
>
|
||||
Unshared
|
||||
{{ $t('m.Unshared') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-else-if="isAuthenticated && !submission.share && isMeSubmisson"
|
||||
|
@ -179,7 +196,7 @@
|
|||
icon="el-icon-share"
|
||||
@click="shareSubmission(true)"
|
||||
>
|
||||
Shared
|
||||
{{ $t('m.Shared') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</div>
|
||||
|
@ -306,7 +323,6 @@ export default {
|
|||
}
|
||||
}
|
||||
// 如果是比赛 需要显示的是比赛题号
|
||||
console.log(this.$route.params.problemID);
|
||||
if (this.$route.params.problemID && data.submission.cid != 0) {
|
||||
data.submission.displayPid = this.$route.params.problemID;
|
||||
}
|
||||
|
@ -345,7 +361,7 @@ export default {
|
|||
api.updateSubmission(data).then(
|
||||
(res) => {
|
||||
this.getSubmission();
|
||||
myMessage.success(res.data.msg);
|
||||
myMessage.success(this.$i18n.t('m.Shared_successfully'));
|
||||
},
|
||||
() => {}
|
||||
);
|
||||
|
|
|
@ -5,16 +5,18 @@
|
|||
<div slot="header">
|
||||
<el-row :gutter="18">
|
||||
<el-col :md="4" :lg="2">
|
||||
<span class="panel-title hidden-md-and-down">Status</span>
|
||||
<span class="panel-title hidden-md-and-down">{{
|
||||
$t('m.Status')
|
||||
}}</span>
|
||||
</el-col>
|
||||
<el-col :xs="10" :sm="8" :md="4" :lg="4">
|
||||
<el-switch
|
||||
style="display: block"
|
||||
v-model="formFilter.onlyMine"
|
||||
active-text="Mine"
|
||||
:active-text="$t('m.Mine')"
|
||||
:width="40"
|
||||
@change="handleOnlyMine"
|
||||
inactive-text="All"
|
||||
:inactive-text="$t('m.All')"
|
||||
>
|
||||
</el-switch>
|
||||
</el-col>
|
||||
|
@ -31,7 +33,9 @@
|
|||
<i class="el-icon-caret-bottom"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="All">All</el-dropdown-item>
|
||||
<el-dropdown-item command="All">{{
|
||||
$t('m.All')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-for="result in Object.keys(JUDGE_STATUS_LIST)"
|
||||
:key="result"
|
||||
|
@ -50,7 +54,7 @@
|
|||
icon="el-icon-refresh"
|
||||
round
|
||||
@click="getSubmissions"
|
||||
>Refresh</el-button
|
||||
>{{ $t('m.Refresh') }}</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :xs="4" class="hidden-sm-and-up">
|
||||
|
@ -66,7 +70,7 @@
|
|||
<el-col :xs="24" :sm="12" :md="5" :lg="5" class="search">
|
||||
<vxe-input
|
||||
v-model="formFilter.problemID"
|
||||
placeholder="Enter Problem ID"
|
||||
:placeholder="$t('m.Enter_Problem_ID')"
|
||||
type="search"
|
||||
size="medium"
|
||||
@keyup.enter.native="handleQueryChange"
|
||||
|
@ -77,7 +81,7 @@
|
|||
<vxe-input
|
||||
v-model="formFilter.username"
|
||||
:disabled="formFilter.onlyMine"
|
||||
placeholder="Enter Author"
|
||||
:placeholder="$t('m.Enter_Author')"
|
||||
type="search"
|
||||
size="medium"
|
||||
@keyup.enter.native="handleQueryChange"
|
||||
|
@ -101,10 +105,14 @@
|
|||
>
|
||||
<vxe-table-column
|
||||
field="submitId"
|
||||
title="Run ID"
|
||||
min-width="100"
|
||||
:title="$t('m.Run_ID')"
|
||||
width="100"
|
||||
></vxe-table-column>
|
||||
<vxe-table-column field="pid" title="Problem" min-width="150">
|
||||
<vxe-table-column
|
||||
field="pid"
|
||||
:title="$t('m.Problem')"
|
||||
min-width="150"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span
|
||||
v-if="contestID"
|
||||
|
@ -120,7 +128,11 @@
|
|||
</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="status" title="Status" min-width="170">
|
||||
<vxe-table-column
|
||||
field="status"
|
||||
:title="$t('m.Status')"
|
||||
min-width="180"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span :class="getStatusColor(row.status)">
|
||||
<i
|
||||
|
@ -139,28 +151,43 @@
|
|||
"
|
||||
@click="reSubmit(row)"
|
||||
></i>
|
||||
{{ JUDGE_STATUS[row.status].name }}
|
||||
{{
|
||||
(row.score != null ? row.score + ' ' : '') +
|
||||
JUDGE_STATUS[row.status].name
|
||||
}}
|
||||
</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="time" title="Time" min-width="96">
|
||||
<vxe-table-column field="time" :title="$t('m.Time')" min-width="96">
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ submissionTimeFormat(row.time) }}</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="memory" title="Memory" min-width="96">
|
||||
<vxe-table-column
|
||||
field="memory"
|
||||
:title="$t('m.Memory')"
|
||||
min-width="96"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ submissionMemoryFormat(row.memory) }}</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
|
||||
<vxe-table-column field="length" title="Length" min-width="80">
|
||||
<vxe-table-column
|
||||
field="length"
|
||||
:title="$t('m.Length')"
|
||||
min-width="80"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ submissionLengthFormat(row.length) }}</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
|
||||
<vxe-table-column field="language" title="Language" min-width="130">
|
||||
<vxe-table-column
|
||||
field="language"
|
||||
:title="$t('m.Language')"
|
||||
min-width="130"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span
|
||||
v-if="!row.share && row.uid != userInfo.uid && !isAdminRole"
|
||||
|
@ -169,7 +196,7 @@
|
|||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
content="查看提交详情"
|
||||
:content="$t('m.View_submission_details')"
|
||||
placement="top"
|
||||
v-else
|
||||
>
|
||||
|
@ -179,13 +206,21 @@
|
|||
</el-tooltip>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="judger" title="Judger" min-width="100">
|
||||
<vxe-table-column
|
||||
field="judger"
|
||||
:title="$t('m.Judger')"
|
||||
min-width="100"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span v-if="row.judger">{{ row.judger }}</span>
|
||||
<span v-else>--</span>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
<vxe-table-column field="username" title="Author" min-width="100">
|
||||
<vxe-table-column
|
||||
field="username"
|
||||
:title="$t('m.Author')"
|
||||
min-width="100"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<a
|
||||
@click="goUserHome(row.username, row.uid)"
|
||||
|
@ -196,7 +231,7 @@
|
|||
</vxe-table-column>
|
||||
<vxe-table-column
|
||||
field="submitTime"
|
||||
title="Submit Time"
|
||||
:title="$t('m.Submit_Time')"
|
||||
min-width="96"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
|
@ -213,7 +248,7 @@
|
|||
<!-- 非比赛提交记录,超级管理员可以对提交进行重判 -->
|
||||
<vxe-table-column
|
||||
v-if="rejudgeColumnVisible"
|
||||
title="Option"
|
||||
:title="$t('m.Option')"
|
||||
min-width="90"
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
|
@ -222,7 +257,7 @@
|
|||
@click="handleRejudge(row)"
|
||||
size="mini"
|
||||
:loading="row.loading"
|
||||
>Rejudge</vxe-button
|
||||
>{{ $t('m.Rejudge') }}</vxe-button
|
||||
>
|
||||
</template>
|
||||
</vxe-table-column>
|
||||
|
@ -372,7 +407,7 @@ export default {
|
|||
this.formFilter.username = '';
|
||||
} else {
|
||||
this.formFilter.onlyMine = false;
|
||||
myMessage.error('请您先登陆!');
|
||||
myMessage.error(this.$i18n.t('m.Please_login_first'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -545,7 +580,7 @@ export default {
|
|||
|
||||
this.submissions[row.index] = res.data.data;
|
||||
this.submissions[row.index].loading = false;
|
||||
myMessage.success(res.data.msg);
|
||||
myMessage.success(this.$i18n.t('m.Rejudge_successfully'));
|
||||
|
||||
// 加入待重判列表
|
||||
this.needCheckSubmitIds[row.submitId] = row.index;
|
||||
|
@ -567,7 +602,7 @@ export default {
|
|||
this.formFilter.username = '';
|
||||
} else {
|
||||
this.formFilter.onlyMine = false;
|
||||
myMessage.error('请您先登陆!');
|
||||
myMessage.error(this.$i18n.t('m.Please_login_first'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -579,7 +614,7 @@ export default {
|
|||
showSubmitDetail(row) {
|
||||
if (!this.isAuthenticated) {
|
||||
this.changeModalStatus({ mode: 'Login', visible: true });
|
||||
myMessage.warning('请先登录后再查看代码!');
|
||||
myMessage.warning(this.$i18n.t('m.Please_login_first'));
|
||||
return;
|
||||
}
|
||||
if (row.cid != 0) {
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
<div>
|
||||
<div class="container">
|
||||
<el-card shadow="always" body-style="{backgroud-color:gray}">
|
||||
<h2 style="text-align: center;">Set New Password - HOJ</h2>
|
||||
<h2 style="text-align: center;">
|
||||
{{ $t('m.Set_New_Password') }}
|
||||
</h2>
|
||||
<el-form
|
||||
:model="formResetPassword"
|
||||
:rules="rules"
|
||||
|
@ -20,7 +22,7 @@
|
|||
v-model="formResetPassword.password"
|
||||
prefix-icon="el-icon-lock"
|
||||
type="password"
|
||||
placeholder="Please Enter New Password"
|
||||
:placeholder="$t('m.Set_New_Password_Msg')"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="passwordAgain">
|
||||
|
@ -28,7 +30,7 @@
|
|||
v-model="formResetPassword.passwordAgain"
|
||||
prefix-icon="el-icon-lock"
|
||||
type="password"
|
||||
placeholder="Please Enter New Password Again"
|
||||
:placeholder="$t('m.Set_New_Password_Again_Msg')"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -38,7 +40,7 @@
|
|||
@click="handleResetPwd"
|
||||
:loading="btnLoading"
|
||||
>
|
||||
重置密码
|
||||
{{ $t('m.Set_New_Password') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
@ -47,7 +49,7 @@
|
|||
</template>
|
||||
<script>
|
||||
import api from '@/common/api';
|
||||
import { mapGetters, mapActions } from 'vuex';
|
||||
import { mapActions } from 'vuex';
|
||||
import mMessage from '@/common/message';
|
||||
export default {
|
||||
data() {
|
||||
|
@ -55,7 +57,7 @@ export default {
|
|||
api.checkUsernameOrEmail(value, undefined).then(
|
||||
(res) => {
|
||||
if (res.data.data.username === false) {
|
||||
callback(new Error('The username does not exists'));
|
||||
callback(new Error(this.$i18n.t('m.The_username_does_not_exists')));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
|
@ -73,7 +75,7 @@ export default {
|
|||
|
||||
const CheckAgainPassword = (rule, value, callback) => {
|
||||
if (value !== this.formResetPassword.password) {
|
||||
callback(new Error('Password does not match'));
|
||||
callback(new Error(this.$i18n.t('m.Password_does_not_match')));
|
||||
}
|
||||
callback();
|
||||
};
|
||||
|
@ -89,7 +91,7 @@ export default {
|
|||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: 'The username is required',
|
||||
message: this.$i18n.t('m.Username_Check_Required'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
{ validator: CheckUsernameNotExist, trigger: 'blur' },
|
||||
|
@ -97,21 +99,21 @@ export default {
|
|||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: 'The password is required',
|
||||
message: this.$i18n.t('m.Password_Check_Required'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 20,
|
||||
trigger: 'blur',
|
||||
message: 'The length of the password is between 6 and 20',
|
||||
message: this.$i18n.t('m.Password_Check_Between'),
|
||||
},
|
||||
{ validator: CheckPassword, trigger: 'blur' },
|
||||
],
|
||||
passwordAgain: [
|
||||
{
|
||||
required: true,
|
||||
message: 'The password again is required',
|
||||
message: this.$i18n.t('m.Password_Again_Check_Required'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
{ validator: CheckAgainPassword, trigger: 'change' },
|
||||
|
@ -140,7 +142,7 @@ export default {
|
|||
api.resetPassword(data).then(
|
||||
(res) => {
|
||||
this.btnLoading = false;
|
||||
mMessage.success('重置密码成功');
|
||||
mMessage.success(this.$i18n.t('m.Your_password_has_been_reset'));
|
||||
this.$router.replace({
|
||||
path: '/',
|
||||
});
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
<el-collapse v-model="activeName" accordion>
|
||||
<el-collapse-item name="Account">
|
||||
<template slot="title">
|
||||
<i class="fa fa-gear"> Account Setting</i>
|
||||
<i class="fa fa-gear"> {{ $t('m.Account_Setting') }}</i>
|
||||
</template>
|
||||
<component :is="Account"></component>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item name="UserInfo">
|
||||
<template slot="title">
|
||||
<i class="fa fa-gear"> UserInfo Setting</i>
|
||||
<i class="fa fa-gear"> {{ $t('m.UserInfo_Setting') }}</i>
|
||||
</template>
|
||||
<component :is="UserInfo"></component>
|
||||
</el-collapse-item>
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
>
|
||||
<el-tag type="success" effect="plain" size="medium">
|
||||
<i class="fa fa-circle">
|
||||
最近上线:{{ profile.recentLoginTime | fromNow }}</i
|
||||
{{ $t('m.Recent_login_time')
|
||||
}}{{ profile.recentLoginTime | fromNow }}</i
|
||||
>
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
|
@ -32,12 +33,12 @@
|
|||
<p>
|
||||
<span
|
||||
><i class="fa fa-graduation-cap" aria-hidden="true"></i>
|
||||
{{ profile.school ? profile.school : '暂未设置' }}</span
|
||||
{{ profile.school ? profile.school : $t('m.Not_set_yet') }}</span
|
||||
>
|
||||
</p>
|
||||
<p class="mood">
|
||||
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
|
||||
{{ profile.signature ? profile.signature : '暂无个性签名' }}
|
||||
{{ profile.signature ? profile.signature : $t('m.Not_set_yet') }}
|
||||
</p>
|
||||
|
||||
<hr id="split" />
|
||||
|
@ -45,27 +46,37 @@
|
|||
<el-row :gutter="12">
|
||||
<el-col :md="6" :sm="24">
|
||||
<el-card shadow="always" class="submission">
|
||||
<p><i class="fa fa-th" aria-hidden="true"></i> Submissions</p>
|
||||
<p>
|
||||
<i class="fa fa-th" aria-hidden="true"></i>
|
||||
{{ $t('m.UserHome_Submissions') }}
|
||||
</p>
|
||||
<p class="data-number">{{ profile.total }}</p>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :md="6" :sm="24">
|
||||
<el-card shadow="always" class="solved">
|
||||
<p>
|
||||
<i class="fa fa-check-circle" aria-hidden="true"></i> Solved
|
||||
<i class="fa fa-check-circle" aria-hidden="true"></i>
|
||||
{{ $t('m.UserHome_Solved') }}
|
||||
</p>
|
||||
<p class="data-number">{{ profile.solvedList.length }}</p>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :md="6" :sm="24">
|
||||
<el-card shadow="always" class="score">
|
||||
<p><i class="fa fa-star" aria-hidden="true"></i> Score</p>
|
||||
<p>
|
||||
<i class="fa fa-star" aria-hidden="true"></i>
|
||||
{{ $t('m.UserHome_Score') }}
|
||||
</p>
|
||||
<p class="data-number">{{ getSumScore(profile.scoreList) }}</p>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :md="6" :sm="24">
|
||||
<el-card shadow="always" class="rating">
|
||||
<p><i class="fa fa-user-secret" aria-hidden="true"></i> Rating</p>
|
||||
<p>
|
||||
<i class="fa fa-user-secret" aria-hidden="true"></i>
|
||||
{{ $t('m.UserHome_Rating') }}
|
||||
</p>
|
||||
<p class="data-number">
|
||||
{{ profile.rating ? profile.rating : '--' }}
|
||||
</p>
|
||||
|
@ -75,7 +86,7 @@
|
|||
|
||||
<div id="problems">
|
||||
<div v-if="profile.solvedList.length">
|
||||
List of AC problems
|
||||
{{ $t('m.List_Solved_Problems') }}
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-refresh"
|
||||
|
@ -84,7 +95,7 @@
|
|||
@click="freshProblemDisplayID"
|
||||
></el-button>
|
||||
</div>
|
||||
<p v-else>暂无数据</p>
|
||||
<p v-else>{{ $t('m.UserHome_Not_Data') }}</p>
|
||||
<div class="btns">
|
||||
<div
|
||||
class="problem-btn"
|
||||
|
@ -131,10 +142,10 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
profile: {
|
||||
username: '暂无数据',
|
||||
username: '',
|
||||
avatar: '',
|
||||
school: '暂无数据',
|
||||
signature: '暂无数据',
|
||||
school: '',
|
||||
signature: '',
|
||||
total: 0,
|
||||
rating: 0,
|
||||
score: 0,
|
||||
|
@ -162,14 +173,16 @@ export default {
|
|||
},
|
||||
freshProblemDisplayID() {
|
||||
this.init();
|
||||
myMessage.success('更新成功!');
|
||||
myMessage.success(this.$i18n.t('m.Update_Successfully'));
|
||||
},
|
||||
getSumScore(scoreList) {
|
||||
var sum = 0;
|
||||
for (let i = 0; i < scoreList.length; i++) {
|
||||
sum += scoreList[i];
|
||||
if (scoreList) {
|
||||
var sum = 0;
|
||||
for (let i = 0; i < scoreList.length; i++) {
|
||||
sum += scoreList[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
return sum;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
|
|
|
@ -17,7 +17,6 @@ const cdn = {
|
|||
vuex:'Vuex',
|
||||
'element-ui':'ELEMENT',
|
||||
'highlight.js': 'hljs',
|
||||
'katex':'katex',
|
||||
'vxe-table':'VXETable',
|
||||
"moment": "moment",
|
||||
'vue-echarts': 'VueECharts',
|
||||
|
@ -27,7 +26,6 @@ const cdn = {
|
|||
// cdn的css链接
|
||||
css: [
|
||||
'https://cdn.bootcdn.net/ajax/libs/element-ui/2.14.0/theme-chalk/index.min.css',
|
||||
"https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/katex.min.css",
|
||||
"https://cdn.bootcdn.net/ajax/libs/github-markdown-css/4.0.0/github-markdown.min.css",
|
||||
"https://cdn.jsdelivr.net/npm/vxe-table@2.9.26/lib/style.css"
|
||||
],
|
||||
|
@ -39,11 +37,11 @@ const cdn = {
|
|||
"https://cdn.bootcdn.net/ajax/libs/vuex/3.5.1/vuex.min.js",
|
||||
"https://cdn.bootcdn.net/ajax/libs/element-ui/2.14.0/index.min.js",
|
||||
"https://cdn.bootcdn.net/ajax/libs/highlight.js/10.3.2/highlight.min.js",
|
||||
"https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/katex.min.js",
|
||||
"https://cdn.jsdelivr.net/npm/xe-utils",
|
||||
"https://cdn.jsdelivr.net/npm/vxe-table@2.9.26",
|
||||
"https://cdn.bootcss.com/moment.js/2.29.1/moment.min.js",
|
||||
"https://cdn.bootcss.com/moment.js/2.29.1/locale/zh-cn.js",
|
||||
"https://cdn.bootcss.com/moment.js/2.29.1/locale/zh-cn.min.js",
|
||||
"https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.1/locale/es-us.min.js",
|
||||
"https://cdn.bootcdn.net/ajax/libs/echarts/4.9.0-rc.1/echarts.min.js",
|
||||
"https://cdn.bootcdn.net/ajax/libs/vue-echarts/5.0.0-beta.0/vue-echarts.min.js"
|
||||
// "https://unpkg.com/mavon-editor@2.9.1/dist/mavon-editor.js"
|
||||
|
|
Loading…
Reference in New Issue