DialogCard.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <template>
  2. <div class="dialog-card-container">
  3. <!-- 普通对话类型 -->
  4. <DigitalDialogue
  5. v-if="dialogue?.type === 'digital'"
  6. :role-name="dialogue?.roleName"
  7. :content="dialogue?.content"
  8. :script-roles="scriptRoles"
  9. :index="index"
  10. />
  11. <!-- 提问类型(只显示提问内容,不显示用户输入) -->
  12. <QuestDialogue
  13. v-else-if="dialogue?.type === 'quest'"
  14. :role-name="dialogue?.roleName"
  15. :content="dialogue?.content"
  16. :script-roles="scriptRoles"
  17. :index="index"
  18. />
  19. <!-- 用户输入类型(根据上一条问题类型显示不同输入方式) -->
  20. <UserDialogue
  21. v-else-if="dialogue?.type === 'user'"
  22. :question="previousQuest?.content"
  23. :question-type="getQuestionType(previousQuest)"
  24. :options="previousQuest?.options"
  25. @user-input-submit="$emit('user-input-submit', $event)"
  26. @single-choice-submit="$emit('single-choice-submit', $event)"
  27. />
  28. <!-- 视频显示 -->
  29. <VideoDisplay
  30. v-else-if="dialogue?.type === 'video'"
  31. :video-url="dialogue?.videoUrl"
  32. @ended="$emit('video-ended', $event)"
  33. />
  34. <!-- 诗词显示 -->
  35. <PoemDisplay
  36. v-if="poemShow"
  37. :content="poemContent"
  38. />
  39. </div>
  40. </template>
  41. <script setup>
  42. import DigitalDialogue from './dialogType/DigitalDialogue.vue';
  43. import QuestDialogue from './dialogType/QuestDialogue.vue';
  44. import UserDialogue from './dialogType/UserDialogue.vue';
  45. import PoemDisplay from './dialogType/PoemDisplay.vue';
  46. import VideoDisplay from './dialogType/VideoDisplay.vue';
  47. /**
  48. * DialogCard - 统一对话卡片容器
  49. * 根据对话类型渲染不同的子组件
  50. */
  51. /**
  52. * Props 定义
  53. * @prop {Object} dialogue - 当前对话数据
  54. * @prop {Array} scriptRoles - 角色列表
  55. * @prop {Number} index - 对话索引
  56. * @prop {Object} previousQuest - 上一条提问对话
  57. * @prop {Boolean} poemShow - 是否显示诗词
  58. * @prop {String} poemContent - 诗词内容
  59. */
  60. defineProps({
  61. dialogue: {
  62. type: Object,
  63. default: null
  64. },
  65. scriptRoles: {
  66. type: Array,
  67. default: () => []
  68. },
  69. index: {
  70. type: Number,
  71. default: 0
  72. },
  73. previousQuest: {
  74. type: Object,
  75. default: null
  76. },
  77. poemShow: {
  78. type: Boolean,
  79. default: false
  80. },
  81. poemContent: {
  82. type: String,
  83. default: ''
  84. }
  85. });
  86. /**
  87. * Emits 定义
  88. * @event user-input-submit - 用户文本输入提交
  89. * @event single-choice-submit - 单选问题提交
  90. * @event video-ended - 视频播放结束
  91. */
  92. defineEmits(['user-input-submit', 'single-choice-submit', 'video-ended']);
  93. /**
  94. * 获取问题类型
  95. * @param {Object} questDialogue - 提问对话数据
  96. * @returns {String} 问题类型:'singleChoice' | 'AI Q&A'
  97. */
  98. const getQuestionType = (questDialogue) => {
  99. if (!questDialogue) return 'AI Q&A';
  100. if (questDialogue.questionType === 'singleChoice' && questDialogue.options?.length > 0) {
  101. return 'singleChoice';
  102. }
  103. return 'AI Q&A';
  104. };
  105. </script>
  106. <style scoped lang="scss">
  107. .dialog-card-container {
  108. display: flex;
  109. flex-direction: column;
  110. align-items: center;
  111. }
  112. </style>