upload.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /**
  2. * 1. 基于 axios 和 SweetAlert2 图片上传插件
  3. * 2. 不支持旧版浏览器, 谨慎使用
  4. * 3. 插件调用如下: 更多参数, 参考 contructor 方法下的 setting 默认配置
  5. */
  6. /* **************************************************************
  7. ## html
  8. ```
  9. <img id="upload-img"
  10. class="upload-img image-border ui popover"
  11. data-variation="inverted"
  12. data-content="【点击我】上传图片吧"
  13. src="{{ default_img() }}" width="320">
  14. ```
  15. ## javascript
  16. ```
  17. $("#upload-img").click(function () {
  18. let self = this;
  19. new MyUploadOne({
  20. 'file_type': '',
  21. success: function (res) {
  22. let path = assert_images(res.data.path);
  23. $(self).attr('src', path);
  24. }
  25. });
  26. });
  27. ```
  28. ************************************************************** */
  29. class MyUploadOne {
  30. constructor(setting = {}){
  31. // 默认值
  32. this.setting = Object.assign({}, {
  33. // 验证单个文件大小限制
  34. fileSingleSizeLimit: 2 * 1024 * 1024,
  35. method: 'POST',
  36. // 文件 name 字段
  37. file_name: 'image',
  38. // 文件所属类型 [ 后台需要 ][ 必填 ]
  39. file_type: '',
  40. // create:上传, update:更新, delete:删除
  41. action: 'create',
  42. // url: ''
  43. // method: ''
  44. // path: '' 更新图片使用
  45. // 上传成功
  46. success: function () {},
  47. // 上传失败
  48. error: function () {}
  49. }, setting);
  50. if (this.setting.action == 'delete') {
  51. let formData = new FormData();
  52. // 自定义formData中的内容
  53. // 文件所属类型 [ 后台需要 ]
  54. formData.append('image_type', this.setting.file_type);
  55. // 动作
  56. formData.append('action', this.setting.action);
  57. if (this.setting.path) {
  58. formData.append('path', this.setting.path);
  59. }
  60. // 上传图片
  61. this.uploadImg(formData);
  62. } else {
  63. this.init();
  64. }
  65. }
  66. init(){
  67. let self = this;
  68. (async function getImage () {
  69. const {value: file} = await Swal.fire({
  70. title: '选择一个图片',
  71. input: 'file',
  72. inputAttributes: {
  73. 'accept': 'image/*',
  74. 'aria-label': 'Upload your profile picture'
  75. }
  76. });
  77. if (file) {
  78. // 展示
  79. let reader = new FileReader;
  80. reader.onload = (e) => {
  81. let imgBase64 = e.target.result;
  82. Swal.fire({
  83. title: '正在上传, 请耐心等待...',
  84. imageUrl: imgBase64,
  85. imageAlt: '图片已准备好, 正在上传'
  86. });
  87. };
  88. reader.readAsDataURL(file);
  89. // 相关上传操作
  90. self.handleInputChange(file);
  91. }
  92. })()
  93. }
  94. handleInputChange(file){
  95. // 检查文件类型
  96. if(['jpeg', 'png', 'gif', 'jpg'].indexOf(file.type.split("/")[1]) < 0){
  97. Swal.fire({
  98. position: 'top-end',
  99. type: 'error',
  100. title: '文件类型仅支持 jpeg/png/gif!',
  101. showConfirmButton: false,
  102. timer: 2000
  103. });
  104. return;
  105. }
  106. // 文件大小限制
  107. if(file.size > this.fileSingleSizeLimit ) {
  108. // 文件大小自定义限制
  109. Swal.fire({
  110. position: 'top-end',
  111. type: 'error',
  112. title: '文件大小不能超过 2MB!',
  113. showConfirmButton: false,
  114. timer: 2000
  115. });
  116. return;
  117. }
  118. this.transformFileToFormData(file);
  119. }
  120. // 将File append进 FormData
  121. transformFileToFormData(file){
  122. let formData = new FormData();
  123. // 自定义formData中的内容
  124. // type
  125. formData.append('type', file.type);
  126. // size
  127. formData.append('size', file.size || "image/jpeg");
  128. // name
  129. formData.append('name', file.name);
  130. // lastModifiedDate
  131. formData.append('lastModifiedDate', file.lastModifiedDate);
  132. // append 文件
  133. formData.append(this.setting.file_name, file);
  134. // 文件所属类型 [ 后台需要 ]
  135. formData.append('image_type', this.setting.file_type);
  136. // 动作
  137. formData.append('action', this.setting.action);
  138. if (this.setting.path) {
  139. formData.append('path', this.setting.path);
  140. }
  141. // 上传图片
  142. this.uploadImg(formData);
  143. }
  144. // 上传图片
  145. uploadImg(formData){
  146. let self = this;
  147. let url = Config.routes.upload_image;
  148. let method = 'POST';
  149. if (this.setting.action != 'create') {
  150. url = this.setting.url;
  151. method = this.setting.method;
  152. }
  153. axios({
  154. url: url,
  155. method: method,
  156. data: formData
  157. }).then((res)=> {
  158. if (self.setting.action != 'delete') {
  159. Swal.fire({
  160. position: 'top-end',
  161. type: 'success',
  162. title: 'upload success',
  163. showConfirmButton: false,
  164. timer: 2000
  165. });
  166. }
  167. // 回调
  168. this.setting.success(res);
  169. }).catch(function (error) {
  170. let response = error.response,
  171. html = '';
  172. if (response.data && response.data.errors) {
  173. for (let error in response.data.errors) {
  174. html += '<p style="text-align: left;">' + response.data.errors[error] + '</p>';
  175. }
  176. Swal.fire({
  177. type: 'error',
  178. html: html,
  179. showConfirmButton: false,
  180. showCancelButton: true
  181. });
  182. } else if(response.data && response.data.message){
  183. Swal.fire({
  184. type: 'error',
  185. text: response.data.message,
  186. showConfirmButton: false,
  187. showCancelButton: true
  188. });
  189. }else {
  190. // 回调
  191. self.setting.error(error);
  192. }
  193. });
  194. }
  195. }
  196. window.MyUploadOne = MyUploadOne;