From 2f12c61337f11fc651a31dbb483dda855ce98f2c Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Tue, 2 Sep 2025 14:12:46 +0800 Subject: [PATCH] fix: The form failed to parse when there are labels in the internal data (#3980) --- ui/src/components/markdown/MdRenderer.vue | 70 +++++++++++++++++++--- ui/src/locales/lang/en-US/dynamics-form.ts | 1 + 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/ui/src/components/markdown/MdRenderer.vue b/ui/src/components/markdown/MdRenderer.vue index abf8fb158..be0fc7485 100644 --- a/ui/src/components/markdown/MdRenderer.vue +++ b/ui/src/components/markdown/MdRenderer.vue @@ -12,7 +12,7 @@ :class="sendMessage && type !== 'log' ? 'cursor' : 'disabled'" > - + {{ item.content }} @@ -48,6 +48,7 @@ import HtmlRander from './HtmlRander.vue' import EchartsRander from './EchartsRander.vue' import FormRander from './FormRander.vue' import ReasoningRander from './ReasoningRander.vue' +import { nanoid } from 'nanoid' config({ markdownItConfig(md) { md.renderer.rules.image = (tokens, idx, options, env, self) => { @@ -204,16 +205,68 @@ const split_form_rander = (result: Array) => { return [...x, ...y] }, []) } +function extractFormRanderContent(html: string) { + const results = [] + const startTag = '' + const endTag = '' + let startIndex = html.indexOf(startTag) + + while (startIndex !== -1) { + let endIndex = html.indexOf(endTag, startIndex) + let depth = 1 + let tempIndex = startIndex + startTag.length + + // 查找匹配的结束标签 + while (depth > 0 && tempIndex < html.length) { + const nextStart = html.indexOf(startTag, tempIndex) + const nextEnd = html.indexOf(endTag, tempIndex) + + if (nextStart !== -1 && nextStart < nextEnd) { + depth++ + tempIndex = nextStart + startTag.length + } else if (nextEnd !== -1) { + depth-- + tempIndex = nextEnd + endTag.length + if (depth === 0) { + endIndex = nextEnd + } + } else { + break + } + } + + if (endIndex !== -1) { + // 提取内容(去掉开始和结束标签) + const contentStart = startIndex + startTag.length + const content = html.substring(contentStart, endIndex) + results.push(content) + startIndex = html.indexOf(startTag, endIndex + endTag.length) + } else { + break + } + } + + return results +} +const _split_form_rander = (source: string, form_rander_list: Array) => { + const uuid = nanoid() + if (form_rander_list.length > 0) { + form_rander_list.forEach((item) => { + source = source.replace(`${item}`, uuid) + }) + } + return source + .split(uuid) + .filter((item) => item !== undefined) + .filter((item) => !form_rander_list?.includes(item)) +} const split_form_rander_ = (source: string, type: string) => { - const temp_md_quick_question_list = source.match(/[\d\D]*?<\/form_rander>/g) + const temp_md_quick_question_list = extractFormRanderContent(source) const md_quick_question_list = temp_md_quick_question_list ? temp_md_quick_question_list.filter((i) => i) : [] - const split_quick_question_value = source - .split(/[\d\D]*?<\/form_rander>/g) - .filter((item) => item !== undefined) - .filter((item) => !md_quick_question_list?.includes(item)) + const split_quick_question_value = _split_form_rander(source, md_quick_question_list) const result = Array.from( { length: md_quick_question_list.length + split_quick_question_value.length }, (v, i) => i, @@ -223,12 +276,11 @@ const split_form_rander_ = (source: string, type: string) => { } else { return { type: 'form_rander', - content: md_quick_question_list[Math.floor(index / 2)] - .replace('', '') - .replace('', ''), + content: md_quick_question_list[Math.floor(index / 2)], } } }) + return result } diff --git a/ui/src/locales/lang/en-US/dynamics-form.ts b/ui/src/locales/lang/en-US/dynamics-form.ts index 709eaabbd..d3c611426 100644 --- a/ui/src/locales/lang/en-US/dynamics-form.ts +++ b/ui/src/locales/lang/en-US/dynamics-form.ts @@ -12,6 +12,7 @@ export default { RadioRow: 'Radio Row', UploadInput: 'File upload', TextareaInput: 'Multiline Input', + MultiRow: 'Multi Row', }, default: { label: 'Default',