index.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969
  1. <template>
  2. <u-popup :show="isShow" @close="close" :closeOnClickOverlay="false">
  3. <view class="page-face-container">
  4. <view class="errortext" v-if="!startVideoStatus">{{ tip }}</view>
  5. <view class="errortext"><text v-if="errortext != ''">{{ errortext }}</text></view>
  6. <view id="show-content" :class="openCamera == true ? '' : 'show-content-hide'">
  7. <view class="home">
  8. <view :class="bgImgClass">
  9. <img src="../../static/neuralNets/img4.png" />
  10. </view>
  11. </view>
  12. <!-- <view class="uer-camera" @tap="changeUserCamera('hou')" v-if="useCamera == 'qian'">
  13. <img src="../../static/neuralNets/change_camera.png" />
  14. </view>
  15. <view class="uer-camera" @tap="changeUserCamera('qian')" v-if="useCamera == 'hou'">
  16. <img src="../../static/neuralNets/change_camera.png" />
  17. </view> -->
  18. <video
  19. src=""
  20. id="video"
  21. :style="{ width: vwidth + 'px', height: vheight + 'px', display: showVideo }"
  22. playsinline
  23. webkit-playsinline autoplay=true muted=true loop=true controls=false show-center-play-btn=false
  24. object-fit=fill>
  25. </video>
  26. </view>
  27. <view class="main_bottom">
  28. 确认为<text style="color: red;padding: 6rpx;"
  29. v-if="userName">{{ userName }}</text>本人照片<br>保持正脸在取景框中根据屏幕指示完成
  30. <view class="bottom_main">
  31. <view class="bottom_main_list">
  32. <img src="../../static/neuralNets/img3.png" />
  33. <p>正对手机</p>
  34. </view>
  35. <view class="bottom_main_list">
  36. <img src="../../static/neuralNets/img2.png" />
  37. <p>光线充足</p>
  38. </view>
  39. <view class="bottom_main_list">
  40. <img src="../../static/neuralNets/img1.png" />
  41. <p>脸无遮挡</p>
  42. </view>
  43. </view>
  44. </view>
  45. <view class="button-view" :style="{ display: (openCamera == true ? 'flex' : 'none') }">
  46. <view class="click-button">
  47. <u-button type="primary" shape="circle" @click="startVideo" v-if="!isMaxVlide"
  48. :disabled="startVideoStatus">{{ !startVideoStatus ? '开始刷脸' : '检测中...' }}</u-button>
  49. <u-button type="error"
  50. shape="circle" @click="close"
  51. :customStyle="{
  52. marginTop: '30rpx'
  53. }">退出</u-button>
  54. </view>
  55. </view>
  56. </view>
  57. </u-popup>
  58. </template>
  59. <script>
  60. import $ from "@/static/collect_face/jquery2.3.js";
  61. import faceFilter from "@/static/neuralNets/jeelizFaceFilter.module.js";
  62. import JeelizCanvas2DHelper from "@/static/neuralNets/JeelizCanvas2DHelper.js";
  63. // 引入uni.webview.1.5.2.js
  64. import '@/static/js/uni.webview.1.5.4.js'
  65. import { compareFace } from '@/api/common/system.js'
  66. import { getToken } from '@/utils/auth'
  67. let VIDEOELEMENT = null;
  68. var CVD = null; // return of Canvas2DDisplay
  69. export default {
  70. props: {
  71. // 用户名
  72. userName: {
  73. type: String,
  74. default: null
  75. },
  76. tip: {
  77. type: String,
  78. default: '需进行人脸验证后再继续学习'
  79. },
  80. querParams: {
  81. type: Object,
  82. default: () => {
  83. return {}
  84. }
  85. },
  86. maxValidNum: {
  87. type: Number,
  88. default: 10000
  89. }
  90. },
  91. data() {
  92. return {
  93. isShow: false,
  94. isTest: false,
  95. againCount: 0,
  96. openCamera: false,
  97. screenSize: {
  98. width: window.screen.width,
  99. height: window.screen.height,
  100. },
  101. vwidth: 240,
  102. vheight: 240,
  103. scanTip: '',
  104. errortext: '点击开始刷脸按钮开始拍摄',
  105. uploadHeadImg: '',
  106. imgUrl: '',
  107. pauseStatus: false,
  108. startCut: false,
  109. faceCoo: null,
  110. detectState: null,
  111. showVideo: 'block',
  112. appendCss: false,
  113. bgImgClass: 'home_wai',
  114. bgImgClass2: 'home_nei',
  115. mediaStreamTrack: null,
  116. startVideoStatus: false,
  117. useCamera: 'qian', //qian代表前置摄像头 hou代表后置摄像头
  118. valideNum: 0, //失败次数
  119. isMaxVlide: false, //是否超过最大次数
  120. }
  121. },
  122. mounted() { },
  123. methods: {
  124. show() {
  125. this.valideNum = 0;
  126. this.isMaxVlide = false;
  127. if (origin.indexOf('https') === -1 && window.location.hostname != "localhost") {
  128. uni.showModal({
  129. title: '提示',
  130. content: `请在 https 环境中使用人脸验证`,
  131. showCancel:false,
  132. confirmText: '确定',
  133. success: function(res) {
  134. if (res.confirm) {
  135. uni.navigateBack()
  136. }
  137. }
  138. })
  139. return false;
  140. }
  141. this.isShow = true;
  142. if (faceFilter && typeof faceFilter.toggle_pause == 'function') {
  143. faceFilter.destroy();
  144. }
  145. var that = this; //a
  146. setTimeout(function () {
  147. //初始化的时候给追加上canvas用作载体
  148. if ($('#jeeFaceFilterCanvas').html() == undefined) {
  149. $('#show-content').append('<canvas class="appendcanvas" width="' + that.vwidth +
  150. '" height="' + that.vheight + '" id="jeeFaceFilterCanvas"></canvas>');
  151. }
  152. if ($('#jeeFaceFilterCanvas2').html() == undefined) {
  153. $('#show-content').append('<canvas class="appendcanvas appendcanvas2" width="' + that
  154. .vwidth + '" height="' + that.vheight + '" id="jeeFaceFilterCanvas2"></canvas>');
  155. }
  156. if (that.appendCss == false) {
  157. $('uni-page-body').append(`<style>
  158. #jeeFaceFilterCanvas{
  159. display:none;
  160. }
  161. #jeeFaceFilterCanvas2{
  162. display:none;
  163. border-radius:50%
  164. }
  165. #video .uni-video-bar{
  166. display:none !important; //去除底部菜单栏
  167. }
  168. #video .uni-video-cover{
  169. display:none !important; //去除中间播放按钮
  170. }
  171. #video video{
  172. transform: rotateY(180deg);
  173. -webkit-transform: rotateY(180deg); /* Safari 和 Chrome */
  174. -moz-transform: rotateY(180deg);
  175. border-radius:50% !important;
  176. }
  177. #video .uni-video-container{border-radius:50% !important;}
  178. #video .uni-video-video{border-radius:50% !important;}
  179. </style>`);
  180. that.appendCss = true;
  181. }
  182. //uniapp编译过后无法获取video的dom,此处追加id
  183. $('#video').find('video').prop('id', 'myVideo');
  184. that.showVideo = 'block';
  185. if (that.isTest == true) {
  186. //是否是测试环境 测试环境直接调用视频
  187. that.openCamera = true;
  188. that.main();
  189. } else {
  190. that.openCamera = true;
  191. that.bgImgClass = 'home_wai remove_animation';
  192. that.bgImgClass2 = 'home_nei remove_animation';
  193. that.errortext = '点击开始刷脸按钮开始拍摄';
  194. }
  195. }, 100)
  196. },
  197. close(type) {
  198. this.valideNum = 0;
  199. this.isMaxVlide = false;
  200. this.startVideoStatus = false;
  201. this.closeVideo();
  202. this.isShow = false
  203. if(type!='confrim') {
  204. this.$emit('close')
  205. }
  206. },
  207. closeVideo() {
  208. try {
  209. //页面卸载的时候关闭视频播放
  210. if (this.mediaStreamTrack) {
  211. this.mediaStreamTrack.getTracks()[0].stop();
  212. }
  213. } catch {
  214. console.log('close mediaStreamTrack error')
  215. }
  216. try {
  217. // const video = document.getElementsByClassName('uni-video-video')[0];
  218. const video = document.getElementById('myVideo');
  219. video.srcObject = null;
  220. } catch {
  221. console.log('close video.srcObject error')
  222. }
  223. try {
  224. faceFilter.toggle_pause(true);
  225. faceFilter.destroy(); //销毁注册对象
  226. } catch {
  227. console.log('close faceFilter toggle_pause error')
  228. }
  229. },
  230. changeUserCamera(type) {
  231. this.useCamera = type;
  232. if (type == 'hou') {
  233. $('uni-page-body').append(`<style>
  234. #video video{
  235. transform: rotateY(0deg);
  236. -webkit-transform: rotateY(0deg); /* Safari 和 Chrome */
  237. -moz-transform: rotateY(0deg);
  238. border-radius:50% !important;
  239. }
  240. </style>`);
  241. } else {
  242. $('uni-page-body').append(`<style>
  243. #video video{
  244. transform: rotateY(180deg);
  245. -webkit-transform: rotateY(180deg); /* Safari 和 Chrome */
  246. -moz-transform: rotateY(180deg);
  247. border-radius:50% !important;
  248. }
  249. </style>`);
  250. }
  251. this.playVideo();
  252. },
  253. startVideo() {
  254. if (this.startVideoStatus == false) {
  255. this.playVideo();
  256. } else {
  257. if (this.pauseStatus == false) {
  258. this.$api.msg('当前正在拍照');
  259. return;
  260. }
  261. this.savePause(false)
  262. }
  263. },
  264. savePause(status) {
  265. this.uploadHeadImg = '';
  266. this.imgUrl = '';
  267. this.pauseStatus = status;
  268. if (status == false) {
  269. this.startCut = false;
  270. this.bgImgClass = 'home_wai';
  271. this.bgImgClass2 = 'home_nei';
  272. this.showVideo = 'none';
  273. $('#jeeFaceFilterCanvas2').hide();
  274. } else {
  275. this.showVideo = 'block';
  276. $('#jeeFaceFilterCanvas2').hide();
  277. }
  278. //console.log(status)
  279. //true 暂停 false 继续执行
  280. faceFilter.toggle_pause(status);
  281. },
  282. playVideo() {
  283. var that = this;
  284. that.uploadHeadImg = '';
  285. that.imgUrl = '';
  286. that.startVideoStatus = true;
  287. that.startCut = false;
  288. var thatUseCamera = that.useCamera;
  289. if (thatUseCamera == 'qian') {
  290. var facingMode = 'user';
  291. } else if (thatUseCamera == 'hou') {
  292. var facingMode = {
  293. exact: "environment"
  294. };
  295. }
  296. if (faceFilter && typeof faceFilter.toggle_pause == 'function') {
  297. faceFilter.destroy();
  298. }
  299. setTimeout(function () {
  300. that.getUserMedia({
  301. //摄像头拍摄的区域
  302. video: {
  303. width: 500,
  304. height: 500,
  305. facingMode: facingMode,
  306. },
  307. /* 前置优先 */
  308. },
  309. that.success,
  310. that.error
  311. );
  312. }, 100)
  313. },
  314. // 访问用户媒体设备
  315. getUserMedia(constrains, success, error) {
  316. if (navigator.mediaDevices.getUserMedia) {
  317. navigator.mediaDevices.getUserMedia(constrains).then(success).catch(error); //最新标准API
  318. } else if (navigator.webkitGetUserMedia) {
  319. navigator.webkitGetUserMedia(constrains).then(success).catch(error); //webkit内核浏览器
  320. } else if (navigator.mozGetUserMedia) {
  321. navagator.mozGetUserMedia(constrains).then(success).catch(error); //Firefox浏览器
  322. } else if (navigator.getUserMedia) {
  323. navigator.getUserMedia(constrains).then(success).catch(error); //旧版API
  324. } else {
  325. this.errortext = "你的浏览器不支持访问用户媒体设备";
  326. }
  327. },
  328. success(stream) {
  329. var that = this;
  330. that.bgImgClass = 'home_wai';
  331. that.bgImgClass2 = 'home_nei';
  332. that.openCamera = true;
  333. that.errortext = '请把人脸放在圆圈内拍摄脸部';
  334. that.mediaStreamTrack = stream;
  335. // const video = document.getElementsByClassName('uni-video-video')[0];
  336. const video = document.getElementById('myVideo');
  337. try {
  338. video.srcObject = stream;
  339. } catch {
  340. this.URL = window.URL || window.webkitURL;
  341. video.src = this.URL.createObjectURL(stream);
  342. }
  343. // webkit内核浏览器
  344. //苹果手机的系统弹框会阻止js的线程的继续执行 手动0.1秒之后自动执行代码
  345. setTimeout(() => {
  346. try {
  347. video.play();
  348. } catch {
  349. that.errortext = '视频流播放失败';
  350. }
  351. that.main();
  352. }, 100);
  353. },
  354. error(e) {
  355. var that = this;
  356. that.startVideoStatus = false;
  357. that.bgImgClass = 'home_wai remove_animation';
  358. that.bgImgClass2 = 'home_nei remove_animation';
  359. if (this.useCamera == 'hou') {
  360. that.errortext = "调用后置摄像头失败:" + (e.name ? e.name : '') + (e.message ? e.message : '');
  361. } else {
  362. that.errortext = "调用前置摄像头失败:" + (e.name ? e.name : '') + (e.message ? e.message : '');
  363. }
  364. },
  365. main() { // entry point
  366. var that = this;
  367. VIDEOELEMENT = document.getElementById('myVideo');
  368. if (VIDEOELEMENT['currentTime'] && VIDEOELEMENT['videoWidth'] && VIDEOELEMENT['videoHeight']) {
  369. that.start();
  370. } else {
  371. setTimeout(function () {
  372. that.main();
  373. }, 100);
  374. }
  375. },
  376. start() { // launched when the video is loaded
  377. var that = this;
  378. faceFilter.init({
  379. canvasId: 'jeeFaceFilterCanvas',
  380. videoSettings: {
  381. videoElement: VIDEOELEMENT
  382. },
  383. rotate: -90,
  384. NNCPath: '../../static/neuralNets/', // root of NN_DEFAULT.json file
  385. callbackReady: function (errCode, spec) {
  386. if (errCode) {
  387. //
  388. that.errortext = '人脸初始化出错' + errCode;
  389. that.startVideoStatus = false;
  390. console.log('AN ERROR HAPPENS. SORRY BRO :( . ERR =', errCode);
  391. return;
  392. }
  393. CVD = JeelizCanvas2DHelper(spec);
  394. CVD.ctx.strokeStyle = 'yellow';
  395. },
  396. callbackTrack: function (detectState) {
  397. //console.log(detectState.detected)
  398. that.detectState = '';
  399. that.faceCoo = '';
  400. if (detectState.detected > 0.9) {
  401. that.detectState = detectState;
  402. that.showVideo = 'block';
  403. $('#jeeFaceFilterCanvas2').hide();
  404. var faceCoo = CVD.getCoordinates(detectState);
  405. that.faceCoo = faceCoo;
  406. CVD.ctx.clearRect(0, 0, CVD.canvas.width, CVD.canvas.height);
  407. CVD.update_canvasTexture();
  408. CVD.draw();
  409. var check = that.checkTrue();
  410. if (check) {
  411. that.errortext = '请保持不动,即将拍照';
  412. if (that.startCut == false) {
  413. that.startCut = true;
  414. setTimeout(function () {
  415. //console.log('setTimeout')
  416. that.savePause(true);
  417. that.cutPhoto();
  418. }, 1000)
  419. }
  420. }
  421. } else {
  422. that.showVideo = 'block';
  423. $('#jeeFaceFilterCanvas2').hide();
  424. that.errortext = '请将完整脸部对准屏幕中央';
  425. }
  426. }
  427. }); //end JEELIZFACEFILTER.init call
  428. },
  429. checkTrue(dump) {
  430. var that = this;
  431. var faceCoo = that.faceCoo;
  432. var faceCooStr = JSON.stringify(faceCoo);
  433. var detectState = that.detectState;
  434. if (!faceCoo || !detectState || detectState == '' || faceCoo == '') {
  435. return false;
  436. }
  437. var x = parseFloat(faceCoo.x).toFixed(2);
  438. var y = parseFloat(faceCoo.y).toFixed(2);
  439. var w = parseFloat(faceCoo.w).toFixed(2);
  440. var h = parseFloat(faceCoo.h).toFixed(2);
  441. var cw = parseFloat(CVD.canvas.width).toFixed(2);
  442. var ch = parseFloat(CVD.canvas.height).toFixed(2);
  443. var xcw = x / cw;
  444. var ycw = y / ch;
  445. if (xcw < 0.25 || xcw > 0.5 || ycw > 0.45 || ycw < 0.1) {
  446. that.errortext = '请将完整脸部对准屏幕中央';
  447. } else {
  448. that.errortext = '';
  449. }
  450. if (that.errortext && that.errortext != '') {
  451. return false;
  452. }
  453. var faceMj = w * h;
  454. var allMj = cw * ch;
  455. var zhanbi = faceMj / allMj;
  456. var mianjiObj = {
  457. faceMj: faceMj,
  458. zhanbi: zhanbi
  459. }
  460. var mianjiobj2 = {
  461. cw: cw,
  462. ch: ch,
  463. allMj: allMj,
  464. }
  465. var mianjiStr = JSON.stringify(mianjiObj);
  466. var mianjiStr2 = JSON.stringify(mianjiobj2);
  467. if (zhanbi < 0.18) {
  468. that.errortext = '请离脸部近一点'
  469. } else if (zhanbi > 0.28) {
  470. that.errortext = '请离脸部远一点'
  471. } else {
  472. return true;
  473. }
  474. return false;
  475. },
  476. cutPhoto(rectparams) {
  477. var that = this;
  478. var check = that.checkTrue(true);
  479. if (check == false) {
  480. that.savePause(false);
  481. return;
  482. }
  483. that.errortext = '拍照成功,请稍后';
  484. that.bgImgClass = 'home_wai remove_animation';
  485. that.bgImgClass2 = 'home_nei remove_animation';
  486. that.showVideo = 'none';
  487. $('#jeeFaceFilterCanvas2').show();
  488. CVD.ctx.clearRect(0, 0, CVD.canvas.width, CVD.canvas.height);
  489. CVD.draw();
  490. var clip = $('#jeeFaceFilterCanvas2')[0];
  491. var context_clip = clip.getContext('2d');
  492. context_clip.drawImage(
  493. $('#jeeFaceFilterCanvas')[0], //规定要使用的图像、画布或视频。
  494. 0, 0, //开始剪切的 x 坐标位置。
  495. CVD.canvas.width, CVD.canvas.height, //被剪切图像的高度。
  496. 0, 0, //在画布上放置图像的 x 、y坐标位置。
  497. this.vwidth, this.vwidth //要使用的图像的宽度、高度
  498. );
  499. //位移来做镜像翻转
  500. if (that.useCamera == 'qian') {
  501. //使用前置摄像头需要反转镜头
  502. context_clip.translate(this.vwidth, 0);
  503. context_clip.scale(-1, 1); //左右镜像翻转
  504. context_clip.drawImage($('#jeeFaceFilterCanvas2')[0], 0, 0, this.vwidth, this.vwidth);
  505. }
  506. this.imgUrl = clip.toDataURL("image/jpeg");
  507. /* clip.toBlob((blob) => {
  508. if (blob) {
  509. this.imgUrl = createObjectURL(blob)
  510. } else {
  511. reject(new Error('Failed to create blob from canvas'));
  512. }
  513. }, 'image/png'); */
  514. this.useImg();
  515. },
  516. useImg() {
  517. this.imgSize();
  518. },
  519. imgSize() {
  520. var that = this;
  521. if (this.imgUrl) {
  522. // 获取base64图片byte大小
  523. const equalIndex = this.imgUrl.indexOf("="); // 获取=号下标
  524. let size;
  525. if (equalIndex > 0) {
  526. const str = this.imgUrl.substring(0, equalIndex); // 去除=号
  527. const strLength = str.length;
  528. const fileLength = strLength - (strLength / 8) * 2; // 真实的图片byte大小
  529. size = Math.floor(fileLength / 1024); // 向下取整
  530. } else {
  531. const strLength = this.imgUrl.length;
  532. const fileLength = strLength - (strLength / 8) * 2;
  533. size = Math.floor(fileLength / 1024); // 向下取整
  534. }
  535. if (size >= 800) {
  536. // 图片超过800k 重新再次压缩
  537. this.imgUrl = $('#jeeFaceFilterCanvas2')[0].toDataURL("image/jpeg", 0.8);
  538. this.imgSize();
  539. } else {
  540. that.faceOpeImg();
  541. }
  542. }
  543. },
  544. async faceOpeImg() {
  545. var that = this;
  546. uni.webView.postMessage({
  547. data: {
  548. photo: this.imgUrl
  549. }
  550. });
  551. // console.log(that.imgUrl,'that.imgUrlthat.imgUrl')
  552. // return false
  553. $('#jeeFaceFilterCanvas2')[0].toBlob(async (blob) => {
  554. if (blob) {
  555. let newBlobUrl = that.createObjectURL(blob)
  556. const {code,data} = await this.uploadFilePromise(newBlobUrl)
  557. if(code == 0) {
  558. // console.log(data,'datadata')
  559. if(data.data == false) {
  560. that.errortext = '不是有效的人脸,请重新拍照';
  561. this.valideNum += 1;
  562. if(this.valideNum >= this.maxValidNum) {
  563. this.isMaxVlide = true
  564. }
  565. that.startVideoStatus = false;
  566. return;
  567. } else {
  568. that.errortext = '人脸识别成功';
  569. that.startVideoStatus = false;
  570. this.$emit('success', data, newBlobUrl, that.imgUrl)
  571. this.close('confrim')
  572. return
  573. }
  574. } else {
  575. that.errortext = '比对人脸失败';
  576. that.startVideoStatus = false;
  577. return;
  578. }
  579. } else {
  580. reject(new Error('Failed to create blob from canvas'));
  581. }
  582. }, 'image/png');
  583. },
  584. /**
  585. * blob转url临时访问地址
  586. * @param String blob 对象
  587. */
  588. createObjectURL(blob){
  589. return URL.createObjectURL(blob);
  590. },
  591. uploadFilePromise(url) {
  592. return new Promise((resolve, reject) => {
  593. // console.log(url,'urlurl')
  594. let a = uni.uploadFile({
  595. url: compareFace, // 仅为示例,非真实的接口地址
  596. header: {
  597. 'Authorization': 'Bearer ' + getToken()
  598. },
  599. filePath: url,
  600. name: 'file',
  601. formData: {
  602. ...this.querParams,
  603. },
  604. success: (res) => {
  605. let data = JSON.parse(res.data)
  606. resolve(data)
  607. },
  608. fail: (err) => {
  609. resolve({
  610. code: -1,
  611. msg: '上传失败'
  612. })
  613. }
  614. });
  615. })
  616. },
  617. },
  618. }
  619. </script>
  620. <style lang="scss" scoped>
  621. .page-face-container {
  622. min-width: 600rpx;
  623. font-size: 28rpx;
  624. height: 100vh;
  625. position: relative;
  626. .contentp1 {
  627. width: 100px;
  628. height: 30px;
  629. background: #EEEEEE;
  630. color: #28A745;
  631. line-height: 30px;
  632. margin-top: 30px;
  633. text-align: center;
  634. }
  635. .contentp {
  636. height: 120px;
  637. }
  638. .errortext {
  639. width: 100%;
  640. height: 40rpx;
  641. line-height: 40rpx;
  642. color: #e03030;
  643. // color: #333333;
  644. text-align: center;
  645. margin-top: 30rpx;
  646. font-size: 30rpx;
  647. }
  648. .img-face {
  649. display: -webkit-box;
  650. /* 老版本语法: Safari, iOS, Android browser, older WebKit browsers. */
  651. display: -moz-box;
  652. /* 老版本语法: Firefox (buggy) */
  653. display: -ms-flexbox;
  654. /* 混合版本语法: IE 10 */
  655. display: -webkit-flex;
  656. /* 新版本语法: Chrome 21+ */
  657. display: flex;
  658. flex-direction: column;
  659. align-items: center;
  660. justify-content: center;
  661. .imgurl {
  662. /* position: fixed;
  663. top: 117.5px;
  664. width: 266px;
  665. height: 266px;
  666. border-radius: 230rpx; */
  667. }
  668. }
  669. #show-content {
  670. width: 100%;
  671. margin-top: 30px;
  672. height: 260px;
  673. display: -webkit-box;
  674. /* 老版本语法: Safari, iOS, Android browser, older WebKit browsers. */
  675. display: -moz-box;
  676. /* 老版本语法: Firefox (buggy) */
  677. display: -ms-flexbox;
  678. /* 混合版本语法: IE 10 */
  679. display: -webkit-flex;
  680. /* 新版本语法: Chrome 21+ */
  681. display: flex;
  682. justify-content: center;
  683. align-items: center;
  684. }
  685. .show-content-hide {
  686. display: none !important;
  687. }
  688. .button-view {
  689. width: 100%;
  690. margin-top: 60rpx;
  691. height: 80rpx;
  692. display: -webkit-box;
  693. /* 老版本语法: Safari, iOS, Android browser, older WebKit browsers. */
  694. display: -moz-box;
  695. /* 老版本语法: Firefox (buggy) */
  696. display: -ms-flexbox;
  697. /* 混合版本语法: IE 10 */
  698. display: -webkit-flex;
  699. /* 新版本语法: Chrome 21+ */
  700. display: flex;
  701. justify-content: center;
  702. align-items: center;
  703. .click-button {
  704. width: 80%;
  705. height: 100%;
  706. }
  707. }
  708. .not-zhuanimg {
  709. width: 17.225rem;
  710. overflow: hidden;
  711. z-index: 10;
  712. position: absolute;
  713. }
  714. .home {
  715. overflow: hidden;
  716. text-align: center;
  717. width: 240px;
  718. height: 240px;
  719. position: absolute;
  720. z-index: 10;
  721. }
  722. .home_wai img {
  723. width: 100%;
  724. overflow: hidden;
  725. animation: myfirst 8s infinite linear;
  726. }
  727. @keyframes myfirst {
  728. 0% {
  729. transform: rotate(0deg) scale(1);
  730. }
  731. 50% {
  732. transform: rotate(360deg) scale(1);
  733. }
  734. 75% {
  735. transform: rotate(540deg) scale(0.9);
  736. }
  737. 100% {
  738. transform: rotate(720deg) scale(1);
  739. }
  740. }
  741. .home_nei {
  742. overflow: hidden;
  743. width: 12.575rem;
  744. margin: 3.69133rem auto;
  745. }
  746. .home_nei img {
  747. width: 100%;
  748. overflow: hidden;
  749. animation: mysecond 8s infinite linear;
  750. }
  751. .remove_animation img {
  752. animation: none;
  753. }
  754. @keyframes mysecond {
  755. 0% {
  756. transform: rotate(0deg) scale(1);
  757. }
  758. 50% {
  759. transform: rotate(-360deg) scale(1);
  760. }
  761. 75% {
  762. transform: rotate(-540deg) scale(0.9);
  763. }
  764. 100% {
  765. transform: rotate(-720deg) scale(1);
  766. }
  767. }
  768. .title {
  769. background: #FFFFFF;
  770. padding: 0.9rem 0;
  771. text-align: center;
  772. box-shadow: 0 0 10px #e5e5e5;
  773. font-size: 0.9rem;
  774. font-weight: bold;
  775. color: #000;
  776. }
  777. .main_top {
  778. padding-top: 2.5rem;
  779. text-align: center;
  780. color: #757575;
  781. font-size: 0.9rem;
  782. font-weight: bold;
  783. }
  784. .main_top_cricle {
  785. margin: 1.25rem auto;
  786. width: 9.2rem;
  787. height: 9.2rem;
  788. position: relative;
  789. overflow: hidden;
  790. }
  791. .main_top_cricle img {
  792. width: 98%;
  793. }
  794. .main_cricle {
  795. position: absolute;
  796. top: 0;
  797. left: 0;
  798. right: 0;
  799. bottom: 0;
  800. overflow: hidden;
  801. z-index: 5;
  802. animation: myfirst 4s infinite linear;
  803. }
  804. @keyframes myfirst {
  805. 0% {
  806. transform: rotate(0deg);
  807. }
  808. 50% {
  809. transform: rotate(360deg);
  810. }
  811. 75% {
  812. transform: rotate(540deg);
  813. }
  814. 100% {
  815. transform: rotate(720deg);
  816. }
  817. }
  818. .main_cricle img {
  819. width: 100%;
  820. height: 100%;
  821. }
  822. .main_bottom {
  823. margin-top: 30rpx;
  824. overflow: hidden;
  825. text-align: center;
  826. font-size: 28rpx;
  827. color: #333;
  828. }
  829. .bottom_main {
  830. margin-top: 1rem;
  831. display: flex;
  832. overflow: hidden;
  833. }
  834. .bottom_main_list {
  835. text-align: center;
  836. flex-grow: 1;
  837. font-size: 28rpx;
  838. color: #333;
  839. }
  840. .bottom_main_list img {
  841. width: 2.5rem;
  842. margin-bottom: 10rpx;
  843. }
  844. .uer-camera {
  845. position: fixed;
  846. top: 200rpx;
  847. right: 42%;
  848. color: #fff;
  849. text-align: center;
  850. font-size: 24rpx;
  851. padding: 6rpx 8rpx 8rpx 6rpx;
  852. border-radius: 24rpx;
  853. height: 88rpx;
  854. width: 88rpx;
  855. overflow: hidden;
  856. }
  857. .uer-camera img {
  858. width: 100%;
  859. height: 100%;
  860. }
  861. }
  862. </style>