Kaynağa Gözat

上传照片增加时间戳,每次绑卡施工人员更新照片,登记记录增加领队人员带时间戳照片

fan 3 hafta önce
ebeveyn
işleme
ea663cab6d

+ 4 - 2
src/views/components/dialog/RiskTipDialog.vue

@@ -414,6 +414,7 @@ export default {
           field004: person.cardNo, //卡号
           field005: Dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss"), //绑卡时间
           field006: person.cause, //进站目的
+          field007: person.photoPath, //人员照片
           pageId: "839895523707068416", //绑卡
         };
         const res = await bindAndUnbindrecord(record);
@@ -505,7 +506,7 @@ export default {
           this.dialogConfig.data.accessControlIds = [
             "789185403352522752", // 进站识别
             "789185626355277824", // 出站识别
-            "833420345783361536", 
+            "833420345783361536",
             "830088938663190528",
             "833426645288230912",
           ];
@@ -742,7 +743,7 @@ export default {
           height: 60px;
           text-align: center;
           position: absolute;
-          bottom: 40px;
+          bottom: 50px;
           left: 50%;
           transform: translate(-50%, 0);
           .el-button {
@@ -759,6 +760,7 @@ export default {
             }
           }
           .btn-handle.el-button {
+            margin-left: 40px;
             background: rgba(0, 159, 221, 0.8);
           }
           .btn-cancel.el-button {

+ 235 - 0
src/views/recognize/components/VideoLocalWindow copy.vue

@@ -0,0 +1,235 @@
+<template>
+  <div>
+    <video ref="video" autoplay muted playsinline></video>
+    <!-- <el-button @click="startCamera">开启摄像头</el-button>
+    <el-button @click="stopCamera" :disabled="!isCameraActive"
+      >关闭摄像头</el-button
+    > -->
+  </div>
+</template>
+
+
+<script>
+import { GetPersonByFace, GetPersonByFaceBase64 } from "@/API/custom";
+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,
+      stream: null,
+      captureInterval: null, // 新增定时器变量
+    };
+  },
+  methods: {
+    async startCamera() {
+      try {
+        const stream = await navigator.mediaDevices.getUserMedia({
+          video: {
+            width: { ideal: 1280 },
+            height: { ideal: 800 },
+            facingMode: "user",
+          },
+        });
+        this.stream = stream;
+        this.isCameraActive = true;
+        this.$refs.video.srcObject = stream;
+
+        if (this.isUpload) {
+          setTimeout(() => {
+            this.uploadImage();
+          }, 1000);
+        } else {
+          // 新增定时截图功能
+          this.captureInterval = setInterval(() => {
+            this.captureImage();
+          }, 3000);
+        }
+      } catch (err) {
+        console.error("摄像头访问错误:", err);
+        alert(`摄像头访问失败: ${err.message}`);
+      }
+    },
+    stopCamera() {
+      if (this.stream) {
+        this.stream.getTracks().forEach((track) => track.stop());
+        this.isCameraActive = false;
+        this.$refs.video.srcObject = null;
+        this.stream = null;
+
+        // 停止定时器
+        if (this.captureInterval) {
+          clearInterval(this.captureInterval);
+          this.captureInterval = null;
+        }
+      }
+    },
+    // 新增截图方法
+    // async captureImage() {
+    //   const video = this.$refs.video;
+    //   video.currentTime = 1;
+    //   const canvas = document.createElement("canvas");
+    //   canvas.width = video.videoWidth;
+    //   canvas.height = video.videoHeight;
+    //   canvas
+    //     .getContext("2d")
+    //     .drawImage(video, 0, 0, canvas.width, canvas.height);
+    //   // 下载到本地
+    //   // const link = document.createElement("a");
+    //   // link.download = `capture_${new Date()
+    //   //   .toISOString()
+    //   //   .replace(/[:.]/g, "-")}.png`;
+    //   // link.href = canvas.toDataURL("image/png");
+    //   // link.click();
+
+    //   // 将canvas转为Blob对象
+    //   canvas.toBlob(async (blob) => {
+    //     if (blob) {
+    //       console.log("blob数据", blob);
+    //       const formData = new FormData();
+    //       formData.append("timestamp", new Date().toISOString());
+    //       formData.append("file", blob, "screenshot.png");
+    //       console.log("上传数据", formData);
+    //       try {
+    //         // const res = await GetPersonByFace(formData);
+    //         // console.log("上传反馈", res);
+    //         // const response = await fetch("System/Person/GetPersonByFace", {
+    //         //   method: "POST",
+    //         //   body: formData,
+    //         // });
+    //       } catch (err) {
+    //         console.error("上传过程中出错:", err);
+    //       }
+    //     }
+    //   }, "image/png");
+    // },
+
+    async captureImage() {
+      const video = this.$refs.video;
+      const canvas = document.createElement("canvas");
+      canvas.width = video.videoWidth;
+      canvas.height = video.videoHeight;
+      canvas.getContext("2d").drawImage(video, 0, 0);
+
+      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);
+          setTimeout(() => {
+            this.stopCamera();
+          }, 200);
+        }
+      } catch (err) {
+        console.error("上传过程中出错:", err);
+      }
+    },
+    async uploadImage() {
+      const video = this.$refs.video;
+      const canvas = document.createElement("canvas");
+      canvas.width = video.videoWidth;
+      canvas.height = video.videoHeight;
+      canvas.getContext("2d").drawImage(video, 0, 0);
+      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);
+      }
+    },
+  },
+  created() {
+    this.startCamera();
+  },
+  beforeDestroy() {
+    this.stopCamera();
+  },
+};
+</script>
+
+<style scoped>
+video {
+  height: 800px;
+  width: 1280px;
+  /* width: 100%;
+  max-width: 500px; */
+  background: #000;
+}
+</style>

