Explorar el Código

增加照片回显

fbw hace 1 semana
padre
commit
558fb129cc

+ 369 - 44
package-lock.json

@@ -1386,6 +1386,155 @@
       "integrity": "sha1-pTUV2yXYA4N0OBtzryC7Ty5QjYc=",
       "dev": true
     },
+    "@tensorflow-models/body-pix": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmmirror.com/@tensorflow-models/body-pix/-/body-pix-2.2.1.tgz",
+      "integrity": "sha512-JeZHcpVMR0mW2znmF0FpZ0f7zpSY7c6+A7FBOmcIyZupTkXmG3MwGGqFPsVjRBwfqaKa4qYCJd7Svqo6rMzJYw=="
+    },
+    "@tensorflow/tfjs": {
+      "version": "4.22.0",
+      "resolved": "https://registry.npmmirror.com/@tensorflow/tfjs/-/tfjs-4.22.0.tgz",
+      "integrity": "sha512-0TrIrXs6/b7FLhLVNmfh8Sah6JgjBPH4mZ8JGb7NU6WW+cx00qK5BcAZxw7NCzxj6N8MRAIfHq+oNbPUNG5VAg==",
+      "requires": {
+        "@tensorflow/tfjs-backend-cpu": "4.22.0",
+        "@tensorflow/tfjs-backend-webgl": "4.22.0",
+        "@tensorflow/tfjs-converter": "4.22.0",
+        "@tensorflow/tfjs-core": "4.22.0",
+        "@tensorflow/tfjs-data": "4.22.0",
+        "@tensorflow/tfjs-layers": "4.22.0",
+        "argparse": "^1.0.10",
+        "chalk": "^4.1.0",
+        "core-js": "3.29.1",
+        "regenerator-runtime": "^0.13.5",
+        "yargs": "^16.0.3"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+        },
+        "core-js": {
+          "version": "3.29.1",
+          "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.29.1.tgz",
+          "integrity": "sha512-+jwgnhg6cQxKYIIjGtAHq2nwUOolo9eoFZ4sHfUH09BLXBgxnH4gA0zEd+t+BO2cNB8idaBtZFcFTRjQJRJmAw=="
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
+          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "@tensorflow/tfjs-backend-cpu": {
+      "version": "4.22.0",
+      "resolved": "https://registry.npmmirror.com/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.22.0.tgz",
+      "integrity": "sha512-1u0FmuLGuRAi8D2c3cocHTASGXOmHc/4OvoVDENJayjYkS119fcTcQf4iHrtLthWyDIPy3JiPhRrZQC9EwnhLw==",
+      "requires": {
+        "@types/seedrandom": "^2.4.28",
+        "seedrandom": "^3.0.5"
+      }
+    },
+    "@tensorflow/tfjs-backend-webgl": {
+      "version": "4.22.0",
+      "resolved": "https://registry.npmmirror.com/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.22.0.tgz",
+      "integrity": "sha512-H535XtZWnWgNwSzv538czjVlbJebDl5QTMOth4RXr2p/kJ1qSIXE0vZvEtO+5EC9b00SvhplECny2yDewQb/Yg==",
+      "requires": {
+        "@tensorflow/tfjs-backend-cpu": "4.22.0",
+        "@types/offscreencanvas": "~2019.3.0",
+        "@types/seedrandom": "^2.4.28",
+        "seedrandom": "^3.0.5"
+      }
+    },
+    "@tensorflow/tfjs-converter": {
+      "version": "4.22.0",
+      "resolved": "https://registry.npmmirror.com/@tensorflow/tfjs-converter/-/tfjs-converter-4.22.0.tgz",
+      "integrity": "sha512-PT43MGlnzIo+YfbsjM79Lxk9lOq6uUwZuCc8rrp0hfpLjF6Jv8jS84u2jFb+WpUeuF4K33ZDNx8CjiYrGQ2trQ=="
+    },
+    "@tensorflow/tfjs-core": {
+      "version": "4.22.0",
+      "resolved": "https://registry.npmmirror.com/@tensorflow/tfjs-core/-/tfjs-core-4.22.0.tgz",
+      "integrity": "sha512-LEkOyzbknKFoWUwfkr59vSB68DMJ4cjwwHgicXN0DUi3a0Vh1Er3JQqCI1Hl86GGZQvY8ezVrtDIvqR1ZFW55A==",
+      "requires": {
+        "@types/long": "^4.0.1",
+        "@types/offscreencanvas": "~2019.7.0",
+        "@types/seedrandom": "^2.4.28",
+        "@webgpu/types": "0.1.38",
+        "long": "4.0.0",
+        "node-fetch": "~2.6.1",
+        "seedrandom": "^3.0.5"
+      },
+      "dependencies": {
+        "@types/offscreencanvas": {
+          "version": "2019.7.3",
+          "resolved": "https://registry.npmmirror.com/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz",
+          "integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A=="
+        }
+      }
+    },
+    "@tensorflow/tfjs-data": {
+      "version": "4.22.0",
+      "resolved": "https://registry.npmmirror.com/@tensorflow/tfjs-data/-/tfjs-data-4.22.0.tgz",
+      "integrity": "sha512-dYmF3LihQIGvtgJrt382hSRH4S0QuAp2w1hXJI2+kOaEqo5HnUPG0k5KA6va+S1yUhx7UBToUKCBHeLHFQRV4w==",
+      "requires": {
+        "@types/node-fetch": "^2.1.2",
+        "node-fetch": "~2.6.1",
+        "string_decoder": "^1.3.0"
+      },
+      "dependencies": {
+        "safe-buffer": {
+          "version": "5.2.1",
+          "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
+          "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+        },
+        "string_decoder": {
+          "version": "1.3.0",
+          "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz",
+          "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+          "requires": {
+            "safe-buffer": "~5.2.0"
+          }
+        }
+      }
+    },
+    "@tensorflow/tfjs-layers": {
+      "version": "4.22.0",
+      "resolved": "https://registry.npmmirror.com/@tensorflow/tfjs-layers/-/tfjs-layers-4.22.0.tgz",
+      "integrity": "sha512-lybPj4ZNj9iIAPUj7a8ZW1hg8KQGfqWLlCZDi9eM/oNKCCAgchiyzx8OrYoWmRrB+AM6VNEeIT+2gZKg5ReihA=="
+    },
     "@types/body-parser": {
       "version": "1.19.2",
       "resolved": "https://registry.npmmirror.com/@types/body-parser/download/@types/body-parser-1.19.2.tgz",
@@ -1463,6 +1612,11 @@
       "integrity": "sha1-l+3JA36gw4WFMgsolk3eOznkZg0=",
       "dev": true
     },
+    "@types/long": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/@types/long/-/long-4.0.2.tgz",
+      "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="
+    },
     "@types/mime": {
       "version": "1.3.2",
       "resolved": "https://registry.npmmirror.com/@types/mime/download/@types/mime-1.3.2.tgz",
@@ -1484,8 +1638,30 @@
     "@types/node": {
       "version": "17.0.10",
       "resolved": "https://registry.npmmirror.com/@types/node/download/@types/node-17.0.10.tgz",
-      "integrity": "sha512-S/3xB4KzyFxYGCppyDt68yzBU9ysL88lSdIah4D6cptdcltc4NCPCAMc0+PCpg/lLIyC7IPvj2Z52OJWeIUkog==",
-      "dev": true
+      "integrity": "sha512-S/3xB4KzyFxYGCppyDt68yzBU9ysL88lSdIah4D6cptdcltc4NCPCAMc0+PCpg/lLIyC7IPvj2Z52OJWeIUkog=="
+    },
+    "@types/node-fetch": {
+      "version": "2.6.12",
+      "resolved": "https://registry.npmmirror.com/@types/node-fetch/-/node-fetch-2.6.12.tgz",
+      "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==",
+      "requires": {
+        "@types/node": "*",
+        "form-data": "^4.0.0"
+      },
+      "dependencies": {
+        "form-data": {
+          "version": "4.0.3",
+          "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.3.tgz",
+          "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==",
+          "requires": {
+            "asynckit": "^0.4.0",
+            "combined-stream": "^1.0.8",
+            "es-set-tostringtag": "^2.1.0",
+            "hasown": "^2.0.2",
+            "mime-types": "^2.1.12"
+          }
+        }
+      }
     },
     "@types/normalize-package-data": {
       "version": "2.4.1",
@@ -1493,6 +1669,11 @@
       "integrity": "sha1-0zV0eaD9/dWQf+Z+F+CoXJBuEwE=",
       "dev": true
     },
+    "@types/offscreencanvas": {
+      "version": "2019.3.0",
+      "resolved": "https://registry.npmmirror.com/@types/offscreencanvas/-/offscreencanvas-2019.3.0.tgz",
+      "integrity": "sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q=="
+    },
     "@types/q": {
       "version": "1.5.5",
       "resolved": "https://registry.npmmirror.com/@types/q/download/@types/q-1.5.5.tgz",
@@ -1511,6 +1692,11 @@
       "integrity": "sha1-zWZ7z90CUhOq+3ylkVqTJZCs3Nw=",
       "dev": true
     },
+    "@types/seedrandom": {
+      "version": "2.4.34",
+      "resolved": "https://registry.npmmirror.com/@types/seedrandom/-/seedrandom-2.4.34.tgz",
+      "integrity": "sha512-ytDiArvrn/3Xk6/vtylys5tlY6eo7Ane0hvcx++TKo6RxQXuVfW0AF/oeWqAj9dN29SyhtawuXstgmPlwNcv/A=="
+    },
     "@types/serve-static": {
       "version": "1.13.10",
       "resolved": "https://registry.npmmirror.com/@types/serve-static/download/@types/serve-static-1.13.10.tgz",
@@ -2328,6 +2514,11 @@
         "@xtuc/long": "4.2.2"
       }
     },
+    "@webgpu/types": {
+      "version": "0.1.38",
+      "resolved": "https://registry.npmmirror.com/@webgpu/types/-/types-0.1.38.tgz",
+      "integrity": "sha512-7LrhVKz2PRh+DD7+S+PVaFd5HxaWQvoMqBbsV9fNJO1pjUs1P8bM2vQVNfk+3URTqbuTI7gkXi0rfsN0IadoBA=="
+    },
     "@xtuc/ieee754": {
       "version": "1.2.0",
       "resolved": "https://registry.nlark.com/@xtuc/ieee754/download/@xtuc/ieee754-1.2.0.tgz",
@@ -2514,7 +2705,6 @@
       "version": "1.0.10",
       "resolved": "https://registry.nlark.com/argparse/download/argparse-1.0.10.tgz",
       "integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=",
-      "dev": true,
       "requires": {
         "sprintf-js": "~1.0.2"
       }
@@ -2670,8 +2860,7 @@
     "asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.nlark.com/asynckit/download/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
-      "dev": true
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
     },
     "atob": {
       "version": "2.1.2",
@@ -3302,6 +3491,22 @@
         "get-intrinsic": "^1.0.2"
       }
     },
