refactor flowchart
Some checks failed
Deploy / deploy (build, debian, 22, /root/OJDeploy/data/clientnext) (push) Has been cancelled
Deploy / deploy (build:staging, school, 8822, /root/OJ/data/dist) (push) Has been cancelled

This commit is contained in:
2026-04-11 02:14:53 -06:00
parent 8521c67e68
commit 1f18f363eb
5 changed files with 31 additions and 14 deletions

View File

@@ -106,7 +106,7 @@ async function submitFlowchartData(flowchartEditorRef: any) {
// 获取流程图的JSON数据 // 获取流程图的JSON数据
const flowchartData = flowchartEditorRef.value.getFlowchartData() const flowchartData = flowchartEditorRef.value.getFlowchartData()
if (flowchartData.nodes.length === 0 || flowchartData.edges.length === 0) { if (!flowchartData?.nodes?.length || !flowchartData?.edges?.length) {
message.error("流程图节点或边不能为空") message.error("流程图节点或边不能为空")
return return
} }

View File

@@ -11,9 +11,17 @@ export function useMermaidConverter() {
let mermaid = "graph TD\n" let mermaid = "graph TD\n"
// Build safe ID mapping to prevent Mermaid syntax errors from special characters
const idMap = new Map<string, string>()
nodes.forEach((node: any, index: number) => {
idMap.set(node.id, `node_${index}`)
})
const safeId = (id: string) =>
idMap.get(id) || id.replace(/[^a-zA-Z0-9_]/g, "_")
// 处理节点 - 根据原始类型和自定义标签 // 处理节点 - 根据原始类型和自定义标签
nodes.forEach((node: any) => { nodes.forEach((node: any) => {
const nodeId = node.id const nodeId = safeId(node.id)
const label = node.data?.customLabel || node.data?.label || "节点" const label = node.data?.customLabel || node.data?.label || "节点"
const originalType = node.data?.originalType || node.type const originalType = node.data?.originalType || node.type
@@ -50,8 +58,8 @@ export function useMermaidConverter() {
// 处理边 // 处理边
edges.forEach((edge: any) => { edges.forEach((edge: any) => {
const source = edge.source const source = safeId(edge.source)
const target = edge.target const target = safeId(edge.target)
const label = edge.label ?? "" const label = edge.label ?? ""
if (label && label.trim() !== "") { if (label && label.trim() !== "") {
@@ -77,7 +85,7 @@ export function useMermaidConverter() {
// 为节点应用样式 // 为节点应用样式
nodes.forEach((node: any) => { nodes.forEach((node: any) => {
const nodeId = node.id const nodeId = safeId(node.id)
const originalType = node.data?.originalType || node.type const originalType = node.data?.originalType || node.type
switch (originalType) { switch (originalType) {

View File

@@ -114,7 +114,11 @@ const handleClear = () => {
// 键盘事件 // 键盘事件
const handleKeyDown = (event: KeyboardEvent) => { const handleKeyDown = (event: KeyboardEvent) => {
if (event.target instanceof HTMLInputElement) return if (
event.target instanceof HTMLInputElement ||
event.target instanceof HTMLTextAreaElement
)
return
if (event.key === "Delete" || event.key === "Backspace") { if (event.key === "Delete" || event.key === "Backspace") {
deleteSelected() deleteSelected()

View File

@@ -22,7 +22,7 @@ const loadMermaid = async () => {
mermaid = mermaidModule.default mermaid = mermaidModule.default
mermaid.initialize({ mermaid.initialize({
startOnLoad: false, startOnLoad: false,
securityLevel: "loose", securityLevel: "strict",
theme: "default", theme: "default",
}) })
} }
@@ -72,12 +72,17 @@ const renderMermaid = async () => {
const errorMessage = error?.message || "请检查代码语法" const errorMessage = error?.message || "请检查代码语法"
renderSuccess.value = false renderSuccess.value = false
mermaidContainer.value.innerHTML = ` const errorDiv = document.createElement("div")
<div style="color: #ff4d4f; padding: 20px; text-align: center; border: 1px dashed #ff4d4f; border-radius: 4px;"> errorDiv.style.cssText = "color: #ff4d4f; padding: 20px; text-align: center; border: 1px dashed #ff4d4f; border-radius: 4px;"
<p>❌ Mermaid语法错误</p> const titleP = document.createElement("p")
<p style="font-size: 12px; color: #666;">${errorMessage}</p> titleP.textContent = "Mermaid语法错误"
</div> const detailP = document.createElement("p")
` detailP.style.cssText = "font-size: 12px; color: #666;"
detailP.textContent = errorMessage
errorDiv.appendChild(titleP)
errorDiv.appendChild(detailP)
mermaidContainer.value.innerHTML = ""
mermaidContainer.value.appendChild(errorDiv)
} }
} }

View File

@@ -14,7 +14,7 @@ export function useMermaid() {
mermaid = mermaidModule.default mermaid = mermaidModule.default
mermaid.initialize({ mermaid.initialize({
startOnLoad: false, startOnLoad: false,
securityLevel: "loose", securityLevel: "strict",
theme: "default", theme: "default",
}) })
} }