aliyunOSSUtil.js 7.8 KB
Newer Older
VK1688's avatar
1.8.5  
VK1688 已提交
1 2 3 4 5
/**
 * 阿里云oss工具类
 */
var aliyunOSSUtil = {};
var counterNum = 0;
VK1688's avatar
1.8.8  
VK1688 已提交
6

VK1688's avatar
1.8.5  
VK1688 已提交
7 8 9 10 11
/**
 * 上传至阿里云oss
vk.callFunctionUtil.uploadFile({
	filePath:tempFilePath,
	fileType:"image",
VK1688's avatar
1.9.2  
VK1688 已提交
12
	provider:"aliyun",
VK1688's avatar
1.8.5  
VK1688 已提交
13 14 15 16 17 18
	index,
	onUploadProgress:function(res){
		// 上传过程中
		if (res.progress > 0) {
			if(list[index]){
				list[index].progress = res.progress;
VK1688's avatar
1.8.8  
VK1688 已提交
19

VK1688's avatar
1.8.5  
VK1688 已提交
20 21 22 23 24
			}
		}
	},
	success:function(res){
		// 上传成功
VK1688's avatar
1.8.8  
VK1688 已提交
25

VK1688's avatar
1.8.5  
VK1688 已提交
26 27 28
	},
	fail:function(res){
		// 上传失败
VK1688's avatar
1.8.8  
VK1688 已提交
29

VK1688's avatar
1.8.5  
VK1688 已提交
30 31 32 33 34 35
	}
});
 */