+ 108 - 12
src/views/recognize/components/VideoLocalWindow.vue

@@ -1,6 +1,9 @@
 <template>
-  <div>
+  <div class="videoContainer">
     <video ref="video" autoplay muted playsinline></video>
+    <div id="timestamp" v-show="false">
+      {{ datetimeData.date + " " + datetimeData.time }}
+    </div>
     <!-- <el-button @click="startCamera">开启摄像头</el-button>
     <el-button @click="stopCamera" :disabled="!isCameraActive"
       >关闭摄像头</el-button
@@ -11,6 +14,8 @@
 
 <script>
 import { GetPersonByFace, GetPersonByFaceBase64 } from "@/API/custom";
+import Dayjs from "dayjs";
+
 export default {
   props: {
     processStep: {
@@ -56,9 +61,29 @@ export default {
       isCameraActive: false,
       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"),
+      },
     };
   },
   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 startCamera() {
       try {
         const stream = await navigator.mediaDevices.getUserMedia({
@@ -143,11 +168,36 @@ export default {
 
     async captureImage() {
       const video = this.$refs.video;
+      if (video.paused) return;
       const canvas = document.createElement("canvas");
-      canvas.width = video.videoWidth;
-      canvas.height = video.videoHeight;
-      canvas.getContext("2d").drawImage(video, 0, 0);
 
+      const cropWidth = video.videoWidth * 0.5;
+      const cropHeight = video.videoHeight * 0.98;
+
+      // 设置canvas尺寸为选择区域大小
+      canvas.width = cropWidth;
+      canvas.height = cropHeight;
+
+      const x = (video.videoWidth - cropWidth) / 2;
+      const y = (video.videoHeight - cropHeight) / 2;
+
+      const ctx = canvas.getContext("2d");
+      //中心60%区域
+      ctx.drawImage(
+        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);
@@ -169,11 +219,12 @@ export default {
         const result = await response.json();
         // console.log("上传反馈", response, result);
         if (result.code === 20000) {
-          console.log("服务器返回数据:", result);
+          // console.log("服务器返回数据:", result);
           this.$emit("output", result.data);
-          setTimeout(() => {
-            this.stopCamera();
-          }, 200);
+          this.uploadImage();
+          // setTimeout(() => {
+          //   this.stopCamera();
+          // }, 200);
         }
       } catch (err) {
         console.error("上传过程中出错:", err);
@@ -182,9 +233,36 @@ export default {
     async uploadImage() {
       const video = this.$refs.video;
       const canvas = document.createElement("canvas");
-      canvas.width = video.videoWidth;
-      canvas.height = video.videoHeight;
-      canvas.getContext("2d").drawImage(video, 0, 0);
+
+      const cropWidth = video.videoWidth * 0.5;
+      const cropHeight = video.videoHeight * 0.98;
+
+      // 设置canvas尺寸为选择区域大小
+      canvas.width = cropWidth;
+      canvas.height = cropHeight;
+
+      const x = (video.videoWidth - cropWidth) / 2;
+      const y = (video.videoHeight - cropHeight) / 2;
+
+      const ctx = canvas.getContext("2d");
+      //中心60%区域
+      ctx.drawImage(
+        video,
+        x,
+        y,
+        cropWidth,
+        cropHeight,
+        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);
@@ -201,7 +279,7 @@ export default {
           }),
         });
         const result = await response.json();
-        console.log("上传反馈", response, result);
+        // console.log("上传反馈", response, result);
         if (result.code === 20000) {
           console.log("服务器上传返回数据:", result);
           this.$emit("outputPath", result.data);
@@ -217,6 +295,7 @@ export default {
   },
   created() {
     this.startCamera();
+    this.refreshTime();
   },
   beforeDestroy() {
     this.stopCamera();
@@ -225,11 +304,28 @@ export default {
 </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;
+}
 </style>

+ 34 - 6
src/views/recognize/index.vue

@@ -594,6 +594,7 @@ export default {
       cardEnable: false, //rfid刷卡
       idEnable: false, //身份证刷卡
       uploadPic: false, //上传录入
+      recognizeSuccess: false, //识别成功
       fullLoading: null,
       rfid: "",
       idCardData: {},
@@ -946,6 +947,7 @@ export default {
           field009: person.dangerousEnable ? "有" : "无", //危险品检查
           field010: person.workerEnable ? "是" : "否", //施工作业
           field011: this.areas, //进站区域
+          field012: person.photoPath, //登记照片
           pageId: "842348058862690304", //入场登记
         };
         console.log("记录基础信息3:", record);
@@ -1037,6 +1039,7 @@ export default {
             break;
           case 9:
             if (this.processStep.num === 10) {
+              this.person.department = this.infomation.department;
               this.processStep.num += 4;
               this.infomation.persons.push(this.person);
             }
@@ -1152,14 +1155,38 @@ export default {
       if (data) {
         switch (this.processStep.num) {
           case 0:
-            this.processStep.num++;
-            this.infomation["photoPath"] = data;
+            if (this.recognizeSuccess) {
+              this.processStep.num += 5;
+            } else {
+              this.processStep.num++;
+            }
+            if (this.personType === 1) {
+              this.infomation["photoPath"] =
+                this.infomation["photoPath"] !== ""
+                  ? this.infomation["photoPath"]
+                  : data;
+            } else {
+              this.infomation["photoPath"] = data;
+            }
             this.uploadPic = false;
+            this.recognizeSuccess = false;
             break;
           case 9:
-            this.processStep.num++;
-            this.person["photoPath"] = data;
+            if (this.recognizeSuccess) {
+              this.processStep.num += 5;
+            } else {
+              this.processStep.num++;
+            }
+            if (this.personType === 1) {
+              this.person["photoPath"] =
+                this.person["photoPath"] !== ""
+                  ? this.person["photoPath"]
+                  : data;
+            } else {
+              this.person["photoPath"] = data;
+            }
             this.uploadPic = false;
+            this.recognizeSuccess = false;
             break;
           default:
             break;
@@ -1169,10 +1196,11 @@ export default {
     // 人脸识别读取
     handleByfaceOut(data) {
       console.log("人脸识别反馈", data);
+      this.recognizeSuccess = true;
       if (data) {
         switch (this.processStep.num) {
           case 0:
-            this.processStep.num += 5;
+            // this.processStep.num += 5;
             this.infomation["id"] = data.id;
             this.infomation["name"] = data.name;
             this.infomation["companyName"] = data.companyName;
@@ -1202,7 +1230,7 @@ export default {
             this.infomation["accessControlIds"] = data.accessControlIds;
             break;
           case 9:
-            this.processStep.num += 5;
+            // this.processStep.num += 5;
             this.person["id"] = data.id;
             this.person["name"] = data.name;
             this.person["companyName"] = data.companyName;