仅给出我的处理方式。如果你有更好的处理方式,欢迎在评论区讨论。
本人使用云开发,图片上传到云存储。
整体思路
具体场景(便于讨论):用户发布评论comment
,图片上传到字段image_upload
。
- 准备:在数据库里创建一个
traceId
集合; - 首先,用户上传图片,触发图片审核,并将
traceId
作为云存储路径; - 异步检测结果推送到来时,如果
'suggest' != 'pass'
:- 将
traceId
和固定前缀拼出一个云存储的fileID
; - 在集合
traceId
,利用fileID
作为一个字段创建一个对象 - 利用
fileID
在相关集合(如comment
)的相关字段(如image_upload
)里找:如果找到则直接删除云存储中的fileID
,找不到则不处理;
- 将
- 用户点击提交,首先先创建相关对象(如一个
comment
对象,其中包括字段image_upload
),创建成功后查询集合traceId
的所有对象(违规图片集合),将现有图片列表和违规图片集合进行比较,删除违规图片,并对相关字段(如:image_upload
移除违规图片的fileID
)进行更新。
具体步骤和代码
1、创建云函数:checkContent
(右键 cloudfunctions
→新建 Node.js 云函数
进行创建),上传并部署:云端安装依赖
//index.js
const cloud = require('wx-server-sdk');
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV })
exports.main = async (event, context) => {
const { value, scene } = event;
const { OPENID } = cloud.getWXContext()
try {
let imageR = false;
//检查 图片内容是否违规
if (value) {
imageR = await cloud.openapi.security.mediaCheckAsync({
openid: OPENID,
scene: scene,
version: 2,
media_type: 2,
media_url: value
})
}
return {
imageR, //图片检查返回值
};
} catch (err) {
return err
}
}
2、在某个page
中的js
文件中:
wx.chooseMedia({
count: 9,
sizeType: ['original', 'compressed'],
mediaType: ['image'],
sourceType: ['album', 'camera'],
camera: 'back',
success: res => {
checkAndUploadManyImages(res.tempFiles, this)
},
fail: err => {
console.log(err)
},
})
其中,checkAndUploadManyImages
函数(放在Page({})
之外)实现:
/**
* 触发图片审核
* @param {待审核图片列表} tempFiles
* @param {page = this} page
*/
function checkAndUploadManyImages(tempFiles, page) {
wx.showLoading({
title: '上传中',
mask: true
})
for (var i = 0; i < tempFiles.length; i++) {
const { tempFilePath } = tempFiles[i]
/**
* 1、触发审核,获取traceId
*/
wx.cloud.callFunction({
name: 'checkContent',
data: {
value: wx.cloud.CDN({
type: 'filePath',
filePath: tempFilePath
}),
scene: 3 //场景枚举值(1 资料;2 评论;3 论坛;4 社交日志)
},
success: json => {
console.log(json)
const { traceId } = json.result.imageR
/**
* 2、将traceId作为图片的云存储路径
*/
wx.cloud.uploadFile({
cloudPath: traceId, // 上传至云端的路径
filePath: tempFilePath, // 小程序临时文件路径
success: res => {
const { fileID } = res
//data里:fileID: []。用于存放图片云存储路径。
page.data.fileID.push(fileID)
page.setData({
fileID: page.data.fileID,
})
wx.hideLoading()
wx.showToast({
title: '上传成功 正在审核',
icon: 'none'
})
},
fail: err => {
console.error('uploadFile err', err)
wx.hideLoading()
wx.showToast({
icon: 'error',
title: '上传失败',
})
}
})
},
fail: err => {
console.log('checkContent err', err)
}
})
}
}
至此,只是触发了图片审核。接下来配置mediaCheckAsync的异步检测结果推送。
1、创建云函数 getMediaCheckResult
,上传并部署:云端安装依赖
//index.js
const cloud = require('wx-server-sdk')
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV })
const db = cloud.database();
const traceId = db.collection('traceId') //在此之前,请数据库创建traceId集合
const head = 'cloud://xxx-xxx/' //这里请观察图片云存储路径(可使用consloe.log进行输出查看),将共同的前缀替换这里的字符串
function deleteImage(fileId) {
cloud.deleteFile({
fileList: [fileId],
success: res => {
return res
},
fail: err => {
return err
}
})
}
// 云函数入口函数
exports.main = async (event, context) => {
const { result, trace_id, CreateTime } = event
const { suggest } = result
const fileId = head + trace_id;
if (suggest != 'pass') {
traceId.add({
data: {
fileId,
CreateTime
}
}).then(() => {
//下面根据需要替换成自己的集合
db.collection('comment').where({
image_upload: fileId
}).get()
.then(() => { deleteImage(fileId); })
.catch((err) => { return err })
})
} else {
return {
suggest
}
}
}
2、点击“云开发”-“设置”-“其他设置”-“添加消息推送”-进行配置(下图)-“确定”
3、回到page
的js
文件:
//用户点击“提交”触发的事件
sendContent: function() {
...
comment.add({
data: {
...
image_upload: that.data.fileID,
},
}).then((res) => {
/**
* 二、图片审核:处理异步检测结果推送
*/
/**
* 1、拿到全部的traceId集合(违规图片集合)
*/
const { _id } = res
traceId.orderBy('CreateTime', 'desc').get()
.then((res) => {
/**
* 2、删除上传图片列表中违规图片
*/
deleteInvalidImages(that.data.fileID, res.data).then((res) => {
/**
* 3、更新图片列表
*/
comment.doc(_id).update({
data: {
image_upload: res
}
}).then(() => {
wx.hideLoading()
})
})
})
})
}
其中,deleteInvalidImages
函数实现:
/**
* 删除已上传图片列表中的违规图片,并移除traceId对象
* @param {已上传图片列表} fileIds
* @param {违规图片集合} cloudFileIds
*/
async function deleteInvalidImages(fileIds, cloudFileIds) {
return new Promise(async function (resolve, reject) {
try {
const promises = [];
let fileIdsWithoutCommon = [];
promises.push(new Promise((resolve, reject) => {
// 找到数组 fileIds 和数组 cloudFileIds 共有的元素
const common = fileIds.filter((elementA) =>
cloudFileIds.some((elementB) => elementA === elementB.fileId)
);
// 删除数组 fileIds 中的共有元素
fileIdsWithoutCommon = fileIds.filter((elementA) =>
!cloudFileIds.some((elementB) => elementA === elementB.fileId)
);
/**
* 删除云存储中的违规图片
*/
wx.cloud.deleteFile({
fileList: common,
success: res => {
console.log(res)
resolve();
},
fail: err => {
console.log(err)
reject(err);
}
})
/**
* 移除traceId对象
*/
traceId.where({
fileId: _.in(common)
}).remove({
success: res => {
console.log(res)
resolve();
},
fail: err => {
console.log(err)
reject(err);
}
})
}));
await Promise.all(promises);
resolve(fileIdsWithoutCommon);
} catch (error) {
reject(error);
}
})
}
云函数里面用wx.cloud.delete不报错吗
一次可以检测多张图片吗