+    "call-bind-apply-helpers": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+      "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+      "requires": {
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2"
+      },
+      "dependencies": {
+        "function-bind": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
+          "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
+        }
+      }
+    },
     "call-me-maybe": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/call-me-maybe/download/call-me-maybe-1.0.1.tgz",
@@ -3761,7 +3966,6 @@
       "version": "1.0.8",
       "resolved": "https://registry.nlark.com/combined-stream/download/combined-stream-1.0.8.tgz",
       "integrity": "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=",
-      "dev": true,
       "requires": {
         "delayed-stream": "~1.0.0"
       }
@@ -4754,8 +4958,7 @@
     "delayed-stream": {
       "version": "1.0.0",
       "resolved": "https://registry.nlark.com/delayed-stream/download/delayed-stream-1.0.0.tgz",
-      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
-      "dev": true
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
     },
     "depd": {
       "version": "1.1.2",
@@ -4934,6 +5137,16 @@
       "integrity": "sha1-P7rwIL/XlIhAcuomsel5HUWmKfA=",
       "dev": true
     },
+    "dunder-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
+      "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+      "requires": {
+        "call-bind-apply-helpers": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "gopd": "^1.2.0"
+      }
+    },
     "duplexer": {
       "version": "0.1.2",
       "resolved": "https://registry.nlark.com/duplexer/download/duplexer-0.1.2.tgz",
@@ -5032,8 +5245,7 @@
     "emoji-regex": {
       "version": "8.0.0",
       "resolved": "https://registry.npmmirror.com/emoji-regex/download/emoji-regex-8.0.0.tgz",
-      "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=",
-      "dev": true
+      "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc="
     },
     "emojis-list": {
       "version": "3.0.0",
@@ -5162,6 +5374,72 @@
         "unbox-primitive": "^1.0.1"
       }
     },
