雲函數開發遇到的問題
在微信雲開發環境當中,普通的用戶並沒有往雲存儲內寫入文件的權限
所以普通用戶想要使用wx.cloud.uploadFile顯然是不現實的
但是我們同時也知道,雲函數是后台服務端,具有管理員權限,只要能調用雲函數上傳文件就可以解決這個問題了
參照官方文檔中雲函數的寫法
const cloud = require('wx-server-sdk') const fs = require('fs') const path = require('path') exports.main = async (event, context) => { const fileStream = fs.createReadStream(path.join(__dirname, 'demo.jpg')) return await cloud.uploadFile({ cloudPath: 'demo.jpg', fileContent: fileStream, }) }
官方文檔寫的雲里霧里,並不是這么容易理解
_dirname代表的是文件根目錄,官方文檔能實現的功能貌似只是移動雲存儲空間中的文件,並不能操作本地文件
解決方案
只上傳文件路徑是不能把本地文件成功上傳到雲存儲的,但是我們可以將本地文件進行 進制 編碼 轉化為字節流上傳到雲函數中,
再在雲函數的操作中把字節或文件轉化為相對應的格式
微信小程序文檔為我們提供了一個很好的用於編碼文件的功能函數
wx.getFileSystemManager()
利用這個函數,可以把圖片編碼成為base64 的形式上傳到雲函數
如果是多個圖片上傳,只需要遍歷即可
wx.getFileSystemManager().readFile({ filePath: that.data.images[i], //選擇圖片返回的相對路徑 encoding: 'base64', //編碼格式 success: res => { //成功的回調 wx.cloud.callFunction({ name:'file', data:{ path: 'pictures/' + util.vcode(new Date())+index+'.png', file: res.data }, success(_res){ console.log(_res) },fail(_res){ console.log(_res) } }) index++; } })
其中index的作用是對圖片進行區分編碼,有不同的名字,不然重名的文件上傳,原文件會被覆蓋
完整的js文件
import { promisify } from '../../utils/promise.util' import { $init, $digest } from '../../utils/common.util' var util = require('../../utils/util.js') const wxUploadFile = promisify(wx.uploadFile) const db = wx.cloud.database() Page({ data: { titleCount: 0, contentCount: 0, content: '', images: [] }, onLoad(options) { $init(this) }, handleTitleInput(e) { const value = e.detail.value this.data.title = value this.data.titleCount = value.length $digest(this) }, handleContentInput(e) { const value = e.detail.value this.data.content = value this.data.contentCount = value.length $digest(this) }, chooseImage(e) { wx.chooseImage({ count: 3, sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success: res => { const images = this.data.images.concat(res.tempFilePaths) this.data.images = images.length <= 3 ? images : images.slice(0, 3) $digest(this) } }) }, removeImage(e) { const idx = e.target.dataset.idx this.data.images.splice(idx, 1) $digest(this) }, handleImagePreview(e) { const idx = e.target.dataset.idx const images = this.data.images wx.previewImage({ current: images[idx], urls: images, }) }, submitForm(e) { var that = this; var index = 0; var len = that.data.images.length; wx.showLoading({ title: '上傳中...', }) for(var i = 0; i < len ; i++) { console.log(i) wx.getFileSystemManager().readFile({ filePath: that.data.images[i], //選擇圖片返回的相對路徑 encoding: 'base64', //編碼格式 success: res => { //成功的回調 wx.cloud.callFunction({ name:'file', data:{ path: 'pictures/' + util.vcode(new Date())+index+'.png', file: res.data }, success(_res){ console.log(_res) wx.hideLoading() //wx.hideLoading() },fail(_res){ console.log(_res) } }) index++; } }) } } })
其中 $digest(this) 與 $init(this) 是setData的封裝寫法
詳細內容如下
微信小程序開發工具包--> Gitee
至於想用什么方式保存 返回的文件 id 取決於自己
雲函數的寫法
// 雲函數入口文件 const cloud = require('wx-server-sdk') const fs = require('fs') const path = require('path') cloud.init({ env: 'kindear-fd77cd' }) exports.main = async (event, context) => { try{ return await cloud.uploadFile({ cloudPath: event.path, fileContent: new Buffer(event.file, 'base64') }) }catch(e){ return e; } }
其中,必須強調的是cloud.init 必須重新確定下環境id
不然上傳的文件或者圖片並不在小程序初始化的環境中
雲函數實現效果
圖片提交界面如圖所示
點擊提交
在雲存儲中查看
成功上傳
一種雲存儲文件名稱的編碼方式
基本方式在js文件中已經有具體描述,通過具體到秒的時間 和 圖片的上傳順序進行編碼 基本可以保證不會有重名的文件存在
現在給出時間的編碼方式
function vcode(date) { var year = date.getFullYear() var month = date.getMonth() + 1 var day = date.getDate() var hour = date.getHours() var minute = date.getMinutes() var second = date.getSeconds() return [year, month, day].map(formatNumber).join('_') + '_'+[hour, minute, second].map(formatNumber).join('_') }
需要小程序開發的請聯系我QQ:1025584691