邃芒智像大屏项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

929 line
23 KiB

  1. <template>
  2. <div class="page">
  3. <div class="bottom">
  4. <!-- 人物框 -->
  5. <!-- <image
  6. v-if="!isSuccess"
  7. class="frameImg"
  8. src="../../assets/img/people.png"
  9. mode="scaleToFill"
  10. /> -->
  11. <video
  12. v-if="!isSuccess"
  13. id="video"
  14. muted
  15. autoplay="autoplay"
  16. :controls="false"
  17. :enable-progress-gesture="false"
  18. ></video>
  19. <div v-if="!isSuccess">
  20. <div class="selectImg" @click="uploadImg">
  21. <img src="../../assets/img/selectImg.png" />
  22. <div class="uploadText">上传照片</div>
  23. </div>
  24. <div id="action" @click="takePicture">
  25. <view v-show="showTakeTips" class="takeTips1">请把脸面向摄像头</view>
  26. <view v-show="showTakeTips" class="takeTips2"
  27. >点击三秒后开始拍照
  28. </view>
  29. <div class="circleInside"></div>
  30. </div>
  31. </div>
  32. <div v-if="isSuccess">
  33. <div class="selectImg" @click="uploadImg">
  34. <img src="../../assets/img/selectImg.png" />
  35. <div class="uploadText">上传照片</div>
  36. </div>
  37. <div class="confirm" @click="confirmPhoto">
  38. <!-- <img src="../../assets/img/success.png" /> -->
  39. <div class="sure">确定</div>
  40. <div class="uploadText">
  41. 就这张了 <img src="../../assets/img/success.png" />
  42. </div>
  43. </div>
  44. <div class="reTry" @click="reTry">
  45. <img src="../../assets/img/reTry.png" />
  46. <div class="uploadText">重新拍摄</div>
  47. </div>
  48. </div>
  49. <canvas
  50. v-if="isShowCanvas"
  51. id="canvas"
  52. style="width: 1530; height: 950"
  53. ></canvas>
  54. <div v-if="isSuccess" class="preview">
  55. <img v-if="!isUpload" class="fromCamera" :src="CimgSrc" />
  56. <img v-if="isUpload" class="fromUpload" :src="UimgSrc" />
  57. </div>
  58. </div>
  59. <div class="top">
  60. <div class="example">
  61. <img src="../../assets/img/c867236efb4fc5707257ef8daf26db4.png" />
  62. </div>
  63. <div class="model" @click="goSelectModel">
  64. <img :src="modelUrl" alt="" />
  65. <div class="reSelect">点击重新选择模板</div>
  66. </div>
  67. </div>
  68. <!-- Top section -->
  69. <u-overlay class="overlay" :show="showQrCode" opacity="0.9">
  70. <view class="content">
  71. <view class="imageBox">
  72. <image :src="QRCodeUrl" mode="scaleToFill" />
  73. </view>
  74. <text>打开微信扫码上传照片</text>
  75. <view class="orangeBtn" style="margin-top: 100rpx" @click="cancelUplaod"
  76. >取&nbsp;消</view
  77. >
  78. </view>
  79. </u-overlay>
  80. </div>
  81. </template>
  82. <script setup>
  83. import { ref, onMounted } from "vue";
  84. import { BASE_URL } from "../../utils/request";
  85. import { onLoad, onShow, onUnload } from "@dcloudio/uni-app";
  86. import { getImageQrcode, findImage } from "../../api/camera.js";
  87. let CimgSrc = ref(""); // 相机拍照的图片路径,上传前需校验
  88. let CimgSrcYASUO = ref(""); // 压缩后的图片
  89. let UimgSrc = ref(""); // 用户上传的图片路径,上传无需校验
  90. let isSuccess = ref(false);
  91. let isShowCanvas = ref(true);
  92. let isUpload = ref(false);
  93. let modelUrl = ref("");
  94. let modelId = ref("");
  95. let modelMouldType = ref("");
  96. let QRCodeUrl = ref("");
  97. let showQrCode = ref(false);
  98. let timer = ref(null);
  99. const getView = () => {
  100. uni.getSystemInfo({
  101. success: (res) => {
  102. const viewportWidth = res.windowWidth; // 视口宽度
  103. const viewportHeight = res.windowHeight; // 视口高度
  104. alert(viewportWidth);
  105. alert(viewportHeight);
  106. },
  107. });
  108. };
  109. const showTakeTips = ref(true);
  110. const startCamera = () => {
  111. function getUserMedia(constraints, success, error) {
  112. if (navigator.mediaDevices.getUserMedia) {
  113. //最新的标准API
  114. navigator.mediaDevices
  115. .getUserMedia({
  116. audio: false,
  117. video: {
  118. facingMode: "user",
  119. // width: 1000,
  120. // height: 1000,
  121. width: 1080,
  122. height: 1305,
  123. // width: 2100,
  124. // height: 2100,
  125. },
  126. })
  127. .then(success)
  128. .catch(error);
  129. } else if (navigator.webkitGetUserMedia) {
  130. //webkit核心浏览器
  131. navigator.webkitGetUserMedia(constraints, success, error);
  132. } else if (navigator.mozGetUserMedia) {
  133. //firfox浏览器
  134. navigator.mozGetUserMedia(constraints, success, error);
  135. } else if (navigator.getUserMedia) {
  136. //旧版API
  137. navigator.getUserMedia(constraints, success, error);
  138. }
  139. }
  140. const video = document.querySelector("video.uni-video-video");
  141. // video.style.transform = "scaleX(-1)";
  142. // video.style.transform = "rotateY(180deg)"; //镜像
  143. let canvas = document.querySelector("canvas.uni-canvas-canvas");
  144. const action = document.querySelector("#action");
  145. let context = canvas.getContext("2d");
  146. function success(stream) {
  147. //兼容webkit核心浏览器
  148. let CompatibleURL = window.URL || window.webkitURL;
  149. //将视频流设置为video元素的源
  150. console.log(stream);
  151. //video.src = CompatibleURL.createObjectURL(stream);
  152. video.srcObject = stream;
  153. video.play();
  154. }
  155. function error(error) {
  156. console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
  157. }
  158. if (
  159. navigator.mediaDevices.getUserMedia ||
  160. navigator.getUserMedia ||
  161. navigator.webkitGetUserMedia ||
  162. navigator.mozGetUserMedia
  163. ) {
  164. //调用用户媒体设备, 访问摄像头
  165. getUserMedia(
  166. {
  167. audio: false,
  168. video: {
  169. facingMode: "user",
  170. // width: 240,
  171. // height: 450,
  172. width: 1080,
  173. height: 1305,
  174. // width: 2100,
  175. // height: 2100,
  176. },
  177. },
  178. success,
  179. error
  180. );
  181. } else {
  182. alert("不支持访问用户媒体");
  183. }
  184. action.addEventListener("click", function () {
  185. showTakeTips.value = false;
  186. uni.showToast({
  187. title: "准备开始拍照",
  188. icon: "success",
  189. });
  190. setTimeout(() => {
  191. let i = 3;
  192. const timer = setInterval(() => {
  193. uni.showLoading({
  194. title: i,
  195. });
  196. i--;
  197. console.log(i);
  198. if (i == 0) {
  199. clearInterval(timer);
  200. setTimeout(async () => {
  201. uni.hideLoading();
  202. // canvas.width = 1530;
  203. // canvas.height = 950;
  204. canvas.width = 1500;
  205. canvas.height = 1500;
  206. context.drawImage(video, 0, 0);
  207. let dataURL = canvas.toDataURL("image/png");
  208. // console.log(dataURL);
  209. CimgSrc.value = dataURL;
  210. UimgSrc.value = "";
  211. setTimeout(() => {
  212. isShowCanvas.value = false;
  213. isSuccess.value = true;
  214. showTakeTips.value = true;
  215. }, 10);
  216. }, 1000);
  217. }
  218. }, 1100);
  219. }, 1000);
  220. });
  221. // 备用方案
  222. // action.addEventListener("click", function () {
  223. // context.drawImage(video, -50, -50, 310, 220);
  224. // const dataURL = canvas.toDataURL("image/png");
  225. // imgSrc.value = dataURL;
  226. // setTimeout(() => {
  227. // isShowCanvas.value = false;
  228. // isSuccess.value = true;
  229. // }, 10);
  230. // console.log(dataURL);
  231. // });
  232. };
  233. //压缩图片
  234. function compressBase64Image(base64String, maxWidth, maxHeight) {
  235. return new Promise((resolve, reject) => {
  236. const img = new Image();
  237. img.src = base64String;
  238. img.onload = function () {
  239. const canvas = document.createElement("canvas");
  240. let width = img.width;
  241. let height = img.height;
  242. if (width > maxWidth) {
  243. height *= maxWidth / width;
  244. width = maxWidth;
  245. }
  246. if (height > maxHeight) {
  247. width *= maxHeight / height;
  248. height = maxHeight;
  249. }
  250. const ctx = canvas.getContext("2d");
  251. canvas.width = width;
  252. canvas.height = height;
  253. ctx.drawImage(img, 0, 0, width, height);
  254. const compressedBase64 = canvas.toDataURL("image/jpeg");
  255. resolve(compressedBase64);
  256. };
  257. img.onerror = function (error) {
  258. reject(error);
  259. };
  260. });
  261. }
  262. const takePicture = () => {
  263. console.log("Take Picture !");
  264. };
  265. const goSelectModel = () => {
  266. uni.navigateTo({
  267. url: `/pages/chooseStyle/index`,
  268. });
  269. };
  270. // 确认照片
  271. const confirmPhoto = () => {
  272. // alert("点击确定");
  273. // alert(UimgSrc.value, "UimgSrc.value");
  274. // alert(CimgSrc.value, "CimgSrc.value");
  275. try {
  276. if (UimgSrc.value) {
  277. uni.navigateTo({
  278. url: `/pages/createing/index?imageUrl=${UimgSrc.value}&id=${modelId.value}`,
  279. });
  280. } else if (CimgSrc.value) {
  281. // 本地存储中的拍照照片
  282. // alert(uni.getStorageSync("CcurrentUrl"), "CcurrentUrl");
  283. // // let CimageUrl = uni.getStorageSync("CcurrentUrl");
  284. // // 用户上一次使用相机拍照的照片,从本地回显,已通过校验,直接放行
  285. if (uni.getStorageSync("CcurrentUrl")) {
  286. uni.navigateTo({
  287. url: `/pages/createing/index?imageUrl=${CimgSrc.value}&id=${modelId.value}`,
  288. });
  289. // // 用户使用相机拍照的照片,未校验,走完校验流程放行
  290. } else {
  291. dealImage(CimgSrc.value);
  292. }
  293. // dealImage(CimgSrcYASUO.value);
  294. }
  295. } catch (e) {
  296. uni.showToast({
  297. title: e,
  298. icon: "success",
  299. mask: true,
  300. });
  301. }
  302. // 用户上传的照片,已通过校验,直接放行
  303. };
  304. const dealImage = async (imageUrl) => {
  305. try {
  306. uni.showLoading({
  307. title: "上传中,马上就好",
  308. });
  309. await compressBase64Image(imageUrl, 1200, 1200)
  310. .then((compressedBase64) => {
  311. CimgSrcYASUO.value = compressedBase64;
  312. })
  313. .catch((error) => {
  314. console.error("压缩失败", error);
  315. });
  316. // 将二进制数据转换为 Blob 对象
  317. // let blob = await dataURLtoBlob(imageUrl);
  318. // checkImageByBaidu(blob);
  319. // let blob = await dataURLtoBlob(imageUrl);
  320. // console.log(dataURLtoBlob(imageUrl));
  321. checkImageByBaidu(dataURLtoBlob(CimgSrcYASUO.value));
  322. } catch (error) {
  323. console.error("压缩失败", error);
  324. }
  325. };
  326. /**
  327. * Base64字符串转二进制流
  328. * @param {String} dataurl Base64字符串(字符串包含Data URI scheme,例如:data:image/png;base64, )
  329. */
  330. const dataURLtoBlob = (dataurl) => {
  331. var arr = dataurl.split(","),
  332. mime = arr[0].match(/:(.*?);/)[1],
  333. bstr = atob(arr[1]),
  334. n = bstr.length,
  335. u8arr = new Uint8Array(n);
  336. while (n--) {
  337. u8arr[n] = bstr.charCodeAt(n);
  338. }
  339. return new Blob([u8arr], {
  340. type: mime,
  341. });
  342. };
  343. // 百度图片校验
  344. const checkImageByBaidu = async (file) => {
  345. try {
  346. uni.showLoading({
  347. title: "正在检测图片合法性 1/3",
  348. });
  349. uni.uploadFile({
  350. url: BASE_URL + "api/baidu/checkPhoto",
  351. file,
  352. header: {
  353. authorization: uni.getStorageSync("token"),
  354. },
  355. timeout: 30000,
  356. // formData: data,
  357. success: (res) => {
  358. console.log(res, "上传成功");
  359. const data = JSON.parse(res.data);
  360. if (data.code == 200) {
  361. uni.hideLoading();
  362. checkImageByMetavatar(file);
  363. } else {
  364. uni.hideLoading();
  365. uni.showToast({
  366. title: "图片不合规哦,请更换一张",
  367. icon: "error",
  368. });
  369. }
  370. },
  371. fail: (res) => {
  372. uni.hideLoading();
  373. uni.showToast({
  374. title: "上传失败,请稍后再试",
  375. icon: "none",
  376. });
  377. console.log(res, "上传失败");
  378. },
  379. });
  380. } catch (error) {
  381. uni.hideLoading();
  382. uni.showToast({
  383. title: "请求失败,请稍后再试",
  384. icon: "none",
  385. });
  386. }
  387. };
  388. // 邃芒人脸校验
  389. const checkImageByMetavatar = async (file) => {
  390. uni.showLoading({
  391. title: "正在检测人脸位置 2/3",
  392. });
  393. uni.uploadFile({
  394. url: BASE_URL + "api/userDigital/checkPhoto",
  395. file,
  396. header: {
  397. authorization: uni.getStorageSync("token"),
  398. },
  399. timeout: 30000,
  400. // formData: data,
  401. success: (res) => {
  402. console.log(res, "上传成功");
  403. const data = JSON.parse(res.data);
  404. if (data.code == 200) {
  405. uni.hideLoading();
  406. uoloadImageAws(file);
  407. } else {
  408. uni.hideLoading();
  409. uni.showToast({
  410. title: "请参考提示区域调整站位哦",
  411. icon: "error",
  412. });
  413. }
  414. },
  415. fail: (res) => {
  416. uni.hideLoading();
  417. uni.showToast({
  418. title: "上传失败,请稍后再试",
  419. icon: "none",
  420. });
  421. console.log(res, "上传失败");
  422. },
  423. });
  424. };
  425. // 上传图片到服务器(两步校验通过后)
  426. const uoloadImageAws = async (file) => {
  427. uni.showLoading({
  428. title: "检测完成,上传中 3/3",
  429. });
  430. uni.uploadFile({
  431. url: BASE_URL + "api/upload/awsImgUpload",
  432. file,
  433. header: {
  434. authorization: uni.getStorageSync("token"),
  435. },
  436. timeout: 30000,
  437. // formData: data,
  438. success: (res) => {
  439. console.log(res, "上传成功");
  440. uni.hideLoading();
  441. const data = JSON.parse(res.data);
  442. if (data.code == 200) {
  443. uni.showToast({
  444. title: "上传成功!",
  445. icon: "success",
  446. duration: 1500,
  447. });
  448. setTimeout(() => {
  449. // 将拍照照片地址存储到本地并清空上传照片地址
  450. // uni.setStorageSync("CcurrentUrl", data.data.url);
  451. uni.setStorageSync("CcurrentUrl", data.data.url);
  452. uni.setStorageSync("UcurrentUrl", null);
  453. uni.navigateTo({
  454. url: `/pages/createing/index?imageUrl=${data.data.url}&id=${modelId.value}`,
  455. });
  456. }, 1000);
  457. } else {
  458. uni.hideLoading();
  459. uni.showToast({
  460. title: "网络波动,请稍后再试",
  461. icon: "error",
  462. });
  463. }
  464. },
  465. fail: (res) => {
  466. uni.hideLoading();
  467. uni.showToast({
  468. title: "上传失败,请稍后再试",
  469. icon: "none",
  470. });
  471. console.log(res, "上传失败");
  472. },
  473. });
  474. };
  475. // 不满意,重新拍一张
  476. const reTry = () => {
  477. isSuccess.value = false;
  478. isUpload.value = false;
  479. isShowCanvas.value = true;
  480. CimgSrc.value = "";
  481. UimgSrc.value = "";
  482. CimgSrcYASUO.value = "";
  483. uni.setStorageSync("CcurrentUrl", null);
  484. setTimeout(() => {
  485. startCamera();
  486. }, 10);
  487. };
  488. // 点击上传照片按钮
  489. const uploadImg = async () => {
  490. const data = {
  491. machineQrcodeId: localStorage.getItem("UserId"),
  492. mouldType: modelMouldType.value,
  493. };
  494. // const UserId = localStorage.getItem("UserId");
  495. // const mouldType = modelMouldType.value;
  496. try {
  497. const res = await getImageQrcode(data);
  498. QRCodeUrl.value = res.data.wxQrcode;
  499. showQrCode.value = true;
  500. // 成功展示二维码之后,轮询获取上传照片状态
  501. timer.value = setInterval(() => {
  502. refreshUploadStatus(res.data.id);
  503. }, 1000);
  504. console.log(res, "res");
  505. } catch (error) {
  506. console.log(error, "error");
  507. }
  508. };
  509. // 刷新状态,直到返回用户上传的图片url
  510. const refreshUploadStatus = async (id) => {
  511. try {
  512. const res = await findImage(id);
  513. console.log(res, "res");
  514. if (res.data.imageList && res.data.imageList.length) {
  515. const imageUrl = res.data.imageList[0];
  516. clearInterval(timer.value);
  517. uni.showToast({
  518. title: "上传成功!",
  519. icon: "success",
  520. });
  521. showQrCode.value = false;
  522. UimgSrc.value = imageUrl;
  523. CimgSrc.value = "";
  524. CimgSrcYASUO.value = "";
  525. isShowCanvas.value = false;
  526. isSuccess.value = true;
  527. isUpload.value = true;
  528. // 将上传照片地址存储到本地并清空拍照照片地址
  529. uni.setStorageSync("CcurrentUrl", null);
  530. uni.setStorageSync("UcurrentUrl", UimgSrc.value);
  531. }
  532. } catch (error) {
  533. console.log(error, "error");
  534. }
  535. };
  536. // 点击取消,关闭二维码弹窗并取消轮询
  537. const cancelUplaod = () => {
  538. showQrCode.value = false;
  539. clearInterval(timer.value);
  540. };
  541. onLoad((options) => {
  542. console.log(options, "options");
  543. modelUrl.value = options.modelUrl;
  544. modelId.value = options.id;
  545. modelMouldType.value = options.mouldType;
  546. });
  547. onMounted(() => {
  548. clearInterval(timer.value);
  549. startCamera();
  550. const CimageUrl = uni.getStorageSync("CcurrentUrl");
  551. const UimageUrl = uni.getStorageSync("UcurrentUrl");
  552. if (CimageUrl || UimageUrl) {
  553. setTimeout(async () => {
  554. showQrCode.value = false;
  555. if (CimageUrl) {
  556. UimgSrc.value = "";
  557. CimgSrc.value = CimageUrl;
  558. isUpload.value = false;
  559. } else if (UimageUrl) {
  560. UimgSrc.value = UimageUrl;
  561. CimgSrc.value = "";
  562. CimgSrcYASUO.value = "";
  563. isUpload.value = true;
  564. }
  565. isShowCanvas.value = false;
  566. isSuccess.value = true;
  567. }, 1000);
  568. }
  569. });
  570. //#region 页面初始化和卸载
  571. const resetTimer = ref(null);
  572. onMounted(() => {
  573. window.document.addEventListener("touchstart", () => {
  574. // 用户点击时,清除之前的定时器
  575. clearTimeout(resetTimer.value);
  576. // 重新设定120秒后触发的定时器
  577. resetTimer.value = setTimeout(() => {
  578. userInfoModulesPinia.clearStorage();
  579. window.webview.raiseEvent("pageRefresh", "test_params");
  580. uni.redirectTo({ url: "/pages/login/index" });
  581. }, 300000);
  582. });
  583. resetTimer.value = setTimeout(() => {
  584. userInfoModulesPinia.clearStorage();
  585. window.webview.raiseEvent("pageRefresh", "test_params");
  586. uni.redirectTo({ url: "/pages/login/index" });
  587. }, 300000);
  588. });
  589. onUnload(() => {
  590. uni.hideLoading();
  591. clearTimeout(resetTimer.value);
  592. });
  593. //#endregion -----------------------
  594. </script>
  595. <style lang="scss" scoped>
  596. :deep(.uni-toast) {
  597. width: 300rpx;
  598. font-size: 50rpx;
  599. font-weight: 900;
  600. padding: 20rpx 30rpx;
  601. color: #ff4f00;
  602. .uni-toast__icon {
  603. width: 50rpx !important;
  604. height: 50rpx !important;
  605. }
  606. }
  607. .page {
  608. width: 100vw;
  609. height: 100vh;
  610. padding: 0;
  611. .top {
  612. display: flex;
  613. width: 100%;
  614. height: 32%;
  615. .example {
  616. width: 60%;
  617. height: 100%;
  618. color: #000;
  619. background-color: #fff;
  620. img {
  621. width: 100%;
  622. height: 100%;
  623. }
  624. }
  625. .model {
  626. position: relative;
  627. width: 40%;
  628. height: 100%;
  629. background-color: #000000;
  630. img {
  631. position: absolute;
  632. top: 50%;
  633. left: 50%;
  634. transform: translate(-50%, -50%);
  635. width: 100%;
  636. height: 100%;
  637. }
  638. .reSelect {
  639. position: absolute;
  640. width: 250rpx;
  641. left: 50%;
  642. bottom: 10rpx;
  643. text-align: center;
  644. transform: translateX(-50%);
  645. }
  646. }
  647. }
  648. .bottom {
  649. position: relative;
  650. width: 100%;
  651. height: 68%;
  652. overflow: hidden;
  653. .frameImg {
  654. position: absolute;
  655. top: 40%;
  656. left: 50%;
  657. transform: translate(-50%, -50%);
  658. width: 60%;
  659. height: 40%;
  660. z-index: 3;
  661. }
  662. video {
  663. width: 100%;
  664. height: 100%;
  665. // width: 1080px;
  666. // height: 1305px;
  667. :deep(.uni-video-video) {
  668. position: absolute;
  669. left: 0;
  670. top: -50px;
  671. width: 100% !important;
  672. height: 720px !important;
  673. }
  674. }
  675. .selectImg {
  676. position: absolute;
  677. left: 65rpx;
  678. bottom: 75rpx;
  679. width: 68rpx;
  680. height: 68rpx;
  681. border: 5rpx solid #ffffff;
  682. border-radius: 5rpx;
  683. z-index: 99;
  684. img {
  685. position: absolute;
  686. left: 50%;
  687. bottom: 50%;
  688. transform: translate(-50%, 50%);
  689. width: 70%;
  690. height: 70%;
  691. }
  692. .uploadText {
  693. position: absolute;
  694. left: 50%;
  695. bottom: -40rpx;
  696. width: 150%;
  697. font-size: 20rpx;
  698. transform: translateX(-40%);
  699. }
  700. }
  701. #action {
  702. position: absolute;
  703. left: 50%;
  704. bottom: 45rpx;
  705. width: 120rpx;
  706. height: 120rpx;
  707. transform: translateX(-50%);
  708. background-color: #ffffff;
  709. border-radius: 60rpx;
  710. z-index: 99;
  711. .takeTips1 {
  712. position: absolute;
  713. width: 300rpx;
  714. top: -70rpx;
  715. left: 50%;
  716. transform: translateX(-50%);
  717. text-align: center;
  718. color: #ff4f00;
  719. }
  720. .takeTips2 {
  721. position: absolute;
  722. width: 300rpx;
  723. top: -40rpx;
  724. left: 50%;
  725. transform: translateX(-50%);
  726. text-align: center;
  727. color: #ff4f00;
  728. }
  729. .circleInside {
  730. position: absolute;
  731. left: 50%;
  732. bottom: 50%;
  733. transform: translate(-50%, 50%);
  734. width: 100rpx;
  735. height: 100rpx;
  736. background-color: #ffffff;
  737. border-radius: 50%;
  738. border: 6rpx solid #000;
  739. }
  740. }
  741. .confirm {
  742. position: absolute;
  743. left: 50%;
  744. bottom: 75rpx;
  745. width: 180rpx;
  746. height: 80rpx;
  747. // border: 5rpx solid #ffffff;
  748. transform: translateX(-50%);
  749. border-radius: 60rpx;
  750. z-index: 9999999;
  751. img {
  752. // position: absolute;
  753. // left: 50%;
  754. // bottom: 50%;
  755. // transform: translate(-50%, 50%);
  756. width: 100%;
  757. height: 100%;
  758. width: 30rpx;
  759. height: 30rpx;
  760. vertical-align: text-top;
  761. }
  762. .sure {
  763. margin-top: 30rpx;
  764. text-align: center;
  765. width: 100%;
  766. height: 50rpx;
  767. line-height: 50rpx;
  768. background-color: #2ba245;
  769. border-radius: 15rpx;
  770. }
  771. .uploadText {
  772. // position: absolute;
  773. // left: 50%;
  774. // bottom: -40rpx;
  775. // width: 150%;
  776. width: 100%;
  777. height: 30rpx;
  778. line-height: 30rpx;
  779. font-size: 20rpx;
  780. // transform: translateX(-32%);
  781. text-align: center;
  782. }
  783. }
  784. .reTry {
  785. position: absolute;
  786. right: 65rpx;
  787. bottom: 75rpx;
  788. width: 68rpx;
  789. height: 68rpx;
  790. border: 5rpx solid #ffffff;
  791. border-radius: 5rpx;
  792. z-index: 99;
  793. img {
  794. position: absolute;
  795. left: 50%;
  796. bottom: 50%;
  797. transform: translate(-50%, 50%);
  798. width: 70%;
  799. height: 70%;
  800. }
  801. .uploadText {
  802. position: absolute;
  803. left: 50%;
  804. bottom: -40rpx;
  805. width: 150%;
  806. font-size: 20rpx;
  807. transform: translateX(-40%);
  808. }
  809. }
  810. .preview {
  811. position: relative;
  812. width: 100%;
  813. height: 100%;
  814. z-index: 1;
  815. .fromCamera {
  816. // position: absolute;
  817. // top: 110rpx;
  818. // left: 130rpx;
  819. width: 100%;
  820. }
  821. .fromUpload {
  822. position: absolute;
  823. top: 110rpx;
  824. left: 50%;
  825. transform: translateX(-50%);
  826. width: 45%;
  827. }
  828. }
  829. }
  830. .overlay {
  831. .content {
  832. width: 100%;
  833. height: 100vh;
  834. display: flex;
  835. flex-direction: column;
  836. align-items: center;
  837. text-align: center;
  838. .imageBox {
  839. position: relative;
  840. margin-top: 200rpx;
  841. width: 300rpx;
  842. height: 300rpx;
  843. border-radius: 30rpx;
  844. background-color: #fff;
  845. .mask {
  846. position: absolute;
  847. width: 100%;
  848. height: 100%;
  849. border-radius: 30rpx;
  850. background-color: rgba($color: #000000, $alpha: 0.7);
  851. z-index: 2;
  852. }
  853. image {
  854. width: 100%;
  855. height: 100%;
  856. border-radius: 30rpx;
  857. background-color: #fff;
  858. }
  859. }
  860. text {
  861. margin-top: 20rpx;
  862. font-weight: 900;
  863. font-size: 32rpx;
  864. }
  865. // .orangeBtn {
  866. // margin-top: 100rpx;
  867. // }
  868. }
  869. }
  870. }
  871. </style>