+    "es-define-property": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
+      "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="
+    },
+    "es-errors": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
+      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="
+    },
+    "es-object-atoms": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+      "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+      "requires": {
+        "es-errors": "^1.3.0"
+      }
+    },
+    "es-set-tostringtag": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+      "requires": {
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.6",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.2"
+      },
+      "dependencies": {
+        "function-bind": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
+          "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
+        },
+        "get-intrinsic": {
+          "version": "1.3.0",
+          "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+          "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+          "requires": {
+            "call-bind-apply-helpers": "^1.0.2",
+            "es-define-property": "^1.0.1",
+            "es-errors": "^1.3.0",
+            "es-object-atoms": "^1.1.1",
+            "function-bind": "^1.1.2",
+            "get-proto": "^1.0.1",
+            "gopd": "^1.2.0",
+            "has-symbols": "^1.1.0",
+            "hasown": "^2.0.2",
+            "math-intrinsics": "^1.1.0"
+          }
+        },
+        "has-symbols": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
+          "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="
+        },
+        "has-tostringtag": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+          "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+          "requires": {
+            "has-symbols": "^1.0.3"
+          }
+        }
+      }
+    },
     "es-to-primitive": {
       "version": "1.2.1",
       "resolved": "https://registry.nlark.com/es-to-primitive/download/es-to-primitive-1.2.1.tgz",
@@ -5189,8 +5467,7 @@
     "escalade": {
       "version": "3.1.1",
       "resolved": "https://registry.nlark.com/escalade/download/escalade-3.1.1.tgz",
-      "integrity": "sha1-2M/ccACWXFoBdLSoLqpcBVJ0LkA=",
-      "dev": true
+      "integrity": "sha1-2M/ccACWXFoBdLSoLqpcBVJ0LkA="
     },
     "escape-html": {
       "version": "1.0.3",
@@ -6100,8 +6377,7 @@
     "get-caller-file": {
       "version": "2.0.5",
       "resolved": "https://registry.nlark.com/get-caller-file/download/get-caller-file-2.0.5.tgz",
-      "integrity": "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34=",
-      "dev": true
+      "integrity": "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34="
     },
     "get-intrinsic": {
       "version": "1.1.1",
@@ -6114,6 +6390,15 @@
         "has-symbols": "^1.0.1"
       }
     },
+    "get-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
+      "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+      "requires": {
+        "dunder-proto": "^1.0.1",
+        "es-object-atoms": "^1.0.0"
+      }
+    },
     "get-stdin": {
       "version": "6.0.0",
       "resolved": "https://registry.nlark.com/get-stdin/download/get-stdin-6.0.0.tgz",
@@ -6203,6 +6488,11 @@
         "slash": "^2.0.0"
       }
     },
+    "gopd": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
+      "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="
+    },
     "graceful-fs": {
       "version": "4.2.9",
       "resolved": "https://registry.npmmirror.com/graceful-fs/download/graceful-fs-4.2.9.tgz",
@@ -6353,6 +6643,21 @@
         "minimalistic-assert": "^1.0.1"
       }
     },
+    "hasown": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
+      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+      "requires": {
+        "function-bind": "^1.1.2"
+      },
+      "dependencies": {
+        "function-bind": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
+          "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
+        }
+      }
+    },
     "he": {
       "version": "1.2.0",
       "resolved": "https://registry.npmmirror.com/he/download/he-1.2.0.tgz",
@@ -7256,8 +7561,7 @@
     "is-fullwidth-code-point": {
       "version": "3.0.0",
       "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz",
-      "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=",
-      "dev": true
+      "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0="
     },
     "is-glob": {
       "version": "4.0.3",
@@ -7866,6 +8170,11 @@
       "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==",
       "dev": true
     },
+    "long": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/long/-/long-4.0.0.tgz",
+      "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
+    },
     "lower-case": {
       "version": "1.1.4",
       "resolved": "https://registry.nlark.com/lower-case/download/lower-case-1.1.4.tgz",
@@ -7942,6 +8251,11 @@
         "zousan": "^2.3.3"
       }
     },
+    "math-intrinsics": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="
+    },
     "md5": {
       "version": "2.3.0",
       "resolved": "https://registry.npmmirror.com/md5/-/md5-2.3.0.tgz",
@@ -8074,14 +8388,12 @@
     "mime-db": {
       "version": "1.51.0",
       "resolved": "https://registry.npmmirror.com/mime-db/download/mime-db-1.51.0.tgz?cache=0&sync_timestamp=1636425985504&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fmime-db%2Fdownload%2Fmime-db-1.51.0.tgz",
-      "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
-      "dev": true
+      "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g=="
     },
     "mime-types": {
       "version": "2.1.34",
       "resolved": "https://registry.npmmirror.com/mime-types/download/mime-types-2.1.34.tgz?cache=0&sync_timestamp=1636432301104&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fmime-types%2Fdownload%2Fmime-types-2.1.34.tgz",
       "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
-      "dev": true,
       "requires": {
         "mime-db": "1.51.0"
       }
@@ -8439,6 +8751,14 @@
         "lower-case": "^1.1.1"
       }
     },
+    "node-fetch": {
+      "version": "2.6.13",
+      "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.6.13.tgz",
+      "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==",
+      "requires": {
+        "whatwg-url": "^5.0.0"
+      }
+    },
     "node-fetch-npm": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz",
@@ -10157,8 +10477,7 @@
     "regenerator-runtime": {
       "version": "0.13.9",
       "resolved": "https://registry.npmmirror.com/regenerator-runtime/download/regenerator-runtime-0.13.9.tgz",
-      "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==",
-      "dev": true
+      "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
     },
     "regenerator-transform": {
       "version": "0.14.5",
@@ -10378,8 +10697,7 @@
     "require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmmirror.com/require-directory/download/require-directory-2.1.1.tgz",
-      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
-      "dev": true
+      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
     },
     "require-main-filename": {
       "version": "2.0.0",
@@ -10558,10 +10876,10 @@
         "typescript": "^3.6.3"
       }
     },
-    "screenfull": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmmirror.com/screenfull/-/screenfull-6.0.2.tgz",
-      "integrity": "sha512-AQdy8s4WhNvUZ6P8F6PB21tSPIYKniic+Ogx0AacBMjKP1GUHN2E9URxQHtCusiwxudnCKkdy4GrHXPPJSkCCw=="
+    "seedrandom": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmmirror.com/seedrandom/-/seedrandom-3.0.5.tgz",
+      "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="
     },
     "select-hose": {
       "version": "2.0.0",
@@ -11233,8 +11551,7 @@
     "sprintf-js": {
       "version": "1.0.3",
       "resolved": "https://registry.nlark.com/sprintf-js/download/sprintf-js-1.0.3.tgz",
-      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
-      "dev": true
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
     },
     "sshpk": {
       "version": "1.17.0",
@@ -11347,7 +11664,6 @@
       "version": "4.2.3",
       "resolved": "https://registry.npmmirror.com/string-width/download/string-width-4.2.3.tgz",
       "integrity": "sha1-JpxxF9J7Ba0uU2gwqOyJXvnG0BA=",
-      "dev": true,
       "requires": {
         "emoji-regex": "^8.0.0",
         "is-fullwidth-code-point": "^3.0.0",
@@ -11386,7 +11702,6 @@
       "version": "6.0.1",
       "resolved": "https://registry.npmmirror.com/strip-ansi/download/strip-ansi-6.0.1.tgz?cache=0&sync_timestamp=1632432619223&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-6.0.1.tgz",
       "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=",
-      "dev": true,
       "requires": {
         "ansi-regex": "^5.0.1"
       },
@@ -11394,8 +11709,7 @@
         "ansi-regex": {
           "version": "5.0.1",
           "resolved": "https://registry.nlark.com/ansi-regex/download/ansi-regex-5.0.1.tgz?cache=0&sync_timestamp=1631634988487&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fansi-regex%2Fdownload%2Fansi-regex-5.0.1.tgz",
-          "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=",
-          "dev": true
+          "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ="
         }
       }
     },
@@ -11864,6 +12178,11 @@
         "punycode": "^2.1.1"
       }
     },
+    "tr46": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz",
+      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+    },
     "tryer": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/tryer/download/tryer-1.0.1.tgz",
@@ -12623,6 +12942,11 @@
         "defaults": "^1.0.3"
       }
     },
