当前位置:   article > 正文

vue 实现人脸识别活体检测_前端vue实现人脸识别

前端vue实现人脸识别
<template>
  <div class="face-verify-approve-index">
    <div class="loading-wrap" v-if="loading">
      <div class="loading">
        <img src="@/assets/img/setting/loading.png" alt=""/>
        <p>{{ $t("approveText.text7") }}</p>
      </div>
    </div>
    <Header1 class="header" headerId="35"></Header1>
    <section class="all-header1-index">
      <div class="page">
        <p class="title" v-if="currentTaskId">{{ $t("faceVerify.tasks" + currentTaskId) }}</p>
        <div class="video-page">
          <van-circle
            v-model="currentRate"
            size="232"
            :stroke-width="30"
            :rate="rate"
            :color="gradientColor"
            layer-color="#F1F1F6"
            class="circle-container"
          >
            <video class="video" id="video" playsinline autoplay x5-video-player-type="h5"></video>
            <!-- <video ref="videoElement" id="video" class="video" autoplay></video> -->
          </van-circle>
          <!-- <input
              id="imgFile"
              class="imgFile"
              type="file"
              accept="video/*"
              capture="camcorder"
              @change="uploadVideo()"
          /> -->

          <!-- 检测结果 -->
          <p class="text" v-if="notFace">{{ notFaceText }}</p>
        </div>
      </div>
    </section>
    <VerifyResultDialog @showDialog="showDialog" :isShowDialog="isShowDialog" :type="type"
                        :url="url"></VerifyResultDialog>
  </div>
</template>
<script>
import {mapState} from "vuex";
import {generateRandomNumber} from "@/utils/index";
import COS from "cos-js-sdk-v5";
import md5 from "@/service/md5.js";
import * as faceapi from "face-api.js";