aliyunOSSUtil.uploadFile = function(obj) {
	let {
		filePath,
VK1688's avatar
2.0.4  
VK1688 已提交
36
		fileType = "image",
VK1688's avatar
1.8.5  
VK1688 已提交
37 38
		name = "file",
		header = {
VK1688's avatar
2.0.1  
VK1688 已提交
39
			"x-oss-forbid-overwrite": true,
VK1688's avatar
1.8.5  
VK1688 已提交
40 41
		},
		index = 0,
VK1688's avatar
2.0.1  
VK1688 已提交
42
		file = {},
VK1688's avatar
2.0.3  
VK1688 已提交
43
		needSave = false,
VK1688's avatar
VK1688 已提交
44 45
		category_id,
		title,
46 47
		cloudPathRemoveChinese = true, // 删除文件名中的中文
		cloudDirectory,
VK1688's avatar
1.8.5  
VK1688 已提交
48 49
	} = obj;
	let vk = getApp().globalData.vk;
VK1688's avatar
VK1688 已提交
50
	if (title) vk.showLoading(title);
VK1688's avatar
1.8.9  
VK1688 已提交
51
	let fileNameObj = createFileName(obj);
VK1688's avatar
1.8.5  
VK1688 已提交
52 53 54
	let aliyunOSS = getConfig();
	let fileName = fileNameObj.fileFullName;
	let formData = vk.pubfn.copyObject(aliyunOSS.uploadData);
VK1688's avatar
2.0.1  
VK1688 已提交
55
	formData["key"] = fileName; // 存储在oss的文件路径
VK1688's avatar
1.8.5  
VK1688 已提交
56 57 58 59 60
	/**
	 * 特别说明
	 * 若已知本地图片,则使用formData["name"] = filePath
	 * 若已知base64,则是用formData["file"] = file;// file base64字符串转成blob对象
	 */
VK1688's avatar
2.0.1  
VK1688 已提交
61
	if (filePath.indexOf(";base64,") > -1) {
VK1688's avatar
1.8.5  
VK1688 已提交
62
		formData["file"] = dataURLtoBlob(filePath);
VK1688's avatar
2.0.1  
VK1688 已提交
63
	} else {
VK1688's avatar
1.8.5  
VK1688 已提交
64 65 66 67 68
		formData["name"] = filePath;
	}
	let Logger = {};
	Logger.startTime = new Date().getTime();
	Logger.filePath = filePath;
VK1688's avatar
VK1688 已提交
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
	return new Promise((resolve, reject) => {
		let uploadTask = uni.uploadFile({
			url: aliyunOSS.action,
			filePath,
			name,
			header,
			formData: formData,
			success: function(res) {
				if (title) vk.hideLoading();
				if (![200, 201].includes(res.statusCode)) {
					if (typeof obj.fail === "function") obj.fail(res);
					Logger.error = res;
				} else {
					// 上传成功
					res.fileID = fileNameObj.url;
84
					res.url = fileNameObj.url;
VK1688's avatar
VK1688 已提交
85
					Logger.result = res;
VK1688's avatar
VK1688 已提交
86 87
					if (typeof obj.success === "function") obj.success(res);
					resolve(res);
VK1688's avatar
VK1688 已提交
88 89 90 91 92 93 94 95 96 97 98 99 100 101
					if (needSave) {
						// 保存文件记录到数据库
						vk.userCenter.addUploadRecord({
							data: {
								url: res.fileID,
								name: file.name,
								size: file.size,
								file_id: res.fileID,
								provider: "aliyun",
								category_id
							},
							filePath,
							fileType,
							success: function() {
VK1688's avatar
VK1688 已提交
102
								if (typeof obj.addSuccess == "function") obj.addSuccess(res);
VK1688's avatar
VK1688 已提交
103 104
							},
							fail: function(res) {
VK1688's avatar
VK1688 已提交
105
								if (typeof obj.addFail === "function") obj.addFail(res);
VK1688's avatar
VK1688 已提交
106 107 108 109 110 111 112
							}
						});
					}
				}
			},
			fail: function(res) {
				if (title) vk.hideLoading();
VK1688's avatar
1.8.5  
VK1688 已提交
113
				Logger.error = res;
VK1688's avatar
2.4.1  
VK1688 已提交
114
				if (res.errMsg && res.errMsg.indexOf('fail url not in domain list') > -1) {
VK1688's avatar
VK1688 已提交
115 116 117 118 119 120 121 122 123 124 125 126 127
					vk.toast('上传域名未在白名单中');
				}
				if (typeof obj.fail === "function") obj.fail(res);
			},
			complete: function() {
				let vk = getApp().globalData.vk;
				let config = vk.callFunctionUtil.config;
				if (config.debug) {
					Logger.endTime = new Date().getTime();
					Logger.runTime = (Logger.endTime - Logger.startTime);
					let colorArr = config.logger.colorArr;
					let colorStr = colorArr[counterNum % colorArr.length];
					counterNum++;
VK1688's avatar
2.4.1  
VK1688 已提交
128
					console.log("%c--------【开始】【阿里云oss文件上传】--------", 'color: ' + colorStr + ';font-size: 12px;font-weight: bold;');
VK1688's avatar
VK1688 已提交
129 130 131 132 133 134
					console.log("【本地文件】: ", Logger.filePath);
					console.log("【返回数据】: ", Logger.result);
					console.log("【预览地址】: ", Logger.result.fileID);
					console.log("【上传耗时】: ", Logger.runTime, "毫秒");
					console.log("【上传时间】: ", vk.pubfn.timeFormat(Logger.startTime, "yyyy-MM-dd hh:mm:ss"));
					if (Logger.error) console.error("【error】:", Logger.error);
VK1688's avatar
2.4.1  
VK1688 已提交
135
					console.log("%c--------【结束】【阿里云oss文件上传】--------", 'color: ' + colorStr + ';font-size: 12px;font-weight: bold;');
VK1688's avatar
2.0.1  
VK1688 已提交
136
				}
VK1688's avatar
1.8.5  
VK1688 已提交
137
			}
VK1688's avatar
VK1688 已提交
138 139 140 141
		});
		uploadTask.onProgressUpdate((res) => {
			if (res.progress > 0) {
				if (typeof obj.onUploadProgress === "function") obj.onUploadProgress(res);
VK1688's avatar
1.8.5  
VK1688 已提交
142
			}
VK1688's avatar
VK1688 已提交
143
		});
VK1688's avatar
1.8.5  
VK1688 已提交
144 145 146 147
	});
};


148
export default aliyunOSSUtil;
VK1688's avatar
1.8.5  
VK1688 已提交
149 150 151


