214 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
			
		
		
	
	
			214 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
| 'use strict';
 | |
| import sheep from '@/sheep';
 | |
| 
 | |
| const ERR_MSG_OK = 'chooseAndUploadFile:ok';
 | |
| const ERR_MSG_FAIL = 'chooseAndUploadFile:fail';
 | |
| 
 | |
| function chooseImage(opts) {
 | |
|   const {
 | |
|     count,
 | |
|     sizeType = ['original', 'compressed'],
 | |
|     sourceType = ['album', 'camera'],
 | |
|     extension,
 | |
|   } = opts;
 | |
|   return new Promise((resolve, reject) => {
 | |
|     uni.chooseImage({
 | |
|       count,
 | |
|       sizeType,
 | |
|       sourceType,
 | |
|       extension,
 | |
|       success(res) {
 | |
|         resolve(normalizeChooseAndUploadFileRes(res, 'image'));
 | |
|       },
 | |
|       fail(res) {
 | |
|         reject({
 | |
|           errMsg: res.errMsg.replace('chooseImage:fail', ERR_MSG_FAIL),
 | |
|         });
 | |
|       },
 | |
|     });
 | |
|   });
 | |
| }
 | |
| 
 | |
| function chooseVideo(opts) {
 | |
|   const { camera, compressed, maxDuration, sourceType = ['album', 'camera'], extension } = opts;
 | |
|   return new Promise((resolve, reject) => {
 | |
|     uni.chooseVideo({
 | |
|       camera,
 | |
|       compressed,
 | |
|       maxDuration,
 | |
|       sourceType,
 | |
|       extension,
 | |
|       success(res) {
 | |
|         const { tempFilePath, duration, size, height, width } = res;
 | |
|         resolve(
 | |
|           normalizeChooseAndUploadFileRes(
 | |
|             {
 | |
|               errMsg: 'chooseVideo:ok',
 | |
|               tempFilePaths: [tempFilePath],
 | |
|               tempFiles: [
 | |
|                 {
 | |
|                   name: (res.tempFile && res.tempFile.name) || '',
 | |
|                   path: tempFilePath,
 | |
|                   size,
 | |
|                   type: (res.tempFile && res.tempFile.type) || '',
 | |
|                   width,
 | |
|                   height,
 | |
|                   duration,
 | |
|                   fileType: 'video',
 | |
|                   cloudPath: '',
 | |
|                 },
 | |
|               ],
 | |
|             },
 | |
|             'video',
 | |
|           ),
 | |
|         );
 | |
|       },
 | |
|       fail(res) {
 | |
|         reject({
 | |
|           errMsg: res.errMsg.replace('chooseVideo:fail', ERR_MSG_FAIL),
 | |
|         });
 | |
|       },
 | |
|     });
 | |
|   });
 | |
| }
 | |
| 
 | |
| function chooseAll(opts) {
 | |
|   const { count, extension } = opts;
 | |
|   return new Promise((resolve, reject) => {
 | |
|     let chooseFile = uni.chooseFile;
 | |
|     if (typeof wx !== 'undefined' && typeof wx.chooseMessageFile === 'function') {
 | |
|       chooseFile = wx.chooseMessageFile;
 | |
|     }
 | |
|     if (typeof chooseFile !== 'function') {
 | |
|       return reject({
 | |
|         errMsg: ERR_MSG_FAIL + ' 请指定 type 类型,该平台仅支持选择 image 或 video。',
 | |
|       });
 | |
|     }
 | |
|     chooseFile({
 | |
|       type: 'all',
 | |
|       count,
 | |
|       extension,
 | |
|       success(res) {
 | |
|         resolve(normalizeChooseAndUploadFileRes(res));
 | |
|       },
 | |
|       fail(res) {
 | |
|         reject({
 | |
|           errMsg: res.errMsg.replace('chooseFile:fail', ERR_MSG_FAIL),
 | |
|         });
 | |
|       },
 | |
|     });
 | |
|   });
 | |
| }
 | |
| 
 | |
