❤ Uniapp使用四( 高阶使用配置和各种功能实现篇)

❤ 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();
},
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林太白

感谢打赏,你拥有了我VIP权限

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值