export default {
  data() {
    return {
      verifyType: "", //认证类型 1为认证 2为校验
      url: "",
      generateRandomNumber,
      md5,
      currentRate: 0,
      rate: 100,
      gradientColor: {
        "0%": "#95B8FA",
        "100%": "#3B80FF",
      },
      timer: null,
      currentTaskId: null,
      selectedTasks: [],
      notFace: false,
      notFaceText: "",
      tasks: [
        //1左右摇头 2点头 3眨眼
        {id: 1, type: false},
        {id: 2, type: false},
        {id: 3, type: false},
      ],
      tasks4: {id: 4, type: false},
      stillTimer: null,
      stillTimeThreshold: 3000, // 3秒
      cos: null, // COS实例
      file: null, // 选择的文件
      imageUrl: "", // 上传后的图片URL
      isShowDialog: false, //人脸认证结果弹框
      type: 3, //认证失败弹框是否可以重新认证 1,不可以 2,可以 ,3,认证成功 4,显示去认证弹框
      countdownTimer: null, // 用于倒计时的计时器
      loading: false,
      nodCounter: 0, // 点头计数器
      nodThreshold: 2, // 点头动作的阈值
      isStill: false, // 是否保持不动
      lastPitch: 0, // 上一次的头部倾斜角度
      shakeCounter: 0, // 摇头计数器
      shakeThreshold: 2, // 摇头动作的阈值
      isStillshake: false, // 摇头是否保持不动
      shakelastPitch: 0, // 摇头上一次的头部倾斜角度
      isFrontCamera: true,
      videoStream: null,
    };
  },
  components: {
    Header1: () => import("@/components/header/header1.vue"),
    VerifyResultDialog: () => import("@/components/faceVerify/verifyResult-dialog.vue"),
  },
  mounted() {
    this.verifyType = this.$route.query.type;
    this.url = this.$route.query.url;
    this.startTasks(); // 初始化COS实例
  },
  computed: {
    ...mapState(["lang", "userInfo"]),
  },
  methods: {
    // 关于navigator.mediaDevices.getUserMedia兼容问题
    // 有一部分老的浏览器不能兼容navigator.mediaDevices.getUserMedia来获取麦克风和摄像头,可用如下来获取
    getAudio() {
      if (
        navigator.mediaDevices.getUserMedia ||
        navigator.getUserMedia ||
        navigator.webkitGetUserMedia ||
        navigator.mozGetUserMedia
      ) {
        this.getUserMediaFun({video: true}); // 调用用户媒体设备,访问摄像头、录音、
      } else {
        console.log("你的浏览器不支持访问用户媒体设备");
      }
    },
    getUserMediaFun(constrains) {
      let that = this;
      if (navigator.mediaDevices.getUserMedia) {
        // 最新标准API、
        navigator.mediaDevices
          .getUserMedia(constrains)
          .then((stream) => {
            that.success(stream);
          })
          .catch((err) => {
            that.error(err);
          });
      } else if (navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
        // webkit内核浏览器
        if (navigator.mediaDevices === undefined) {
          navigator.mediaDevices = {};
        }

        // 一些浏览器部分支持 mediaDevices。我们不能直接给对象设置 getUserMedia
        // 因为这样可能会覆盖已有的属性。这里我们只会在没有getUserMedia属性的时候添加它。
        if (navigator.mediaDevices.getUserMedia === undefined) {
          navigator.mediaDevices.getUserMedia = function (constraints) {
            // 首先,如果有getUserMedia的话,就获得它
            var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

            // 一些浏览器根本没实现它 - 那么就返回一个error到promise的reject来保持一个统一的接口
            if (!getUserMedia) {
              return Promise.reject(new Error("getUserMedia is not implemented in this browser"));
            }

            // 否则,为老的navigator.getUserMedia方法包裹一个Promise
            return new Promise(function (resolve, reject) {
              getUserMedia.call(navigator, constraints, resolve, reject);
            });
          };
        }
        navigator.mediaDevices
          .getUserMedia(constrains)
          .then((stream) => {
            that.success(stream);
          })
          .catch((err) => {
            that.error(err);
          });
      } else if (navigator.getUserMedia) {
        // 旧版API
        navigator
          .getUserMedia(constrains)
          .then((stream) => {
            that.success(stream);
          })
          .catch((err) => {
            that.error(err);
          });
      }
    },
    // 成功的回调函数
    success(stream) {
      const videoElement = document.getElementById("video"); // 获取视频元素
      this.videoStream = stream; // 保存视频流,以便在组件销毁时停止摄像头
      videoElement.srcObject = stream;
      // 如果是前置摄像头,添加翻转类
      videoElement.classList.add("flipped");
    },
    // 异常的回调函数
    error(error) {
      console.log("访问用户媒体设备失败:", error.name, error.message);
    },

    startTasks() {
      // 随机选择两个任务
      this.selectedTasks = this.shuffleArray(this.tasks).slice(0, 2);
      this.completeTask();
    },
    shuffleArray(array) {
      // 随机打乱数组顺序
      for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
      }
      return array;
    },
    completeTask() {
      // console.log("循环了", this.timer);
      // 如果当前任务是保持不动的任务,完成后直接调用接口
      // console.log(this.selectedTasks, "剩余任务");
      if (!this.timer) {
        this.startCamera()
          .then(() => {
            this.timer = window.setInterval(this.detectFace, 1000);
          })
          .catch((err) => {
            console.log("startCamera函数报错了", err);
          });
      }
      const allTasksCompleted = this.selectedTasks.every((task) => task.type === true);
      // console.log("完成了所有的任务:", allTasksCompleted);
      if (allTasksCompleted) {
        //随机两项全部通过,开始最后静止不动3s
        this.currentTaskId = 4;
        if (this.timer) {
          clearInterval(this.timer);
          this.timer = null; // Add this line to set timer to null
        }
      } else {
        if (!this.selectedTasks[0].type) {
          this.currentTaskId = this.selectedTasks[0].id;
        } else if (!this.selectedTasks[1].type) {
          this.currentTaskId = this.selectedTasks[1].id;
        } else if (!this.selectedTasks[2].type) {
          this.currentTaskId = this.selectedTasks[2].id;
        } else {
          //全部通过
          this.currentTaskId = null;
          if (this.timer) {
            clearInterval(this.timer);
            this.timer = null; // Add this line to set timer to null
          }
        }
      }
    },
    // 在 async 函数中初始化摄像头和 face-api.js
    async startCamera() {
      // try {
      //     const stream = await navigator.mediaDevices.getUserMedia({ video: true });
      //     this.videoStream = stream; // 保存视频流,以便在组件销毁时停止摄像头
      //     this.$refs.videoElement.srcObject = stream;
      //     console.log(this.$refs.videoElement.srcObject);
      // } catch (error) {
      //     console.error("Error starting camera:", error);
      // }
      this.getAudio();
      // 初始化 face-api.js 模型
      await Promise.all([
        faceapi.nets.tinyFaceDetector.loadFromUri(`${process.env.BASE_URL}/models`),
        faceapi.nets.faceLandmark68Net.loadFromUri(`${process.env.BASE_URL}/models`),
      ]);
    },
    // 开始实时捕获
    async detectFace() {
      const video = document.getElementById("video");
      if (!video) {
        return; // 视频元素不存在,直接返回,避免报错
      }
      const detections = await faceapi
        .detectSingleFace(video, new faceapi.TinyFaceDetectorOptions({inputSize: 128}))
        .withFaceLandmarks();
      // const detections = await faceapi.detectSingleFace(video, new faceapi.TinyFaceDetectorOptions()).withFaceLandmarks();
      if (detections) {
        // 如果检测到人脸
        this.notFace = false; // 重置未检测到人脸的标志
        this.notFaceText = ""; // 清空提示文本
        if (this.currentTaskId) {
          // 如果当前有任务正在进行
          if (this.currentTaskId === 1) {
            this.shakeHeadfunc(detections);
          } else if (this.currentTaskId === 2) {
            this.nodHeadfunc(detections);
          } else if (this.currentTaskId === 3) {
            this.winkfunc(detections);
          } else if (this.currentTaskId === 4) {
            // 静止不动任务
            if (!this.stillTimer) {
              this.stillTimer = setTimeout(() => {
                this.stillTimer = null;
                this.captureStillImage();
              }, this.stillTimeThreshold);
            }
            if (!this.countdownTimer) {
              this.countdownTimer = setTimeout(() => {
                this.currentTaskId = null; // 完成所有任务,重置当前任务
                this.countdownTimer = null; // 清除计时器
              }, this.stillTimeThreshold);
            }
          }
        } else {
          // 没有任务正在进行,进行下一个任务
          this.completeTask();
        }
      } else {
        // 没有检测到人脸
        this.notFace = true;
        this.notFaceText = this.$t("approveText.text8");
      }
    },
    //循环任务摇头中的处理
    shakeHeadfunc(detections) {
      console.log("摇头");
      if (detections) {
        const landmarks = detections.landmarks;
        const leftEye = landmarks.getLeftEye()[0];
        const rightEye = landmarks.getRightEye()[3];
        const pitch = this.calculateYaw(leftEye, rightEye);
        // 判断用户是否摇头
        if (Math.abs(pitch - this.shakelastPitch) < 1) {
          console.log("用户保持不动");
        } else {
          if (this.isShaking(pitch)) {
            this.shakeCounter++;
            if (this.shakeCounter >= this.shakeThreshold) {
              this.shakeCounter = 0;
              this.notFace = false;
              this.notFaceText = this.$t("approveText.text9");
              this.selectedTasks = this.selectedTasks.filter((task) => task.id !== this.currentTaskId);
            }
          } else {
            this.shakeCounter = 0;
            this.notFace = true;
            this.notFaceText = this.$t("approveText.text10");
          }
        }
        setTimeout(() => {
          this.completeTask();
        }, 1000);
        this.shakelastPitch = pitch;
      }
    },
    //循环点头中的处理
    nodHeadfunc(detections) {
      console.log("点头");
      if (detections) {
        const landmarks = detections.landmarks;
        // const nose = landmarks.getNose();
        const leftEye = landmarks.getLeftEye();
        const rightEye = landmarks.getRightEye();
        // 计算头部倾斜角度
        const pitch = this.calculatePitch(leftEye, rightEye);
        // 判断点头动作
        if (Math.abs(pitch - this.lastPitch) < 1) {
          console.log("用户保持不动");
        } else {
          if (this.isNodding(pitch)) {
            this.nodCounter++;
            if (this.nodCounter >= this.nodThreshold) {
              this.nodCounter = 0;
              this.notFace = false;
              this.notFaceText = this.$t("approveText.text11");
              this.selectedTasks = this.selectedTasks.filter((task) => task.id !== this.currentTaskId);
            }
          } else {
            this.nodCounter = 0;
            this.notFace = true;
            this.notFaceText = this.$t("approveText.text12");
          }
        }
        setTimeout(() => {
          this.completeTask();
        }, 1000);
        this.lastPitch = pitch;
      }
    },
    //眨眼中的处理
    winkfunc(detections) {
      console.log("眨眼");
      if (detections) {
        const landmarks = detections.landmarks;
        const leftEye = landmarks.getLeftEye();
        const rightEye = landmarks.getRightEye();
        // 计算左眼和右眼的闭合程度
        const leftEyeOpenness = this.calculateEyeOpenness(leftEye);
        const rightEyeOpenness = this.calculateEyeOpenness(rightEye);
        // 判断是否眨眼(根据闭合程度)
        const isBlinking = leftEyeOpenness < 10 && rightEyeOpenness < 10;
        if (isBlinking) {
          this.notFace = false;
          this.notFaceText = this.$t("approveText.text13");
          //删除任务数组对应项
          this.selectedTasks = this.selectedTasks.filter((task) => task.id !== this.currentTaskId);
        } else {
          this.notFace = true;
          this.notFaceText = this.$t("approveText.text14");
        }
        setTimeout(() => {
          this.completeTask();
        }, 1000);
      }
    },
    //摇头计算方法
    calculateYaw(leftEye, rightEye) {
      const deltaX = rightEye.x - leftEye.x;
      const deltaY = rightEye.y - leftEye.y;
      const angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI);
      return angle;
    },
    //判断摇头动作
    isShaking(pitch) {
      const mediumRange = {min: -10, max: 10}; // 范围可根据实际情况调整
      return pitch >= mediumRange.min && pitch <= mediumRange.max;
    },
    //点头计算方法
    calculatePitch(leftEye, rightEye) {
      // 在这里计算头部倾斜角度
      const leftEyeCenter = {
        x: (leftEye[0].x + leftEye[3].x) / 2,
        y: (leftEye[0].y + leftEye[3].y) / 2,
      };
      const rightEyeCenter = {
        x: (rightEye[0].x + rightEye[3].x) / 2,
        y: (rightEye[0].y + rightEye[3].y) / 2,
      };

      const deltaX = rightEyeCenter.x - leftEyeCenter.x;
      const deltaY = rightEyeCenter.y - leftEyeCenter.y;
      const radians = Math.atan2(deltaY, deltaX);
      // 将弧度转换为角度
      const degrees = radians * (180 / Math.PI);
      return degrees;
    },
    //判断点头动作
    isNodding(pitch) {
      // console.log("角度:", pitch);
      // 在这里判断点头动作
      // 根据头部倾斜角度进行判断
      // 返回 true 或 false
      const mediumRange = {min: -10, max: 10}; // 范围可根据实际情况调整
      return pitch >= mediumRange.min && pitch <= mediumRange.max;
    },
    //眨眼计算方法
    calculateEyeOpenness(eyeLandmarks) {
      // 计算眼睛的闭合程度
      const eyeTop = eyeLandmarks[1].y;
      const eyeBottom = eyeLandmarks[5].y;
      const eyeHeight = eyeBottom - eyeTop;
      // console.log(eyeHeight, "eyeHeight");
      const eyeOpenness = eyeHeight / 3; // 根据实际情况进行调整
      return eyeOpenness;
    },
    // 保存当前帧作为图像
    async captureStillImage() {
      if (!this.imageUrl) {
        const video = document.getElementById("video");
        const canvas = document.createElement("canvas");
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        const context = canvas.getContext("2d");
        context.drawImage(video, 0, 0, canvas.width, canvas.height);
        const imgDataUrl = canvas.toDataURL("image/jpeg");
        // 现在你可以将imgDataUrl用作捕获的静态图像。
        // console.log("捕获的图像数据URL:", imgDataUrl);
        // 如果需要,你还可以在界面上显示捕获的图像。
        // 例如,你可以创建一个<img>元素,并将其src属性设置为imgDataUrl。
        this.getOssObject(imgDataUrl);
      }
    },
    //调后台接口获取腾讯云上传临时参数
    getOssObject(imgDataUrl) {
      this.loading = true;
      this.$api
        .tencentOss({})
        .then((res) => {
          this.cos = new COS({
            SecretId: res.data.cred.Credentials.TmpSecretId,
            SecretKey: res.data.cred.Credentials.TmpSecretKey,
            SecurityToken: res.data.cred.Credentials.Token,
          });
          // 上传文件到腾讯云对象存储
          this.cos.putObject(
            {
              Bucket: res.data.bucket,
              Region: res.data.region,
              Key: `/resource/being_dev/user_face/${this.userInfo.user_info.uid}_${Date.now()}.jpg`, // 设置文件在COS中的路径
              Body: this.dataURLtoBlob(imgDataUrl),
              // ContentLength: base64Image.length,
            },
            (err, data) => {
              if (err) {
                console.error("Upload error:", err);
              } else {
                this.imageUrl = data.Location; // 获取上传后的图片URL
                if (this.verifyType == "1") {
                  this.personalBindorCheck(this.imageUrl, "1");
                } else if (this.verifyType == "2") {
                  this.personalBindorCheck(this.imageUrl, "2");
                }
              }
            }
          );
        })
        .catch((err) => {
          clearInterval(this.timer);
          console.log(err);
        });
    },
    // 替换域名方法
    replaceDomainWithCom(originalUrl, newDomain) {
      const regex = /^(https?:\/\/)?(www\.)?[^\/]+/;
      const replacedUrl = originalUrl.replace(regex, newDomain);
      return replacedUrl;
    },
    // 人脸绑定/校验接口
    personalBindorCheck(imageUrl, val) {
      const newDomain = 'https://b1.being.com';
      const replacedUrl = this.replaceDomainWithCom(imageUrl, newDomain); //处理后的新的url
      const currentDate = new Date();
      currentDate.setHours(0, 0, 0, 0); // 设置时分秒为0
      const currentDateTimestamp = Math.floor(currentDate.getTime() / 1000); // 转换为秒级时间戳
      let ramdomCount = this.generateRandomNumber(32);
      let deviceModel = `${this.userInfo.user_info.uid}-${currentDateTimestamp}-${this.userInfo.user_info.uid}-${currentDateTimestamp}`;
      let md5Count = `${replacedUrl}${ramdomCount.slice(-5)}`;
      let md5param = md5.hexMD5(md5Count);
      let actionType = "";
      if (val == "1") {
        actionType = "personnel_bind";
      } else if (val == "2") {
        actionType = "face_verify";
      }
      let params = {
        url: replacedUrl, // 图
        device: deviceModel, // 设备号,
        rand_str: ramdomCount, //随机数
        md5: md5param, //加密数
        action: actionType, //方法名
      };
      let apiMethod = null;
      if (val === "1") {
        apiMethod = this.$api.personnelBind;
      } else if (val === "2") {
        apiMethod = this.$api.faceVerify;
      }
      apiMethod(params)
        .then((res) => {
          this.loading = false;
          this.isShowDialog = true;
          if (!res.error_code) {
            if (val === "1") {
              this.type = 3;
            } else if (val === "2") {
              this.type = 4;
            }
          } else {
            this.type = res.error_code;
          }
        })
        .catch((err) => {
          this.loading = false;
          console.log(err);
        });
    },
    // 去掉Base64头部
    dataURLtoBlob(dataurl) {
      var arr = dataurl.split(",");
      var mime = arr[0].match(/:(.*?);/)[1];
      var bstr = atob(arr[1]);
      var n = bstr.length;
      var u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], {type: mime});
    },
    showDialog() {
      this.isShowDialog = false;
    },
  },
  beforeDestroy() {
    if (this.timer) {
      clearInterval(this.timer);
      this.timer = null; // Add this line to set timer to null
    }
    if (this.stillTimer) {
      clearTimeout(this.stillTimer);
      this.stillTimer = null;
    }
    if (this.countdownTimer) {
      clearTimeout(this.countdownTimer);
      this.countdownTimer = null;
    }
    if (this.videoStream) {
      this.videoStream.getTracks().forEach((track) => track.stop());
    }
  },
};
</script>

