documentComponent.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <template>
  2. <div class="document-container" v-if="fileList.length === 0">
  3. <n-upload action="/api/system/user/edit/avatar" :max=1 directory-dnd :default-file-list="fileList"
  4. :headers="headers" @finish="handleFinish">
  5. <n-upload-dragger>
  6. <div class="document-container-img">
  7. <img src="@/assets/fileType.png" alt="">
  8. </div>
  9. <div>
  10. <n-p depth="3" style="margin: 8px 0 0 0">
  11. 点击或拖拽上传,即享翻译与AI问答
  12. </n-p>
  13. </div>
  14. <n-p depth="3" style="margin: 8px 0 0 0">支持 pdf, word, ppt, xls,txt,epub,srt,xml 多种格式文档</n-p>
  15. </n-upload-dragger>
  16. </n-upload>
  17. </div>
  18. <div class="document-containers" v-else>
  19. <div class="name-fileList">
  20. <div v-for="item in 2" class="file-item" :class="{ 'file-item-selected': selectedFileId === item }"
  21. @click="selectedFileId = item" :key="item">
  22. <p class="file-name">文件名称{{ item }}</p>
  23. <p class="file-id">时间:2025/1/9</p>
  24. </div>
  25. </div>
  26. <div class="name-content">
  27. <div :style="{ borderRight: aiAnswer ? '1px dashed #ccc' : 'none' }">
  28. <vue-office-pdf :src="pdf" style="height: calc(100vh - 120px)" @rendered="rendered" />
  29. </div>
  30. <div v-if="aiAnswer">2</div>
  31. </div>
  32. <div class="name-button">
  33. <n-button strong secondary round type="success" style="margin-bottom: 10px;"
  34. @click="aiAnswer = !aiAnswer">AI问答</n-button>
  35. <n-button strong secondary round type="success">下载文档</n-button>
  36. </div>
  37. </div>
  38. </template>
  39. <script setup lang="ts">
  40. import { ref } from 'vue'
  41. import { NUpload, UploadFileInfo, useMessage, NUploadDragger, NP, NButton } from 'naive-ui'
  42. import { getToken } from '@/store/modules/auth/helper'
  43. import VueOfficePdf from '@vue-office/pdf'
  44. const message = useMessage()
  45. const token = getToken()
  46. const headers = {
  47. Authorization: `Bearer ${token}`
  48. }
  49. let aiAnswer = ref(false)
  50. let pdf = ref('http://static.shanhuxueyuan.com/test.pdf')
  51. const selectedFileId = ref<number | null>(1)
  52. function rendered(e: any) {
  53. console.log(e)
  54. }
  55. let fileList = ref<UploadFileInfo[]>([
  56. {
  57. id: 'avatar',
  58. name: '头像预览',
  59. status: 'finished',
  60. url: 'http://panda-1253683406.cos.ap-guangzhou.myqcloud.com/panda/2024/01/03/0e3600b455914b0dade9943f281be19b.png'
  61. },
  62. ])
  63. function handleFinish({
  64. event
  65. }: {
  66. file: UploadFileInfo
  67. event?: ProgressEvent
  68. }) {
  69. const ext = (event?.target as XMLHttpRequest).response
  70. let file = {
  71. id: 'avatar',
  72. name: '头像预览',
  73. status: 'finished',
  74. url: ext
  75. }
  76. fileList.value.push(file as UploadFileInfo)
  77. message.success('上传成功!')
  78. }
  79. </script>
  80. <style scoped lang="less">
  81. .document-container {
  82. height: calc(100vh - 100px);
  83. .document-container-img {
  84. display: flex;
  85. justify-content: center;
  86. align-items: center;
  87. height: auto;
  88. width: 300px;
  89. margin: 0 auto;
  90. }
  91. }
  92. .document-containers {
  93. height: calc(100vh - 100px);
  94. display: flex;
  95. justify-content: space-between;
  96. border: 1px solid #ccc;
  97. border-radius: 10px;
  98. div {
  99. padding: 10px;
  100. }
  101. .name-fileList {
  102. width: 300px;
  103. height: 100%;
  104. border-right: 1px solid #ccc;
  105. .file-item {
  106. border: 1px solid #ccc;
  107. margin-bottom: 10px;
  108. border-radius: 10px;
  109. cursor: pointer;
  110. }
  111. .file-item:hover {
  112. background-color: #19bdee;
  113. }
  114. .file-item-selected {
  115. background-color: #19bdee;
  116. color: white;
  117. }
  118. }
  119. .name-content {
  120. width: 100%;
  121. height: 100%;
  122. display: flex;
  123. justify-content: space-between;
  124. div:nth-child(1) {
  125. flex: 1;
  126. padding: 0;
  127. }
  128. div:nth-child(2) {
  129. flex: 1;
  130. padding: 0 0 0 10px;
  131. border-left: 1px dashed #ccc;
  132. }
  133. }
  134. .name-button {
  135. width: 150px;
  136. height: 100%;
  137. border-left: 1px solid #ccc;
  138. }
  139. }
  140. </style>