// 获取配置
VK1688's avatar
2.0.1  
VK1688 已提交
152
function getConfig() {
VK1688's avatar
1.8.5  
VK1688 已提交
153
	let vk = getApp().globalData.vk;
VK1688's avatar
2.10.1  
VK1688 已提交
154
	let aliyunOSS = vk.getConfig("service.aliyunOSS");
VK1688's avatar
1.8.5  
VK1688 已提交
155
	let configData = {};
VK1688's avatar
2.0.1  
VK1688 已提交
156
	if (aliyunOSS && aliyunOSS.uploadData && aliyunOSS.uploadData.OSSAccessKeyId) {
VK1688's avatar
1.9.2  
VK1688 已提交
157
		try {
VK1688's avatar
2.10.1  
VK1688 已提交
158
			// 只有开启按userId分组且开启了vk的vuex功能,才可以自动按userId分组
VK1688's avatar
2.0.1  
VK1688 已提交
159
			if (aliyunOSS.groupUserId && typeof vk.getVuex === "function") {
VK1688's avatar
1.9.2  
VK1688 已提交
160
				let userInfo = vk.getVuex("$user.userInfo");
VK1688's avatar
2.0.1  
VK1688 已提交
161 162
				if (vk.pubfn.isNotNull(userInfo) && userInfo._id) {
					aliyunOSS.dirname += `/${userInfo._id}`;
VK1688's avatar
1.9.2  
VK1688 已提交
163 164
				}
			}
VK1688's avatar
2.0.1  
VK1688 已提交
165
		} catch (err) {}
VK1688's avatar
1.8.5  
VK1688 已提交
166
		configData = {
VK1688's avatar
2.0.1  
VK1688 已提交
167
			uploadData: {
VK1688's avatar
1.8.5  
VK1688 已提交
168 169 170
				OSSAccessKeyId: aliyunOSS.uploadData.OSSAccessKeyId,
				policy: aliyunOSS.uploadData.policy,
				signature: aliyunOSS.uploadData.signature,
VK1688's avatar
2.0.1  
VK1688 已提交
171 172
				success_action_status: 200,
				key: "test.png"
VK1688's avatar
1.8.5  
VK1688 已提交
173
			},
VK1688's avatar
2.0.1  
VK1688 已提交
174 175 176
			action: aliyunOSS.action,
			dirname: aliyunOSS.dirname,
			host: aliyunOSS.host,
VK1688's avatar
1.8.5  
VK1688 已提交
177 178 179 180 181
		};
	}
	return configData;
}
// 生成文件名
VK1688's avatar
2.0.1  
VK1688 已提交
182
function createFileName(obj = {}) {
VK1688's avatar
1.8.8  
VK1688 已提交
183
	let {
184 185
		file,
		filePath,
VK1688's avatar
1.8.9  
VK1688 已提交
186
		index = 0,
187 188
		cloudPathRemoveChinese = true,
		cloudDirectory
VK1688's avatar
1.8.8  
VK1688 已提交
189
	} = obj;
VK1688's avatar
1.8.5  
VK1688 已提交
190 191 192 193 194
	let vk = getApp().globalData.vk;
	let aliyunOSS = getConfig();
	let dirname = aliyunOSS.dirname;
	let host = aliyunOSS.host;
	let fileObj = {};
VK1688's avatar
1.9.2  
VK1688 已提交
195

VK1688's avatar
2.0.4  
VK1688 已提交
196
	let suffix = getFileSuffix(obj);
VK1688's avatar
1.8.9  
VK1688 已提交
197
	let oldName = index + "." + suffix;
VK1688's avatar
2.0.3  
VK1688 已提交
198 199 200
	if (file && file.name) {
		let suffixName = file.name.substring(file.name.lastIndexOf(".") + 1);
		if (suffixName && suffixName.length < 5) oldName = file.name;
VK1688's avatar
VK1688 已提交
201
		// 只保留["数字","英文",".","-"]
202 203 204
		if (cloudPathRemoveChinese) {
			oldName = oldName.replace(/[^a-zA-Z.-d]/g, '');
		}
VK1688's avatar
VK1688 已提交
205
		if (oldName.indexOf(".") == 0) oldName = "0" + oldName;
VK1688's avatar
2.0.3  
VK1688 已提交
206
	}
VK1688's avatar
1.8.5  
VK1688 已提交
207
	let date = new Date();
VK1688's avatar
2.0.1  
VK1688 已提交
208
	let dateYYYYMMDD = vk.pubfn.timeFormat(date, "yyyy/MM/dd");
VK1688's avatar
1.8.5  
VK1688 已提交
209 210
	let dateTime = date.getTime().toString(); // 时间戳
	// 时间戳后8位
VK1688's avatar
2.0.1  
VK1688 已提交
211
	let dateTimeEnd8 = dateTime.substring(dateTime.length - 8, dateTime.length);
VK1688's avatar
1.8.5  
VK1688 已提交
212 213
	let randomNumber = vk.pubfn.random(8); // 8位随机数
	// 文件路径 = 固定路径名 + 业务路径
214 215
	
	// 业务路径
VK1688's avatar
1.8.5  
VK1688 已提交
216
	let servicePath = "";
217 218 219 220 221 222 223 224 225 226
	if (cloudDirectory) {
		// 如果自定义了上传目录,则使用自定义的上传目录
		if (cloudDirectory.lastIndexOf("/") !== cloudDirectory.length-1) {
			cloudDirectory = cloudDirectory + "/";
		}
		servicePath = cloudDirectory;
	} else {
		// 否则,使用年月日作为上传目录
		servicePath = dateYYYYMMDD + "/";
	}
VK1688's avatar
1.8.5  
VK1688 已提交
227 228
	// 文件名 = 时间戳后8位 - 随机数8位 + 后缀名
	let fileNickName = dateTimeEnd8 + randomNumber + "-" + oldName;
229 230 231 232 233
	// 文件相对路径 = 业务目录 + 文件名
	let fileRelativePath = servicePath + fileNickName;
	// 文件名全称(包含文件路径) = 根目录 + 文件相对路径
	let fileFullName = dirname + "/" + fileRelativePath;
	// 外网地址 = 外网域名 + 文件名全称
VK1688's avatar
2.0.1  
VK1688 已提交
234
	let url = host + "/" + fileFullName;
VK1688's avatar
1.8.5  
VK1688 已提交
235 236 237 238 239
	fileObj.url = url;
	fileObj.fileFullName = fileFullName;
	fileObj.fileNickName = fileNickName;
	return fileObj;
}
VK1688's avatar
2.4.1  
VK1688 已提交
240 241

