const CONFIG = require('../config') const Parse = getApp().Parse let config = { qiniuRegion: '', qiniuImageURLPrefix: '', qiniuUploadToken: '', qiniuUploadTokenURL: '', qiniuUploadTokenFunction: null, qiniuShouldUseQiniuFileName: false } let spaceLimit = 1024 * 1024 * 1024; // 默认1GB // 在整个程序生命周期中,只需要 init 一次即可 // 如果需要变更参数,再调用 init 即可 function init(options) { config = { qiniuRegion: '', qiniuImageURLPrefix: '', qiniuUploadToken: '', qiniuUploadTokenURL: '', qiniuUploadTokenFunction: null, qiniuShouldUseQiniuFileName: false }; updateConfigWithOptions(options); } function updateConfigWithOptions(options) { if (options.region) { config.qiniuRegion = options.region; } else { console.error('qiniu uploader need your bucket region'); } if (options.uptoken) { config.qiniuUploadToken = options.uptoken; } else if (options.uptokenURL) { config.qiniuUploadTokenURL = options.uptokenURL; } else if (options.uptokenFunc) { config.qiniuUploadTokenFunction = options.uptokenFunc; } if (options.domain) { config.qiniuImageURLPrefix = options.domain; } config.qiniuShouldUseQiniuFileName = options.shouldUseQiniuFileName } function upload(filePath, success, fail, options, progress, cancelTask, before, complete) { if (null == filePath) { console.error('qiniu uploader need filePath to upload'); return; } options && updateConfigWithOptions(options); if (config.qiniuUploadToken) { doUpload(filePath, success, fail, options, progress, cancelTask, before, complete); } else if (config.qiniuUploadTokenURL) { getQiniuToken(function () { doUpload(filePath, success, fail, options, progress, cancelTask, before, complete); }); } else if (config.qiniuUploadTokenFunction) { config.qiniuUploadToken = config.qiniuUploadTokenFunction(); if (null == config.qiniuUploadToken && config.qiniuUploadToken.length > 0) { console.error('qiniu UploadTokenFunction result is null, please check the return value'); return } doUpload(filePath, success, fail, options, progress, cancelTask, before, complete); } else { console.error('qiniu uploader need one of [uptoken, uptokenURL, uptokenFunc]'); return; } } /* 文件上传函数 */ async function doUpload(filePath, success, fail, options, progress, cancelTask, before, complete) { if (null == config.qiniuUploadToken && config.qiniuUploadToken.length > 0) { console.error('qiniu UploadToken is null, please check the init config or networking'); return } let authLoad = await authSpaceCount() if (!authLoad) { wx.showModal({ title: '上传失败', content: '文件存储空间已满,请联系维护人员。', showCancel: false, cancelColor: '#000000', confirmText: '确定', confirmColor: '#3CC51F', }); return } let url = uploadURLFromRegionCode(config.qiniuRegion); let fileName = filePath.split('//')[1]; if (options && options.key) { fileName = options.key; } let formData = { 'token': config.qiniuUploadToken }; if (!config.qiniuShouldUseQiniuFileName) { formData['key'] = fileName } before && before(); let uploadTask = wx.uploadFile({ url: url, filePath: filePath, name: 'file', formData: formData, success: async function (res) { let dataString = res.data try { let dataObject = JSON.parse(dataString); //do something let fileUrl = config.qiniuImageURLPrefix + '/' + dataObject.key; dataObject.fileUrl = fileUrl dataObject.imageURL = fileUrl; let size = await getFileInfo(filePath) dataObject.size = size console.log(dataObject); if (success) { success(dataObject); } let type = dataObject.imageURL.split('.').slice(-1) let startIndex = dataObject.imageURL.lastIndexOf('/') let name = dataObject.imageURL.slice(startIndex + 1) let file = { name: name, type: formatFile(type), size: size, url: dataObject.fileUrl, } console.log(file); saveAttachment(file) } catch (e) { console.log('parse JSON failed, origin String is: ' + dataString) if (fail) { fail(e); } } }, fail: function (error) { console.error(error); if (fail) { fail(error); } }, complete: function (data) { complete && complete(data); } }) uploadTask.onProgressUpdate((res) => { progress && progress(res) }) cancelTask && cancelTask(() => { uploadTask.abort() }) } function getQiniuToken(callback) { wx.request({ url: config.qiniuUploadTokenURL, success: function (res) { let token = res.data.uptoken; if (token && token.length > 0) { config.qiniuUploadToken = token; if (callback) { callback(); } } else { console.error('qiniuUploader cannot get your token, please check the uptokenURL or server') } }, fail: function (error) { console.error('qiniu UploadToken is null, please check the init config or networking: ' + error); } }) } function uploadURLFromRegionCode(code) { let uploadURL = null; switch (code) { case 'ECN': uploadURL = 'https://up.qiniup.com'; break; case 'NCN': uploadURL = 'https://up-z1.qiniup.com'; break; case 'SCN': uploadURL = 'https://up-z2.qiniup.com'; break; case 'NA': uploadURL = 'https://up-na0.qiniup.com'; break; case 'ASG': uploadURL = 'https://up-as0.qiniup.com'; break; default: console.error('please make the region is with one of [ECN, SCN, NCN, NA, ASG]'); } return uploadURL; } /* 上传校验空间 */ async function authSpaceCount() { let company = CONFIG.default.company let query = new Parse.Query("Company"); query.select("configSpace") let comObj = await query.get(company); let limit = comObj.get("configSpace") && comObj.get("configSpace").limit; return new Promise((res, rej) => { wx.request({ url: `https://server.fmode.cn/api/storage/space?c=${company}`, data: {}, header: { 'content-type': 'application/json' }, method: 'GET', dataType: 'json', responseType: 'text', success: (result) => { let data = result?.data?.data let spaceMap = data; let _spaceLimit = getLimitBytes(limit) || spaceLimit; let spaceUsed = spaceMap.totalSize; console.log('总空间:', _spaceLimit); console.log('已用空间:', spaceUsed); if (!_spaceLimit || spaceUsed > _spaceLimit) { res(false) return } res(true) }, fail: (err) => { console.warn(err); rej('request space API fail') }, complete: () => { } }); }) } // 单位 function getLimitBytes(limit) { if (limit) { let num = Number(limit.slice(0, limit.length - 2)) let unit = limit.slice(-2) switch (unit) { case "EB": unit = 1024 * 1024 * 1024 * 1024 * 1024 * 1024 break; case "PB": unit = 1024 * 1024 * 1024 * 1024 * 1024 break; case "TB": unit = 1024 * 1024 * 1024 * 1024 break; case "GB": unit = 1024 * 1024 * 1024 break; case "MB": unit = 1024 * 1024 break; case "KB": unit = 1024 break; default: break; } return num * unit } return 0 } //上传保存Attachment async function saveAttachment(file, cateId) { let query = new Parse.Query("Attachment"); query.equalTo("url", file.url); let attachment = await query.first(); if (attachment && attachment.id) { console.error("该文件已存在,无需重复上传"); return } else { let Attachment = Parse.Object.extend("Attachment") attachment = new Attachment(); attachment.set("size", file.size) attachment.set("url", file.url) attachment.set("name", file.name) attachment.set("mime", file.type) attachment.set("company", { __type: "Pointer", className: "Company", objectId: CONFIG.default.company }) cateId && attachment.set("category", { __type: "Pointer", className: "Category", objectId: cateId }) return await attachment.save() } } // 获取本地存储文件大小 function getFileInfo(filePath) { return new Promise((result) => { wx.getFileInfo({ filePath: filePath, success(res) { result(res.size) }, fail(err){ result(0) } }) }) } function formatFile(type) { let fileJson = { "doc": "xapplication/vnd.openxmlformats-officedocument.wordprocessingml.document", "doc": "application/msword", "pdf": "application/pdf", "rtf": "application/rtf", "xls": "application/vnd.ms-excel", "ppt": "application/vnd.ms-powerpoint", "rar": "application/x-rar-compressed", "swf": "application/x-shockwave-flash", "zip": "application/zip", "mid": "audio/midi", "midi": "audio/midi", "kar": "audio/midi", "mp3": "audio/mpeg", "ogg": "audio/ogg", "m4a": "audio/x-m4a", "ra": "audio/x-realaudio", "gif": "image/gif", "jpeg": "image/jpeg", "jpg": "image/jpeg", "png": "image/png", "tif": "image/tiff", "tiff": " image/tiff", "wbmp": " image/vnd.wap.wbmp", "ico": "image/x-icon", "jng": "image/x-jng", "bmp": "image/x-ms-bmp", "svg": "image/svg+xml", "svgz": " image/svg+xml", "webp": " image/webp", "css": "text/css", "html": " text/html", "htm": "text/html", "shtm": "l text/html", "txt": "text/plain", "xml": "text/xml", "3gpp": " video/3gpp", "3gp": "video/3gpp", "mp4": "video/mp4", "mpeg": " video/mpeg", "mpg": "video/mpeg", "mov": "video/quicktime", "webm": "video/webm", "flv": "video/x-flv", "m4v": "video/x-m4v", "wmv": "video/x-ms-wmv", "avi": "video/x-msvideo", } return fileJson[type] || type } module.exports = { init: init, upload: upload, }