choose-and-upload-file.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. 'use strict';
  2. const ERR_MSG_OK = 'chooseAndUploadFile:ok';
  3. const ERR_MSG_FAIL = 'chooseAndUploadFile:fail';
  4. function chooseImage(opts) {
  5. const {
  6. count,
  7. sizeType = ['original', 'compressed'],
  8. sourceType = ['album', 'camera'],
  9. extension
  10. } = opts
  11. return new Promise((resolve, reject) => {
  12. // #ifdef APP-PLUS
  13. let num = uni.getStorageSync('android.hardware.camera') || 0;
  14. if (plus.os.name == 'Android' && plus.navigator.checkPermission(
  15. 'android.hardware.camera') === 'undetermined' && num < 2) {
  16. // uni.showModal({
  17. // title: '相机授权提示',
  18. // content: '用于获取图片文件信息、识别/上传文件内容',
  19. // showCancel:false,
  20. // confirmText:'知道了',
  21. // success: function (res) {
  22. // console.log('用户点击确定');
  23. // }
  24. // });
  25. uni.showToast({
  26. icon:"none",
  27. title: '相机授权提示:用于获取图片文件信息、识别/上传文件内容',
  28. duration: 5000,
  29. position:"top"
  30. });
  31. }
  32. // #endif
  33. uni.chooseImage({
  34. count,
  35. sizeType,
  36. sourceType,
  37. extension,
  38. success(res) {
  39. resolve(normalizeChooseAndUploadFileRes(res, 'image'));
  40. },
  41. fail(res) {
  42. num++
  43. uni.setStorageSync('android.hardware.camera', num)
  44. reject({
  45. errMsg: res.errMsg.replace('chooseImage:fail', ERR_MSG_FAIL),
  46. });
  47. },
  48. });
  49. });
  50. }
  51. function chooseVideo(opts) {
  52. const {
  53. camera,
  54. compressed,
  55. maxDuration,
  56. sourceType = ['album', 'camera'],
  57. extension
  58. } = opts;
  59. return new Promise((resolve, reject) => {
  60. uni.chooseVideo({
  61. camera,
  62. compressed,
  63. maxDuration,
  64. sourceType,
  65. extension,
  66. success(res) {
  67. const {
  68. tempFilePath,
  69. duration,
  70. size,
  71. height,
  72. width
  73. } = res;
  74. resolve(normalizeChooseAndUploadFileRes({
  75. errMsg: 'chooseVideo:ok',
  76. tempFilePaths: [tempFilePath],
  77. tempFiles: [{
  78. name: (res.tempFile && res.tempFile.name) || '',
  79. path: tempFilePath,
  80. size,
  81. type: (res.tempFile && res.tempFile.type) || '',
  82. width,
  83. height,
  84. duration,
  85. fileType: 'video',
  86. cloudPath: '',
  87. }, ],
  88. }, 'video'));
  89. },
  90. fail(res) {
  91. reject({
  92. errMsg: res.errMsg.replace('chooseVideo:fail', ERR_MSG_FAIL),
  93. });
  94. },
  95. });
  96. });
  97. }
  98. function chooseAll(opts) {
  99. const {
  100. count,
  101. extension
  102. } = opts;
  103. return new Promise((resolve, reject) => {
  104. let chooseFile = uni.chooseFile;
  105. if (typeof wx !== 'undefined' &&
  106. typeof wx.chooseMessageFile === 'function') {
  107. chooseFile = wx.chooseMessageFile;
  108. }
  109. if (typeof chooseFile !== 'function') {
  110. return reject({
  111. errMsg: ERR_MSG_FAIL + ' 请指定 type 类型,该平台仅支持选择 image 或 video。',
  112. });
  113. }
  114. chooseFile({
  115. type: 'all',
  116. count,
  117. extension,
  118. success(res) {
  119. resolve(normalizeChooseAndUploadFileRes(res));
  120. },
  121. fail(res) {
  122. reject({
  123. errMsg: res.errMsg.replace('chooseFile:fail', ERR_MSG_FAIL),
  124. });
  125. },
  126. });
  127. });
  128. }
  129. function normalizeChooseAndUploadFileRes(res, fileType) {
  130. res.tempFiles.forEach((item, index) => {
  131. if (!item.name) {
  132. item.name = item.path.substring(item.path.lastIndexOf('/') + 1);
  133. }
  134. if (fileType) {
  135. item.fileType = fileType;
  136. }
  137. item.cloudPath =
  138. Date.now() + '_' + index + item.name.substring(item.name.lastIndexOf('.'));
  139. });
  140. if (!res.tempFilePaths) {
  141. res.tempFilePaths = res.tempFiles.map((file) => file.path);
  142. }
  143. return res;
  144. }
  145. function uploadCloudFiles(files, max = 5, onUploadProgress) {
  146. files = JSON.parse(JSON.stringify(files))
  147. const len = files.length
  148. let count = 0
  149. let self = this
  150. return new Promise(resolve => {
  151. while (count < max) {
  152. next()
  153. }
  154. function next() {
  155. let cur = count++
  156. if (cur >= len) {
  157. !files.find(item => !item.url && !item.errMsg) && resolve(files)
  158. return
  159. }
  160. const fileItem = files[cur]
  161. const index = self.files.findIndex(v => v.uuid === fileItem.uuid)
  162. fileItem.url = ''
  163. delete fileItem.errMsg
  164. uniCloud
  165. .uploadFile({
  166. filePath: fileItem.path,
  167. cloudPath: fileItem.cloudPath,
  168. fileType: fileItem.fileType,
  169. onUploadProgress: res => {
  170. res.index = index
  171. onUploadProgress && onUploadProgress(res)
  172. }
  173. })
  174. .then(res => {
  175. fileItem.url = res.fileID
  176. fileItem.index = index
  177. if (cur < len) {
  178. next()
  179. }
  180. })
  181. .catch(res => {
  182. fileItem.errMsg = res.errMsg || res.message
  183. fileItem.index = index
  184. if (cur < len) {
  185. next()
  186. }
  187. })
  188. }
  189. })
  190. }
  191. function uploadFiles(choosePromise, {
  192. onChooseFile,
  193. onUploadProgress
  194. }) {
  195. return choosePromise
  196. .then((res) => {
  197. if (onChooseFile) {
  198. const customChooseRes = onChooseFile(res);
  199. if (typeof customChooseRes !== 'undefined') {
  200. return Promise.resolve(customChooseRes).then((chooseRes) => typeof chooseRes === 'undefined' ?
  201. res : chooseRes);
  202. }
  203. }
  204. return res;
  205. })
  206. .then((res) => {
  207. if (res === false) {
  208. return {
  209. errMsg: ERR_MSG_OK,
  210. tempFilePaths: [],
  211. tempFiles: [],
  212. };
  213. }
  214. return res
  215. })
  216. }
  217. function chooseAndUploadFile(opts = {
  218. type: 'all'
  219. }) {
  220. if (opts.type === 'image') {
  221. return uploadFiles(chooseImage(opts), opts);
  222. } else if (opts.type === 'video') {
  223. return uploadFiles(chooseVideo(opts), opts);
  224. }
  225. return uploadFiles(chooseAll(opts), opts);
  226. }
  227. export {
  228. chooseAndUploadFile,
  229. uploadCloudFiles
  230. };