function getFileSuffix(obj = {}) {
VK1688's avatar
2.0.4  
VK1688 已提交
242 243
	let {
		file,
VK1688's avatar
2.11.6  
VK1688 已提交
244 245
		filePath,
		suffix = "png"
VK1688's avatar
2.0.4  
VK1688 已提交
246 247 248 249 250
	} = obj;
	if (filePath) {
		let suffixName = filePath.substring(filePath.lastIndexOf(".") + 1);
		if (suffixName && suffixName.length < 5) suffix = suffixName;
	}
VK1688's avatar
2.4.1  
VK1688 已提交
251
	if (file) {
VK1688's avatar
2.0.4  
VK1688 已提交
252 253 254 255 256 257 258 259 260 261 262
		if (file.path) {
			let suffixName = file.path.substring(file.path.lastIndexOf(".") + 1);
			if (suffixName && suffixName.length < 5) suffix = suffixName;
		}
		if (file.name) {
			let suffixName = file.name.substring(file.name.lastIndexOf(".") + 1);
			if (suffixName && suffixName.length < 5) suffix = suffixName;
		}
	}
	return suffix;
}
VK1688's avatar
1.8.5  
VK1688 已提交
263

VK1688's avatar
2.0.1  
VK1688 已提交
264 265 266 267 268 269
function dataURLtoBlob(dataurl) {
	let arr = dataurl.split(','),
		mime = arr[0].match(/:(.*?);/)[1],
		bstr = atob(arr[1]),
		n = bstr.length,
		u8arr = new Uint8Array(n);
VK1688's avatar
1.8.5  
VK1688 已提交
270 271 272 273
	while (n--) {
		u8arr[n] = bstr.charCodeAt(n);
	}
	return new Blob([u8arr], { type: mime });
VK1688's avatar
1.8.8  
VK1688 已提交
274
}