<style>
/* 在这里可以添加样式 */
</style>

<style scoped lang="less">
.face-verify-approve-index {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: #fff;
  position: relative;

  .loading-wrap {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: #d9d9d9;
    z-index: 99999;
    display: flex; /* 使用Flex布局 */
    justify-content: center; /* 水平居中 */
    align-items: center; /* 垂直居中 */

    .loading {
      width: 1.26rem;
      height: 1.26rem;
      background: #ffffff;
      border-radius: 0.12rem;
      z-index: 99999;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;

      & > img {
        width: 0.44rem;
        height: 0.44rem;
        animation: rotate 1s linear infinite;
      }

      @keyframes rotate {
        from {
          transform: rotate(0deg);
        }
        to {
          transform: rotate(360deg);
        }
      }

      & > p {
        font-size: 0.16rem;
        font-weight: bold;
        color: #000000;
        margin-top: 0.1rem;
      }
    }
  }

  .header {
    background-color: #fff;
    border-bottom: 1px solid #f6f7f8;
    color: #000;
  }

  section {
    flex: 1;
    display: flex;
    flex-direction: column;
    padding: 0.4rem 0.2rem;
    box-sizing: border-box;

    .page {
      width: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;

      .title {
        font-size: 0.24rem;
        font-weight: bold;
        color: #000000;
        line-height: 0.22rem;
        text-align: center;
      }

      .video-page {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        position: relative;
        margin-top: 0.24rem;
        width: 232px;
        height: 232px;
        overflow: hidden;
        border-radius: 232px;

        .circle-container {
          width: 232px;
          height: 232px;
          display: flex;
          align-items: center;
          justify-content: center;
          position: relative;
          overflow: hidden;
        }

        /* 使用深度选择器,确保样式作用到 .circle-container 内的 svg 元素 */

        /deep/ .circle-container > svg {
          z-index: 11 !important;
        }

        video {
          width: 215px;
          height: 215px;
          border-radius: 50%;
          // position: absolute;
          // top: 50%;
          // left: 50%;
          // transform: translate(-50%, -50%);
          overflow: hidden;
          display: flex;
          align-items: center;
          justify-content: center;
          object-fit: cover; /* 保持视频比例,填满容器 */
          // z-index: 99;
        }

        .flipped {
          width: 215px;
          height: 215px;
          border-radius: 50%;
          // position: absolute;
          // top: 50%;
          // left: 50%;
          transform: translate(-50%, -50%);
          overflow: hidden;
          display: flex;
          align-items: center;
          justify-content: center;
          object-fit: cover; /* 保持视频比例,填满容器 */
          transform: scaleX(-1);
        }

        .text {
          position: absolute;
          bottom: 0.07rem;
          left: 50%;
          transform: translate(-50%, 0);
          width: 215px;
          height: 68px;
          background: rgba(0, 0, 0, 0.5);
          font-size: 0.16rem;
          color: #fff;
          line-height: 0.18rem;
          text-align: center;
          padding: 0.16rem 0.35rem;
          box-sizing: border-box;
          // z-index: 999;
        }
      }
    }
  }
}
</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528
  • 529
  • 530
  • 531
  • 532
  • 533
  • 534
  • 535
  • 536
  • 537
  • 538
  • 539
  • 540
  • 541
  • 542
  • 543
  • 544
  • 545
  • 546
  • 547
  • 548
  • 549
  • 550
  • 551
  • 552
  • 553
  • 554
  • 555
  • 556
  • 557
  • 558
  • 559
  • 560
  • 561
  • 562
  • 563
  • 564
  • 565
  • 566
  • 567
  • 568
  • 569
  • 570
  • 571
  • 572
  • 573
  • 574
  • 575
  • 576
  • 577
  • 578
  • 579
  • 580
  • 581
  • 582
  • 583
  • 584
  • 585
  • 586
  • 587
  • 588
  • 589
  • 590
  • 591
  • 592
  • 593
  • 594
  • 595
  • 596
  • 597
  • 598
  • 599
  • 600
  • 601
  • 602
  • 603
  • 604
  • 605
  • 606
  • 607
  • 608
  • 609
  • 610
  • 611
  • 612
  • 613
  • 614
  • 615
  • 616
  • 617
  • 618
  • 619
  • 620
  • 621
  • 622
  • 623
  • 624
  • 625
  • 626
  • 627
  • 628
  • 629
  • 630
  • 631
  • 632
  • 633
  • 634
  • 635
  • 636
  • 637
  • 638
  • 639
  • 640
  • 641
  • 642
  • 643
  • 644
  • 645
  • 646
  • 647
  • 648
  • 649
  • 650
  • 651
  • 652
  • 653
  • 654
  • 655
  • 656
  • 657
  • 658
  • 659
  • 660
  • 661
  • 662
  • 663
  • 664
  • 665
  • 666
  • 667
  • 668
  • 669
  • 670
  • 671
  • 672
  • 673
  • 674
  • 675
  • 676
  • 677
  • 678
  • 679
  • 680
  • 681
  • 682
  • 683
  • 684
  • 685
  • 686
  • 687
  • 688
  • 689
  • 690
  • 691
  • 692
  • 693
  • 694
  • 695
  • 696
  • 697
  • 698
  • 699
  • 700
  • 701
  • 702
  • 703
  • 704
  • 705
  • 706
  • 707
  • 708
  • 709
  • 710
  • 711
  • 712
  • 713
  • 714
  • 715
  • 716
  • 717
  • 718
  • 719
  • 720
  • 721
  • 722
  • 723
  • 724
  • 725
  • 726
  • 727
  • 728
  • 729
  • 730
  • 731
  • 732
  • 733
  • 734
  • 735
  • 736
  • 737
  • 738
  • 739
  • 740
  • 741
  • 742
  • 743
  • 744
  • 745
  • 746
  • 747
  • 748
  • 749
  • 750
  • 751
  • 752
  • 753
  • 754
  • 755
  • 756
  • 757
  • 758
  • 759
  • 760
  • 761
  • 762
  • 763
  • 764
  • 765
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/701535
推荐阅读
相关标签
  

闽ICP备14008679号