|
- <template>
- <div class="page">
- <div class="bottom">
- <video
- v-if="!isSuccess"
- id="video"
- muted
- autoplay="autoplay"
- :controls="false"
- :enable-progress-gesture="false"
- ></video>
- <div v-if="!isSuccess">
- <div class="selectImg" @click="uploadImg">
- <img src="../../assets/img/selectImg.png" />
- <div class="uploadText">上传照片</div>
- </div>
-
- <div id="action" @click="takePicture">
- <div class="circleInside"></div>
- </div>
- </div>
-
- <div v-if="isSuccess">
- <div class="selectImg" @click="uploadImg">
- <img src="../../assets/img/selectImg.png" />
- <div class="uploadText">上传照片</div>
- </div>
-
- <div class="confirm" @click="confirmPhoto">
- <!-- <img src="../../assets/img/success.png" /> -->
- <div class="sure">确定</div>
-
- <div class="uploadText">
- 就这张了 <img src="../../assets/img/success.png" />
- </div>
- </div>
-
- <div class="reTry" @click="reTry">
- <img src="../../assets/img/reTry.png" />
- <div class="uploadText">重新拍摄</div>
- </div>
- </div>
-
- <canvas
- v-if="isShowCanvas"
- id="canvas"
- style="width: 1530; height: 950"
- ></canvas>
-
- <div v-if="isSuccess" class="preview">
- <img v-if="!isUpload" class="fromCamera" :src="CimgSrc" />
- <img v-if="isUpload" class="fromUpload" :src="UimgSrc" />
- </div>
- </div>
-
- <div class="top">
- <div class="example">
- <img src="../../assets/img/c867236efb4fc5707257ef8daf26db4.png" />
- </div>
- <div class="model" @click="goSelectModel">
- <img :src="modelUrl" alt="" />
- <div class="reSelect">点击重新选择模板</div>
- </div>
- </div>
- <!-- Top section -->
- <u-overlay class="overlay" :show="showQrCode" opacity="0.9">
- <view class="content">
- <view class="imageBox">
- <image :src="QRCodeUrl" mode="scaleToFill" />
- </view>
- <text>打开微信扫码上传照片</text>
- <view class="orangeBtn" style="margin-top: 100rpx" @click="cancelUplaod"
- >取 消</view
- >
- </view>
- </u-overlay>
- </div>
- </template>
-
- <script setup>
- import { ref, onMounted } from "vue";
- import { BASE_URL } from "../../utils/request";
- import { onLoad, onShow, onUnload } from "@dcloudio/uni-app";
-
- import { getImageQrcode, findImage } from "../../api/camera.js";
-
- let CimgSrc = ref(""); // 相机拍照的图片路径,上传前需校验
- let CimgSrcYASUO = ref(""); // 压缩后的图片
- let UimgSrc = ref(""); // 用户上传的图片路径,上传无需校验
- let isSuccess = ref(false);
- let isShowCanvas = ref(true);
- let isUpload = ref(false);
-
- let modelUrl = ref("");
- let modelId = ref("");
- let modelMouldType = ref("");
-
- let QRCodeUrl = ref("");
- let showQrCode = ref(false);
-
- let timer = ref(null);
- const getView = () => {
- uni.getSystemInfo({
- success: (res) => {
- const viewportWidth = res.windowWidth; // 视口宽度
- const viewportHeight = res.windowHeight; // 视口高度
- alert(viewportWidth);
- alert(viewportHeight);
- },
- });
- };
-
- const startCamera = () => {
- function getUserMedia(constraints, success, error) {
- if (navigator.mediaDevices.getUserMedia) {
- //最新的标准API
- navigator.mediaDevices
- .getUserMedia({
- audio: false,
- video: {
- facingMode: "user",
- // width: 1000,
- // height: 1000,
- width: 1080,
- height: 1305,
- // width: 2100,
- // height: 2100,
- },
- })
- .then(success)
- .catch(error);
- } else if (navigator.webkitGetUserMedia) {
- //webkit核心浏览器
- navigator.webkitGetUserMedia(constraints, success, error);
- } else if (navigator.mozGetUserMedia) {
- //firfox浏览器
- navigator.mozGetUserMedia(constraints, success, error);
- } else if (navigator.getUserMedia) {
- //旧版API
- navigator.getUserMedia(constraints, success, error);
- }
- }
-
- const video = document.querySelector("video.uni-video-video");
- let canvas = document.querySelector("canvas.uni-canvas-canvas");
- const action = document.querySelector("#action");
- let context = canvas.getContext("2d");
-
- function success(stream) {
- //兼容webkit核心浏览器
- let CompatibleURL = window.URL || window.webkitURL;
- //将视频流设置为video元素的源
- console.log(stream);
-
- //video.src = CompatibleURL.createObjectURL(stream);
- video.srcObject = stream;
- video.play();
- }
-
- function error(error) {
- console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
- }
-
- if (
- navigator.mediaDevices.getUserMedia ||
- navigator.getUserMedia ||
- navigator.webkitGetUserMedia ||
- navigator.mozGetUserMedia
- ) {
- //调用用户媒体设备, 访问摄像头
- getUserMedia(
- {
- audio: false,
- video: {
- facingMode: "user",
- // width: 240,
- // height: 450,
- width: 1080,
- height: 1305,
- // width: 2100,
- // height: 2100,
- },
- },
- success,
- error
- );
- } else {
- alert("不支持访问用户媒体");
- }
-
- action.addEventListener("click", function () {
- uni.showToast({
- title: "准备好了吗?",
- icon: "success",
- });
- setTimeout(() => {
- let i = 3;
- const timer = setInterval(() => {
- uni.showLoading({
- title: i,
- });
- i--;
- console.log(i);
- if (i == 0) {
- clearInterval(timer);
-
- setTimeout(async () => {
- uni.hideLoading();
- // canvas.width = 1530;
- // canvas.height = 950;
- canvas.width = 1500;
- canvas.height = 1500;
- context.drawImage(video, 0, 0);
- let dataURL = canvas.toDataURL("image/png");
- console.log(dataURL);
- CimgSrc.value = dataURL;
- UimgSrc.value = "";
-
- setTimeout(() => {
- isShowCanvas.value = false;
- isSuccess.value = true;
- }, 10);
- }, 1000);
- }
- }, 1100);
- }, 1000);
- });
-
- // 备用方案
- // action.addEventListener("click", function () {
- // context.drawImage(video, -50, -50, 310, 220);
- // const dataURL = canvas.toDataURL("image/png");
- // imgSrc.value = dataURL;
-
- // setTimeout(() => {
- // isShowCanvas.value = false;
- // isSuccess.value = true;
- // }, 10);
- // console.log(dataURL);
- // });
- };
- //压缩图片
- function compressBase64Image(base64String, maxWidth, maxHeight) {
- return new Promise((resolve, reject) => {
- const img = new Image();
- img.src = base64String;
-
- img.onload = function () {
- const canvas = document.createElement("canvas");
- let width = img.width;
- let height = img.height;
-
- if (width > maxWidth) {
- height *= maxWidth / width;
- width = maxWidth;
- }
-
- if (height > maxHeight) {
- width *= maxHeight / height;
- height = maxHeight;
- }
-
- const ctx = canvas.getContext("2d");
- canvas.width = width;
- canvas.height = height;
- ctx.drawImage(img, 0, 0, width, height);
-
- const compressedBase64 = canvas.toDataURL("image/jpeg");
- resolve(compressedBase64);
- };
-
- img.onerror = function (error) {
- reject(error);
- };
- });
- }
-
- const takePicture = () => {
- console.log("Take Picture !");
- };
-
- const goSelectModel = () => {
- uni.navigateTo({
- url: `/pages/chooseStyle/index`,
- });
- };
-
- // 确认照片
- const confirmPhoto = () => {
- // alert("点击确定");
- // alert(UimgSrc.value, "UimgSrc.value");
- // alert(CimgSrc.value, "CimgSrc.value");
- try {
- if (UimgSrc.value) {
- uni.navigateTo({
- url: `/pages/createing/index?imageUrl=${UimgSrc.value}&id=${modelId.value}`,
- });
- } else if (CimgSrc.value) {
- // 本地存储中的拍照照片
- // alert(uni.getStorageSync("CcurrentUrl"), "CcurrentUrl");
- // // let CimageUrl = uni.getStorageSync("CcurrentUrl");
- // // 用户上一次使用相机拍照的照片,从本地回显,已通过校验,直接放行
- if (uni.getStorageSync("CcurrentUrl")) {
- uni.navigateTo({
- url: `/pages/createing/index?imageUrl=${CimgSrc.value}&id=${modelId.value}`,
- });
- // // 用户使用相机拍照的照片,未校验,走完校验流程放行
- } else {
- dealImage(CimgSrc.value);
- }
- // dealImage(CimgSrcYASUO.value);
- }
- } catch (e) {
- uni.showToast({
- title: e,
- icon: "success",
- mask: true,
- });
- }
- // 用户上传的照片,已通过校验,直接放行
- };
-
- const dealImage = async (imageUrl) => {
- try {
- uni.showLoading({
- title: "上传中,马上就好",
- });
- await compressBase64Image(imageUrl, 1200, 1200)
- .then((compressedBase64) => {
- CimgSrcYASUO.value = compressedBase64;
- })
- .catch((error) => {
- console.error("压缩失败", error);
- });
- // 将二进制数据转换为 Blob 对象
- // let blob = await dataURLtoBlob(imageUrl);
- // checkImageByBaidu(blob);
- // let blob = await dataURLtoBlob(imageUrl);
- // console.log(dataURLtoBlob(imageUrl));
- checkImageByBaidu(dataURLtoBlob(CimgSrcYASUO.value));
- } catch (error) {
- console.error("压缩失败", error);
- }
- };
-
- /**
- * Base64字符串转二进制流
- * @param {String} dataurl Base64字符串(字符串包含Data URI scheme,例如:data:image/png;base64, )
- */
- const dataURLtoBlob = (dataurl) => {
- var arr = dataurl.split(","),
- mime = arr[0].match(/:(.*?);/)[1],
- bstr = atob(arr[1]),
- n = bstr.length,
- u8arr = new Uint8Array(n);
- while (n--) {
- u8arr[n] = bstr.charCodeAt(n);
- }
- return new Blob([u8arr], {
- type: mime,
- });
- };
-
- // 百度图片校验
- const checkImageByBaidu = async (file) => {
- try {
- uni.showLoading({
- title: "正在检测图片合法性 1/3",
- });
- uni.uploadFile({
- url: BASE_URL + "api/baidu/checkPhoto",
- file,
- header: {
- authorization: uni.getStorageSync("token"),
- },
- timeout: 30000,
- // formData: data,
- success: (res) => {
- console.log(res, "上传成功");
- const data = JSON.parse(res.data);
- if (data.code == 200) {
- uni.hideLoading();
- checkImageByMetavatar(file);
- } else {
- uni.hideLoading();
- uni.showToast({
- title: "图片不合规哦,请更换一张",
- icon: "error",
- });
- }
- },
- fail: (res) => {
- uni.hideLoading();
- uni.showToast({
- title: "上传失败,请稍后再试",
- icon: "none",
- });
- console.log(res, "上传失败");
- },
- });
- } catch (error) {
- uni.hideLoading();
- uni.showToast({
- title: "请求失败,请稍后再试",
- icon: "none",
- });
- }
- };
-
- // 邃芒人脸校验
- const checkImageByMetavatar = async (file) => {
- uni.showLoading({
- title: "正在检测人脸位置 2/3",
- });
- uni.uploadFile({
- url: BASE_URL + "api/userDigital/checkPhoto",
- file,
- header: {
- authorization: uni.getStorageSync("token"),
- },
- timeout: 30000,
- // formData: data,
- success: (res) => {
- console.log(res, "上传成功");
- const data = JSON.parse(res.data);
- if (data.code == 200) {
- uni.hideLoading();
- uoloadImageAws(file);
- } else {
- uni.hideLoading();
- uni.showToast({
- title: "请参考提示区域调整站位哦",
- icon: "error",
- });
- }
- },
- fail: (res) => {
- uni.hideLoading();
- uni.showToast({
- title: "上传失败,请稍后再试",
- icon: "none",
- });
- console.log(res, "上传失败");
- },
- });
- };
-
- // 上传图片到服务器(两步校验通过后)
- const uoloadImageAws = async (file) => {
- uni.showLoading({
- title: "检测完成,上传中 3/3",
- });
- uni.uploadFile({
- url: BASE_URL + "api/upload/awsImgUpload",
- file,
- header: {
- authorization: uni.getStorageSync("token"),
- },
- timeout: 30000,
- // formData: data,
- success: (res) => {
- console.log(res, "上传成功");
- uni.hideLoading();
- const data = JSON.parse(res.data);
- if (data.code == 200) {
- uni.showToast({
- title: "上传成功!",
- icon: "success",
- duration: 1500,
- });
- setTimeout(() => {
- // 将拍照照片地址存储到本地并清空上传照片地址
- // uni.setStorageSync("CcurrentUrl", data.data.url);
- uni.setStorageSync("CcurrentUrl", data.data.url);
- uni.setStorageSync("UcurrentUrl", null);
- uni.navigateTo({
- url: `/pages/createing/index?imageUrl=${data.data.url}&id=${modelId.value}`,
- });
- }, 1000);
- } else {
- uni.hideLoading();
- uni.showToast({
- title: "网络波动,请稍后再试",
- icon: "error",
- });
- }
- },
- fail: (res) => {
- uni.hideLoading();
- uni.showToast({
- title: "上传失败,请稍后再试",
- icon: "none",
- });
- console.log(res, "上传失败");
- },
- });
- };
-
- // 不满意,重新拍一张
- const reTry = () => {
- isSuccess.value = false;
- isUpload.value = false;
- isShowCanvas.value = true;
- CimgSrc.value = "";
- UimgSrc.value = "";
- CimgSrcYASUO.value = "";
- uni.setStorageSync("CcurrentUrl", null);
- setTimeout(() => {
- startCamera();
- }, 10);
- };
-
- // 点击上传照片按钮
- const uploadImg = async () => {
- const data = {
- machineQrcodeId: localStorage.getItem("UserId"),
- mouldType: modelMouldType.value,
- };
- // const UserId = localStorage.getItem("UserId");
- // const mouldType = modelMouldType.value;
- try {
- const res = await getImageQrcode(data);
- QRCodeUrl.value = res.data.wxQrcode;
- showQrCode.value = true;
-
- // 成功展示二维码之后,轮询获取上传照片状态
- timer.value = setInterval(() => {
- refreshUploadStatus(res.data.id);
- }, 1000);
- console.log(res, "res");
- } catch (error) {
- console.log(error, "error");
- }
- };
-
- // 刷新状态,直到返回用户上传的图片url
- const refreshUploadStatus = async (id) => {
- try {
- const res = await findImage(id);
- console.log(res, "res");
- if (res.data.imageList && res.data.imageList.length) {
- const imageUrl = res.data.imageList[0];
- clearInterval(timer.value);
- uni.showToast({
- title: "上传成功!",
- icon: "success",
- });
- showQrCode.value = false;
- UimgSrc.value = imageUrl;
- CimgSrc.value = "";
- CimgSrcYASUO.value = "";
- isShowCanvas.value = false;
- isSuccess.value = true;
- isUpload.value = true;
-
- // 将上传照片地址存储到本地并清空拍照照片地址
- uni.setStorageSync("CcurrentUrl", null);
- uni.setStorageSync("UcurrentUrl", UimgSrc.value);
- }
- } catch (error) {
- console.log(error, "error");
- }
- };
-
- // 点击取消,关闭二维码弹窗并取消轮询
- const cancelUplaod = () => {
- showQrCode.value = false;
- clearInterval(timer.value);
- };
-
- onLoad((options) => {
- console.log(options, "options");
- modelUrl.value = options.modelUrl;
- modelId.value = options.id;
- modelMouldType.value = options.mouldType;
- });
-
- onMounted(() => {
- clearInterval(timer.value);
- startCamera();
- const CimageUrl = uni.getStorageSync("CcurrentUrl");
- const UimageUrl = uni.getStorageSync("UcurrentUrl");
- if (CimageUrl || UimageUrl) {
- setTimeout(async () => {
- showQrCode.value = false;
- if (CimageUrl) {
- UimgSrc.value = "";
- CimgSrc.value = CimageUrl;
- isUpload.value = false;
- } else if (UimageUrl) {
- UimgSrc.value = UimageUrl;
- CimgSrc.value = "";
- CimgSrcYASUO.value = "";
- isUpload.value = true;
- }
-
- isShowCanvas.value = false;
- isSuccess.value = true;
- }, 1000);
- }
- });
-
- //#region 页面初始化和卸载
- const resetTimer = ref(null);
- onMounted(() => {
- window.document.addEventListener("touchstart", () => {
- // 用户点击时,清除之前的定时器
- clearTimeout(resetTimer.value);
- // 重新设定120秒后触发的定时器
- resetTimer.value = setTimeout(() => {
- userInfoModulesPinia.clearStorage();
- window.webview.raiseEvent("pageRefresh", "test_params");
- uni.redirectTo({ url: "/pages/login/index" });
- }, 300000);
- });
- resetTimer.value = setTimeout(() => {
- userInfoModulesPinia.clearStorage();
- window.webview.raiseEvent("pageRefresh", "test_params");
- uni.redirectTo({ url: "/pages/login/index" });
- }, 300000);
- });
- onUnload(() => {
- uni.hideLoading();
- clearTimeout(resetTimer.value);
- });
- //#endregion -----------------------
- </script>
-
- <style lang="scss" scoped>
- .page {
- width: 100vw;
- height: 100vh;
- padding: 0;
-
- .top {
- display: flex;
- width: 100%;
- height: 32%;
- .example {
- width: 60%;
- height: 100%;
- color: #000;
- background-color: #fff;
- img {
- width: 100%;
- height: 100%;
- }
- }
- .model {
- position: relative;
- width: 40%;
- height: 100%;
- background-color: #000000;
- img {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 100%;
- height: 100%;
- }
- .reSelect {
- position: absolute;
- width: 250rpx;
- left: 50%;
- bottom: 10rpx;
- text-align: center;
- transform: translateX(-50%);
- }
- }
- }
- .bottom {
- position: relative;
- width: 100%;
- height: 68%;
- overflow: hidden;
- video {
- width: 100%;
- height: 100%;
- // width: 1080px;
- // height: 1305px;
- :deep(.uni-video-video) {
- position: absolute;
- left: 0;
- top: -50px;
- width: 100% !important;
- height: 720px !important;
- }
- }
- .selectImg {
- position: absolute;
- left: 65rpx;
- bottom: 75rpx;
- width: 68rpx;
- height: 68rpx;
- border: 5rpx solid #ffffff;
- border-radius: 5rpx;
- z-index: 99;
- img {
- position: absolute;
- left: 50%;
- bottom: 50%;
- transform: translate(-50%, 50%);
- width: 70%;
- height: 70%;
- }
- .uploadText {
- position: absolute;
- left: 50%;
- bottom: -40rpx;
- width: 150%;
- font-size: 20rpx;
- transform: translateX(-40%);
- }
- }
-
- #action {
- position: absolute;
- left: 50%;
- bottom: 45rpx;
- width: 120rpx;
- height: 120rpx;
- transform: translateX(-50%);
- background-color: #ffffff;
- border-radius: 60rpx;
- z-index: 99;
- .circleInside {
- position: absolute;
- left: 50%;
- bottom: 50%;
- transform: translate(-50%, 50%);
- width: 100rpx;
- height: 100rpx;
- background-color: #ffffff;
- border-radius: 50%;
- border: 6rpx solid #000;
- }
- }
-
- .confirm {
- position: absolute;
- left: 50%;
- bottom: 75rpx;
- width: 180rpx;
- height: 80rpx;
- // border: 5rpx solid #ffffff;
- transform: translateX(-50%);
- border-radius: 60rpx;
- z-index: 9999999;
- img {
- // position: absolute;
- // left: 50%;
- // bottom: 50%;
- // transform: translate(-50%, 50%);
- width: 100%;
- height: 100%;
- width: 30rpx;
- height: 30rpx;
- vertical-align: text-top;
- }
- .sure {
- margin-top: 30rpx;
- text-align: center;
- width: 100%;
- height: 50rpx;
- line-height: 50rpx;
- background-color: #2ba245;
- border-radius: 15rpx;
- }
- .uploadText {
- // position: absolute;
- // left: 50%;
- // bottom: -40rpx;
- // width: 150%;
-
- width: 100%;
- height: 30rpx;
- line-height: 30rpx;
- font-size: 20rpx;
- // transform: translateX(-32%);
- text-align: center;
- }
- }
-
- .reTry {
- position: absolute;
- right: 65rpx;
- bottom: 75rpx;
- width: 68rpx;
- height: 68rpx;
- border: 5rpx solid #ffffff;
- border-radius: 5rpx;
- z-index: 99;
- img {
- position: absolute;
- left: 50%;
- bottom: 50%;
- transform: translate(-50%, 50%);
- width: 70%;
- height: 70%;
- }
- .uploadText {
- position: absolute;
- left: 50%;
- bottom: -40rpx;
- width: 150%;
- font-size: 20rpx;
- transform: translateX(-40%);
- }
- }
-
- .preview {
- position: relative;
- width: 100%;
- height: 100%;
- z-index: 1;
- .fromCamera {
- // position: absolute;
- // top: 110rpx;
- // left: 130rpx;
- width: 100%;
- }
- .fromUpload {
- position: absolute;
- top: 110rpx;
- left: 50%;
- transform: translateX(-50%);
- width: 45%;
- }
- }
- }
- .overlay {
- .content {
- width: 100%;
- height: 100vh;
- display: flex;
- flex-direction: column;
- align-items: center;
- text-align: center;
- .imageBox {
- position: relative;
- margin-top: 200rpx;
- width: 300rpx;
- height: 300rpx;
- border-radius: 30rpx;
- background-color: #fff;
- .mask {
- position: absolute;
- width: 100%;
- height: 100%;
- border-radius: 30rpx;
- background-color: rgba($color: #000000, $alpha: 0.7);
- z-index: 2;
- }
- image {
- width: 100%;
- height: 100%;
- border-radius: 30rpx;
- background-color: #fff;
- }
- }
- text {
- margin-top: 20rpx;
- font-weight: 900;
- font-size: 32rpx;
- }
- // .orangeBtn {
- // margin-top: 100rpx;
- // }
- }
- }
- }
- </style>
|