add create a problem.

This commit is contained in:
2023-03-27 20:27:30 +08:00
parent 9bc1a1b5b5
commit 1698626704
10 changed files with 122 additions and 32 deletions

View File

@@ -1,9 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { SelectOption } from "naive-ui"
import { getProblemTagList } from "~/shared/api"
import TextEditor from "~/shared/TextEditor.vue" import TextEditor from "~/shared/TextEditor.vue"
import Monaco from "~/shared/Monaco.vue"
import { SelectOption } from "naive-ui"
import { unique } from "~/utils/functions" import { unique } from "~/utils/functions"
import { Problem, Tag } from "~/utils/types" import { Problem, Tag } from "~/utils/types"
import { getProblemTagList } from "~/shared/api"
import { LANGUAGE_SHOW_VALUE } from "~/utils/constants"
import { cTemplate, cppTemplate, blankTemplate } from "./templates"
interface AlterProblem { interface AlterProblem {
spj_language: string spj_language: string
@@ -39,7 +43,7 @@ const problem = reactive<Omit<Problem, ExcludeKeys> & AlterProblem>({
visible: true, visible: true,
share_submission: false, share_submission: false,
tags: [], tags: [],
languages: ["C", "C++", "Python3"], languages: ["C", "Python3"],
template: {}, template: {},
samples: [{ input: "", output: "" }], samples: [{ input: "", output: "" }],
spj: false, spj: false,
@@ -58,9 +62,12 @@ const problem = reactive<Omit<Problem, ExcludeKeys> & AlterProblem>({
}, },
}) })
const template = shallowRef({})
const existingTags = shallowRef<Tag[]>([]) const existingTags = shallowRef<Tag[]>([])
const fromExistingTags = shallowRef<string[]>([]) const fromExistingTags = shallowRef<string[]>([])
const newTags = shallowRef<string[]>([]) const newTags = shallowRef<string[]>([])
const [needTemplate] = useToggle(false)
const difficultyOptions: SelectOption[] = [ const difficultyOptions: SelectOption[] = [
{ label: "简单", value: "Low" }, { label: "简单", value: "Low" },
@@ -69,12 +76,12 @@ const difficultyOptions: SelectOption[] = [
] ]
const languageOptions = [ const languageOptions = [
{ label: "C", value: "C" }, { label: LANGUAGE_SHOW_VALUE["C"], value: "C" },
{ label: "C++", value: "C++" }, { label: LANGUAGE_SHOW_VALUE["Python3"], value: "Python3" },
{ label: "Python", value: "Python3" }, { label: LANGUAGE_SHOW_VALUE["C++"], value: "C++" },
{ label: "Java", value: "Java" }, { label: LANGUAGE_SHOW_VALUE["Java"], value: "Java" },
{ label: "JS", value: "JavaScript" }, { label: LANGUAGE_SHOW_VALUE["JavaScript"], value: "JavaScript" },
{ label: "Go", value: "Golang" }, { label: LANGUAGE_SHOW_VALUE["Golang"], value: "Golang" },
] ]
const tagOptions = computed(() => const tagOptions = computed(() =>
@@ -118,6 +125,11 @@ watch([fromExistingTags, newTags], (tags) => {
const uniqueTags = unique<string>(tags[0].concat(tags[1])) const uniqueTags = unique<string>(tags[0].concat(tags[1]))
problem.tags = uniqueTags problem.tags = uniqueTags
}) })
watch(
() => problem.languages,
() => {}
)
</script> </script>
<template> <template>
@@ -202,6 +214,35 @@ watch([fromExistingTags, newTags], (tags) => {
添加用例 添加用例
</n-button> </n-button>
<TextEditor v-model:value="problem.hint" title="提示" /> <TextEditor v-model:value="problem.hint" title="提示" />
<n-space class="title">
<n-checkbox v-model:checked="needTemplate" label="代码模板" />
</n-space>
<n-tabs type="segment" v-if="needTemplate">
<n-tab-pane
v-for="(lang, index) in problem.languages"
:name="LANGUAGE_SHOW_VALUE[lang]"
:key="index"
>
<Monaco
v-if="lang === 'C'"
v-model:value="cTemplate"
:font-size="12"
height="320px"
/>
<Monaco
v-else-if="lang === 'C++'"
v-model:value="cppTemplate"
:font-size="12"
height="320px"
/>
<Monaco
v-else
v-model:value="blankTemplate"
:font-size="12"
height="320px"
/>
</n-tab-pane>
</n-tabs>
<n-form> <n-form>
<n-form-item label="题目的来源"> <n-form-item label="题目的来源">
<n-input <n-input

View File

@@ -0,0 +1,44 @@
export const cTemplate = `//PREPEND BEGIN
#include <stdio.h>
//PREPEND END
//TEMPLATE BEGIN
int add(int a, int b) {
// 请填空
return ___________;
}
//TEMPLATE END
//APPEND BEGIN
int main() {
printf("%d", add(1, 2));
return 0;
}
//APPEND END`
export const cppTemplate = `//PREPEND BEGIN
#include <iostream>
//PREPEND END
//TEMPLATE BEGIN
int add(int a, int b) {
// 请填空
return ___________;
}
//TEMPLATE END
//APPEND BEGIN
int main() {
std::cout << add(1, 2);
return 0;
}
//APPEND END`
export const blankTemplate = `//PREPEND BEGIN
//PREPEND END
//TEMPLATE BEGIN
//TEMPLATE END
//APPEND BEGIN
//APPEND END`

1
src/components.d.ts vendored
View File

@@ -56,7 +56,6 @@ declare module '@vue/runtime-core' {
NTabPane: typeof import('naive-ui')['NTabPane'] NTabPane: typeof import('naive-ui')['NTabPane']
NTabs: typeof import('naive-ui')['NTabs'] NTabs: typeof import('naive-ui')['NTabs']
NTag: typeof import('naive-ui')['NTag'] NTag: typeof import('naive-ui')['NTag']
NTextarea: typeof import('naive-ui')['NTextarea']
NTooltip: typeof import('naive-ui')['NTooltip'] NTooltip: typeof import('naive-ui')['NTooltip']
NUpload: typeof import('naive-ui')['NUpload'] NUpload: typeof import('naive-ui')['NUpload']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']

View File

@@ -32,9 +32,6 @@ watch(
{ immediate: true } { immediate: true }
) )
function change(v: string) {
code.value = v
}
function prev() { function prev() {
router.push(`/learn/step-${step.value - 1}`) router.push(`/learn/step-${step.value - 1}`)
} }
@@ -59,7 +56,7 @@ function next() {
</n-scrollbar> </n-scrollbar>
</n-gi> </n-gi>
<n-gi :span="14"> <n-gi :span="14">
<Monaco :value="code" @change="change" /> <Monaco v-model:value="code" />
</n-gi> </n-gi>
</n-grid> </n-grid>
<div v-else> <div v-else>
@@ -74,7 +71,7 @@ function next() {
</n-button> </n-button>
</n-space> </n-space>
</n-scrollbar> </n-scrollbar>
<Monaco :value="code" @change="change" height="calc(50vh - 42px)" /> <Monaco v-model:value="code" height="calc(50vh - 42px)" />
</div> </div>
</template> </template>

View File

@@ -15,10 +15,6 @@ const props = defineProps<Props>()
code.language = props.problem.languages[0] || "C" code.language = props.problem.languages[0] || "C"
code.value = props.problem.template[code.language] || SOURCES[code.language] code.value = props.problem.template[code.language] || SOURCES[code.language]
function change(value: string) {
code.value = value
}
const editorHeight = computed(() => const editorHeight = computed(() =>
isDesktop.value ? "calc(100vh - 150px)" : "calc(100vh - 200px)" isDesktop.value ? "calc(100vh - 150px)" : "calc(100vh - 200px)"
) )
@@ -28,9 +24,8 @@ const editorHeight = computed(() =>
<Form :problem="props.problem" /> <Form :problem="props.problem" />
<Monaco <Monaco
class="editor" class="editor"
v-model:value="code.value"
:language="code.language" :language="code.language"
:value="code.value"
@change="change"
:height="editorHeight" :height="editorHeight"
/> />
</template> </template>

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { DropdownOption } from "naive-ui" import { DropdownOption } from "naive-ui"
import { SOURCES } from "utils/constants" import { LANGUAGE_SHOW_VALUE, SOURCES } from "utils/constants"
import { Problem } from "utils/types" import { Problem } from "utils/types"
import { code } from "oj/composables/code" import { code } from "oj/composables/code"
import { isDesktop, isMobile } from "~/shared/composables/breakpoints" import { isDesktop, isMobile } from "~/shared/composables/breakpoints"
@@ -47,7 +47,7 @@ const options: DropdownOption[] = props.problem.languages.map((it) => ({
transform: "translateY(3px)", transform: "translateY(3px)",
}, },
}), }),
it, LANGUAGE_SHOW_VALUE[it],
], ],
value: it, value: it,
})) }))

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { getSubmission } from "oj/api" import { getSubmission } from "oj/api"
import { Submission } from "utils/types" import { Submission } from "utils/types"
import { JUDGE_STATUS, LANGUAGE_VALUE } from "utils/constants" import { JUDGE_STATUS, LANGUAGE_FORMAT_VALUE } from "utils/constants"
import { import {
parseTime, parseTime,
submissionMemoryFormat, submissionMemoryFormat,
@@ -73,7 +73,7 @@ onMounted(init)
</n-space> </n-space>
<n-code <n-code
class="code" class="code"
:language="LANGUAGE_VALUE[submission.language]" :language="LANGUAGE_FORMAT_VALUE[submission.language]"
:code="submission.code" :code="submission.code"
show-line-numbers show-line-numbers
/> />

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type * as Monaco from "monaco-editor" import type * as Monaco from "monaco-editor"
import { LANGUAGE_VALUE } from "utils/constants" import { LANGUAGE_FORMAT_VALUE } from "utils/constants"
import { LANGUAGE } from "utils/types" import { LANGUAGE } from "utils/types"
import { isMobile } from "~/shared/composables/breakpoints" import { isMobile } from "~/shared/composables/breakpoints"
import { isDark } from "./composables/dark" import { isDark } from "./composables/dark"
@@ -22,7 +22,7 @@ const props = withDefaults(defineProps<Props>(), {
}) })
const emit = defineEmits<{ const emit = defineEmits<{
(e: "change", value: string): void (e: "update:value", value: string): void
}>() }>()
const monacoEditorRef = ref() const monacoEditorRef = ref()
@@ -33,7 +33,7 @@ onMounted(async () => {
if (!monaco.value) await init() if (!monaco.value) await init()
model = monaco.value!.editor.createModel( model = monaco.value!.editor.createModel(
props.value, props.value,
LANGUAGE_VALUE[props.language] LANGUAGE_FORMAT_VALUE[props.language]
) )
editor = monaco.value!.editor.create(monacoEditorRef.value, { editor = monaco.value!.editor.create(monacoEditorRef.value, {
@@ -45,7 +45,7 @@ onMounted(async () => {
lineNumbersMinChars: 2, lineNumbersMinChars: 2,
automaticLayout: true, // 自适应布局 automaticLayout: true, // 自适应布局
tabSize: 4, tabSize: 4,
fontSize: isMobile.value ? 20 : 22, // 字体大小 fontSize: props.fontSize || (isMobile.value ? 20 : 22), // 字体大小
scrollBeyondLastLine: false, scrollBeyondLastLine: false,
lineDecorationsWidth: 0, lineDecorationsWidth: 0,
scrollBeyondLastColumn: 0, scrollBeyondLastColumn: 0,
@@ -60,7 +60,7 @@ onMounted(async () => {
model.onDidChangeContent(() => { model.onDidChangeContent(() => {
const value = model.getValue().toString() const value = model.getValue().toString()
emit("change", value) emit("update:value", value)
}) })
editor.onKeyDown((e) => { editor.onKeyDown((e) => {
@@ -74,7 +74,10 @@ onMounted(async () => {
watchEffect(() => { watchEffect(() => {
if (!monaco.value) return if (!monaco.value) return
monaco.value.editor.setModelLanguage(model, LANGUAGE_VALUE[props.language]) monaco.value.editor.setModelLanguage(
model,
LANGUAGE_FORMAT_VALUE[props.language]
)
}) })
watchEffect(() => { watchEffect(() => {

View File

@@ -212,7 +212,7 @@ export const DEAD_RESULTS = {
}, },
} }
export const LANGUAGE_VALUE = { export const LANGUAGE_FORMAT_VALUE = {
C: "c", C: "c",
"C++": "cpp", "C++": "cpp",
Java: "java", Java: "java",
@@ -221,3 +221,13 @@ export const LANGUAGE_VALUE = {
JavaScript: "javascript", JavaScript: "javascript",
Golang: "go", Golang: "go",
} }
export const LANGUAGE_SHOW_VALUE = {
C: "C",
"C++": "C++",
Java: "Java",
Python2: "Python",
Python3: "Python",
JavaScript: "JS",
Golang: "Go",
}

View File

@@ -23,6 +23,7 @@ export default defineConfig({
manualChunks: { manualChunks: {
fancy: ["highlight.js", "party-js"], fancy: ["highlight.js", "party-js"],
chart: ["vue-chartjs", "chart.js"], chart: ["vue-chartjs", "chart.js"],
editor: ["@wangeditor/editor"],
}, },
}, },
}, },