AResult.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <script setup lang="ts">
  2. import { AResultRecord } from '@/hooks/web/useSSE'
  3. import ResultMessageView from '@/views/OaSystem/aiQA/components/ResultMessageView.vue'
  4. import PDFView from '@/components/PDF/PDFView.vue'
  5. interface AResultProps {
  6. data: AResultRecord
  7. }
  8. const layoutRightRef = inject('layoutRightRef')
  9. onMounted(() => {
  10. console.log('onMounted: ', layoutRightRef.value)
  11. })
  12. const props = defineProps<AResultProps>()
  13. const { data } = toRefs(props)
  14. // 格式化处理pdf文件
  15. const pdfFiles = computed(() => {
  16. return (data?.value?.result?.['0']?.docs ?? [])?.map((text) => {
  17. // 提取索引号(假设索引号是第一个方括号中的数字)
  18. const indexMatch = text.match(/\[\[(\d+)\]\]/)
  19. const index = indexMatch != null ? indexMatch[1] : null
  20. // 提取名称和链接(Markdown格式的链接)
  21. const linkMatch = text.match(/\[(.*?)\]\((.*?)\)/)
  22. const name = linkMatch != null ? `[${linkMatch[1]}]` : null
  23. const link = linkMatch != null ? linkMatch[2] : null
  24. // 提取内容(链接之后的所有文本)
  25. const contentStartIndex = text.indexOf('](') + 2 // 链接结束的位置
  26. let content = text.slice(contentStartIndex).trim()
  27. // 清理内容中的Markdown链接残留(如果有)
  28. content = content.replace(/\]\(.*?\)/g, '').trim()
  29. return {
  30. index,
  31. name,
  32. link,
  33. content
  34. }
  35. })
  36. })
  37. const dialogVisible = ref(false)
  38. const pdfIndex = ref<string>()
  39. const targetViewPdf = computed(
  40. () => pdfFiles.value?.find?.(({ index }) => String(index) === String(pdfIndex.value))
  41. )
  42. const handlePdfView = (fileIndex: string): void => {
  43. if (pdfFiles.value?.some(({ index }) => String(index) === String(fileIndex))) {
  44. pdfIndex.value = fileIndex
  45. dialogVisible.value = true
  46. } else {
  47. console.log('未找到文件')
  48. }
  49. }
  50. const handleClose = (): void => {
  51. pdfIndex.value = undefined
  52. }
  53. </script>
  54. <template>
  55. <div class="a-result-body">
  56. <ResultMessageView
  57. :data="data?.result?.['3']?.choices?.[0]?.delta?.content"
  58. :handlePDFView="handlePdfView"
  59. />
  60. <div class="result-files" v-if="(pdfFiles?.length ?? 0) > 0">
  61. <div class="label">【来源文件】:</div>
  62. <div class="files-container">
  63. <template v-for="file in pdfFiles" :key="file?.index">
  64. <div v-if="file" class="file" @click="handlePdfView(file.index)">
  65. <span>{{ file?.name ?? '' }}</span>
  66. </div>
  67. </template>
  68. </div>
  69. </div>
  70. <!-- PDF预览弹窗 -->
  71. <!-- :append-to="layoutRightRef" 该属性2.4.3开始支持 -->
  72. <el-dialog
  73. class="pdf-view-dialog"
  74. v-model="dialogVisible"
  75. width="80%"
  76. @close="handleClose"
  77. append-to-body
  78. destroy-on-close
  79. >
  80. <template #header>
  81. <div class="pdf-view-header">
  82. <h4 class="title">{{ targetViewPdf?.name ?? '' }}</h4>
  83. <a class="pdf-link" :href="targetViewPdf?.link">
  84. <el-button class="down-load-btn">
  85. <el-icon class="el-icon--left">
  86. <Download />
  87. </el-icon>
  88. 下载
  89. </el-button>
  90. </a>
  91. </div>
  92. </template>
  93. <div class="pdf-view-body">
  94. <PDFView
  95. v-if="targetViewPdf?.link"
  96. :url="targetViewPdf?.link"
  97. :highLightContent="targetViewPdf?.content"
  98. />
  99. </div>
  100. <template #footer></template>
  101. </el-dialog>
  102. </div>
  103. </template>
  104. <style scoped lang="scss">
  105. .a-result-body {
  106. .result-files {
  107. margin-top: 15px;
  108. display: flex;
  109. .label {
  110. margin-top: 10px;
  111. flex-shrink: 0;
  112. }
  113. .files-container {
  114. flex-grow: 1;
  115. .file {
  116. cursor: pointer;
  117. padding: 10px;
  118. color: #666;
  119. margin-bottom: 10px;
  120. background: #f1f9ff;
  121. border-radius: 8px;
  122. &:hover {
  123. text-decoration: underline;
  124. }
  125. }
  126. }
  127. }
  128. }
  129. .pdf-view-body {
  130. width: 100%;
  131. height: 70vh;
  132. overflow-y: auto;
  133. }
  134. .pdf-view-header {
  135. display: flex;
  136. align-items: center;
  137. .down-load-btn {
  138. margin-left: 10px;
  139. }
  140. }
  141. </style>
  142. <style>
  143. .pdf-view-dialog{
  144. margin: calc(50vh - 375px) calc(10% - 92px) calc(50vh - 375px) calc(10% + 92px);
  145. }
  146. </style>