|
|
@@ -2,17 +2,13 @@
|
|
|
<view class="zhuapai-drop-container" id="Drop" ref="DropRef" :style="style" @touchmove="touchmove($event)"
|
|
|
@touchstart="touchstart($event)">
|
|
|
<view class="phone-camera-box-zhuapai">
|
|
|
- <video ref="videoRef" class="video-view-box" :class="myClass" id="videoZhaPai" :controls="false"></video>
|
|
|
- <!-- 隐藏抓拍绘制图片 -->
|
|
|
- <canvas id="canvasZhuaPai" class="video-view-box canvas-view-box" :class="myClass"></canvas>
|
|
|
+ <camera class="camera" device-position="back" flash="off" style="width: 200px;height: 200px" :class="myClass" @initdone="onVideoSuccess"></camera>
|
|
|
<!-- 用于抓拍切出去传递固定img-->
|
|
|
- <!-- #ifdef H5 -->
|
|
|
- <img :src="imgUrl" alt="" id="gdImg" v-show="false">
|
|
|
- <!-- #endif -->
|
|
|
+ <img :src="imgUrl" alt="" v-show="false">
|
|
|
<!-- 测试抓拍使用 -->
|
|
|
<!-- <button @click="handleZhua">抓拍</button> -->
|
|
|
</view>
|
|
|
- <span v-show="showVideo" @click="noShowVideoBtn" class="shiti-video-hidden-btn"><i></i></span>
|
|
|
+ <span v-show="showVideo" @click="noShowVideoBtn" class="shiti-video-hidden-btn"><i>隐藏</i></span>
|
|
|
<span v-show="!showVideo" @click="showVideoBtn" class="shiti-video-show-btn"><i></i></span>
|
|
|
</view>
|
|
|
</template>
|
|
|
@@ -22,21 +18,21 @@
|
|
|
ref,
|
|
|
onUnmounted,
|
|
|
nextTick,
|
|
|
- computed
|
|
|
+ computed,
|
|
|
} from "vue";
|
|
|
- import {
|
|
|
- useH5Camera
|
|
|
- } from "@/components/zhuapaiConfirm/useCamera";
|
|
|
import * as ksApi from "@/api/kaoshi.js"
|
|
|
import {
|
|
|
getStaticUrl
|
|
|
} from "@/utils/common.js"
|
|
|
+
|
|
|
+ import {useZhuapaiStore} from "@/store/zhuapai.js"
|
|
|
+ import {getFileUpload} from "@/api/kaoshi.js"
|
|
|
+
|
|
|
+ const zhuapaiStore = useZhuapaiStore();
|
|
|
|
|
|
const imgUrl = getStaticUrl('static/images/exam/nokaoshi.png')
|
|
|
|
|
|
- let zhuapaiFun = null;
|
|
|
- let stopCamera = null;
|
|
|
- let playVideoFun = null;
|
|
|
+ const cameraContext = ref(null);
|
|
|
|
|
|
const DropRef = ref(null);
|
|
|
const DropContainerRef = ref(null);
|
|
|
@@ -68,7 +64,6 @@
|
|
|
|
|
|
function showVideoBtn() {
|
|
|
showVideo.value = true;
|
|
|
- playVideoFun && playVideoFun();
|
|
|
}
|
|
|
|
|
|
function touchmove(event) {
|
|
|
@@ -76,14 +71,16 @@
|
|
|
let moveX = event.touches[0].pageX - disX.value;
|
|
|
let moveY = event.touches[0].pageY - disY.value;
|
|
|
|
|
|
- const systemInfo = uni.getSystemInfoSync();
|
|
|
+ const systemInfo = uni.getAppBaseInfo();
|
|
|
const windowHeight = systemInfo.windowHeight; // 可视区域高度 :ml-citation{ref="1,3" data="citationList"}
|
|
|
const windowWidth = systemInfo.windowWidth; // 可视区域高度 :ml-citation{ref="1,3" data="citationList"}
|
|
|
|
|
|
|
|
|
// 3,获取容器的宽高和拖动元素的宽高 每一次移动都会获取一次 ,建议放在外面进行获取
|
|
|
- let dragHeight = DropRef.value.$el.offsetHeight;
|
|
|
- let dragWidth = DropRef.value.$el.offsetWidth;
|
|
|
+ // let dragHeight = DropRef.value.$el.offsetHeight;
|
|
|
+ // let dragWidth = DropRef.value.$el.offsetWidth;
|
|
|
+ let dragHeight = 0;
|
|
|
+ let dragWidth = 0;
|
|
|
|
|
|
// 4,控制范围:在元素 被拖拽的过程中 判断 元素的定位值 是否到达边界 如果到了 就不能在走了
|
|
|
if (moveX <= 0) {
|
|
|
@@ -108,8 +105,10 @@
|
|
|
}
|
|
|
|
|
|
function touchstart(event) {
|
|
|
- disX.value = event.touches[0].pageX - DropRef.value.$el.offsetLeft;
|
|
|
- disY.value = event.touches[0].pageY - DropRef.value.$el.offsetTop;
|
|
|
+ // disX.value = event.touches[0].pageX - DropRef.value.$el.offsetLeft;
|
|
|
+ // disY.value = event.touches[0].pageY - DropRef.value.$el.offsetTop;
|
|
|
+ disX.value = 0;
|
|
|
+ disY.value = 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -126,34 +125,105 @@
|
|
|
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
|
|
|
function startCamera() {
|
|
|
// 请求摄像头权限并获取流
|
|
|
- // #ifdef H5
|
|
|
- console.log('navigator', navigator)
|
|
|
- const {
|
|
|
- startH5Camera,
|
|
|
- handlePaiZhao,
|
|
|
- stopH5Camera,
|
|
|
- playVideo
|
|
|
- } = useH5Camera({
|
|
|
- elVideoId: '#videoZhaPai',
|
|
|
- elCanvasId: '#canvasZhuaPai',
|
|
|
- onVideoSuccess,
|
|
|
- onVideoError,
|
|
|
- zhuapaiHttp: ksApi.getClientZhuaPaiUpdate,
|
|
|
- operId: operId.value
|
|
|
+ cameraContext.value = uni.createCameraContext();
|
|
|
+ }
|
|
|
+
|
|
|
+ function urlToBase64(url) {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ // #ifdef MP-WEIXIN
|
|
|
+ // 微信小程序平台
|
|
|
+ uni.getFileSystemManager().readFile({
|
|
|
+ filePath: url, // 图片临时路径
|
|
|
+ encoding: 'base64', // 指定编码格式
|
|
|
+ success: (res) => {
|
|
|
+ // 拼接Data URL前缀,注意图片类型可能需要根据实际情况调整(如png)
|
|
|
+ let base64 = 'data:image/jpeg;base64,' + res.data;
|
|
|
+ resolve(base64);
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ reject(err);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // #endif
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ function getSnapShotImage(data) {
|
|
|
+ urlToBase64(data).then((d1) => {
|
|
|
+ const imgData = d1.split(';base64,');
|
|
|
+
|
|
|
+ if (!imgData.length) {
|
|
|
+ console.error('【源 :拍照数据异常,未找到图片二进制数据分割节点: `;base64,`】');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const opt = {
|
|
|
+ data: imgData[1],
|
|
|
+ prefix: 'kaoshi/zhuapai',
|
|
|
+ suffix: 'png',
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ getFileUpload(opt).then(res => {
|
|
|
+ const dOption = {
|
|
|
+ operId:operId.value,
|
|
|
+ url: res.data
|
|
|
+ }
|
|
|
+ ksApi.getClientZhuaPaiUpdate(dOption)
|
|
|
+ .then(res => {
|
|
|
+ console.log('【源 : 获取抓拍数据】');
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ console.error('源 :抓拍接口异常', err);
|
|
|
+ uni.showToast({
|
|
|
+ icon: 'none',
|
|
|
+ title: '抓拍图片异常!'
|
|
|
+ })
|
|
|
+ uni.redirectTo({
|
|
|
+ url: "/pages/client/Kaoshi/list"
|
|
|
+ })
|
|
|
+ });
|
|
|
+ }).catch(err => {
|
|
|
+ uni.showToast({
|
|
|
+ icon: 'none',
|
|
|
+ title: '当前网络可能存在异常,请稍后重试,如持续异常,请联系管理员。注:若异常未联系管理员,可能会影响考试结果。'
|
|
|
+ })
|
|
|
+ uni.redirectTo({
|
|
|
+ url: "/pages/client/Kaoshi/list"
|
|
|
+ })
|
|
|
+ })
|
|
|
})
|
|
|
- startH5Camera();
|
|
|
- zhuapaiFun = handlePaiZhao;
|
|
|
- stopCamera = stopH5Camera;
|
|
|
- playVideoFun = playVideo;
|
|
|
- // #endif
|
|
|
-
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ function doZhuaiPai(ImageFile) {
|
|
|
+ try {
|
|
|
+ if (zhuapaiStore.status == 0) {
|
|
|
+ getSnapShotImage(ImageFile);
|
|
|
+ } else {
|
|
|
+ const ImageFile1 = imgUrl.value;
|
|
|
+ getSnapShotImage(ImageFile1);
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ console.error('源 :绘图失败', err);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
function handleZhua() {
|
|
|
- zhuapaiFun && zhuapaiFun()
|
|
|
+ cameraContext.value.takePhoto({
|
|
|
+ quality: 'high',
|
|
|
+ success: (res) => {
|
|
|
+ doZhuaiPai(res.tempImagePath)
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ console.error('拍照失败:', err);
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
function onVideoSuccess() {
|
|
|
@@ -161,12 +231,10 @@
|
|
|
// 首次运行进行抓拍一次
|
|
|
handleZhua();
|
|
|
}, 3000);
|
|
|
- addVideoListener();
|
|
|
}
|
|
|
|
|
|
function onVideoError() {
|
|
|
emits('error')
|
|
|
- removeVideoListener()
|
|
|
}
|
|
|
|
|
|
// 针对视频通话的监听处理
|
|
|
@@ -198,24 +266,6 @@
|
|
|
console.log('结束')
|
|
|
}, 10 * 1000)
|
|
|
}
|
|
|
- function addVideoListener() {
|
|
|
- let video = document.querySelector(`#videoZhaPai .uni-video-video`)
|
|
|
- // 判定有流
|
|
|
- video.addEventListener('progress', onProgress);
|
|
|
- video.addEventListener('timeupdate', onTimeupdate);
|
|
|
- }
|
|
|
- function removeVideoListener() {
|
|
|
- let video =document.querySelector(`#videoZhaPai .uni-video-video`)
|
|
|
- video && video.removeEventListener('progress', onProgress);
|
|
|
- video && video.removeEventListener('timeupdate', onTimeupdate);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- onUnmounted(() => {
|
|
|
- // 组件销毁时停止摄像头
|
|
|
- stopCamera && stopCamera();
|
|
|
- removeVideoListener();
|
|
|
- })
|
|
|
|
|
|
defineExpose({
|
|
|
init,
|