+    "webidl-conversions": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+    },
     "webpack": {
       "version": "4.46.0",
       "resolved": "https://registry.npmmirror.com/webpack/download/webpack-4.46.0.tgz",
@@ -13132,6 +13456,15 @@
       "integrity": "sha1-f4RzvIOd/YdgituV1+sHUhFXikI=",
       "dev": true
     },
+    "whatwg-url": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz",
+      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+      "requires": {
+        "tr46": "~0.0.3",
+        "webidl-conversions": "^3.0.0"
+      }
+    },
     "which": {
       "version": "1.3.1",
       "resolved": "https://registry.nlark.com/which/download/which-1.3.1.tgz",
@@ -13178,7 +13511,6 @@
       "version": "7.0.0",
       "resolved": "https://registry.nlark.com/wrap-ansi/download/wrap-ansi-7.0.0.tgz",
       "integrity": "sha1-Z+FFz/UQpqaYS98RUpEdadLrnkM=",
-      "dev": true,
       "requires": {
         "ansi-styles": "^4.0.0",
         "string-width": "^4.1.0",
@@ -13189,7 +13521,6 @@
           "version": "4.3.0",
           "resolved": "https://registry.npmmirror.com/ansi-styles/download/ansi-styles-4.3.0.tgz",
           "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-          "dev": true,
           "requires": {
             "color-convert": "^2.0.1"
           }
@@ -13198,7 +13529,6 @@
           "version": "2.0.1",
           "resolved": "https://registry.npmmirror.com/color-convert/download/color-convert-2.0.1.tgz",
           "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
-          "dev": true,
           "requires": {
             "color-name": "~1.1.4"
           }
@@ -13206,8 +13536,7 @@
         "color-name": {
           "version": "1.1.4",
           "resolved": "https://registry.nlark.com/color-name/download/color-name-1.1.4.tgz",
-          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
-          "dev": true
+          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI="
         }
       }
     },
@@ -13253,7 +13582,6 @@
       "version": "16.2.0",
       "resolved": "https://registry.npmmirror.com/yargs/download/yargs-16.2.0.tgz",
       "integrity": "sha1-HIK/D2tqZur85+8w43b0mhJHf2Y=",
