index.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <template>
  2. <div class="root">
  3. <div class="card" v-if="step === 1">
  4. <div class="logo">
  5. <img alt="RunForge" src="/logo.svg" height="40">
  6. <span class="title">RunForge | 人脸采集</span>
  7. </div>
  8. <input type="text" id="name" placeholder="姓名">
  9. <input type="text" id="student_num" placeholder="学号">
  10. <input type="text" id="captcha" placeholder="验证码">
  11. <div id="captchaImg" @click="getCaptcha()" title="点击更换验证码">
  12. <img alt="点我重试" :src="ImageCaptcha" v-if="!captchaLoading" />
  13. <a-spin dot v-else />
  14. </div>
  15. <a-button type="primary" shape="round" size="large" @click="getUserInfo"
  16. :loading="buttonLoading">开始人脸采集</a-button>
  17. </div>
  18. <div class="card" v-else-if="step === 2">
  19. <div class="logo">
  20. <img alt="RunForge" src="/logo.svg" height="40">
  21. <span class="title">人脸采集注意事项</span>
  22. </div>
  23. <Doc />
  24. <a-button type="primary" shape="round" size="large" @click="step = 3"
  25. :loading="buttonLoading">我已阅读并同意</a-button>
  26. </div>
  27. <div class="card" v-else-if="step === 3">
  28. <div class="logo">
  29. <img alt="RunForge" src="/logo.svg" height="40">
  30. <span class="title">RunForge | 人脸采集</span>
  31. </div>
  32. <FaceReco :userInfo="userInfo" />
  33. </div>
  34. </div>
  35. </template>
  36. <script setup>
  37. import { ref, onMounted } from 'vue'
  38. import { Message } from '@arco-design/web-vue'
  39. import { BeginFaceReco } from '@/api/lepao'
  40. import { getImageCaptcha } from '@/api/login'
  41. import Doc from './components/doc.vue'
  42. import FaceReco from './components/faceReco.vue'
  43. const step = ref(1)
  44. const buttonLoading = ref(false)
  45. const userInfo = ref({})
  46. const captchaLoading = ref(true)
  47. let CaptchaId = ref('')
  48. let ImageCaptcha = ref('')
  49. const getCaptcha = async () => {
  50. try {
  51. captchaLoading.value = true
  52. const res = await getImageCaptcha()
  53. if (!res || res.code != 0)
  54. return Message.error('获取图片验证码失败!' + res?.msg ?? '')
  55. ImageCaptcha.value = res.data.img
  56. CaptchaId.value = res.data.id
  57. } catch (error) {
  58. Message.error('获取图片验证码失败!')
  59. } finally {
  60. captchaLoading.value = false
  61. }
  62. }
  63. const getUserInfo = async () => {
  64. try {
  65. buttonLoading.value = true
  66. const name = document.getElementById('name').value
  67. const student_num = document.getElementById('student_num').value
  68. const captchaEl = document.getElementById('captcha')
  69. const captcha = captchaEl.value
  70. if (!name || !student_num || !captcha)
  71. return Message.error('请将信息填写完整')
  72. const res = await BeginFaceReco({ name, student_num, captcha, id: CaptchaId.value })
  73. if (!res || res.code !== 0) {
  74. Message.error(res?.msg ?? '获取人脸识别信息失败!请稍后再试')
  75. getCaptcha()
  76. captchaEl.value = ''
  77. return
  78. }
  79. userInfo.value = res.data
  80. step.value = 2
  81. } catch (error) {
  82. return Message.error('获取人脸识别信息失败!请稍后再试')
  83. } finally {
  84. buttonLoading.value = false
  85. }
  86. }
  87. // 预加载模型
  88. onMounted(() => {
  89. getCaptcha()
  90. })
  91. </script>
  92. <style lang="less" scoped>
  93. .root {
  94. width: 100%;
  95. min-height: 100vh;
  96. font-family: 'Arial', sans-serif;
  97. background: linear-gradient(to right, #74ebd5, #ACB6E5);
  98. display: flex;
  99. flex-direction: column;
  100. align-items: center;
  101. justify-content: center;
  102. .card {
  103. background-color: #fff;
  104. border-radius: 20px;
  105. box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
  106. padding: 30px;
  107. width: 75%;
  108. max-width: 500px;
  109. min-width: 300px;
  110. min-height: 300px;
  111. text-align: center;
  112. margin-bottom: 30px;
  113. margin-top: 30px;
  114. display: flex;
  115. flex-direction: column;
  116. align-items: center;
  117. justify-content: center;
  118. .logo {
  119. display: flex;
  120. justify-content: center;
  121. align-items: center;
  122. height: 60px;
  123. margin-bottom: 20px;
  124. .title {
  125. color: #3370FF;
  126. font-size: 1.6em;
  127. font-weight: bold;
  128. margin-left: 10px;
  129. font-family: Alimama ShuHeiTi, -apple-system, BlinkMacSystemFont;
  130. }
  131. img {
  132. margin-top: 0;
  133. }
  134. }
  135. }
  136. input[type="text"],
  137. input[type="password"] {
  138. padding: 10px;
  139. border: 1px solid #ccc;
  140. border-radius: 10px;
  141. width: 80%;
  142. margin-bottom: 10px;
  143. }
  144. button {
  145. padding: 20px 20px;
  146. border: none;
  147. border-radius: 10px;
  148. background-color: #4A90E2;
  149. color: #fff;
  150. cursor: pointer;
  151. margin-top: 20px;
  152. }
  153. }
  154. </style>