index.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. <template>
  2. <div class="container_all">
  3. <div class="container_public" :style="{ transform: `scale(${scale})` }">
  4. <div v-for="pageNumber in loadedPages" :key="pageNumber">
  5. <vue-pdf
  6. v-if="pageNumber < 3"
  7. class="container_pdf"
  8. :src="fileUrl"
  9. :page="pageNumber"
  10. @page-loaded="onPageLoaded"
  11. ></vue-pdf>
  12. <vue-pdf
  13. v-else
  14. class="container_pdf"
  15. :src="{
  16. url: fileUrl,
  17. cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.9.359/cmaps/',
  18. cMapPacked: true,
  19. }"
  20. :page="pageNumber"
  21. @page-loaded="onPageLoaded"
  22. ></vue-pdf>
  23. </div>
  24. </div>
  25. <img
  26. v-if="loadAll"
  27. src="../../static/explain/down_up.png"
  28. class="absolute_image1"
  29. @click="download"
  30. />
  31. <!-- <img
  32. v-if="loadAll"
  33. src="../../static/explain/scale_in.png"
  34. class="absolute_image2"
  35. @click="scaleIn"
  36. />
  37. <img
  38. v-if="loadAll"
  39. src="../../static/explain/scale_out.png"
  40. class="absolute_image3"
  41. @click="scaleOut"
  42. /> -->
  43. </div>
  44. </template>
  45. <script>
  46. import { detail } from "@/api/explain.js";
  47. import VuePdf from "vue-pdf";
  48. export default {
  49. components: {
  50. VuePdf,
  51. },
  52. data() {
  53. return {
  54. loadAll: false,
  55. name: "",
  56. fileUrl: "",
  57. fileName: "",
  58. currentPage: 1,
  59. numPages: 0,
  60. scale: 1,
  61. loadedPages: 1,
  62. };
  63. },
  64. onLoad(e) {
  65. var that = this;
  66. that.id = e.id;
  67. that.getDetail();
  68. },
  69. methods: {
  70. // 滚动加载逻辑
  71. // {"type":"scroll","timeStamp":24324.79999999702,"detail":{},
  72. // "target":{"id":"","offsetLeft":0,"offsetTop":0,"dataset":{}},
  73. // "currentTarget":{"id":"","offsetLeft":0,"offsetTop":0,"dataset":{}},"touches":[],
  74. // "changedTouches":[],"mp":{"@warning":"mp is deprecated","type":"scroll",
  75. // "timeStamp":24324.79999999702,"detail":{},"target":{"id":"","offsetLeft":0,"offsetTop":0,"dataset":{}},
  76. // "currentTarget":{"id":"","offsetLeft":0,"offsetTop":0,"dataset":{}},"touches":[],"changedTouches":[]},
  77. // "_processed":true}
  78. handleScroll(e) {
  79. // const target = e.target;
  80. // var offsetTop = target.offsetTop;
  81. // // 滚动到底部且未加载完所有页
  82. // if (this.loadedPages < this.numPages) {
  83. // this.loadedPages += 1; // 加载下一页
  84. // }
  85. },
  86. ///接口获取数据
  87. getDetail() {
  88. var that = this;
  89. var id = that.id;
  90. detail(id).then((res) => {
  91. if (res.code === 0) {
  92. that.name = res.data.name;
  93. that.fileUrl = res.data.fileUrl;
  94. that.fileName = that.getFileExtension(that.fileUrl);
  95. that.getPdfPages();
  96. }
  97. });
  98. },
  99. async getPdfPages() {
  100. var that = this;
  101. const loadingTask = VuePdf.createLoadingTask(that.fileUrl);
  102. const pdf = await loadingTask.promise;
  103. this.numPages = pdf.numPages;
  104. // this.loadedPages = this.numPages;
  105. if (this.numPages == 0) {
  106. return;
  107. }
  108. this.loadedPages = this.numPages;
  109. // this.loadedPages = this.numPages > 2 ? 2 : this.numPages;
  110. },
  111. ///截取文件
  112. getFileExtension(fileUrl) {
  113. var filename = fileUrl.split("/").pop();
  114. var lastDotIndex = filename.lastIndexOf(".");
  115. if (lastDotIndex === -1 || lastDotIndex === filename.length - 1) {
  116. return "";
  117. } else {
  118. return filename.substring(lastDotIndex + 1).toLowerCase();
  119. }
  120. },
  121. prevPage() {
  122. if (this.currentPage > 1) {
  123. this.currentPage--;
  124. }
  125. },
  126. nextPage() {
  127. if (this.currentPage < this.numPages) {
  128. this.currentPage++;
  129. }
  130. },
  131. scaleIn() {
  132. this.scale *= 1.1;
  133. },
  134. scaleOut() {
  135. this.scale /= 1.1;
  136. },
  137. onPageLoaded(page) {
  138. if (this.numPages > 0) {
  139. if (!this.loadAll) {
  140. this.loadAll = true;
  141. }
  142. var p = this.loadedPages;
  143. if (p < this.numPages) {
  144. this.loadedPages = p + 1;
  145. }
  146. }
  147. },
  148. async download() {
  149. var that = this;
  150. var name = that.name;
  151. var fileUrl = that.fileUrl;
  152. var fileName = that.fileName;
  153. var finalName = "";
  154. if (name != null && name != "") {
  155. finalName = name + "." + fileName;
  156. } else {
  157. finalName = new Date().getTime() + "." + fileName;
  158. }
  159. try {
  160. // https://music-play.oss-cn-shenzhen.aliyuncs.com/backOss/file/f5f5ed93fae74fb683e8d116c40a884c.xlsx
  161. const response = await fetch(fileUrl);
  162. if (!response.ok) {
  163. throw new Error(`HTTP error! status: ${response.status}`);
  164. }
  165. const blob = await response.blob();
  166. const url = window.URL.createObjectURL(blob);
  167. const a = document.createElement("a");
  168. a.style.display = "none";
  169. a.href = url;
  170. a.download = finalName;
  171. document.body.appendChild(a);
  172. a.click();
  173. window.URL.revokeObjectURL(url);
  174. } catch (error) {}
  175. },
  176. },
  177. };
  178. </script>
  179. <style scoped>
  180. .container_all {
  181. width: 100vw;
  182. height: 100vh;
  183. }
  184. .container_public {
  185. width: 100vw;
  186. height: 100vh;
  187. overflow-y: auto;
  188. }
  189. .container_pdf {
  190. width: calc(100vw-2px);
  191. margin: 10px auto;
  192. border: 1px solid #e5e5e5;
  193. box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  194. }
  195. .absolute_image1 {
  196. position: fixed;
  197. bottom: 365px;
  198. right: 20px;
  199. width: 30px;
  200. height: 30px;
  201. padding: 5px 5px;
  202. background-color: white;
  203. color: white;
  204. border: none;
  205. border-radius: 5px;
  206. cursor: pointer;
  207. }
  208. .absolute_image2 {
  209. position: fixed;
  210. bottom: 305px;
  211. right: 20px;
  212. width: 30px;
  213. height: 30px;
  214. padding: 5px 5px;
  215. background-color: white;
  216. color: white;
  217. border: none;
  218. border-radius: 5px;
  219. cursor: pointer;
  220. }
  221. .absolute_image3 {
  222. position: fixed;
  223. bottom: 260px;
  224. right: 20px;
  225. width: 30px;
  226. height: 30px;
  227. padding: 5px 5px;
  228. background-color: white;
  229. color: white;
  230. border: none;
  231. border-radius: 5px;
  232. cursor: pointer;
  233. }
  234. </style>