-      "dev": true,
       "requires": {
         "cliui": "^7.0.2",
         "escalade": "^3.1.1",
@@ -13268,7 +13596,6 @@
           "version": "7.0.4",
           "resolved": "https://registry.nlark.com/cliui/download/cliui-7.0.4.tgz",
           "integrity": "sha1-oCZe5lVHb8gHrqnfPfjfd4OAi08=",
-          "dev": true,
           "requires": {
             "string-width": "^4.2.0",
             "strip-ansi": "^6.0.0",
@@ -13278,16 +13605,14 @@
         "y18n": {
           "version": "5.0.8",
           "resolved": "https://registry.nlark.com/y18n/download/y18n-5.0.8.tgz",
-          "integrity": "sha1-f0k00PfKjFb5UxSTndzS3ZHOHVU=",
-          "dev": true
+          "integrity": "sha1-f0k00PfKjFb5UxSTndzS3ZHOHVU="
         }
       }
     },
     "yargs-parser": {
       "version": "20.2.9",
       "resolved": "https://registry.npmmirror.com/yargs-parser/download/yargs-parser-20.2.9.tgz?cache=0&sync_timestamp=1637031214824&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fyargs-parser%2Fdownload%2Fyargs-parser-20.2.9.tgz",
-      "integrity": "sha1-LrfcOwKJcY/ClfNidThFxBoMlO4=",
-      "dev": true
+      "integrity": "sha1-LrfcOwKJcY/ClfNidThFxBoMlO4="
     },
     "yorkie": {
       "version": "2.0.0",

+ 2 - 0
package.json

@@ -10,6 +10,8 @@
   },
   "dependencies": {
     "@datorama/akita": "^7.1.1",
+    "@tensorflow-models/body-pix": "^2.2.1",
+    "@tensorflow/tfjs": "^4.22.0",
     "animate.css": "^3.5.1",
     "axios": "^0.25.0",
     "cesium": "^1.84.0",

+ 6 - 2
src/components/IdReader/index.vue

@@ -36,6 +36,7 @@ export default {
   },
   watch: {
     enable(newValue, oldValue) {
+      console.log("启动项", newValue, oldValue);
       if (!oldValue && newValue) {
         this.OcrRecognition();
         this.timer = setInterval(() => {
@@ -43,6 +44,7 @@ export default {
           this.ReadIDCardNoJudge();
         }, 3000);
       } else if (oldValue && !newValue) {
+        this.timer = null;
         this.closeConnect();
       }
     },
@@ -95,7 +97,7 @@ export default {
           //   document.all["BackPhotoDisplay"].src =
           //     "data:image/jpeg;base64," + alldata[21];//反面
           // }
-          //回传 
+          //回传
           this.$emit("output", this.response);
         } else {
           console.log("读取数据信息", res.data);
@@ -109,7 +111,9 @@ export default {
       paramTimeOut = "timeout=" + paramTimeOut;
       var parameterAll = paramTimeOut;
       let val = "04?" + parameterAll;
-      this.websockets.send(val);
+      if (this.websockets !== null) {
+        this.websockets.send(val);
+      }
     },
     //关闭连接
     closeConnect() {

+ 5 - 5
src/utils/request.js

@@ -67,16 +67,16 @@ $http.interceptors.response.use(
     if ((res.code + "").startsWith("2")) {
       return res;
     } else if (res.code === 40000) {
-      // console.log("ERROR:", res, localStorage.getItem("token"));
+      // console.log("ERROR:", response, res, localStorage.getItem("token"));
       Message({
         message: "登录超时,请重新登录",
         type: "error",
         duration: 800,
       });
-      setTimeout(() => {
-        localStorage.clear();
-        window.location.reload();
-      }, 500);
+      localStorage.clear();
+      // setTimeout(() => {
+      //   window.location.reload();
+      // }, 500);
       // this.$router.push("/login");
     } else {
       // Message({

+ 10 - 5
src/views/components/baseHeader/left.vue

@@ -111,17 +111,22 @@ export default {
           name: "首页",
           path: "/basePage",
         },
-        {
-          id: "2",
-          name: "今日进站",
-          path: "/leave",
-        },
+        // {
+        //   id: "2",
+        //   name: "今日进站",
+        //   path: "/leave",
+        // },
         {
           id: "3",
           name: "退出登记",
           path: "/basePage",
         },
         // {
+        //   id: "4",
+        //   name: "退出登记",
+        //   path: "/test",
+        // },
+        // {
         //   id: "2",
         //   name: "关闭弹窗",
         //   path: "/basePage",

+ 15 - 9
src/views/components/dialog/RiskTipDialog.vue

@@ -385,15 +385,21 @@ export default {
     },
     async savePersonInfo(person) {
       try {
-        const res = await savePerson(person);
-        this.response = res;
-        if (this.dialogConfig.type == 1) {
-          console.log("绑定成功");
-          this.bindRecord(person);
-        }
-        if (this.dialogConfig.type == 2) {
-          console.log("解绑成功");
-          this.unbindRecord(person);
+        if (person.name !== "") {
+          const res = await savePerson(person);
+          this.response = res;
+          if (this.dialogConfig.type == 1) {
+            console.log("绑定成功");
+            this.bindRecord(person);
+          }
+          if (this.dialogConfig.type == 2) {
+            console.log("解绑成功");
+            this.unbindRecord(person);
+          }
+        } else {
+          if (this.dialogConfig.type == 2) {
+            this.$message.error("请将需要解绑的卡片贴近感应区");
+          }
         }
       } catch (err) {
         console.log(err);

+ 5 - 5
src/views/leave/index.vue

@@ -205,7 +205,7 @@ export default {
         this.personComingList.forEach((e) => {
           this.personsCount += Number(e.field007);
         });
-        console.log("入场登记报表sql", params, res);
+        // console.log("入场登记报表sql", params, res);
         this.refreKey++;
       } catch (err) {
         console.log(err);
@@ -223,7 +223,7 @@ export default {
         // this.personComingList.forEach((e) => {
         //   this.personsCount += Number(e.field007);
         // });
-        console.log("今日绑卡", params, res);
+        // console.log("今日绑卡", params, res);
         this.refreKey++;
       } catch (err) {
         console.log(err);
@@ -306,7 +306,7 @@ export default {
 </script>
 <style>
 .el-input__inner {
-  height: 120px;
+  height: 40px;
 }
 </style>
 <style lang="less" scoped>
@@ -322,7 +322,7 @@ export default {
     height: 100%;
     .infomation_prompt {
       font-size: 40px;
-      margin-top: 40px;
+      margin-top: 20px;
       margin-left: 20px;
     }
     .infomation_prop {
@@ -335,7 +335,7 @@ export default {
       font-size: 60px;
     }
     .infomation_data_line {
-      margin-top: 40px;
+      margin-top: 20px;
     }
     .infomation_table {
       height: 195px;

+ 373 - 0
src/views/recognize/components/VideoLocalWindowTest.vue

@@ -0,0 +1,373 @@
+<template>
+  <div class="videoContainer">
+    <video
+      ref="video"
+      id="video"
+      :width="1280"
+      :height="800"
+      autoplay
+      muted
+      playsinline
+    ></video>
+    <div id="timestamp" v-show="false">
+      {{ datetimeData.date + " " + datetimeData.time }}
+    </div>
+    <canvas id="blurred-canvas" :width="1280" :height="800"></canvas>
+    <!-- <el-button @click="startCamera">开启摄像头</el-button>
+    <el-button @click="stopCamera" :disabled="!isCameraActive"
+      >关闭摄像头</el-button
+    > -->
+  </div>
+</template>
+
+
+<script>
+/* eslint-disable */
+import * as tf from "@tensorflow/tfjs";
+import * as bodyPix from "@tensorflow-models/body-pix";
+import { GetPersonByFace, GetPersonByFaceBase64 } from "@/API/custom";
+import Dayjs from "dayjs";
+
+export default {
+  props: {
+    processStep: {
+      type: String,
+      require: true,
+    },
+    isUpload: {
+      type: String,
+      require: false,
+    },
+    cameraData: {
+      type: Object,
+      default: () => ({}),
+    },
+  },
+  watch: {
+    processStep: {
+      handler(step) {
+        if (step == 0 || step == 9) {
+          this.startCamera();
+        } else {
+          this.stopCamera();
+        }
+      },
+      deep: true,
+      immediate: true,
+    },
+    isUpload: {
+      handler(val) {
+        console.log("上传子级开关", val);
+        if (val) {
+          this.uploadImage();
+        } else {
+          this.isUpload = false;
+        }
+      },
+      deep: true,
+      immediate: true,
+    },
+  },
+  data() {
+    return {
+      isCameraActive: false,
+      video: null,
+      stream: null,
+      captureInterval: null, // 新增定时器变量
+      datetimeData: {
+        date: Dayjs(new Date()).format("YYYY-MM-DD"),
+        time: Dayjs(new Date()).format("HH:mm:ss"),
+        week: Dayjs(new Date()).format("dddd"),
+      },
+      // BodyPix模型加载
+      net: null,
+      // 修改默认值为 true,自动开启背景虚化
+      showBlurred: true,
+      loading: true,
+    };
+  },
+  methods: {
+    refreshTime() {
+      let speed = 1000;
+      let timer = null;
+      let theNowTime = () => {
+        // this.datePersonData.time = Dayjs(new Date()).format('HH:mm:ss')
+        this.datetimeData.time = Dayjs(new Date()).format("HH:mm:ss");
+        this.datetimeData.date = Dayjs(new Date()).format("YYYY-MM-DD");
+        this.datetimeData.week = Dayjs(new Date()).format("dddd");
+      };
+      timer = setInterval(theNowTime, speed);
+      this.$once("hook:beforeDestroy", () => {
+        clearInterval(timer);
+        timer = null;
+      });
+    },
+    async loadBodyPix() {
+      this.net = await bodyPix.load();
+      this.processVideoFrame();
+    },
+    async processVideoFrame() {
+      // 确保 video 和 blurredCanvas 存在
+      if (this.showBlurred && this.video && this.blurredCanvas) {
+        try {
+          const segmentation = await this.net.segmentPerson(this.video);
+          const backgroundBlurAmount = 5;
+          const edgeBlurAmount = 3;
+          const flipHorizontal = false;
+
+          bodyPix.drawBokehEffect(
+            this.blurredCanvas,
+            this.video,
+            segmentation,
+            backgroundBlurAmount,
+            edgeBlurAmount,
+            flipHorizontal
+          );
+        } catch (err) {
+          console.error("处理视频帧时出错:", err);
+        }
+      }
+
+      requestAnimationFrame(() => this.processVideoFrame());
+    },
+    async startCamera() {
+      try {
+        this.stream = await navigator.mediaDevices.getUserMedia({
+          video: true,
+        });
+        this.video = document.getElementById("video");
+        this.isCameraActive = true;
+
+        if (this.video) {
+          this.video.srcObject = this.stream;
+          this.loading = false;
+          this.loadBodyPix();
+        } else {
+          this.error = "未能找到视频元素,请检查 HTML 结构。";
+          this.loading = false;
+        }
+
+        if (this.isUpload) {
+          setTimeout(() => {
+            this.uploadImage();
+          }, 1000);
+        } else {
+          // 新增定时截图功能
+          this.captureInterval = setInterval(() => {
+            this.captureImage();
+            console.log("截图上传");
+          }, 2500);
+        }
+      } catch (err) {
+        console.error("摄像头访问错误:", err);
+        alert(`摄像头访问失败: ${err.message}`);
+        this.loading = false;
+      }
+    },
+    stopCamera() {
+      if (this.stream) {
+        this.stream.getTracks().forEach((track) => track.stop());
+        this.isCameraActive = false;
+        this.video.srcObject = null;
+        this.stream = null;
+
+        // 停止定时器
+        if (this.captureInterval) {
+          clearInterval(this.captureInterval);
+          this.captureInterval = null;
+        }
+      }
+    },
+    async captureImage() {
+      if (this.video.paused) return;
+      const canvas = document.createElement("canvas");
+
+      const cropWidth = this.video.videoWidth * 0.5;
+      const cropHeight = this.video.videoHeight * 0.98;
+
+      // 设置canvas尺寸为选择区域大小
+      canvas.width = cropWidth;
+      canvas.height = cropHeight;
+
+      const x = (this.video.videoWidth - cropWidth) / 2;
+      const y = (this.video.videoHeight - cropHeight) / 2;
+
+      const ctx = canvas.getContext("2d");
+      //中心60%区域
+      ctx.drawImage(
+        this.video,
+        x,
+        y,
+        cropWidth,
+        cropHeight,
+        0,
+        0,
+        cropWidth,
+        cropHeight
+      );
+      // canvas.width = video.videoWidth;
+      // canvas.height = video.videoHeight;
+      // const ctx = canvas.getContext("2d");
+      // ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
+      try {
+        const base64Data = canvas.toDataURL("image/png");
+        // console.log("上传数据:Base64", base64Data);
+        // 替换YOUR_SERVER_URL为你的实际服务器地址
+        const response = await fetch(
+          "/yapi/System/Person/GetPersonByFaceBase64",
+          {
+            method: "POST",
+            headers: {
+              token: localStorage.getItem("token"),
+              "Content-Type": "application/json",
+            },
+            body: JSON.stringify({
+              data: base64Data,
+              fileModule: 2,
+            }),
+          }
+        );
+        const result = await response.json();
+        // console.log("上传反馈", response, result);
+        if (result.code === 20000) {
+          // console.log("服务器返回数据:", result);
+          this.$emit("output", result.data);
+          this.uploadImage();
+          // setTimeout(() => {
+          //   this.stopCamera();
+          // }, 200);
+        }
+      } catch (err) {
+        console.error("上传过程中出错:", err);
+      }
+    },
+    async uploadImage() {
+      const canvas = document.createElement("canvas");
+
+      const cropWidth = this.video.videoWidth * 0.5;
+      const cropHeight = this.video.videoHeight * 0.98;
+
+      // 设置canvas尺寸为选择区域大小
+      canvas.width = cropWidth;
+      canvas.height = cropHeight;
+
+      const x = (this.video.videoWidth - cropWidth) / 2;
+      const y = (this.video.videoHeight - cropHeight) / 2;
+
+      const ctx = canvas.getContext("2d");
+      console.log(
+        "???????????????????",
+        x,
+        y,
+        cropWidth,
+        cropHeight,
+        this.video,
+        this.blurredCanvas,
+        canvas
+      );
+      //中心60%区域
+      ctx.drawImage(
+        this.video,
+        x,
+        y,
+        cropWidth,
+        cropHeight,
+        0,
+        0,
+        cropWidth,
+        cropHeight
+      );
+      ctx.drawImage(
+        this.showBlurred ? this.blurredCanvas : this.video,
+        x,
+        y,
+        this.blurredCanvas.width,
+        this.blurredCanvas.height,
+        0,
+        0,
+        cropWidth,
+        cropHeight
+      );
+      // ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
+      const timestampDiv = document.getElementById("timestamp");
+      // 在canvas上绘制时间戳
+      ctx.font = "24px Arial";
+      ctx.fillStyle = "white";
+      ctx.fillText(timestampDiv.textContent, 20, canvas.height - 20);
+      try {
+        const base64Data = canvas.toDataURL("image/png");
+        // console.log("上传数据:Base64", base64Data);
+        // 替换YOUR_SERVER_URL为你的实际服务器地址
+        const response = await fetch("/yapi/File/UploadBase64", {
+          method: "POST",
+          headers: {
+            token: localStorage.getItem("token"),
+            "Content-Type": "application/json",
+          },
+          body: JSON.stringify({
+            data: base64Data,
+            fileModule: 1,
+          }),
+        });
+        const result = await response.json();
+        // console.log("上传反馈", response, result);
+        if (result.code === 20000) {
+          console.log("服务器上传返回数据:", result);
+          this.$emit("outputPath", result.data);
+          setTimeout(() => {
+            this.stopCamera();
+          }, 200);
+        }
+        this.isUpload = false;
+      } catch (err) {
+        console.error("上传过程中出错:", err);
+      }
+    },
+  },
+  mounted() {
+    if (this.loading) {
+      this.blurredCanvas = document.getElementById("blurred-canvas");
+      if (this.blurredCanvas) {
+        this.ctx = this.blurredCanvas.getContext("2d");
+      }
+    }
+  },
+  created() {
+    this.startCamera();
+    this.refreshTime();
+  },
+  beforeDestroy() {
+    this.stopCamera();
+  },
+};
+</script>
+
+<style scoped>
+.videoContainer {
+  position: relative;
+  width: 50%; /* 容器宽度设为50% */
+  height: 100%; /* 容器高度设为100% */
+  margin: 0 auto; /* 居中显示 */
+  overflow: hidden; /* 隐藏溢出部分 */
+}
+video {
+  height: 800px;
+  width: 1280px;
+  transform: translate(-25%, 0%);
+  /* width: 100%;
+  max-width: 500px; */
+  background: #000;
+}
+#timestamp {
+  position: absolute;
+  bottom: 20px;
+  left: 20px;
+  color: white;
+  font-size: 24px;
+  background-color: rgba(0, 0, 0, 0.5);
+  padding: 5px;
+}
+#blurred-video {
+  display: none;
+}
+</style>

+ 90 - 21
src/views/recognize/index.vue

@@ -96,6 +96,20 @@
               />
             </span>
           </div>
+          <div class="infomation_data" v-if="processStep.num == 1">
+            <el-image
+              :key="refreshKey"
+              style="
+                width: 300px;
+                height: 400px;
+                top: 340px;
+                left: 260px;
+                position: absolute;
+              "
+              :src="tempPhotoPath"
+            >
+            </el-image>
+          </div>
           <div class="infomation_button">
             <el-button
               style="width: 160px; height: 80px; font-size: xx-large"
@@ -205,6 +219,32 @@
               </span>
             </div>
           </div>
+          <div class="infomation_data">
+            <el-image
+              v-if="personType == 1"
+              :key="refreshKey"
+              style="
+                width: 200px;
+                height: 300px;
+                top: 340px;
+                position: absolute;
+              "
+              :src="tempPhotoPath"
+            >
+            </el-image>
+            <el-image
+              v-if="personType == 2"
+              :key="refreshKey"
+              style="
+                width: 200px;
+                height: 300px;
+                top: 380px;
+                position: absolute;
+              "
+              :src="tempPhotoPath"
+            >
+            </el-image>
+          </div>
           <div class="infomation_button">
             <el-button
               style="
@@ -394,6 +434,20 @@
               />
             </span>
           </div>
+          <div class="infomation_data">
+            <el-image
+              :key="refreshKey"
+              style="
+                width: 300px;
+                height: 400px;
+                top: 340px;
+                left: 260px;
+                position: absolute;
+              "
+              :src="tempPhotoPath"
+            >
+            </el-image>
+          </div>
           <div class="infomation_button">
             <el-button
               style="width: 160px; height: 80px; font-size: xx-large"
@@ -591,6 +645,7 @@ export default {
   },
   data() {
     return {
+      tempPhotoPath: "",
       refreshKey: 0, //页面刷新
       cardEnable: false, //rfid刷卡
       idEnable: false, //身份证刷卡
@@ -683,10 +738,10 @@ export default {
       ],
       infomation: {
         id: "",
-        name: "112",
-        company: "333",
+        name: "",
+        company: "",
         idNumber: "",
-        telephone: "444",
+        telephone: "",
         cause: "",
         label: "",
         areasEnable: [2],
@@ -798,6 +853,7 @@ export default {
         ],
         tableData: [],
       },
+      pPath: "~@/assets/imgs/stationMap/default_0.png",
     };
   },
   watch: {
@@ -876,6 +932,14 @@ export default {
       deep: true,
       immediate: true,
     },
+    tempPhotoPath: {
+      handler(newVal, oldVal) {
+        console.log("照片路径:", newVal);
+        this.refresh();
+      },
+      deep: true,
+      immediate: true,
+    },
     nameEnbale: {
       handler(newVal) {
         console.log("重名检测", newVal);
@@ -902,6 +966,9 @@ export default {
   },
   computed: {
     ...mapGetters(["personInfo"]),
+    VUE_APP_BASE_API() {
+      return process.env.VUE_APP_BASE_API;
+    },
   },
   methods: {
     init() {
@@ -937,7 +1004,7 @@ export default {
     },
     recognize() {
       if (this.recognizeEnable) {
-        console.log("人脸识别", this.processStep);
+        // console.log("人脸识别", this.processStep);
         // setTimeout(() => {
         //   this.processStep.num++;
         // }, 3000);
@@ -1013,7 +1080,7 @@ export default {
       setTimeout(() => {
         loading.close();
         this.processStep.num++;
-      }, 2000);
+      }, 1000);
     },
     handleAudio(key, element = document) {
       const options = {
@@ -1034,14 +1101,14 @@ export default {
         switch (type) {
           case 8:
             this.processStep.num--;
-            console.log("上一步");
+            // console.log("上一步");
             break;
           case 7:
             this.processStep.num++;
-            console.log("跳过人脸识别");
+            // console.log("跳过人脸识别");
             break;
           case 1:
-            console.log("人员登记信息流程");
+            // console.log("人员登记信息流程");
             if (this.processStep.num === 1 && this.infomation.id === "") {
               this.getPersonList({ name: this.infomation.name });
             }
@@ -1054,7 +1121,7 @@ export default {
           case 2:
             this.openFullScreen();
             // this.processStep.num++;
-            console.log("入场登记通知领导");
+            // console.log("入场登记通知领导");
             break;
           case 3:
             if (this.infomation.personEnable) {
@@ -1062,17 +1129,17 @@ export default {
             } else {
               this.processStep.num += 6;
             }
-            console.log("人脸识别");
+            // console.log("人脸识别");
             break;
           case 4:
             this.processStep.num++;
             this.initTableInfo();
-            console.log("登记绑卡");
+            // console.log("登记绑卡");
             break;
           case 6:
             this.checkPersonCardNo();
             this.bindInfoRecord(this.infomation);
-            console.log("完成登记");
+            // console.log("完成登记");
             break;
           case 5:
             if (this.personType == 1 && this.processStep.num === 11) {
@@ -1084,7 +1151,7 @@ export default {
               }
               this.processStep.num++;
             }
-            console.log("同行人员信息");
+            // console.log("同行人员信息");
             break;
           case 9:
             if (this.processStep.num === 10) {
@@ -1126,14 +1193,14 @@ export default {
         });
         this.person.id = "";
         this.tableConfig.tableData = this.infomation.persons;
-        console.log("删除", data, this.infomation.persons);
+        // console.log("删除", data, this.infomation.persons);
         this.refresh();
       }
       if (btnType === "close") {
-        console.log("解绑", data);
+        // console.log("解绑", data);
       }
       if (btnType === "input") {
-        console.log("录入人脸", data);
+        // console.log("录入人脸", data);
       }
     },
     addPerson() {
@@ -1200,7 +1267,7 @@ export default {
     },
     handleByfaceUpload() {
       this.uploadPic = true;
-      console.log("上传父级开关", this.uploadPic);
+      // console.log("上传父级开关", this.uploadPic);
     },
     // 头像上传
     handleByfaceUploadPath(data) {
@@ -1225,6 +1292,7 @@ export default {
             } else {
               this.infomation["photoPath"] = data;
             }
+            this.tempPhotoPath = "https://10.0.0.201:8083" + "/yapi" + data;
             this.uploadPic = false;
             this.recognizeSuccess = false;
             break;
@@ -1246,6 +1314,7 @@ export default {
             } else {
               this.person["photoPath"] = data;
             }
+            this.tempPhotoPath = "https://10.0.0.201:8083" + "/yapi" + data;
             this.uploadPic = false;
             this.recognizeSuccess = false;
             break;
@@ -1256,7 +1325,7 @@ export default {
     },
     // 人脸识别读取
     handleByfaceOut(data) {
-      console.log("人脸识别反馈", data);
+      // console.log("人脸识别反馈", data);
       this.recognizeSuccess = true;
       if (data) {
         switch (this.processStep.num) {
@@ -1323,9 +1392,9 @@ export default {
             this.person["accessControlIds"] = data.typeBelong;
             if (!this.checkIn(data.id)) {
               this.infomation.persons.push(this.person);
-              console.log("添加", data.name);
+              // console.log("添加", data.name);
             } else {
-              console.log("人员已添加");
+              // console.log("人员已添加");
             }
             break;
           default:
@@ -1335,7 +1404,7 @@ export default {
     },
     // 读取身份证
     readIdCard(data) {
-      console.log("身份证信息", data);
+      // console.log("身份证信息", data);
       if (data) {
         switch (this.processStep.num) {
           case 3:

+ 94 - 60
src/views/test/index.vue

@@ -1,20 +1,23 @@
 <template>
-  <div>
-    <div v-if="loading">正在加载摄像头,请授予访问权限...</div>
-    <div v-else-if="error">{{ error }}</div>
-    <div v-else id="video-container">
-      <video id="video" :width="640" :height="480" autoplay></video>
-      <canvas
-        id="blurred-canvas"
-        :width="640"
-        :height="480"
-        v-if="showBlurred"
-      ></canvas>
+  <div class="recognize-main">
+    <div style="display: flex; gap: 20px">
+      <div id="video-container">
+        <video id="video" :width="640" :height="480" autoplay></video>
+      </div>
+      <!-- 新增虚化显示框 -->
+      <div>
+        <canvas
+          v-show="false"
+          id="blurred-canvas"
+          :width="640"
+          :height="480"
+        ></canvas>
+      </div>
     </div>
     <div>
-      <button id="capture-btn" @click="capture" :disabled="!video">截图</button>
+      <button id="capture-btn" @click="capture">截图</button>
       <!-- 新增虚化背景按钮 -->
-      <button id="blur-btn" @click="toggleBlurred" :disabled="!video">
+      <button id="blur-btn" @click="toggleBlurred">
         {{ showBlurred ? "隐藏虚化" : "显示虚化" }}
       </button>
     </div>
@@ -23,8 +26,8 @@
     </div>
   </div>
 </template>
-
-<script>
+  
+  <script>
 /* eslint-disable */
 import * as tf from "@tensorflow/tfjs";
 import * as bodyPix from "@tensorflow-models/body-pix";
@@ -39,38 +42,47 @@ export default {
       blurredCanvas: null,
       ctx: null,
       net: null,
-      // 新增状态,用于控制虚化画面的显示
-      showBlurred: false,
-      // 新增加载状态
+      // 修改默认值为 true,自动开启背景虚化
+      showBlurred: true,
       loading: true,
-      // 新增错误状态
       error: null,
-      stream: null
+      stream: null,
     };
   },
   mounted() {
     this.initializeCamera();
+    // 提前获取 canvas 元素
+    this.canvas = document.getElementById("canvas");
+    this.blurredCanvas = document.getElementById("blurred-canvas");
+    if (this.blurredCanvas) {
+      this.ctx = this.blurredCanvas.getContext("2d");
+    }
   },
   beforeDestroy() {
-    // 组件卸载时释放摄像头资源
     if (this.stream) {
-      this.stream.getTracks().forEach(track => track.stop());
+      this.stream.getTracks().forEach((track) => track.stop());
     }
   },
   methods: {
     async initializeCamera() {
       try {
-        this.stream = await navigator.mediaDevices.getUserMedia({ video: true });
+        this.stream = await navigator.mediaDevices.getUserMedia({
+          video: true,
+        });
         this.video = document.getElementById("video");
-        this.video.srcObject = this.stream;
-        this.loading = false;
-        // 加载 BodyPix 模型
-        this.loadBodyPix();
+        if (this.video) {
+          this.video.srcObject = this.stream;
+          this.loading = false;
+          this.loadBodyPix();
+        } else {
+          this.error = "未能找到视频元素,请检查 HTML 结构。";
+          this.loading = false;
+        }
       } catch (err) {
         console.error("访问摄像头失败:", err);
-        if (err.name === 'NotAllowedError') {
+        if (err.name === "NotAllowedError") {
           this.error = "您拒绝了摄像头访问权限,请刷新页面并允许访问。";
-        } else if (err.name === 'NotFoundError') {
+        } else if (err.name === "NotFoundError") {
           this.error = "未检测到摄像头设备,请检查设备连接。";
         } else {
           this.error = "无法访问摄像头,请检查权限或设备连接。";
@@ -83,49 +95,72 @@ export default {
       this.processVideoFrame();
     },
     async processVideoFrame() {
-      if (this.showBlurred) {
-        const segmentation = await this.net.segmentPerson(this.video);
-        const backgroundBlurAmount = 5;
-        const edgeBlurAmount = 3;
-        const flipHorizontal = false;
+      // 确保 video 和 blurredCanvas 存在
+      if (this.showBlurred && this.video && this.blurredCanvas) {
+        try {
+          const segmentation = await this.net.segmentPerson(this.video);
+          const backgroundBlurAmount = 5;
+          const edgeBlurAmount = 3;
+          const flipHorizontal = false;
 
-        bodyPix.drawBokehEffect(
-          this.blurredCanvas,
-          this.video,
-          segmentation,
-          backgroundBlurAmount,
-          edgeBlurAmount,
-          flipHorizontal
-        );
+          bodyPix.drawBokehEffect(
+            this.blurredCanvas,
+            this.video,
+            segmentation,
+            backgroundBlurAmount,
+            edgeBlurAmount,
+            flipHorizontal
+          );
+        } catch (err) {
+          console.error("处理视频帧时出错:", err);
+        }
       }
 
       requestAnimationFrame(() => this.processVideoFrame());
     },
     capture() {
-      const ctx = this.canvas.getContext("2d");
-      ctx.drawImage(
-        this.showBlurred ? this.blurredCanvas : this.video,
-        0,
-        0,
-        this.canvas.width,
-        this.canvas.height
-      );
+      if (this.canvas) {
+        const ctx = this.canvas.getContext("2d");
+        ctx.drawImage(
+          this.showBlurred ? this.blurredCanvas : this.video,
+          0,
+          0,
+          this.canvas.width,
+          this.canvas.height
+        );
 
-      // 保存截图
-      const link = document.createElement("a");
-      link.download = "snapshot.png";
-      link.href = this.canvas.toDataURL();
-      link.click();
+        const link = document.createElement("a");
+        link.download = "snapshot.png";
+        link.href = this.canvas.toDataURL();
+        link.click();
+      } else {
+        console.error("未能找到截图 canvas 元素");
+      }
     },
-    // 新增方法,用于切换虚化画面的显示状态
     toggleBlurred() {
       this.showBlurred = !this.showBlurred;
+      // 确保在切换时 canvas 已正确获取上下文
+      if (this.showBlurred) {
+        this.blurredCanvas = document.getElementById("blurred-canvas");
+        if (this.blurredCanvas) {
+          this.ctx = this.blurredCanvas.getContext("2d");
+        } else {
+          console.error("未能找到虚化 canvas 元素");
+        }
+      }
     },
   },
 };
 </script>
-
-<style scoped>
+  
+  <style scoped>
+.recognize-main {
+  width: 100%;
+  height: 100%;
+  padding: 100px 30px 40px;
+  pointer-events: auto;
+  color: #fff;
+}
 #video-container {
   margin-bottom: 20px;
 }
@@ -134,8 +169,7 @@ export default {
 }
 #capture-btn,
 #blur-btn {
-  /* 按钮背景虚化 */
-  backdrop-filter: blur(8px);
+  backdrop-filter: blur(12px);
   background-color: rgba(255, 255, 255, 0.5);
   border: none;
   padding: 10px 20px;

+ 4 - 4
vue.config.js

@@ -17,9 +17,9 @@ module.exports = {
     },
     proxy: {
       '/yapi': {
-        // target: 'https://10.0.0.201:8080/prod-api/', // 托克托现场
+        target: 'https://10.0.0.201:8080/prod-api/', // 托克托现场
         // target: 'http://172.168.0.62:8080/prod-api/', // 托克托现场
-        target: 'https://192.168.195.136:8080/prod-api/', // 托克托本地虚拟机
+        // target: 'https://192.168.195.136:8080/prod-api/', // 托克托本地虚拟机
         // target: "http://localhost:5002", // 远程服务器-赵哥
         changeOrigin: true,
         pathRewrite: {
@@ -27,9 +27,9 @@ module.exports = {
         },
       },
       '/model': {
-        // target: 'https://10.0.0.201:8081/model/', //托克托模型现场服务器
+        target: 'https://10.0.0.201:8081/model/', //托克托模型现场服务器
         // target: 'http://172.168.0.62:8081/model/', //托克托模型现场服务器
-        target: 'https://192.168.195.136:8081/model/', //托克托模型虚拟机
+        // target: 'https://192.168.195.136:8081/model/', //托克托模型虚拟机
         changeOrigin: true,
         pathRewrite: {
           '^/model': '/',