add cache for admin problem detail
This commit is contained in:
@@ -3,7 +3,11 @@ import TextEditor from "~/shared/components/TextEditor.vue"
|
|||||||
import { unique } from "~/utils/functions"
|
import { unique } from "~/utils/functions"
|
||||||
import { BlankProblem, LANGUAGE, Tag } from "~/utils/types"
|
import { BlankProblem, LANGUAGE, Tag } from "~/utils/types"
|
||||||
import { getProblemTagList } from "~/shared/api"
|
import { getProblemTagList } from "~/shared/api"
|
||||||
import { LANGUAGE_SHOW_VALUE, CODE_TEMPLATES } from "~/utils/constants"
|
import {
|
||||||
|
LANGUAGE_SHOW_VALUE,
|
||||||
|
CODE_TEMPLATES,
|
||||||
|
STORAGE_KEY,
|
||||||
|
} from "~/utils/constants"
|
||||||
import download from "~/utils/download"
|
import download from "~/utils/download"
|
||||||
import {
|
import {
|
||||||
createContestProblem,
|
createContestProblem,
|
||||||
@@ -37,7 +41,7 @@ const title = computed(
|
|||||||
"admin contest problem edit": "编辑比赛题目",
|
"admin contest problem edit": "编辑比赛题目",
|
||||||
})[<string>route.name],
|
})[<string>route.name],
|
||||||
)
|
)
|
||||||
const problem = reactive<BlankProblem>({
|
const problem = useLocalStorage<BlankProblem>(STORAGE_KEY.ADMIN_PROBLEM, {
|
||||||
_id: "",
|
_id: "",
|
||||||
title: "",
|
title: "",
|
||||||
description: "",
|
description: "",
|
||||||
@@ -75,9 +79,19 @@ const problem = reactive<BlankProblem>({
|
|||||||
const template = reactive(JSON.parse(JSON.stringify(CODE_TEMPLATES)))
|
const template = reactive(JSON.parse(JSON.stringify(CODE_TEMPLATES)))
|
||||||
const currentActiveTemplate = ref<LANGUAGE>("C")
|
const currentActiveTemplate = ref<LANGUAGE>("C")
|
||||||
|
|
||||||
const existingTags = shallowRef<Tag[]>([])
|
// 从服务器来的tag列表
|
||||||
const fromExistingTags = shallowRef<string[]>([])
|
const tagList = shallowRef<Tag[]>([])
|
||||||
const newTags = shallowRef<string[]>([])
|
|
||||||
|
interface Tags {
|
||||||
|
select: string[]
|
||||||
|
upload: string[]
|
||||||
|
}
|
||||||
|
// 选择的 和 新的
|
||||||
|
const tags = useLocalStorage<Tags>(STORAGE_KEY.ADMIN_PROBLEM_TAGS, {
|
||||||
|
select: [],
|
||||||
|
upload: [],
|
||||||
|
})
|
||||||
|
|
||||||
const [needTemplate, toggleNeedTemplate] = useToggle(false)
|
const [needTemplate, toggleNeedTemplate] = useToggle(false)
|
||||||
const [ready, toggleReady] = useToggle(false)
|
const [ready, toggleReady] = useToggle(false)
|
||||||
|
|
||||||
@@ -93,7 +107,7 @@ const languageOptions = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const tagOptions = computed(() =>
|
const tagOptions = computed(() =>
|
||||||
existingTags.value.map((tag) => ({ label: tag.name, value: tag.name })),
|
tagList.value.map((tag) => ({ label: tag.name, value: tag.name })),
|
||||||
)
|
)
|
||||||
|
|
||||||
async function getProblemDetail() {
|
async function getProblemDetail() {
|
||||||
@@ -103,76 +117,76 @@ async function getProblemDetail() {
|
|||||||
}
|
}
|
||||||
const { data } = await getProblem(props.problemID)
|
const { data } = await getProblem(props.problemID)
|
||||||
toggleReady(true)
|
toggleReady(true)
|
||||||
problem.id = data.id
|
problem.value.id = data.id
|
||||||
problem._id = data._id
|
problem.value._id = data._id
|
||||||
problem.title = data.title
|
problem.value.title = data.title
|
||||||
problem.description = data.description
|
problem.value.description = data.description
|
||||||
problem.input_description = data.input_description
|
problem.value.input_description = data.input_description
|
||||||
problem.output_description = data.output_description
|
problem.value.output_description = data.output_description
|
||||||
problem.time_limit = data.time_limit
|
problem.value.time_limit = data.time_limit
|
||||||
problem.memory_limit = data.memory_limit
|
problem.value.memory_limit = data.memory_limit
|
||||||
problem.memory_limit = data.memory_limit
|
problem.value.memory_limit = data.memory_limit
|
||||||
problem.difficulty = data.difficulty
|
problem.value.difficulty = data.difficulty
|
||||||
problem.visible = data.visible
|
problem.value.visible = data.visible
|
||||||
problem.share_submission = data.share_submission
|
problem.value.share_submission = data.share_submission
|
||||||
problem.tags = data.tags
|
problem.value.tags = data.tags
|
||||||
problem.languages = data.languages
|
problem.value.languages = data.languages
|
||||||
problem.template = data.template
|
problem.value.template = data.template
|
||||||
problem.samples = data.samples
|
problem.value.samples = data.samples
|
||||||
problem.samples = data.samples
|
problem.value.samples = data.samples
|
||||||
problem.spj = data.spj
|
problem.value.spj = data.spj
|
||||||
problem.spj_language = data.spj_language
|
problem.value.spj_language = data.spj_language
|
||||||
problem.spj_code = data.spj_code
|
problem.value.spj_code = data.spj_code
|
||||||
problem.spj_compile_ok = data.spj_compile_ok
|
problem.value.spj_compile_ok = data.spj_compile_ok
|
||||||
problem.test_case_id = data.test_case_id
|
problem.value.test_case_id = data.test_case_id
|
||||||
problem.test_case_score = data.test_case_score
|
problem.value.test_case_score = data.test_case_score
|
||||||
problem.rule_type = data.rule_type
|
problem.value.rule_type = data.rule_type
|
||||||
problem.hint = data.hint
|
problem.value.hint = data.hint
|
||||||
problem.source = data.source
|
problem.value.source = data.source
|
||||||
problem.io_mode = data.io_mode
|
problem.value.io_mode = data.io_mode
|
||||||
if (problem.contest_id) {
|
if (problem.value.contest_id) {
|
||||||
problem.contest_id = problem.contest_id
|
problem.value.contest_id = problem.value.contest_id
|
||||||
}
|
}
|
||||||
|
|
||||||
// 下面是用来显示的:
|
// 下面是用来显示的:
|
||||||
// 代码模板 和 模板开关
|
// 代码模板 和 模板开关
|
||||||
problem.languages.forEach((lang) => {
|
problem.value.languages.forEach((lang) => {
|
||||||
if (data.template[lang]) {
|
if (data.template[lang]) {
|
||||||
template[lang] = data.template[lang]
|
template[lang] = data.template[lang]
|
||||||
toggleNeedTemplate(true)
|
toggleNeedTemplate(true)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// 标签
|
// 标签
|
||||||
fromExistingTags.value = data.tags
|
tags.value.select = data.tags
|
||||||
}
|
}
|
||||||
|
|
||||||
async function listTags() {
|
async function getTagList() {
|
||||||
const res = await getProblemTagList()
|
const res = await getProblemTagList()
|
||||||
existingTags.value = res.data
|
tagList.value = res.data
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateNewTags(v: string[]) {
|
function updateNewTags(v: string[]) {
|
||||||
const blanks = []
|
const blanks = []
|
||||||
const uniqueTags = unique(v)
|
const uniqueTags = unique(v)
|
||||||
const tags = existingTags.value.map((t) => t.name)
|
const items = tagList.value.map((t) => t.name)
|
||||||
for (let i = 0; i < uniqueTags.length; i++) {
|
for (let i = 0; i < uniqueTags.length; i++) {
|
||||||
const tag = uniqueTags[i]
|
const tag = uniqueTags[i]
|
||||||
if (tags.indexOf(tag) < 0) {
|
if (items.indexOf(tag) < 0) {
|
||||||
blanks.push(tag)
|
blanks.push(tag)
|
||||||
} else {
|
} else {
|
||||||
message.error("已经存在标签:" + tag)
|
message.error("已经存在标签:" + tag)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newTags.value = blanks
|
tags.value.upload = blanks
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSample() {
|
function addSample() {
|
||||||
problem.samples.push({ input: "", output: "" })
|
problem.value.samples.push({ input: "", output: "" })
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeSample(index: number) {
|
function removeSample(index: number) {
|
||||||
problem.samples.splice(index, 1)
|
problem.value.samples.splice(index, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetTemplate(language: LANGUAGE) {
|
function resetTemplate(language: LANGUAGE) {
|
||||||
@@ -182,7 +196,7 @@ function resetTemplate(language: LANGUAGE) {
|
|||||||
async function handleUploadTestcases({ file }: UploadCustomRequestOptions) {
|
async function handleUploadTestcases({ file }: UploadCustomRequestOptions) {
|
||||||
try {
|
try {
|
||||||
const res = await uploadTestcases(file.file!)
|
const res = await uploadTestcases(file.file!)
|
||||||
// @ts-ignore:
|
// @ts-ignore
|
||||||
if (res.error) {
|
if (res.error) {
|
||||||
message.error("上传测试用例失败")
|
message.error("上传测试用例失败")
|
||||||
return
|
return
|
||||||
@@ -190,51 +204,51 @@ async function handleUploadTestcases({ file }: UploadCustomRequestOptions) {
|
|||||||
const testcases = res.data.info
|
const testcases = res.data.info
|
||||||
for (let file of testcases) {
|
for (let file of testcases) {
|
||||||
file.score = (100 / testcases.length).toFixed(0)
|
file.score = (100 / testcases.length).toFixed(0)
|
||||||
if (!file.output_name && problem.spj) {
|
if (!file.output_name && problem.value.spj) {
|
||||||
file.output_name = "-"
|
file.output_name = "-"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
problem.test_case_score = testcases
|
problem.value.test_case_score = testcases
|
||||||
problem.test_case_id = res.data.id
|
problem.value.test_case_id = res.data.id
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
message.error("上传测试用例失败")
|
message.error("上传测试用例失败")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function downloadTestcases() {
|
function downloadTestcases() {
|
||||||
download("test_case?problem_id=" + problem.id)
|
download("test_case?problem_id=" + problem.value.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 题目是否有漏写的
|
// 题目是否有漏写的
|
||||||
function detectProblemCompletion() {
|
function detectProblemCompletion() {
|
||||||
let flag = false
|
let flag = false
|
||||||
// 标题
|
// 标题
|
||||||
if (!problem._id || !problem.title) {
|
if (!problem.value._id || !problem.value.title) {
|
||||||
message.error("编号或标题没有填写")
|
message.error("编号或标题没有填写")
|
||||||
flag = true
|
flag = true
|
||||||
}
|
}
|
||||||
// 标签
|
// 标签
|
||||||
else if (newTags.value.length === 0 && fromExistingTags.value.length === 0) {
|
else if (tags.value.upload.length === 0 && tags.value.select.length === 0) {
|
||||||
message.error("标签没有填写")
|
message.error("标签没有填写")
|
||||||
flag = true
|
flag = true
|
||||||
}
|
}
|
||||||
// 题目
|
// 题目
|
||||||
else if (
|
else if (
|
||||||
!problem.description ||
|
!problem.value.description ||
|
||||||
!problem.input_description ||
|
!problem.value.input_description ||
|
||||||
!problem.output_description
|
!problem.value.output_description
|
||||||
) {
|
) {
|
||||||
message.error("题目或输入或输出没有填写")
|
message.error("题目或输入或输出没有填写")
|
||||||
flag = true
|
flag = true
|
||||||
}
|
}
|
||||||
// 样例
|
// 样例
|
||||||
else if (problem.samples.length == 0) {
|
else if (problem.value.samples.length == 0) {
|
||||||
message.error("样例没有填写")
|
message.error("样例没有填写")
|
||||||
flag = true
|
flag = true
|
||||||
}
|
}
|
||||||
// 样例是空的
|
// 样例是空的
|
||||||
else if (
|
else if (
|
||||||
problem.samples.some(
|
problem.value.samples.some(
|
||||||
(sample) => sample.output === "" || sample.input === "",
|
(sample) => sample.output === "" || sample.input === "",
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
@@ -242,10 +256,10 @@ function detectProblemCompletion() {
|
|||||||
flag = true
|
flag = true
|
||||||
}
|
}
|
||||||
// 测试用例
|
// 测试用例
|
||||||
else if (problem.test_case_score.length === 0) {
|
else if (problem.value.test_case_score.length === 0) {
|
||||||
message.error("测试用例没有上传")
|
message.error("测试用例没有上传")
|
||||||
flag = true
|
flag = true
|
||||||
} else if (problem.languages.length === 0) {
|
} else if (problem.value.languages.length === 0) {
|
||||||
message.error("编程语言没有选择")
|
message.error("编程语言没有选择")
|
||||||
flag = true
|
flag = true
|
||||||
}
|
}
|
||||||
@@ -258,13 +272,13 @@ function detectProblemCompletion() {
|
|||||||
|
|
||||||
function getTemplate() {
|
function getTemplate() {
|
||||||
if (!needTemplate.value) {
|
if (!needTemplate.value) {
|
||||||
problem.template = {}
|
problem.value.template = {}
|
||||||
} else {
|
} else {
|
||||||
problem.languages.forEach((lang) => {
|
problem.value.languages.forEach((lang) => {
|
||||||
if (CODE_TEMPLATES[lang] !== template[lang]) {
|
if (CODE_TEMPLATES[lang] !== template[lang]) {
|
||||||
problem.template[lang] = template[lang]
|
problem.value.template[lang] = template[lang]
|
||||||
} else {
|
} else {
|
||||||
delete problem.template[lang]
|
delete problem.value.template[lang]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -272,8 +286,8 @@ function getTemplate() {
|
|||||||
|
|
||||||
function filterHint() {
|
function filterHint() {
|
||||||
// 编辑器会自动添加一段 HTML
|
// 编辑器会自动添加一段 HTML
|
||||||
if (problem.hint === "<p><br></p>") {
|
if (problem.value.hint === "<p><br></p>") {
|
||||||
problem.hint = ""
|
problem.value.hint = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +296,6 @@ async function submit() {
|
|||||||
if (notCompleted) return
|
if (notCompleted) return
|
||||||
filterHint()
|
filterHint()
|
||||||
getTemplate()
|
getTemplate()
|
||||||
problem.tags = [...newTags.value, ...fromExistingTags.value]
|
|
||||||
const api = {
|
const api = {
|
||||||
"admin problem create": createProblem,
|
"admin problem create": createProblem,
|
||||||
"admin problem edit": editProblem,
|
"admin problem edit": editProblem,
|
||||||
@@ -293,10 +306,12 @@ async function submit() {
|
|||||||
route.name === "admin contest problem create" ||
|
route.name === "admin contest problem create" ||
|
||||||
route.name === "admin contest problem edit"
|
route.name === "admin contest problem edit"
|
||||||
) {
|
) {
|
||||||
problem.contest_id = props.contestID
|
problem.value.contest_id = props.contestID
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await api!(problem)
|
await api!(problem.value)
|
||||||
|
problem.value = null
|
||||||
|
tags.value = null
|
||||||
if (
|
if (
|
||||||
route.name === "admin problem create" ||
|
route.name === "admin problem create" ||
|
||||||
route.name === "admin contest problem create"
|
route.name === "admin contest problem create"
|
||||||
@@ -323,19 +338,38 @@ async function submit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const showClear = computed(
|
||||||
|
() =>
|
||||||
|
route.name === "admin problem create" ||
|
||||||
|
route.name === "admin contest problem create",
|
||||||
|
)
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
problem.value = null
|
||||||
|
tags.value = null
|
||||||
|
// TODO: 这里是 TextEditor 不更新,所以刷一下页面
|
||||||
|
location.reload()
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
listTags()
|
getTagList()
|
||||||
getProblemDetail()
|
getProblemDetail()
|
||||||
})
|
})
|
||||||
|
|
||||||
watch([fromExistingTags, newTags], (tags) => {
|
watch(
|
||||||
const uniqueTags = unique<string>(tags[0].concat(tags[1]))
|
() => [tags.value.select, tags.value.upload],
|
||||||
problem.tags = uniqueTags
|
(tags) => {
|
||||||
})
|
const uniqueTags = unique<string>(tags[0].concat(tags[1]))
|
||||||
|
problem.value.tags = uniqueTags
|
||||||
|
},
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<h2 class="title">{{ title }}</h2>
|
<n-flex>
|
||||||
|
<h2 class="title">{{ title }}</h2>
|
||||||
|
<n-button v-if="showClear" @click="clear">清空缓存</n-button>
|
||||||
|
</n-flex>
|
||||||
<n-form inline label-placement="left">
|
<n-form inline label-placement="left">
|
||||||
<n-form-item label="显示编号">
|
<n-form-item label="显示编号">
|
||||||
<n-input class="w-100" v-model:value="problem._id" />
|
<n-input class="w-100" v-model:value="problem._id" />
|
||||||
@@ -359,12 +393,15 @@ watch([fromExistingTags, newTags], (tags) => {
|
|||||||
<n-select
|
<n-select
|
||||||
class="tag"
|
class="tag"
|
||||||
multiple
|
multiple
|
||||||
v-model:value="fromExistingTags"
|
v-model:value="tags.select"
|
||||||
:options="tagOptions"
|
:options="tagOptions"
|
||||||
/>
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="新增的标签">
|
<n-form-item label="新增的标签">
|
||||||
<n-dynamic-tags v-model:value="newTags" @update:value="updateNewTags" />
|
<n-dynamic-tags
|
||||||
|
v-model:value="tags.upload"
|
||||||
|
@update:value="updateNewTags"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-form>
|
</n-form>
|
||||||
<TextEditor
|
<TextEditor
|
||||||
@@ -436,7 +473,7 @@ watch([fromExistingTags, newTags], (tags) => {
|
|||||||
:name="lang"
|
:name="lang"
|
||||||
>
|
>
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
v-model="template[lang]"
|
v-model:value="template[lang]"
|
||||||
:language="lang"
|
:language="lang"
|
||||||
:font-size="16"
|
:font-size="16"
|
||||||
height="200px"
|
height="200px"
|
||||||
@@ -503,7 +540,13 @@ watch([fromExistingTags, newTags], (tags) => {
|
|||||||
</n-button>
|
</n-button>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-form>
|
</n-form>
|
||||||
<n-space>
|
<n-space align="center">
|
||||||
|
<n-tooltip placement="left">
|
||||||
|
<template #trigger>
|
||||||
|
<n-button text>温馨提醒</n-button>
|
||||||
|
</template>
|
||||||
|
【测试用例】最好要有10个,要考虑边界情况,不要跟【测试样例】一模一样
|
||||||
|
</n-tooltip>
|
||||||
<n-upload
|
<n-upload
|
||||||
:show-file-list="false"
|
:show-file-list="false"
|
||||||
accept=".zip"
|
accept=".zip"
|
||||||
@@ -511,7 +554,7 @@ watch([fromExistingTags, newTags], (tags) => {
|
|||||||
>
|
>
|
||||||
<n-button type="info">上传测试用例</n-button>
|
<n-button type="info">上传测试用例</n-button>
|
||||||
</n-upload>
|
</n-upload>
|
||||||
<n-button type="primary" @click="submit">保存</n-button>
|
<n-button type="primary" @click="submit">提交</n-button>
|
||||||
</n-space>
|
</n-space>
|
||||||
</n-space>
|
</n-space>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ const styleTheme = EditorView.baseTheme({
|
|||||||
})
|
})
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: string
|
|
||||||
language?: LANGUAGE
|
language?: LANGUAGE
|
||||||
fontSize?: number
|
fontSize?: number
|
||||||
height?: string
|
height?: string
|
||||||
@@ -36,28 +35,16 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
placeholder: "",
|
placeholder: "",
|
||||||
})
|
})
|
||||||
|
|
||||||
const code = ref(props.modelValue)
|
const code = defineModel<string>("value")
|
||||||
|
|
||||||
const isDark = useDark()
|
const isDark = useDark()
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.modelValue,
|
|
||||||
(v) => {
|
|
||||||
code.value = v
|
|
||||||
},
|
|
||||||
)
|
|
||||||
const emit = defineEmits(["update:modelValue"])
|
|
||||||
|
|
||||||
const lang = computed(() => {
|
const lang = computed(() => {
|
||||||
if (props.language === "Python3" || props.language === "Python2") {
|
if (props.language === "Python3" || props.language === "Python2") {
|
||||||
return python()
|
return python()
|
||||||
}
|
}
|
||||||
return cpp()
|
return cpp()
|
||||||
})
|
})
|
||||||
|
|
||||||
function onChange(v: string) {
|
|
||||||
emit("update:modelValue", v)
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Codemirror
|
<Codemirror
|
||||||
@@ -68,6 +55,5 @@ function onChange(v: string) {
|
|||||||
:tabSize="4"
|
:tabSize="4"
|
||||||
:placeholder="props.placeholder"
|
:placeholder="props.placeholder"
|
||||||
:style="{ height: props.height, fontSize: props.fontSize + 'px' }"
|
:style="{ height: props.height, fontSize: props.fontSize + 'px' }"
|
||||||
@change="onChange"
|
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -5,21 +5,18 @@ import { Editor, Toolbar } from "@wangeditor/editor-for-vue"
|
|||||||
import { uploadImage } from "../../admin/api"
|
import { uploadImage } from "../../admin/api"
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
value: string
|
|
||||||
title: string
|
title: string
|
||||||
minHeight?: number
|
minHeight?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rawHtml = defineModel<string>("value")
|
||||||
type InsertFnType = (url: string, alt: string, href: string) => void
|
type InsertFnType = (url: string, alt: string, href: string) => void
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
minHeight: 0,
|
minHeight: 0,
|
||||||
})
|
})
|
||||||
const emit = defineEmits(["update:value"])
|
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
const rawHtml = ref(props.value)
|
|
||||||
watch(rawHtml, () => emit("update:value", rawHtml.value))
|
|
||||||
|
|
||||||
const editorRef = shallowRef<IDomEditor>()
|
const editorRef = shallowRef<IDomEditor>()
|
||||||
|
|
||||||
|
|||||||
@@ -121,6 +121,8 @@ export const PROBLEM_PERMISSION = {
|
|||||||
export const STORAGE_KEY = {
|
export const STORAGE_KEY = {
|
||||||
AUTHED: "authed",
|
AUTHED: "authed",
|
||||||
LANGUAGE: "problemLanguage",
|
LANGUAGE: "problemLanguage",
|
||||||
|
ADMIN_PROBLEM: "adminProblem",
|
||||||
|
ADMIN_PROBLEM_TAGS: "adminProblemTags",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DIFFICULTY = {
|
export const DIFFICULTY = {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import Components from "unplugin-vue-components/vite"
|
|||||||
import { NaiveUiResolver } from "unplugin-vue-components/resolvers"
|
import { NaiveUiResolver } from "unplugin-vue-components/resolvers"
|
||||||
|
|
||||||
const dev = process.env.NODE_ENV === "development"
|
const dev = process.env.NODE_ENV === "development"
|
||||||
const url = dev ? "http://localhost:8080" : "https://oj.xuyue.cc"
|
const url = dev ? "https://ojtest.xuyue.cc" : "https://oj.xuyue.cc"
|
||||||
const proxyConfig = {
|
const proxyConfig = {
|
||||||
target: url,
|
target: url,
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user