dynamicFaceCheck.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. <template>
  2. <view class="content">
  3. <view class="camera-box" v-if="showcamera">
  4. <view class="camera-bg-box">
  5. <camera v-if="isOk" class="camera" device-position="front" flash="off" resolution="low"></camera>
  6. </view>
  7. <view v-show="tipsText" class="camera-tip">{{ tipsText }}</view>
  8. </view>
  9. </view>
  10. </template>
  11. <script>
  12. import {
  13. mapState,
  14. mapMutations
  15. } from "vuex";
  16. export default {
  17. data() {
  18. return {
  19. cameraEngine: null,
  20. VKSession: null,
  21. showcamera: true,
  22. tipsText: "开始人脸检测",
  23. isOk: true,
  24. guestId: 0,
  25. idNumber: null,
  26. name: null,
  27. };
  28. },
  29. computed: {
  30. ...mapState('m_user', ['userInfo']),
  31. ...mapState("m_business", ["currentHotelId"]),
  32. },
  33. onShow() {
  34. let that = this;
  35. wx.getSetting({
  36. success(res) {
  37. if (!res.authSetting["scope.camera"]) {
  38. //获取摄像头权限
  39. wx.authorize({
  40. scope: "scope.camera",
  41. success() {
  42. that.showcamera = true;
  43. wx.showToast({
  44. title: "授权成功",
  45. icon: "success",
  46. duration: 1000,
  47. });
  48. },
  49. fail() {
  50. console.log("相机授权fail");
  51. wx.showModal({
  52. title: "提示",
  53. content: "尚未进行授权,功能将无法使用",
  54. cancelText: "取消",
  55. confirmText: "授权",
  56. success(res) {
  57. console.log(res);
  58. if (res.confirm) {
  59. console.log("用户点击确定");
  60. wx.openSetting({
  61. //这里的方法是调到一个添加权限的页面,这里可以测试在拒绝授权的情况下设置中是否存在相机选项
  62. success: (res) => {
  63. if (!res.authSetting[
  64. "scope.camera"]) {
  65. wx.authorize({
  66. scope: "scope.camera",
  67. success() {
  68. wx.showToast({
  69. title: "授权成功",
  70. icon: "success",
  71. duration: 1000,
  72. });
  73. setTimeout(
  74. function() {
  75. wx
  76. .navigateBack();
  77. }, 1000
  78. );
  79. },
  80. fail() {
  81. wx.showToast({
  82. title: "您已取消授权",
  83. icon: "error",
  84. duration: 1000,
  85. });
  86. setTimeout(
  87. function() {
  88. wx
  89. .navigateBack();
  90. }, 1000
  91. );
  92. },
  93. });
  94. }
  95. },
  96. fail: function() {
  97. console.log("相机授权设置失败");
  98. },
  99. });
  100. } else if (res.cancel) {
  101. console.log("用户点击取消");
  102. wx.showToast({
  103. title: "您已取消授权",
  104. icon: "error",
  105. duration: 1000,
  106. });
  107. setTimeout(function() {
  108. wx.navigateBack();
  109. }, 1000);
  110. }
  111. },
  112. });
  113. },
  114. });
  115. }
  116. },
  117. fail(res) {
  118. console.log("22222222222222222" + JSON.stringify(res));
  119. },
  120. });
  121. console.log("OKkkkkkk");
  122. // 初始化相机引擎,更改调用,引用新接口
  123. this.initData();
  124. },
  125. onLoad(options) {
  126. console.log("tipsText", this.tipsText);
  127. this.guestId = options.guestId;
  128. this.idNumber = options.idNumber;
  129. this.name = options.name;
  130. console.log("guestId ", this.guestId);
  131. console.log("idNumber ", this.idNumber);
  132. console.log("name", this.name);
  133. },
  134. methods: {
  135. //visionkit人脸必须函数
  136. async detectFace(frame) {
  137. console.log("frame", frame.data);
  138. this.VKSession.detectFace({
  139. frameBuffer: frame.data,
  140. width: frame.width,
  141. height: frame.height,
  142. scoreThreshold: 0.8,
  143. sourceType: 0,
  144. modelMode: 1,
  145. });
  146. },
  147. //初始化相机引擎
  148. initData() {
  149. let that = this;
  150. //使用visionkit
  151. that.cameraEngine = wx.createCameraContext();
  152. let count = 0;
  153. //初始化相机
  154. const listener = that.cameraEngine.onCameraFrame((frame) => {
  155. count++;
  156. //每十帧分析一次
  157. if (count === 10) {
  158. this.detectFace(frame);
  159. count = 0;
  160. }
  161. });
  162. //开始监听数据帧
  163. listener.start();
  164. //创建VK对象
  165. that.VKSession = wx.createVKSession({
  166. version: "v1",
  167. track: {
  168. plane: {
  169. mode: 1,
  170. },
  171. face: {
  172. mode: 2,
  173. },
  174. },
  175. });
  176. //启动VK对象
  177. that.VKSession.start((errno) => {
  178. console.log("VKSession.start errno", errno);
  179. if (errno) {
  180. wx.showModal({
  181. title: "提示",
  182. content: "网络错误,请退出后重试",
  183. showCancel: false,
  184. confirmText: "确定",
  185. success(res) {
  186. console.log(res);
  187. if (res.confirm) {
  188. wx.navigateBack();
  189. }
  190. },
  191. });
  192. }
  193. });
  194. that.VKSession.on("updateAnchors", (anchors) => {
  195. console.log("anchors", anchors);
  196. console.log("anchors.length", anchors.length);
  197. anchors.forEach((anchor) => {
  198. console.log("anchor.points", anchor.points);
  199. console.log("anchor.origin", anchor.origin);
  200. console.log("anchor.size", anchor.size);
  201. console.log("anchor.angle", anchor.angle);
  202. console.log("anchor", anchor.confidence);
  203. if (anchors.length > 1) {
  204. that.tipsText = "请保证只有一个人";
  205. } else {
  206. const {
  207. pitch,
  208. roll,
  209. yaw
  210. } = anchor.angle;
  211. const standard = 0.3;
  212. if (
  213. Math.abs(pitch) >= standard ||
  214. Math.abs(roll) >= standard ||
  215. Math.abs(yaw) >= standard
  216. ) {
  217. that.tipsText = "请平视摄像头";
  218. } else if (
  219. anchor.origin.x < 0.15 ||
  220. anchor.origin.x > 0.3 ||
  221. anchor.origin.y < 0.2 ||
  222. anchor.origin.y > 0.45
  223. ) {
  224. this.tipsText = "请将人脸对准中心位置";
  225. } else if (
  226. anchor.confidence[0] <= 0.8 ||
  227. anchor.confidence[1] <= 0.8 ||
  228. anchor.confidence[2] <= 0.8 ||
  229. anchor.confidence[3] <= 0.8 ||
  230. anchor.confidence[4] <= 0.8
  231. ) {
  232. that.tipsText = "请勿遮挡五官";
  233. } else {
  234. listener.stop();
  235. that.tipsText = "即将拍照,请保持!";
  236. setTimeout(function() {
  237. that.handleTakePhotoClick();
  238. }, 1000);
  239. return;
  240. }
  241. }
  242. });
  243. });
  244. },
  245. // 拍照
  246. handleTakePhotoClick() {
  247. this.tipsText = "正在上传...";
  248. uni.showLoading({
  249. title: "正在人脸认证,请稍后",
  250. });
  251. this.cameraEngine.takePhoto({
  252. quality: "normal",
  253. success: ({
  254. tempImagePath
  255. }) => {
  256. let mybase64 = wx
  257. .getFileSystemManager()
  258. .readFileSync(tempImagePath, "base64");
  259. this.afterRead(mybase64);
  260. },
  261. });
  262. },
  263. //上传
  264. async afterRead(mybase64) {
  265. let that = this;
  266. uni.$http
  267. .post("/faceVerification/checkPic", {
  268. hotelId: this.currentHotelId,
  269. faceData: mybase64,
  270. })
  271. .then(async (res) => {
  272. uni.hideLoading();
  273. console.log("mybase64", mybase64);
  274. if (res.data.code === 200 && res.data.success === true) {
  275. that.isOk = false;
  276. if (this.userInfo.skipIdMatching) {
  277. that.isOk = true;
  278. uni.showModal({
  279. content: "图片检查通过!",
  280. showCancel: false,
  281. success: function(res) {
  282. if (res.confirm) {
  283. console.log("用户点击确定");
  284. setTimeout(function() {
  285. let pages = getCurrentPages();
  286. console.log("pages", pages);
  287. let prevPage = pages[pages.length - 2];
  288. wx.navigateBack({
  289. success: () => {
  290. prevPage.$vm
  291. .setGuestPicBase64ById(
  292. that
  293. .guestId,
  294. mybase64
  295. );
  296. },
  297. });
  298. }, 1000);
  299. }
  300. },
  301. });
  302. } else {
  303. uni.showLoading({
  304. title: "正在人证比对,请稍后",
  305. });
  306. let yunjiFaceCheckInfo = {
  307. idNo: that.idNumber,
  308. name: that.name,
  309. image: mybase64,
  310. };
  311. let res = await uni.$http.post(
  312. "/faceVerification/yunjiVerification",
  313. yunjiFaceCheckInfo
  314. );
  315. uni.hideLoading();
  316. if (res.data.success === true) {
  317. uni.showModal({
  318. content: "人证比对通过!",
  319. showCancel: false,
  320. success: function(res) {
  321. if (res.confirm) {
  322. console.log("用户点击确定");
  323. setTimeout(function() {
  324. let pages = getCurrentPages();
  325. console.log("pages", pages);
  326. let prevPage = pages[pages.length - 2];
  327. // prevPage.setData({
  328. // pic: mybase64,
  329. // });
  330. wx.navigateBack({
  331. success: () => {
  332. prevPage.$vm
  333. .setGuestPicBase64ById(
  334. that
  335. .guestId,
  336. mybase64
  337. );
  338. },
  339. });
  340. }, 1000);
  341. }
  342. },
  343. });
  344. } else {
  345. that.isOk = true
  346. uni.showModal({
  347. content: "人证比对失败,请重试",
  348. showCancel: false,
  349. success: function(res) {
  350. if (res.confirm) {
  351. console.log("用户点击确定");
  352. that.initData();
  353. }
  354. },
  355. });
  356. }
  357. }
  358. } else {
  359. uni.showModal({
  360. content: "人脸认证失败,请重试",
  361. showCancel: false,
  362. success: function(res) {
  363. if (res.confirm) {
  364. console.log("用户点击确定");
  365. that.initData();
  366. }
  367. },
  368. });
  369. }
  370. console.log("checkPicRes", res);
  371. });
  372. },
  373. },
  374. };
  375. </script>
  376. <style lang="scss">
  377. .content {
  378. position: absolute;
  379. top: 0;
  380. right: 0;
  381. bottom: 0;
  382. left: 0;
  383. .camera-box {
  384. position: relative;
  385. width: 100%;
  386. height: 100%;
  387. }
  388. .camera-bg-box {
  389. position: relative;
  390. width: 100%;
  391. height: 100%;
  392. overflow: hidden;
  393. &::after {
  394. content: "";
  395. position: absolute;
  396. left: 50%;
  397. top: 50%;
  398. transform: translateX(-50%) translateY(-50%);
  399. border-radius: 100%;
  400. width: 600rpx;
  401. height: 600rpx;
  402. border: 1000rpx solid rgba(255, 255, 255, 0.998);
  403. }
  404. }
  405. .camera {
  406. width: 100%;
  407. height: 100%;
  408. border-top: 200rpx solid black;
  409. border-bottom: 200rpx solid black;
  410. box-sizing: border-box;
  411. }
  412. .camera-tip {
  413. position: absolute;
  414. bottom: 220rpx;
  415. left: 50%;
  416. color: rgb(0, 0, 0);
  417. transform: translateX(-50%);
  418. // .text-40-fff-600();
  419. }
  420. }
  421. </style>