MUpload.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <template>
  2. <div class="m-upload">
  3. <van-uploader v-if="!cropper" v-model="list" :preview-full-image="false" :preview-image="previewImage" :deletable="deletable" :before-read="beforeRead" :after-read="afterRead" class="muploader" accept="image/*">
  4. <slot name="default"></slot>
  5. </van-uploader>
  6. <div class="mcropper" v-if="cropper">
  7. <div class="mcropperSection" v-if="previewImage">
  8. <van-image v-if="value || defaultImg" fit="cover" position="center" class="uploadImg" :src="value || defaultImg" />
  9. <van-icon v-else name="photograph" size="32" />
  10. </div>
  11. <slot name="default"></slot>
  12. <MCropper v-if="cropper" :option="options" @getFile="getFile" />
  13. </div>
  14. </div>
  15. </template>
  16. <script>
  17. import MCropper from "@/components/MCropper";
  18. import { getUploadSign, onOnlyFileUpload } from "@/helpers/oss-file-upload";
  19. export default {
  20. name: "m-upload",
  21. components: { MCropper },
  22. props: {
  23. value: String,
  24. cropper: Boolean,
  25. deletable: Boolean,
  26. defaultImg: String,
  27. previewImage: {
  28. type: Boolean,
  29. default: true,
  30. },
  31. options: Object,
  32. },
  33. data() {
  34. return {
  35. fileUrl: this.value,
  36. list: this.value ? [{ url: this.value }] : [],
  37. };
  38. },
  39. methods: {
  40. beforeRead(file) {
  41. const isLt2M = file.size / 1024 / 1024 < 5;
  42. if (!isLt2M) {
  43. this.$toast("图片大小不能超过 5MB");
  44. return false;
  45. }
  46. // if (name && name == "file") {
  47. // let arr = ["psd", "ai", "eps", "svg", "sketch"];
  48. // let typeArr = file.name.split(".");
  49. // let type = typeArr[typeArr.length - 1];
  50. // if (arr.indexOf(type) == -1) {
  51. // this.$toast("请上传正确的文件");
  52. // return false;
  53. // }
  54. // }
  55. return true;
  56. },
  57. async afterRead(file) {
  58. try {
  59. file.status = "uploading";
  60. file.message = "";
  61. let tempName = file.file.name || "";
  62. const fileName = tempName && tempName.replace(/ /gi, "_");
  63. let key = new Date().getTime() + fileName;
  64. let objTemp = {
  65. filename: key,
  66. bucketName: "gym",
  67. postData: {
  68. filename: key,
  69. acl: "public-read",
  70. key: key,
  71. unknowValueField: [],
  72. },
  73. };
  74. const res = await getUploadSign(objTemp);
  75. const obj = {
  76. policy: res.data.policy,
  77. signature: res.data.signature,
  78. key: key,
  79. KSSAccessKeyId: res.data.kssAccessKeyId,
  80. acl: "public-read",
  81. name: key,
  82. file: file.file,
  83. };
  84. const uploadUrl = await onOnlyFileUpload(this.ossUploadUrl, obj);
  85. file.status = "done";
  86. this.fileUrl = uploadUrl;
  87. this.$emit("input", uploadUrl);
  88. } catch (e) {
  89. //
  90. file.status = "failed";
  91. file.message = "上传失败";
  92. this.list[origin] = [];
  93. this.fileUrl = "";
  94. return false;
  95. }
  96. },
  97. async getFile(file) {
  98. let tempName = file.name || "";
  99. const fileName = tempName && tempName.replace(/ /gi, "_");
  100. let key = new Date().getTime() + fileName;
  101. let objTemp = {
  102. filename: key,
  103. bucketName: "gym",
  104. postData: {
  105. filename: key,
  106. acl: "public-read",
  107. key: key,
  108. unknowValueField: [],
  109. },
  110. };
  111. const res = await getUploadSign(objTemp);
  112. const obj = {
  113. policy: res.data.policy,
  114. signature: res.data.signature,
  115. key: key,
  116. KSSAccessKeyId: res.data.kssAccessKeyId,
  117. acl: "public-read",
  118. name: key,
  119. file: file,
  120. };
  121. const uploadUrl = await onOnlyFileUpload(this.ossUploadUrl, obj);
  122. this.$emit("input", uploadUrl);
  123. },
  124. },
  125. };
  126. </script>
  127. <style lang="less">
  128. .mcropper {
  129. position: relative;
  130. .mcropperSection {
  131. position: absolute;
  132. top: 0;
  133. left: 0;
  134. right: 0;
  135. bottom: 0;
  136. width: 80px;
  137. height: 80px;
  138. color: #ccc;
  139. display: flex;
  140. align-items: center;
  141. justify-content: center;
  142. z-index: 3;
  143. }
  144. .cropper {
  145. // position: absolute;
  146. // top: 0;
  147. // left: 0;
  148. // right: 0;
  149. // bottom: 0;
  150. z-index: 9;
  151. position: relative;
  152. }
  153. }
  154. </style>