filePreview.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <template>
  2. <div>
  3. <van-field class="preview">
  4. <template #input>
  5. <div
  6. class="preview_file"
  7. v-for="(item, index) in dataModel"
  8. :key="index"
  9. >
  10. <div class="preview_item">
  11. <i
  12. class="van-icon van-icon-description van-uploader__file-icon"
  13. ></i>
  14. <span
  15. style="
  16. white-space: nowrap;
  17. overflow: hidden;
  18. text-overflow: ellipsis;
  19. width: 1.8rem;
  20. "
  21. >{{ item.name || item.url }}</span
  22. >
  23. </div>
  24. <div class="preview_btn">
  25. <!-- <van-button @click="downLoadFile2(item.url)" type="info" size="mini"
  26. >下载</van-button
  27. > -->
  28. <van-button
  29. :disabled="!checkFileSuffix(item.url)"
  30. v-if="checkFileSuffix(item.url)"
  31. @click="downLoadFile(item.url)"
  32. type="info"
  33. size="mini"
  34. >预览</van-button
  35. >
  36. </div>
  37. </div>
  38. </template>
  39. </van-field>
  40. <van-popup position="bottom" v-model="filePreview" style="height: 100%">
  41. <van-sticky>
  42. <m-header
  43. :backUrl="backUrl"
  44. :isFixed="false"
  45. :appHide="true"
  46. name="预览"
  47. />
  48. </van-sticky>
  49. <div
  50. id="previewIframe"
  51. style="height: calc(100vh - 0.44rem)"
  52. v-if="filePreview && (fileType == 'xls' || fileType == 'pdf')"
  53. ></div>
  54. <div
  55. style="height: calc(100vh - 0.44rem)"
  56. v-if="filePreview && fileType == 'doc'"
  57. ></div>
  58. </van-popup>
  59. </div>
  60. </template>
  61. <script>
  62. import MHeader from "@/components/header";
  63. import { browser } from "@/common/util";
  64. import { postMessage } from "@/helpers/native-message";
  65. export default {
  66. props: ["dataModel"],
  67. components: { MHeader },
  68. data() {
  69. return {
  70. filePreview: false,
  71. fileType: "xls",
  72. previewUrl: "",
  73. backUrl: {
  74. status: true,
  75. callBack: () => {
  76. this.filePreview = false;
  77. },
  78. },
  79. };
  80. },
  81. mounted() {
  82. console.log(this.dataModel);
  83. },
  84. methods: {
  85. checkFileSuffix(url) {
  86. let urlArr = url.split(".");
  87. let suffix = urlArr[urlArr.length - 1];
  88. // || suffix == 'doc' || suffix == 'docx'
  89. if (suffix == "xlsx" || suffix == "xls" || suffix == "pdf") {
  90. return true;
  91. } else {
  92. return false;
  93. }
  94. },
  95. getFileSuffix(url) {
  96. let urlArr = url.split(".");
  97. let suffix = urlArr[urlArr.length - 1];
  98. if (suffix == "xlsx" || suffix == "xls") {
  99. return "xls";
  100. } else if (suffix == "doc" || suffix == "docx") {
  101. return "doc";
  102. } else if (suffix == "pdf") {
  103. return "pdf";
  104. } else {
  105. return "";
  106. }
  107. },
  108. downLoadFile2(file) {
  109. this.$toast.loading({
  110. duration: 0, // 持续展示 toast
  111. forbidClick: true,
  112. message: "下载中...",
  113. });
  114. if (browser().isApp) {
  115. this.$toast.clear();
  116. postMessage(
  117. { api: "downloadFile", content: { downloadUrl: file } },
  118. () => {
  119. this.$toast.clear();
  120. }
  121. );
  122. } else {
  123. this.$toast.clear();
  124. window.location.href = file;
  125. }
  126. },
  127. downLoadFile(file) {
  128. // this.previewUrl = 'https://view.officeapps.live.com/op/view.aspx?src=' + file
  129. this.filePreview = true;
  130. this.fileType = this.getFileSuffix(file);
  131. if (this.fileType == "xls" || this.fileType == "pdf") {
  132. this.$toast.loading({
  133. duration: 0, // 持续展示 toast
  134. forbidClick: true,
  135. message: "加载中...",
  136. });
  137. let _this = this;
  138. this.$nextTick(() => {
  139. let iframe = document.createElement("iframe");
  140. iframe.id = "preview_iframe";
  141. iframe.style.width = "100%";
  142. iframe.style.height = "100%";
  143. iframe.style.border = "none";
  144. if (this.fileType == "xls") {
  145. if (browser().android) {
  146. iframe.src =
  147. "https://api.idocv.com/view/url?url=" +
  148. encodeURIComponent(file + "?times=" + new Date().getTime());
  149. } else {
  150. iframe.src =
  151. "https://view.officeapps.live.com/op/view.aspx?src=" + file;
  152. }
  153. } else {
  154. iframe.src =
  155. window.location.origin +
  156. "/pdf/web/viewer.html?file=" +
  157. encodeURIComponent(file);
  158. }
  159. if (iframe.attachEvent) {
  160. iframe.attachEvent("onload", function () {
  161. _this.$toast.clear();
  162. });
  163. } else {
  164. iframe.onload = function () {
  165. _this.$toast.clear();
  166. // setTimeout(() => {
  167. // let dom = document.querySelector('#preview_iframe').contentWindow.document
  168. // let scripts = dom.querySelectorAll('script[src]')
  169. // if(scripts)
  170. // }, 2000);
  171. };
  172. }
  173. document.querySelector("#previewIframe").appendChild(iframe);
  174. });
  175. } else if (this.fileType == "doc") {
  176. // // this.previewUrl = 'https://view.officeapps.live.com/op/view.aspx?src=' + file
  177. }
  178. },
  179. },
  180. };
  181. </script>
  182. <style lang="less" scoped>
  183. .preview {
  184. padding: 0;
  185. /deep/.van-field__control {
  186. display: flex;
  187. flex-direction: column;
  188. }
  189. }
  190. .preview_file {
  191. width: 100%;
  192. font-size: 14px;
  193. display: flex;
  194. justify-content: space-between;
  195. background: #f7f7f7;
  196. padding: 0.08rem;
  197. margin-bottom: 0.08rem;
  198. box-sizing: border-box;
  199. .preview_item {
  200. display: flex;
  201. align-items: center;
  202. flex-basis: 70%;
  203. }
  204. .preview_btn {
  205. text-align: right;
  206. flex-basis: 30%;
  207. }
  208. }
  209. </style>