upload.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <template>
  2. <div>
  3. <el-upload
  4. ref="upload_com"
  5. :headers="headers"
  6. :action="action"
  7. :show-file-list="showFileList"
  8. :file-list="fileList"
  9. :on-success="_onSuccess"
  10. :on-preview="_onPreview"
  11. :http-request="oss_upload"
  12. :on-remove="_onRemove"
  13. :before-remove="_onBeforeRemove"
  14. :before-upload="_beforeUpload"
  15. :on-exceed="_onExceed"
  16. :limit="limit"
  17. :on-change="handleChange"
  18. :multiple="multiple"
  19. >
  20. <slot></slot>
  21. <slot name="tip"></slot>
  22. </el-upload>
  23. <el-progress v-show="showProcess" :percentage="processLength" :stroke-width="2"></el-progress>
  24. </div>
  25. </template>
  26. <script>
  27. function noop() {}
  28. import moment from 'moment';
  29. import axios from 'axios';
  30. export default {
  31. props: {
  32. action: {
  33. //必选参数,上传的地址
  34. type: String,
  35. required: true
  36. },
  37. headers: {
  38. //设置上传的请求头部
  39. type: Object,
  40. default() {
  41. return {};
  42. }
  43. },
  44. data: Object, //上传时附带的额外参数
  45. multiple: Boolean, //是否支持多选文件
  46. name: {
  47. //上传的文件字段名
  48. type: String,
  49. default: 'file'
  50. },
  51. drag: Boolean, //是否启用拖拽上传
  52. showFileList: {
  53. //是否显示已上传文件列表
  54. type: Boolean,
  55. default: false
  56. },
  57. accept: String, // 接受上传的文件类型(thumbnail-mode 模式下此参数无效)
  58. beforeUpload: Function, // 上传文件之前的钩子,参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传。
  59. onRemove: {
  60. //文件列表移除文件时的钩子
  61. type: Function,
  62. default: noop
  63. },
  64. onBeforeRemove: {
  65. //删除文件之前的钩子,参数为上传的文件和文件列表,若返回 false 或者返回 Promise 且被 reject,则停止删除。
  66. type: Function,
  67. default: noop
  68. },
  69. onPreview: {
  70. //点击文件列表中已上传的文件时的钩子
  71. type: Function
  72. },
  73. onSuccess: {
  74. //文件上传成功时的钩子
  75. type: Function,
  76. default: noop
  77. },
  78. fileList: {
  79. //必选参数,上传的地址
  80. type: Array,
  81. default() {
  82. return [];
  83. }
  84. },
  85. limit: {
  86. //必选参数,上传的地址
  87. type: Number,
  88. default: () => {
  89. return 1;
  90. }
  91. },
  92. onExceed: {
  93. //必选参数,上传的地址
  94. type: Function,
  95. default: noop
  96. }
  97. },
  98. name: 'upload',
  99. data() {
  100. return {
  101. processLength: 0,
  102. showProcess: false,
  103. files: {},
  104. config: null
  105. };
  106. },
  107. methods: {
  108. handleChange(file, fileList) {
  109. this.files = file;
  110. },
  111. handleChanges(file) {
  112. if (file.status === 'ready') {
  113. this.processLength = 0;
  114. this.showProcess = true;
  115. const interval = setInterval(() => {
  116. if (this.processLength >= 99) {
  117. clearInterval(interval);
  118. return;
  119. }
  120. this.processLength += 1;
  121. }, 20);
  122. }
  123. if (file.status === 'success') {
  124. this.processLength = 100;
  125. this.showProcess = false;
  126. }
  127. },
  128. get_sign(callback) {
  129. axios
  130. .get('https://intesys.cms.g107.com/integral.php/Api/get_signature', {
  131. headers: {
  132. 'Content-Type': 'application/json; charset=utf-8',
  133. 'A-Token': this.$getToken()
  134. }
  135. })
  136. .then(res => {
  137. this.config = res.data.data;
  138. callback();
  139. });
  140. },
  141. _beforeUpload(file) {
  142. if (!this.beforeUpload(file)) {
  143. return false;
  144. } else {
  145. this.handleChanges(this.files);
  146. }
  147. },
  148. oss_upload(upload_obj) {
  149. let self = this;
  150. this.get_sign(function() {
  151. self.upload(upload_obj.file);
  152. });
  153. },
  154. _onExceed(files, fileList) {
  155. this.$message.warning(`最多选择 ${this.limit} 个文件`);
  156. },
  157. _onSuccess(response, file, fileList) {
  158. this.onSuccess(response, file, fileList);
  159. },
  160. _onPreview(file) {
  161. this.onPreview(file);
  162. },
  163. _onRemove(file, fileList) {
  164. this.onRemove(file, fileList);
  165. },
  166. _onBeforeRemove(file, fileList) {
  167. if (file.status == 'success') {
  168. return this.$confirm(`确定移除此项?`);
  169. }
  170. },
  171. random_string(len) {
  172. len = len || 32;
  173. var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
  174. var maxPos = chars.length;
  175. var pwd = '';
  176. for (let i = 0; i < len; i++) {
  177. pwd += chars.charAt(Math.floor(Math.random() * maxPos));
  178. }
  179. return pwd;
  180. },
  181. upload(item) {
  182. let self = this;
  183. const photo = item; // 获取图片对象
  184. const photoName = item.name; // 原图片的名称
  185. const url = 'https://integralsys.oss-cn-shenzhen.aliyuncs.com';
  186. let date = moment().format('YYYY/MM/DD');
  187. let param = new FormData();
  188. let randomStr = this.random_string(32);
  189. let key = 'intesys/dd/' + this.$getUserData().site_id + '/' + date + '/' + randomStr + '.png';
  190. param.append('Filename', photoName);
  191. param.append('key', key);
  192. param.append('policy', this.config.policy);
  193. param.append('OSSAccessKeyId', this.config.accessid);
  194. param.append('success_action_status', '200'); // 不要问为什么,照做
  195. param.append('callback', this.config.callback);
  196. param.append('signature', this.config.signature);
  197. param.append('file', photo); // 这个**切记**一定要放到最后去 append ,不然阿里云会一直报 key 的错误
  198. axios.post(url, param, {
  199. headers: {
  200. 'Content-Type': 'multipart/form-data'
  201. }
  202. })
  203. .then(response => {
  204. if (response.data.Status == 'Ok') {
  205. this.processLength = 100;
  206. this.showProcess = false;
  207. setTimeout(() => {
  208. this.processLength = 0;
  209. }, 200);
  210. self.fileList.push({
  211. name: randomStr + photoName,
  212. url: 'https://integralsys.oss-cn-shenzhen.aliyuncs.com/' + key,
  213. name: item.name,
  214. response: {
  215. url: 'https://integralsys.oss-cn-shenzhen.aliyuncs.com/' + key
  216. }
  217. });
  218. self._onSuccess({ status: 1, url: 'https://integralsys.oss-cn-shenzhen.aliyuncs.com/' + key, file_name: randomStr + photoName }, item, self.fileList);
  219. }
  220. })
  221. .catch(err => {
  222. this.showProcess = false;
  223. });
  224. }
  225. }
  226. };
  227. </script>
  228. <style scoped></style>