1.前台页面
1.1wxml问阿金
<!-- 说明一个上传页面的按钮 -->
<button type="primary" bindtap="uploadPage">上传页面展示</button>
<!-- 声明一个上传服务器的按钮 -->
<button type="warn" bindtap="uploadSever">上传服务器</button>
<!-- 实现点击图片有个预览效果 -->
<view wx:for="{{imgSrcArr}}" bindtap="uploadPreview" wx:key="index" class="img">
<!-- 动态展示图片 -->
<image class="pic" src="{{item.tempFilePath}}" />
<!-- 删除图片 -->
<!-- catchtap并阻止其冒泡到父元素,因为父元素有updatePreview时间 -->
<view class="delete-button" catchtap="deleteImage" data-index="{{index}}">删除</view>
</view>
展示
1.2js文件
1.2.1 uploadPage
说明:调用方法就是属性值是一个函数,因此要注意this问题。要将this指向原来的位置。
uploadPage() {// 改变this,特别是调用方法// 说明:调用方法就是属性值是一个函数,因此要注意this问题let that = thiswx.chooseMedia({count: 9, //表示可以选择的最大图片数量限制,这里设置为 9 表示最多可以选择 9 张图片mediaType: ['image'], //表示媒体文件的类型,在这里设置为 ['image'] 表示只能选择图片类型的文件sourceType: ['album', 'camera'], //表示可以选择的媒体来源,这里设置为 ['album', 'camera'] 表示可以从相册或相机进行选择camera: 'back', //表示前后摄像头的选择,默认为后置摄像头。当然设置的就是后置摄像头success(res) {that.setData({// 可以上传多张图,通过es6解构数组的方式imgSrcArr: [...that.data.imgSrcArr, ...res.tempFiles]})}})},
展示
说明:点击上传页面展示,在这里我点击了两次 !
1.2.2uploadPreview
说明:需要学习Array.map方法的使用。
// 图片预览uploadPreview() {let that = thiswx.previewImage({current: "", // 当前显示图片的http链接// 说明map方法就是遍历数字然后生成一个新的数组,item就是遍历的数组里面的对象,返回tempFilePathurls: that.data.imgSrcArr.map(item => item.tempFilePath)// 需要预览的图片http链接列表,[url,url]这样的})},
展示
说明:点击图片后全屏显示
1.2.3deleteImage按钮
说明:点击删除按钮删除图片
// 删除图片deleteImage(event) {// 解构拿到数组的索引const {index} = event.currentTarget.dataset;// 拿到图片数组const {imgSrcArr} = this.data;// 删除当前索引,删除长度为1imgSrcArr.splice(index, 1);this.setData({imgSrcArr: imgSrcArr});},
sass文件
// 图片
.img {position: relative;.pic {}
// 图片里面的按钮.delete-button {position: absolute;top: 0;right: 0;padding: 4px;font-size: 15px;color: #ffffff;background-color: #BDA066;border-radius: 5px;}
}
说明:如果不写catchtap="deleteImage",因为事件冒泡到了父元素,触发了uploadPreview事件。
1.2.4 上传图片到服务器
说明:使用原生的上传图片目前我只能一张一张上传,因此我是采用了map方法使用,遍历数组每个值,进行上传。
uploadSever() {let that = this
//拿到图片的url地址,map使用that.data.imgSrcArr.map(item => {wx.uploadFile({url: '***********', //服务器地址//图片的地址filePath: item.tempFilePath,// 前台必须传递image,后台规定的字段。name: 'image',success(res) {console.log(res);}})})},
展示,图片存在云数据库的位置
2.后端逻辑
说明:为了自己能够看,不再阐释说明。
import cloud from '@lafjs/cloud'
import { S3, PutObjectCommand } from "@aws-sdk/client-s3";
import fs from 'fs'const s3 = new S3({endpoint: cloud.env.OSS_EXTERNAL_ENDPOINT,region: cloud.env.OSS_REGION,credentials: {accessKeyId: cloud.env.OSS_ACCESS_KEY,secretAccessKey: cloud.env.OSS_ACCESS_SECRET,},forcePathStyle: true,
});
// 正文开始,这才是内容
export async function main(ctx: FunctionContext) {const image = ctx.files[0]// 判断前台上传的图片是否包含 images 字段if (image.fieldname !== "image") {// 如果不存在 images 字段,则返回错误信息return {statusCode: 400,body: JSON.stringify({error: 'Missing images field in the request.'})};}// 将图片的临时位置读取了const fileContent = fs.readFileSync(image.path); // 能够上传成功,展示图片是花的const bucket = "”************************"; // 这里改成你要上传的云储存名称// 文件的路径,存储位置就是images文件夹const path = "/images/" + image.filenameconst command = new PutObjectCommand({// 储存桶的位置Bucket: bucket,// 文件的路径Key: path,Body: fileContent,ContentType: image.mimetype,});let restry {res = await s3.send(command)// console.log("文件上传成功:", res);} catch (error) {return error}let { $metadata: { httpStatusCode } } = reslet { filename } = ctx.files[0]let fileObject = { httpStatusCode, filename }return fileObject
}