add create a problem.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
44
src/admin/problem/templates.ts
Normal file
44
src/admin/problem/templates.ts
Normal 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
1
src/components.d.ts
vendored
@@ -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']
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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,
|
||||||
}))
|
}))
|
||||||
|
|||||||
@@ -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
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -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(() => {
|
||||||
|
|||||||
@@ -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",
|
||||||
|
}
|
||||||
|
|||||||
@@ -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"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user