remove contest type
This commit is contained in:
@@ -56,9 +56,7 @@ const contest = reactive<BlankContest & { id: number }>({
|
||||
tag: "练习",
|
||||
start_time: "",
|
||||
end_time: "",
|
||||
rule_type: "ACM",
|
||||
password: "",
|
||||
real_time_rank: true,
|
||||
visible: false,
|
||||
allowed_ip_ranges: [],
|
||||
})
|
||||
@@ -79,9 +77,7 @@ async function getContestDetail() {
|
||||
contest.tag = data.tag
|
||||
contest.start_time = data.start_time
|
||||
contest.end_time = data.end_time
|
||||
contest.rule_type = "ACM"
|
||||
contest.password = data.password
|
||||
contest.real_time_rank = true
|
||||
contest.visible = data.visible
|
||||
contest.allowed_ip_ranges = []
|
||||
|
||||
|
||||
@@ -24,23 +24,41 @@ const emit = defineEmits<{
|
||||
const activeTab = ref(props.languages[0] || "Python3")
|
||||
|
||||
const ENGINE_OPTIONS: SelectOption[] = [
|
||||
{ label: "节点检查", type: "group", key: "node_group", children: [
|
||||
{ label: "必须存在", value: "must_exist_node" },
|
||||
{ label: "不能存在", value: "must_not_exist_node" },
|
||||
{ label: "出现次数", value: "count_node" },
|
||||
]},
|
||||
{ label: "函数调用", type: "group", key: "func_group", children: [
|
||||
{ label: "必须调用函数", value: "must_call_function" },
|
||||
{ label: "不能调用函数", value: "must_not_call_function" },
|
||||
{ label: "函数调用次数", value: "count_function_call" },
|
||||
]},
|
||||
{ label: "方法调用", type: "group", key: "method_group", children: [
|
||||
{ label: "必须调用方法", value: "must_call_method" },
|
||||
{ label: "不能调用方法", value: "must_not_call_method" },
|
||||
]},
|
||||
{ label: "运算符", type: "group", key: "op_group", children: [
|
||||
{ label: "必须使用运算符", value: "must_use_operator" },
|
||||
]},
|
||||
{
|
||||
label: "节点检查",
|
||||
type: "group",
|
||||
key: "node_group",
|
||||
children: [
|
||||
{ label: "必须存在", value: "must_exist_node" },
|
||||
{ label: "不能存在", value: "must_not_exist_node" },
|
||||
{ label: "出现次数", value: "count_node" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "函数调用",
|
||||
type: "group",
|
||||
key: "func_group",
|
||||
children: [
|
||||
{ label: "必须调用函数", value: "must_call_function" },
|
||||
{ label: "不能调用函数", value: "must_not_call_function" },
|
||||
{ label: "函数调用次数", value: "count_function_call" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "方法调用",
|
||||
type: "group",
|
||||
key: "method_group",
|
||||
children: [
|
||||
{ label: "必须调用方法", value: "must_call_method" },
|
||||
{ label: "不能调用方法", value: "must_not_call_method" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "运算符",
|
||||
type: "group",
|
||||
key: "op_group",
|
||||
children: [{ label: "必须使用运算符", value: "must_use_operator" }],
|
||||
},
|
||||
]
|
||||
|
||||
const NODE_TARGET_OPTIONS: SelectOption[] = [
|
||||
@@ -83,16 +101,30 @@ const OPERATOR_TARGET_OPTIONS: SelectOption[] = [
|
||||
]
|
||||
|
||||
const NODE_ENGINES = ["must_exist_node", "must_not_exist_node", "count_node"]
|
||||
const FUNCTION_ENGINES = ["must_call_function", "must_not_call_function", "count_function_call"]
|
||||
const FUNCTION_ENGINES = [
|
||||
"must_call_function",
|
||||
"must_not_call_function",
|
||||
"count_function_call",
|
||||
]
|
||||
const METHOD_ENGINES = ["must_call_method", "must_not_call_method"]
|
||||
const OPERATOR_ENGINES = ["must_use_operator"]
|
||||
const COUNT_ENGINES = ["count_node", "count_function_call"]
|
||||
|
||||
function isNodeEngine(engine: string) { return NODE_ENGINES.includes(engine) }
|
||||
function isFunctionEngine(engine: string) { return FUNCTION_ENGINES.includes(engine) }
|
||||
function isMethodEngine(engine: string) { return METHOD_ENGINES.includes(engine) }
|
||||
function isOperatorEngine(engine: string) { return OPERATOR_ENGINES.includes(engine) }
|
||||
function isCountEngine(engine: string) { return COUNT_ENGINES.includes(engine) }
|
||||
function isNodeEngine(engine: string) {
|
||||
return NODE_ENGINES.includes(engine)
|
||||
}
|
||||
function isFunctionEngine(engine: string) {
|
||||
return FUNCTION_ENGINES.includes(engine)
|
||||
}
|
||||
function isMethodEngine(engine: string) {
|
||||
return METHOD_ENGINES.includes(engine)
|
||||
}
|
||||
function isOperatorEngine(engine: string) {
|
||||
return OPERATOR_ENGINES.includes(engine)
|
||||
}
|
||||
function isCountEngine(engine: string) {
|
||||
return COUNT_ENGINES.includes(engine)
|
||||
}
|
||||
|
||||
const COUNT_MODE_OPTIONS: SelectOption[] = [
|
||||
{ label: "精确", value: "exact" },
|
||||
@@ -126,9 +158,15 @@ function updateExactCount(lang: string, index: number, v: number | null) {
|
||||
updateRules(lang, rules)
|
||||
}
|
||||
|
||||
function needsTargetDropdown(engine: string) { return isNodeEngine(engine) }
|
||||
function needsTargetInput(engine: string) { return isFunctionEngine(engine) || isMethodEngine(engine) }
|
||||
function needsOperatorDropdown(engine: string) { return isOperatorEngine(engine) }
|
||||
function needsTargetDropdown(engine: string) {
|
||||
return isNodeEngine(engine)
|
||||
}
|
||||
function needsTargetInput(engine: string) {
|
||||
return isFunctionEngine(engine) || isMethodEngine(engine)
|
||||
}
|
||||
function needsOperatorDropdown(engine: string) {
|
||||
return isOperatorEngine(engine)
|
||||
}
|
||||
|
||||
function getRulesForLang(lang: string): AstRule[] {
|
||||
if (!props.modelValue) return []
|
||||
@@ -149,13 +187,19 @@ function getTargetLabel(engine: string, target: string): string | undefined {
|
||||
if (isNodeEngine(engine))
|
||||
return (NODE_TARGET_OPTIONS.find((o) => o.value === target) as any)?.label
|
||||
if (isOperatorEngine(engine))
|
||||
return (OPERATOR_TARGET_OPTIONS.find((o) => o.value === target) as any)?.label
|
||||
return (OPERATOR_TARGET_OPTIONS.find((o) => o.value === target) as any)
|
||||
?.label
|
||||
return undefined
|
||||
}
|
||||
|
||||
function addRule(lang: string) {
|
||||
const rules = [...getRulesForLang(lang)]
|
||||
rules.push({ engine: "must_exist_node", target: "for_loop", label: "for 循环", message: "" })
|
||||
rules.push({
|
||||
engine: "must_exist_node",
|
||||
target: "for_loop",
|
||||
label: "for 循环",
|
||||
message: "",
|
||||
})
|
||||
updateRules(lang, rules)
|
||||
}
|
||||
|
||||
@@ -171,9 +215,16 @@ function updateRule(lang: string, index: number, field: string, value: any) {
|
||||
|
||||
if (field === "engine") {
|
||||
rule.engine = value
|
||||
if (isNodeEngine(value)) { rule.target = "for_loop"; rule.label = "for 循环" }
|
||||
else if (isOperatorEngine(value)) { rule.target = "+"; rule.label = "+" }
|
||||
else { rule.target = ""; delete rule.label }
|
||||
if (isNodeEngine(value)) {
|
||||
rule.target = "for_loop"
|
||||
rule.label = "for 循环"
|
||||
} else if (isOperatorEngine(value)) {
|
||||
rule.target = "+"
|
||||
rule.label = "+"
|
||||
} else {
|
||||
rule.target = ""
|
||||
delete rule.label
|
||||
}
|
||||
delete rule.min
|
||||
delete rule.max
|
||||
delete rule.exact
|
||||
@@ -196,25 +247,39 @@ function updateRule(lang: string, index: number, field: string, value: any) {
|
||||
updateRules(lang, rules)
|
||||
}
|
||||
|
||||
watch(() => props.languages, (langs) => {
|
||||
if (langs.length && !langs.includes(activeTab.value as LANGUAGE)) {
|
||||
activeTab.value = langs[0]
|
||||
}
|
||||
})
|
||||
watch(
|
||||
() => props.languages,
|
||||
(langs) => {
|
||||
if (langs.length && !langs.includes(activeTab.value as LANGUAGE)) {
|
||||
activeTab.value = langs[0]
|
||||
}
|
||||
},
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-collapse>
|
||||
<n-collapse-item title="代码规则检查(选填)" name="ast-rules">
|
||||
<n-tabs v-if="languages.length" type="segment" v-model:value="activeTab">
|
||||
<n-tab-pane v-for="lang in languages" :key="lang" :name="lang" :tab="lang">
|
||||
<n-tab-pane
|
||||
v-for="lang in languages"
|
||||
:key="lang"
|
||||
:name="lang"
|
||||
:tab="lang"
|
||||
>
|
||||
<n-flex vertical>
|
||||
<div v-for="(rule, index) in getRulesForLang(lang)" :key="index" style="margin-bottom: 8px">
|
||||
<div
|
||||
v-for="(rule, index) in getRulesForLang(lang)"
|
||||
:key="index"
|
||||
style="margin-bottom: 8px"
|
||||
>
|
||||
<n-flex align="center" :wrap="false">
|
||||
<n-select
|
||||
:options="ENGINE_OPTIONS"
|
||||
:value="rule.engine"
|
||||
@update:value="(v: string) => updateRule(lang, index, 'engine', v)"
|
||||
@update:value="
|
||||
(v: string) => updateRule(lang, index, 'engine', v)
|
||||
"
|
||||
style="width: 150px"
|
||||
size="small"
|
||||
/>
|
||||
@@ -222,7 +287,9 @@ watch(() => props.languages, (langs) => {
|
||||
v-if="needsTargetDropdown(rule.engine)"
|
||||
:options="NODE_TARGET_OPTIONS"
|
||||
:value="rule.target"
|
||||
@update:value="(v: string) => updateRule(lang, index, 'target', v)"
|
||||
@update:value="
|
||||
(v: string) => updateRule(lang, index, 'target', v)
|
||||
"
|
||||
style="width: 150px"
|
||||
size="small"
|
||||
filterable
|
||||
@@ -230,7 +297,9 @@ watch(() => props.languages, (langs) => {
|
||||
<n-input
|
||||
v-if="needsTargetInput(rule.engine)"
|
||||
:value="rule.target"
|
||||
@update:value="(v: string) => updateRule(lang, index, 'target', v)"
|
||||
@update:value="
|
||||
(v: string) => updateRule(lang, index, 'target', v)
|
||||
"
|
||||
placeholder="函数/方法名"
|
||||
style="width: 150px"
|
||||
size="small"
|
||||
@@ -239,7 +308,9 @@ watch(() => props.languages, (langs) => {
|
||||
v-if="needsOperatorDropdown(rule.engine)"
|
||||
:options="OPERATOR_TARGET_OPTIONS"
|
||||
:value="rule.target"
|
||||
@update:value="(v: string) => updateRule(lang, index, 'target', v)"
|
||||
@update:value="
|
||||
(v: string) => updateRule(lang, index, 'target', v)
|
||||
"
|
||||
style="width: 150px"
|
||||
size="small"
|
||||
/>
|
||||
@@ -247,14 +318,18 @@ watch(() => props.languages, (langs) => {
|
||||
<n-select
|
||||
:options="COUNT_MODE_OPTIONS"
|
||||
:value="getCountMode(rule)"
|
||||
@update:value="(v: 'exact' | 'range') => updateCountMode(lang, index, v)"
|
||||
@update:value="
|
||||
(v: 'exact' | 'range') => updateCountMode(lang, index, v)
|
||||
"
|
||||
style="width: 80px"
|
||||
size="small"
|
||||
/>
|
||||
<n-input-number
|
||||
v-if="getCountMode(rule) === 'exact'"
|
||||
:value="rule.exact ?? null"
|
||||
@update:value="(v: number | null) => updateExactCount(lang, index, v)"
|
||||
@update:value="
|
||||
(v: number | null) => updateExactCount(lang, index, v)
|
||||
"
|
||||
placeholder="次数"
|
||||
style="width: 100px"
|
||||
size="small"
|
||||
@@ -264,7 +339,9 @@ watch(() => props.languages, (langs) => {
|
||||
<template v-else>
|
||||
<n-input-number
|
||||
:value="rule.min ?? null"
|
||||
@update:value="(v: number | null) => updateRule(lang, index, 'min', v)"
|
||||
@update:value="
|
||||
(v: number | null) => updateRule(lang, index, 'min', v)
|
||||
"
|
||||
placeholder="最少"
|
||||
style="width: 100px"
|
||||
size="small"
|
||||
@@ -273,7 +350,9 @@ watch(() => props.languages, (langs) => {
|
||||
/>
|
||||
<n-input-number
|
||||
:value="rule.max ?? null"
|
||||
@update:value="(v: number | null) => updateRule(lang, index, 'max', v)"
|
||||
@update:value="
|
||||
(v: number | null) => updateRule(lang, index, 'max', v)
|
||||
"
|
||||
placeholder="最多"
|
||||
style="width: 100px"
|
||||
size="small"
|
||||
@@ -284,17 +363,29 @@ watch(() => props.languages, (langs) => {
|
||||
</template>
|
||||
<n-input
|
||||
:value="rule.message"
|
||||
@update:value="(v: string) => updateRule(lang, index, 'message', v)"
|
||||
@update:value="
|
||||
(v: string) => updateRule(lang, index, 'message', v)
|
||||
"
|
||||
placeholder="错误提示(选填)"
|
||||
style="flex: 1"
|
||||
size="small"
|
||||
/>
|
||||
<n-button size="small" tertiary type="error" @click="removeRule(lang, index)">
|
||||
<n-button
|
||||
size="small"
|
||||
tertiary
|
||||
type="error"
|
||||
@click="removeRule(lang, index)"
|
||||
>
|
||||
删除
|
||||
</n-button>
|
||||
</n-flex>
|
||||
</div>
|
||||
<n-button size="small" tertiary type="primary" @click="addRule(lang)">
|
||||
<n-button
|
||||
size="small"
|
||||
tertiary
|
||||
type="primary"
|
||||
@click="addRule(lang)"
|
||||
>
|
||||
添加规则
|
||||
</n-button>
|
||||
</n-flex>
|
||||
|
||||
@@ -87,12 +87,24 @@ const columns: DataTableColumn<AdminProblemFiltered>[] = [
|
||||
render: (row) =>
|
||||
h(NFlex, { size: 4, align: "center" }, () => [
|
||||
row.allow_flowchart
|
||||
? h(Icon, { width: 18, icon: "vscode-icons:file-type-drawio", title: "绘图" })
|
||||
? h(Icon, {
|
||||
width: 18,
|
||||
icon: "vscode-icons:file-type-drawio",
|
||||
title: "绘图",
|
||||
})
|
||||
: row.show_flowchart
|
||||
? h(Icon, { width: 18, icon: "vscode-icons:file-type-graphql", title: "流程图" })
|
||||
? h(Icon, {
|
||||
width: 18,
|
||||
icon: "vscode-icons:file-type-graphql",
|
||||
title: "流程图",
|
||||
})
|
||||
: null,
|
||||
row.has_ast_rules
|
||||
? h(Icon, { width: 18, icon: "vscode-icons:file-type-light-todo", title: "AST" })
|
||||
? h(Icon, {
|
||||
width: 18,
|
||||
icon: "vscode-icons:file-type-light-todo",
|
||||
title: "AST",
|
||||
})
|
||||
: null,
|
||||
]),
|
||||
},
|
||||
|
||||
@@ -211,7 +211,7 @@ export async function getContestProblems(contestID: string) {
|
||||
|
||||
export function getContestRank(
|
||||
contestID: string,
|
||||
query: { limit: number; offset: number; force_refresh: "1" | "0" },
|
||||
query: { limit: number; offset: number },
|
||||
) {
|
||||
return http.get("contest_rank", {
|
||||
params: {
|
||||
|
||||
@@ -95,7 +95,6 @@ async function listRanks() {
|
||||
const res = await getContestRank(props.contestID, {
|
||||
limit: query.limit,
|
||||
offset: query.limit * (query.page - 1),
|
||||
force_refresh: "1",
|
||||
})
|
||||
total.value = res.data.total
|
||||
data.value = res.data.results
|
||||
@@ -225,7 +224,6 @@ async function downloadExcel() {
|
||||
const res = await getContestRank(props.contestID, {
|
||||
limit: total.value || 10000,
|
||||
offset: 0,
|
||||
force_refresh: "1",
|
||||
})
|
||||
const allRanks: ContestRank[] = res.data.results
|
||||
|
||||
|
||||
@@ -119,29 +119,41 @@ function ruleDescription(rule: AstRule): string {
|
||||
const targetLabel = rule.label || NODE_TARGET_LABELS[target] || target
|
||||
const countDesc = () => {
|
||||
if (rule.exact !== undefined) return `出现 ${rule.exact} 次`
|
||||
if (rule.min !== undefined && rule.max !== undefined) return `出现 ${rule.min}~${rule.max} 次`
|
||||
if (rule.min !== undefined && rule.max !== undefined)
|
||||
return `出现 ${rule.min}~${rule.max} 次`
|
||||
if (rule.min !== undefined) return `至少出现 ${rule.min} 次`
|
||||
if (rule.max !== undefined) return `至多出现 ${rule.max} 次`
|
||||
return ""
|
||||
}
|
||||
const callDesc = () => {
|
||||
if (rule.exact !== undefined) return `调用 ${rule.exact} 次`
|
||||
if (rule.min !== undefined && rule.max !== undefined) return `调用 ${rule.min}~${rule.max} 次`
|
||||
if (rule.min !== undefined && rule.max !== undefined)
|
||||
return `调用 ${rule.min}~${rule.max} 次`
|
||||
if (rule.min !== undefined) return `至少调用 ${rule.min} 次`
|
||||
if (rule.max !== undefined) return `至多调用 ${rule.max} 次`
|
||||
return ""
|
||||
}
|
||||
switch (rule.engine) {
|
||||
case "must_exist_node": return `必须使用 ${targetLabel}`
|
||||
case "must_not_exist_node": return `不能使用 ${targetLabel}`
|
||||
case "count_node": return `${targetLabel} ${countDesc()}`
|
||||
case "must_call_function": return `必须调用 ${target}()`
|
||||
case "must_not_call_function": return `不能调用 ${target}()`
|
||||
case "count_function_call": return `${target}() ${callDesc()}`
|
||||
case "must_call_method": return `必须调用 .${target}()`
|
||||
case "must_not_call_method": return `不能调用 .${target}()`
|
||||
case "must_use_operator": return `必须使用 ${target} 运算符`
|
||||
default: return rule.engine
|
||||
case "must_exist_node":
|
||||
return `必须使用 ${targetLabel}`
|
||||
case "must_not_exist_node":
|
||||
return `不能使用 ${targetLabel}`
|
||||
case "count_node":
|
||||
return `${targetLabel} ${countDesc()}`
|
||||
case "must_call_function":
|
||||
return `必须调用 ${target}()`
|
||||
case "must_not_call_function":
|
||||
return `不能调用 ${target}()`
|
||||
case "count_function_call":
|
||||
return `${target}() ${callDesc()}`
|
||||
case "must_call_method":
|
||||
return `必须调用 .${target}()`
|
||||
case "must_not_call_method":
|
||||
return `不能调用 .${target}()`
|
||||
case "must_use_operator":
|
||||
return `必须使用 ${target} 运算符`
|
||||
default:
|
||||
return rule.engine
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +165,9 @@ function ruleTagType(engine: string): "error" | "success" | "info" {
|
||||
|
||||
const astRulesForDisplay = computed(() => {
|
||||
if (!problem.value?.ast_rules) return []
|
||||
return Object.entries(problem.value.ast_rules).filter(([, rules]) => rules.length > 0)
|
||||
return Object.entries(problem.value.ast_rules).filter(
|
||||
([, rules]) => rules.length > 0,
|
||||
)
|
||||
})
|
||||
|
||||
async function test(sample: Sample, index: number) {
|
||||
@@ -302,14 +316,18 @@ function type(status: ProblemStatus) {
|
||||
</n-flex>
|
||||
</p>
|
||||
<div v-for="[lang, rules] in astRulesForDisplay" :key="lang">
|
||||
<p v-if="astRulesForDisplay.length > 1" class="lang-label">{{ lang }}</p>
|
||||
<p v-if="astRulesForDisplay.length > 1" class="lang-label">
|
||||
{{ lang }}
|
||||
</p>
|
||||
<n-list bordered style="margin-bottom: 8px">
|
||||
<n-list-item v-for="(rule, i) in rules" :key="i">
|
||||
<n-flex align="center">
|
||||
<n-tag :type="ruleTagType(rule.engine)">
|
||||
{{ ruleDescription(rule) }}
|
||||
</n-tag>
|
||||
<span v-if="rule.message" class="rule-message">{{ rule.message }}</span>
|
||||
<span v-if="rule.message" class="rule-message">{{
|
||||
rule.message
|
||||
}}</span>
|
||||
</n-flex>
|
||||
</n-list-item>
|
||||
</n-list>
|
||||
|
||||
@@ -43,7 +43,10 @@ const msg = computed(() => {
|
||||
msg += "请仔细检查,看看代码的格式是不是写错了!\n\n"
|
||||
}
|
||||
|
||||
if (result !== SubmissionStatus.ast_check_failed && props.submission.statistic_info?.err_info) {
|
||||
if (
|
||||
result !== SubmissionStatus.ast_check_failed &&
|
||||
props.submission.statistic_info?.err_info
|
||||
) {
|
||||
msg += props.submission.statistic_info.err_info
|
||||
}
|
||||
|
||||
@@ -153,7 +156,14 @@ const columns: DataTableColumn<Submission["info"]["data"][number]>[] = [
|
||||
:title="JUDGE_STATUS[submission.result]['title']"
|
||||
class="mb-3"
|
||||
/>
|
||||
<n-flex vertical v-if="msg || infoTable.length || submission.statistic_info?.ast_results?.length">
|
||||
<n-flex
|
||||
vertical
|
||||
v-if="
|
||||
msg ||
|
||||
infoTable.length ||
|
||||
submission.statistic_info?.ast_results?.length
|
||||
"
|
||||
>
|
||||
<n-card v-if="submission.statistic_info?.ast_results?.length" embedded>
|
||||
<n-flex vertical :size="8">
|
||||
<n-flex
|
||||
@@ -162,7 +172,9 @@ const columns: DataTableColumn<Submission["info"]["data"][number]>[] = [
|
||||
align="center"
|
||||
:size="6"
|
||||
>
|
||||
<n-icon :color="rule.passed ? theme.successColor : theme.errorColor">
|
||||
<n-icon
|
||||
:color="rule.passed ? theme.successColor : theme.errorColor"
|
||||
>
|
||||
<Icon :icon="rule.passed ? 'ep:select' : 'ep:close-bold'" />
|
||||
</n-icon>
|
||||
<span>{{ rule.description }}</span>
|
||||
|
||||
@@ -149,7 +149,10 @@ watch(
|
||||
result === SubmissionStatus.submitting
|
||||
)
|
||||
return
|
||||
if (result !== SubmissionStatus.accepted && result !== SubmissionStatus.ast_check_failed) {
|
||||
if (
|
||||
result !== SubmissionStatus.accepted &&
|
||||
result !== SubmissionStatus.ast_check_failed
|
||||
) {
|
||||
problemStore.incrementFailCount()
|
||||
}
|
||||
},
|
||||
@@ -159,7 +162,11 @@ watch(
|
||||
watch(
|
||||
() => submission.value?.result,
|
||||
async (result) => {
|
||||
if (result !== SubmissionStatus.accepted && result !== SubmissionStatus.ast_check_failed) return
|
||||
if (
|
||||
result !== SubmissionStatus.accepted &&
|
||||
result !== SubmissionStatus.ast_check_failed
|
||||
)
|
||||
return
|
||||
|
||||
// 1. 刷新题目状态
|
||||
problem.value!.my_status = 0
|
||||
|
||||
@@ -267,7 +267,11 @@ watch(isMobile, (value) => {
|
||||
>
|
||||
<ProblemComment />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane v-if="myFlowchartStore.showing" name="my-flowchart" tab="我的流程图">
|
||||
<n-tab-pane
|
||||
v-if="myFlowchartStore.showing"
|
||||
name="my-flowchart"
|
||||
tab="我的流程图"
|
||||
>
|
||||
<MyFlowchartTab />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="submission" tab="提交" :disabled="!!props.problemSetId">
|
||||
|
||||
@@ -102,11 +102,11 @@ export function secondsToDuration(seconds: number): string {
|
||||
start: 0,
|
||||
end: seconds * 1000,
|
||||
})
|
||||
return [
|
||||
duration.hours ?? 0,
|
||||
duration.minutes ?? 0,
|
||||
duration.seconds ?? 0,
|
||||
].join(":")
|
||||
const hours = (duration.days ?? 0) * 24 + (duration.hours ?? 0)
|
||||
const pad = (n: number) => String(n).padStart(2, "0")
|
||||
return [hours, pad(duration.minutes ?? 0), pad(duration.seconds ?? 0)].join(
|
||||
":",
|
||||
)
|
||||
}
|
||||
|
||||
export function submissionMemoryFormat(memory: number | string | undefined) {
|
||||
|
||||
@@ -65,7 +65,20 @@ export type LANGUAGE =
|
||||
export type LANGUAGE_SHOW_LABEL =
|
||||
(typeof LANGUAGE_SHOW_VALUE)[keyof typeof LANGUAGE_SHOW_VALUE]
|
||||
|
||||
export type SUBMISSION_RESULT = -2 | -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
|
||||
export type SUBMISSION_RESULT =
|
||||
| -2
|
||||
| -1
|
||||
| 0
|
||||
| 1
|
||||
| 2
|
||||
| 3
|
||||
| 4
|
||||
| 5
|
||||
| 6
|
||||
| 7
|
||||
| 8
|
||||
| 9
|
||||
| 10
|
||||
|
||||
export type ProblemStatus = "passed" | "failed" | "not_test"
|
||||
|
||||
@@ -137,7 +150,15 @@ export interface Problem {
|
||||
flowchart_data?: Record<string, any>
|
||||
flowchart_hint?: string
|
||||
show_flowchart?: boolean
|
||||
ast_rules?: { [key: string]: { engine: string; target?: string; min?: number; max?: number; message: string }[] } | null
|
||||
ast_rules?: {
|
||||
[key: string]: {
|
||||
engine: string
|
||||
target?: string
|
||||
min?: number
|
||||
max?: number
|
||||
message: string
|
||||
}[]
|
||||
} | null
|
||||
has_ast_rules?: boolean
|
||||
}
|
||||
|
||||
@@ -482,9 +503,7 @@ export interface BlankContest {
|
||||
tag: string
|
||||
start_time: string
|
||||
end_time: string
|
||||
rule_type: "ACM" | "OI"
|
||||
password: string
|
||||
real_time_rank: boolean
|
||||
visible: boolean
|
||||
allowed_ip_ranges: { value: string }[]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user