| function normalizeChooseAndUploadFileRes(res, fileType) {
 | |
|   res.tempFiles.forEach((item, index) => {
 | |
|     if (!item.name) {
 | |
|       item.name = item.path.substring(item.path.lastIndexOf('/') + 1);
 | |
|     }
 | |
|     if (fileType) {
 | |
|       item.fileType = fileType;
 | |
|     }
 | |
|     item.cloudPath = Date.now() + '_' + index + item.name.substring(item.name.lastIndexOf('.'));
 | |
|   });
 | |
|   if (!res.tempFilePaths) {
 | |
|     res.tempFilePaths = res.tempFiles.map((file) => file.path);
 | |
|   }
 | |
|   return res;
 | |
| }
 | |
| 
 | |
| function uploadCloudFiles(files, max = 5, onUploadProgress) {
 | |
|   files = JSON.parse(JSON.stringify(files));
 | |
|   const len = files.length;
 | |
|   let count = 0;
 | |
|   let self = this;
 | |
|   return new Promise((resolve) => {
 | |
|     while (count < max) {
 | |
|       next();
 | |
|     }
 | |
| 
 | |
|     function next() {
 | |
|       let cur = count++;
 | |
|       if (cur >= len) {
 | |
|         !files.find((item) => !item.url && !item.errMsg) && resolve(files);
 | |
|         return;
 | |
|       }
 | |
|       const fileItem = files[cur];
 | |
|       const index = self.files.findIndex((v) => v.uuid === fileItem.uuid);
 | |
|       fileItem.url = '';
 | |
|       delete fileItem.errMsg;
 | |
| 
 | |
|       uniCloud
 | |
|         .uploadFile({
 | |
|           filePath: fileItem.path,
 | |
|           cloudPath: fileItem.cloudPath,
 | |
|           fileType: fileItem.fileType,
 | |
|           onUploadProgress: (res) => {
 | |
|             res.index = index;
 | |
|             onUploadProgress && onUploadProgress(res);
 | |
|           },
 | |
|         })
 | |
|         .then((res) => {
 | |
|           fileItem.url = res.fileID;
 | |
|           fileItem.index = index;
 | |
|           if (cur < len) {
 | |
|             next();
 | |
|           }
 | |
|         })
 | |
|         .catch((res) => {
 | |
|           fileItem.errMsg = res.errMsg || res.message;
 | |
|           fileItem.index = index;
 | |
|           if (cur < len) {
 | |
|             next();
 | |
|           }
 | |
|         });
 | |
|     }
 | |
|   });
 | |
| }
 | |
| 
 | |
| function uploadFiles(choosePromise, { onChooseFile, onUploadProgress }) {
 | |
|   return choosePromise
 | |
|     .then((res) => {
 | |
|       if (onChooseFile) {
 | |
|         const customChooseRes = onChooseFile(res);
 | |
|         if (typeof customChooseRes !== 'undefined') {
 | |
|           return Promise.resolve(customChooseRes).then((chooseRes) =>
 | |
|             typeof chooseRes === 'undefined' ? res : chooseRes,
 | |
|           );
 | |
|         }
 | |
|       }
 | |
|       return res;
 | |
|     })
 | |
|     .then((res) => {
 | |
|       if (res === false) {
 | |
|         return {
 | |
|           errMsg: ERR_MSG_OK,
 | |
|           tempFilePaths: [],
 | |
|           tempFiles: [],
 | |
|         };
 | |
|       }
 | |
|       return res;
 | |
|     })
 | |
|     .then(async (files) => {
 | |
|       for (let file of files.tempFiles) {
 | |
|         let { path } = await sheep.$api.app.upload(file.path, 'ugc');
 | |
|         file.url = path;
 | |
|       }
 | |
|       return files;
 | |
|     });
 | |
| }
 | |
| 
 | |
| function chooseAndUploadFile(
 | |
|   opts = {
 | |
|     type: 'all',
 | |
|   },
 | |
| ) {
 | |
|   if (opts.type === 'image') {
 | |
|     return uploadFiles(chooseImage(opts), opts);
 | |
|   } else if (opts.type === 'video') {
 | |
|     return uploadFiles(chooseVideo(opts), opts);
 | |
|   }
 | |
|   return uploadFiles(chooseAll(opts), opts);
 | |
| }
 | |
| 
 | |
| export { chooseAndUploadFile, uploadCloudFiles };
 |