BlockRenderer.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. <template>
  2. <!-- markdown 正文 -->
  3. <MarkdownBlock v-if="block.kind === 'markdown'" :text="block.text" :streaming="streaming" />
  4. <!-- 普通代码块 -->
  5. <CodeBlock v-else-if="block.kind === 'code'" :text="block.text" :lang="block.lang" :pending="block.pending" />
  6. <!-- HTML 渲染 -->
  7. <HtmlBlock v-else-if="block.kind === 'html'" :html="block.text" :pending="block.pending" />
  8. <!-- ECharts 图表 -->
  9. <EChartsBlock
  10. v-else-if="block.kind === 'echarts'"
  11. :option="block.data"
  12. :pending="block.pending"
  13. :error="block.error"
  14. />
  15. <!--
  16. 关系图谱不再渲染模型输出的 ```graph 围栏。
  17. 图谱必须来自 get_case_graph 的后端全量 graph_data,挂在对应工具调用下面;
  18. 模型生成的图数据不是原始接口数据,可能丢关系/连错端点,统一忽略。
  19. -->
  20. <div v-else-if="block.kind === 'graph'" class="ai-graph-ignored">
  21. 该历史图谱来自模型输出,已停用;请重新查询关系图谱以使用后端原始数据。
  22. </div>
  23. <!-- AI 研判结构化产物(```insight 围栏) -->
  24. <InsightBlock
  25. v-else-if="block.kind === 'insight'"
  26. :data="block.data"
  27. :text="block.text"
  28. :pending="block.pending"
  29. :error="block.error"
  30. />
  31. <!-- 兜底:未知块按纯文本输出,避免内容丢失 -->
  32. <CodeBlock v-else :text="block.text" :lang="block.lang" />
  33. </template>
  34. <script lang="ts" setup>
  35. /**
  36. * 富内容块渲染分发器
  37. *
  38. * 输入是 scanner 解析出的 ContentBlock,按 kind 分发到具体块组件。
  39. * 每种块独立成组件,便于单独演进。
  40. */
  41. import type { ContentBlock } from '../utils/scanner';
  42. import MarkdownBlock from './blocks/MarkdownBlock.vue';
  43. import CodeBlock from './blocks/CodeBlock.vue';
  44. import HtmlBlock from './blocks/HtmlBlock.vue';
  45. import EChartsBlock from './blocks/EChartsBlock.vue';
  46. import InsightBlock from './blocks/InsightBlock.vue';
  47. withDefaults(
  48. defineProps<{
  49. block: ContentBlock;
  50. /** 所属消息是否仍在流式输出 */
  51. streaming?: boolean;
  52. }>(),
  53. { streaming: false },
  54. );
  55. </script>
  56. <style lang="less" scoped>
  57. .ai-graph-ignored {
  58. margin: var(--ai-sp-2) 0;
  59. padding: 8px 10px;
  60. font-size: 12px;
  61. color: var(--ai-text-2);
  62. background: var(--ai-bg-subtle, #f7f8fa);
  63. border: 1px dashed var(--ai-border, #e5e7eb);
  64. border-radius: 6px;
  65. }
  66. </style>