64
src/oj/problem/components/ProblemFlowchart.vue
Normal file
64
src/oj/problem/components/ProblemFlowchart.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<script setup lang="ts">
|
||||
import { useProblemStore } from "oj/store/problem"
|
||||
import { nanoid } from "nanoid"
|
||||
|
||||
const problemStore = useProblemStore()
|
||||
const { problem } = storeToRefs(problemStore)
|
||||
const mermaidContainer = useTemplateRef<HTMLElement>("mermaidContainer")
|
||||
|
||||
// 动态导入 mermaid
|
||||
let mermaid: any = null
|
||||
|
||||
// 动态加载 Mermaid
|
||||
const loadMermaid = async () => {
|
||||
if (!mermaid) {
|
||||
const mermaidModule = await import("mermaid")
|
||||
mermaid = mermaidModule.default
|
||||
mermaid.initialize({
|
||||
startOnLoad: false,
|
||||
securityLevel: "loose",
|
||||
theme: "default",
|
||||
flowchart: {
|
||||
useMaxWidth: true,
|
||||
htmlLabels: true,
|
||||
curve: "basis",
|
||||
},
|
||||
sequence: {
|
||||
useMaxWidth: true,
|
||||
},
|
||||
gantt: {
|
||||
useMaxWidth: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
return mermaid
|
||||
}
|
||||
|
||||
// 初始化Mermaid并渲染
|
||||
onMounted(async () => {
|
||||
// 确保 mermaid 已加载
|
||||
await loadMermaid()
|
||||
|
||||
// 渲染流程图
|
||||
if (mermaidContainer.value && problem.value?.mermaid_code) {
|
||||
const id = `mermaid-${nanoid()}`
|
||||
const { svg } = await mermaid.render(id, problem.value.mermaid_code)
|
||||
mermaidContainer.value.innerHTML = svg
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="mermaidContainer" class="container"></div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-height: 300px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
@@ -26,6 +26,9 @@ const ProblemSubmission = defineAsyncComponent(
|
||||
const ProblemComment = defineAsyncComponent(
|
||||
() => import("./components/ProblemComment.vue"),
|
||||
)
|
||||
const ProblemFlowchart = defineAsyncComponent(
|
||||
() => import("./components/ProblemFlowchart.vue"),
|
||||
)
|
||||
|
||||
interface Props {
|
||||
problemID: string
|
||||
@@ -49,6 +52,9 @@ const { isMobile, isDesktop } = useBreakpoints()
|
||||
|
||||
const tabOptions = computed(() => {
|
||||
const options: string[] = ["content"]
|
||||
if (problem.value?.show_flowchart) {
|
||||
options.push("flowchart")
|
||||
}
|
||||
if (isMobile.value) {
|
||||
options.push("editor")
|
||||
}
|
||||
@@ -115,6 +121,13 @@ watch(isMobile, (value) => {
|
||||
<n-tab-pane name="content" tab="题目描述">
|
||||
<ProblemContent />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane
|
||||
v-if="problem.show_flowchart"
|
||||
name="flowchart"
|
||||
tab="流程图表"
|
||||
>
|
||||
<ProblemFlowchart />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="info" tab="题目统计">
|
||||
<ProblemInfo />
|
||||
</n-tab-pane>
|
||||
@@ -130,7 +143,10 @@ watch(isMobile, (value) => {
|
||||
<n-tab-pane name="content" tab="描述">
|
||||
<ProblemContent />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="editor" tab="编辑">
|
||||
<n-tab-pane v-if="problem.show_flowchart" name="flowchart" tab="流程">
|
||||
<ProblemFlowchart />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="editor" tab="代码">
|
||||
<ProblemEditor v-if="shouldUseProblemEditor" />
|
||||
<ContestEditor v-else />
|
||||
</n-tab-pane>
|
||||
|
||||
Reference in New Issue
Block a user