❤ Uniapp使用四( 复杂配置和各种实现篇)
(1)图片上传
图片选择
const maxCount = fileMap.imageUrls ? fileMap.maxSize - fileMap.imageUrls.length : fileMap.maxSize; // 限制最多可以选择的图片张数
uni.chooseMedia({
count: maxCount,
mediaType: ["image"],
sizeType: ["compressed"],
camera: "back",
success: (res) => {
const tempFiles = res.tempFiles;
const accept = ["jpg", "jpeg", "png", "JPG", "JPEG", "PNG"];
let fail = false;
tempFiles.forEach((item, index) => {
console.log("压缩之后的图片大小", item.size)
const extension = item.tempFilePath
.split(".")[1];
if (accept.indexOf(extension) === -1 || Number(item.size) >
Number(
5242880) ||
fileMap.imageUrls.length >= fileMap.maxSize
) {
fail = true;
} else {
this.uploadFile(item, fileMap);
}
});
if (fail) {
uni.showToast({
title: `仅支持照片文件,最大支持5M,最多传${fileMap.maxSize}张`,
icon: "none",
duration: 3000,
});
}
},
});
uni.loadFile上传至文件服务器
uploadFile(file, fileMap) {
this.showLoading = true;
// 以文件流的方式上传文件
uni.uploadFile({
url: config.baseUrl + '/common/uploadFile',
filePath: file.tempFilePath || '',
name: 'file',
formData: {},
headers: { 'Content-Type': 'multipart/form-data' },
success: (uploadFileRes) => {
this.showLoading = false;
console.log('uploadFileRes>>',uploadFileRes);
if (uploadFileRes && uploadFileRes.errMsg == 'uploadFile:ok') {
let picItem = uploadFileRes && uploadFileRes.data ? JSON.parse(uploadFileRes.data) || {} : {}
if (picItem.errCode == -1) {
let url = picItem.data || ''
const result = { data: {url} }
this.addImageInfoEvt(fileMap, result) // 更新图片列表
} else {
uni.showToast({
icon: 'error',
title: picItem.errMsg || '文件上传失败,请重试'
})
}
}
},
fail: (err) => {
this.showLoading = false;
console.log('图片上传接口调用失败', err)
}
})
}
(2)视频上传
视频选择
chooseFile() {
uni.chooseVideo({
count: 1,
sourceType: ["camera", "album"],
maxDuration: 30,
mediaType: ["video"],
success: (res) => {
if (res.size / 1024 / 1024 > 50) {
return uni.showToast({
icon: "none",
title: "拍摄视频过大,请重新拍摄!",
});
}
this.uploadFile(res);
},
});
}
视频上传
uploadFile(file) {
uni.showLoading({ title: "努力加载中", mask: true });
// 以文件流的方式上传文件
uni.uploadFile({
url: config.baseUrl + "/common/uploadFile",
filePath: file.tempFilePath || "",
name: "file",
formData: {},
headers: { "Content-Type": "multipart/form-data" },
success: async (uploadFileRes) => {
uni.hideLoading()
console.log("uploadFileRes>>", uploadFileRes);
if (uploadFileRes && uploadFileRes.errMsg == "uploadFile:ok") {
const item =
uploadFileRes && uploadFileRes.data
? JSON.parse(uploadFileRes.data) || {}
: {};
const params = {
applyId: this.applyId,
type: 1,
VEDIO_SP: item.data,
};
const { flag } = await this.$api.investigate.addImageInfoCredit(
params
);
if (flag) this.getImageInfoCredit();
}
},
fail: (err) => {
uni.hideLoading()
console.log("图片上传接口调用失败", err);
},
});
}
(3)音频上传
音频上传,微信小程序不支持,可以使用uni.chooseMessageFile,从聊天记录中选中音频上传
音频选择
chooseFile() {
uni.chooseMessageFile({
count: 1,
extension: [".mp3"],
success: (res) => {
console.log("从聊天记录中获取文件", res);
const { errMsg, tempFiles } = res;
if (errMsg == "chooseMessageFile:ok" && tempFiles.length) {
const { name, size, path } = tempFiles[0];
console.log("临时文件", { size, path });
if (name.slice(-4) != ".mp3") {
return uni.showToast({
icon: "none",
title: "请上传mp3文件!",
duration: 2000,
});
}
if (size / 1024 / 1024 > 50) {
return uni.showToast({
icon: "none",
title: "音频文件过大,请重新选择!",
});
}
this.uploadFile(path);
}
},
});
},
音频uni.loadFile上传至文件服务器
uploadFile(path) {
uni.showLoading({ title: "努力加载中", mask: true });
// 以文件流的方式上传文件
uni.uploadFile({
url: config.baseUrl + "/common/uploadFile",
filePath: path || "",
name: "file",
formData: {},
headers: { "Content-Type": "multipart/form-data" },
success: async (uploadFileRes) => {
uni.hideLoading();
console.log("uploadFileRes>>", uploadFileRes);
if (uploadFileRes && uploadFileRes.errMsg == "uploadFile:ok") {
const item =
uploadFileRes && uploadFileRes.data
? JSON.parse(uploadFileRes.data) || {}
: {};
const params = {
applyId: this.applyId,
type: 1,
VEDIO_LY: item.data,
};
const { flag } = await this.$api.investigate.addImageInfoCredit(
params
);
if (flag) this.getImageInfoCredit();
}
},
fail: (err) => {
uni.hideLoading();
console.log("图片上传接口调用失败", err);
},
});
}
音频播放
data() {
return {
audioUrls: [], // 音频列表
innerAudioContext: null,
currentIndex: "",
};
},
onLoad(query) {
this.getImageInfoCredit(); // 获取音频列表
this.initInnerAudioContext();
},
onHide() {
this.innerAudioContext && this.innerAudioContext.stop();
},
onUnload() {
this.innerAudioContext && this.innerAudioContext.stop();
},
methods: {
async getImageInfoCredit() {
const params = { applyId: this.applyId, type: 1 };
const { flag, data } = await this.$api.investigate.getImageInfoCredit(
params
);
if (flag) {
const list =
data.VEDIO_LY.map((item) => ({ audio: item, icon: "play-circle" })) ||
[];
this.audioUrls = list;
}
},
// 音频播放器初始化
initInnerAudioContext() {
this.innerAudioContext = uni.createInnerAudioContext();
this.innerAudioContext.autoplay = true;
this.innerAudioContext.obeyMuteSwitch = false;
this.innerAudioContext.sessionCategory = "playback";
this.innerAudioContext.onPlay(() => {
this.audioUrls = this.audioUrls.map((item, i) => ({
...item,
icon: this.currentIndex == i ? "pause-circle" : "play-circle",
}));
uni.showToast({ icon: "none", title: "开始播放", duration: 2000 });
});
this.innerAudioContext.onPause(() => {
this.audioUrls = this.audioUrls.map((item) => ({
...item,
icon: "play-circle",
}));
uni.showToast({ icon: "none", title: "暂停播放", duration: 2000 });
});
this.innerAudioContext.onEnded(() => {
this.audioUrls = this.audioUrls.map((item) => ({
...item,
icon: "play-circle",
}));
uni.showToast({ icon: "none", title: "播放完成", duration: 2000 });
});
this.innerAudioContext.onError((res) => {
if(res.errCode != -1) uni.showToast({ icon: "none", title: "播放错误", duration: 2000 }); // 手机上从小程序回到主页面,再次进入到小程序时,会触发onError,错误码是-1,这种情况不需要弹出播放错误的提示
console.log("错误", res.errMsg);
console.log("错误", res.errCode);
});
},
handlePlay(item, index) {
this.innerAudioContext.src = item.audio;
if (item.icon == "play-circle") {
// 暂停时,继续播放
this.innerAudioContext.play();
this.currentIndex = index;
} else {
// 正在播放时,暂停播放
this.innerAudioContext.pause();
}
},
}
(4)uniapp引入 vant
引入方式
1、下载vant源码
方式一:从 Vant 官网首页进入 GitHub下载对应版本的压缩包,将文件解压后备用,确保下载的压缩包里有dist 文件夹
2、创建 uniapp 项目,在根目录下新建 一个文件夹wxcomponents ,将下载好的压缩包中的 dist 文件夹放到 wxcomponents 里, 推荐将 dist 重命名为 vant,
3、在根目录下App.vue中引入UI样式index.wxss,如下图
@import "/wxcomponents/vant/common/index.wxss";
4、main.js
实现配置启动页面和四个底部tab切换栏目
先放图片,开发属于底部界面tab栏目
配置启动页面和四个底部tab切换栏目
底部tab栏切换进行配置对应的界面
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "启动页面"
}
},
{
"path": "pages/tabBar/component",
"style": {
"navigationBarTitleText": "内置组件",
"backgroundColor": "#F8F8F8"
}
}, {
"path": "pages/tabBar/API",
"style": {
"navigationBarTitleText": "接口",
"backgroundColor": "#F8F8F8"
}
}, {
"path": "pages/tabBar/CSS",
"style": {
"navigationBarTitleText": "CSS",
"backgroundColor": "#F8F8F8"
}
},
{
"path": "pages/tabBar/template",
"style": {
"navigationBarTitleText": "模板"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#007AFF",
"borderStyle": "black",
"backgroundColor": "#F8F8F8",
"list": [{
"pagePath": "pages/tabBar/component",
"iconPath": "static/component.png",
"selectedIconPath": "static/componentHL.png",
"text": "内置组件"
},
{
"pagePath": "pages/tabBar/API",
"iconPath": "static/api.png",
"selectedIconPath": "static/apiHL.png",
"text": "接口"
},
{
"pagePath": "pages/tabBar/CSS",
"iconPath": "static/css.png",
"selectedIconPath": "static/cssHL.png",
"text": "CSS"
},
{
"pagePath": "pages/tabBar/template",
"iconPath": "static/template.png",
"selectedIconPath": "static/templateHL.png",
"text": "模板"
}
]
},
"uniIdRouter": {}
}
配置跳转完成以后的界面:
转的主页面
uni.switchTab({
url:'/pages/tabBar/API'
})
(5)实现人脸检测
搭建
进入tabBar => 下面的component界面,因为我们设置的该页面为加载页面以后的页面:
写一个人脸检测按钮:
格外注意:
uniapp的css样式和我们的平时写的css pc端样式略微不同,采用单位为rpx
(大致就是我们px的二分之一)
uniapp的全屏宽为 750rpx;
所以按钮样式为
.btnface{
// 750 - 690 = 60
width: 690rpx;
height: 80rpx;
line-height: 80rpx;
text-align: center;
background-color: cadetblue;
color: #fff;
margin:30rpx;
border-radius: 10rpx;
}
为了方便,我们可以直接写一个固定的页面:方便调试
查看效果 不用想我们大致也能猜到 ,跳转进入我们的人脸检测界面
(人脸检测界面前提:我们在目录下搭建文件夹 并且 上面的pages.json 进行了配置 )
// 去人脸识别
uni.navigateTo({
url:'/pages/face/face',
})
思路
1 检测授权
2调用相机
(穿插是否活体检测人脸)
3开始录制
4结束录制
功能
放进去我们的相机组件和相对应的相机方法
<camera ref="video" device-position="front" flash="off" @initdone="initdone" @error="error"
style="width:100%;height:100%;border-radius:50%;
-webkit-backface-visibility: hidden;
overflow: hidden;
position: relative;
-webkit-transform: translate3d(0, 0, 0);">
</camera>
//初始化相机以及初始化相机失败
initdone() {
let _this = this;
// 1、检测相机权限
// 2、录制15s视频
_this.ctx = uni.createCameraContext(); // 初始化相机
//调用人脸检测方法
},
// 相机初始化失败
error(e) {
let _this = this;
console.log(e.detail);
if (e.detail.errMsg == 'insertCamera:fail auth deny') {
_this.tishimsg = '相机授权失败,点击重新授权!';
}
uni.showToast({
title: '相机授权失败,请点击重新授权!',
icon: 'none',
duration: 2000
});
},
//人脸检测方法
// 人脸识别start
isfaceact() {
let _this = this;
console.log('走人脸识别!!!!!!!');
_this.tishimsg = '初始化人脸识别!';
wx.initFaceDetect();
// console.log(wx.initFaceDetect(),'初始化人脸识别');
// createVKSession
// 2、创建 camera 上下文 CameraContext 对象
// _
// this.cameraEngine = wx.createCameraContext();
// 3、获取 Camera 实时帧数据
const listener = this.ctx.onCameraFrame((frame) => {
// if (this.tempImg) {
// return;
// }
// VKSession.detectFace
// 4、人脸识别,使用前需要通过 wx.initFaceDetect 进行一次初始化,推荐使用相机接口返回的帧数据
//wx.faceDetect VKSession.detectFace
wx.faceDetect({
frameBuffer: frame.data,
width: frame.width,
height: frame.height,
enablePoint: true,
enableConf: true,
enableAngle: true,
enableMultiFace: true,
success: (faceData) => {
let face = faceData.faceInfo[0]
if (faceData.x == -1 || faceData.y == -1) {
this.tishimsg = '请保持在相机中!';
// this.showrppg(1);
} else {
if (faceData.faceInfo.length > 1) {
this.tishimsg = '请保证只有一个人';
// this.showrppg(1);
} else {
const {
pitch,
roll,
yaw
} = face.angleArray;
const standard = 0.5
if (Math.abs(pitch) >= standard || Math.abs(roll) >= standard ||
Math.abs(yaw) >= standard) {
this.tishimsg = '请平视摄像头';
} else if (face.confArray.global <= 0.8 || face.confArray
.leftEye <=
0.8 || face.confArray.mouth <= 0.8 || face.confArray.nose <=
0.8 ||
face.confArray.rightEye <= 0.8) {
// 人脸置信度
this.tishimsg = `请勿遮挡五官${face.confArray}`;
} else {
this.tishimsg = '正在录制!';
// this.showrppg(2);
}
}
}
},
fail: (err) => {
if (err.x == -1 || err.y == -1) {
this.tishimsg = '检测不到人';
// this.showrppg(1);
} else {
// console.log(err.errMsg)
this.tishimsg = '网络错误,请退出页面重试';
// this.showrppg(1);
}
},
})
})
// 5、开始监听帧数据
listener.start();
},