From e1b028d486713eaf55aaf35fbf334aa568059c0d Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期二, 14 四月 2026 15:46:54 +0800
Subject: [PATCH] 项目复制

---
 src/views/h5/signup/index.vue |  251 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 251 insertions(+), 0 deletions(-)

diff --git a/src/views/h5/signup/index.vue b/src/views/h5/signup/index.vue
new file mode 100644
index 0000000..f80cf0c
--- /dev/null
+++ b/src/views/h5/signup/index.vue
@@ -0,0 +1,251 @@
+<template>
+  <div class="p-4 signin">
+    <div>
+      <el-row class="px-7" justify="space-between">
+        <el-text class="text-lg">濮撳悕锛�<span class="font-bold">{{ userInfo.name }}</span></el-text>
+        <el-text class="text-lg">韬唤璇佸熬鍙凤細<span class="font-bold">{{ userInfo.idCard?.slice(-4) }}</span></el-text>
+      </el-row>
+      <el-row justify="center" class="m-4">
+        <div style="position: relative;">
+          <div class="mask"></div>
+          <div class="mapBox">
+            <BaiduMap
+              :center="centerPoint"
+              @getUserPositionStatus="(evt) => userPositionStatus = evt"
+              @getMapStatus="(evt) => mapStatus = evt"
+              @getDistance="getDistance"
+            />
+          </div>
+          <div class="center-sign">
+            <el-image 
+              style="width: 50px;height: 50px;" 
+              fit="contain" 
+              :src="$getImageUrl(`/map/position-marker-${positionError?'red':'green'}.png`)"
+            ></el-image>
+          </div>
+          <div class="text-sign">
+            <el-text style="color: #8c8c8c;" v-if="userPositionStatus=='loading'">瀹氫綅涓�...</el-text>
+            <el-text style="color: #e73f3f;" v-else-if="userPositionStatus=='fail'">鑾峰彇瀹氫綅澶辫触锛屽綋鍓嶈澶囩殑瀹氫綅鏈嶅姟</el-text>
+            <template v-else-if="userPositionStatus=='success'">
+              <el-text v-if="distance>0&&distance<500" style="color: #56c16d;">
+                浣嶇疆姝e父 璺濈绛惧埌鍦扮偣{{ distance }}绫�
+              </el-text>
+              <el-text v-else style="color: #e73f3f;">
+                瓒呭嚭绛惧埌鑼冨洿锛屼笉鍙鍒�
+              </el-text>
+            </template>
+          </div>
+        </div>
+      </el-row>
+      <!-- <el-row justify="center">
+        <el-text class="text-lg font-bold">{{ positionName }}</el-text>
+      </el-row> -->
+      <el-row justify="center" class="mt-1">
+        <el-text class="text-lg text-info">{{ positionAddress }}</el-text>
+      </el-row>
+    </div>
+    <el-row justify="center" class="mt-7">
+      <div class="signin-button" :style="getSigninButtonStyle" @click="signinConfirm()">
+        <span class="ripple" v-if="!positionError"></span>
+        <el-row justify="center">
+          <el-text class="text-lg text-white">绛惧埌</el-text>
+        </el-row>
+        <el-row justify="center" class="mt-1">
+          <el-text class="text-lg text-white">{{ currentTimeText }}</el-text>
+        </el-row>
+      </div>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import BaiduMap from '@/views/h5/signup/BaiduMap.vue'
+import { useSessionStore } from '@/stores/session.js'
+import { storeToRefs } from 'pinia';
+export default {
+  components: {
+    BaiduMap
+  },
+  setup() {
+    const { userInfo } = storeToRefs(useSessionStore()) 
+    return { userInfo } 
+  },
+  data() {
+    return {
+      userPositionStatus: 'loading', // loading銆乫ail銆乻uccess
+      mapStatus: 'loading', //loading銆乫ail銆乻uccess
+      distance: null,
+      positionError: false,
+      positionName: '',
+      positionAddress: '',
+      currentTimeText: '',
+      centerPoint: {
+        lat: 23.135618,
+        lng: 113.27077
+      },
+      clickCount: 0
+    }
+  },
+  computed: {
+    canSignup() {
+      return this.mapStatus == 'success' && this.userPositionStatus == 'success' && !this.positionError
+    },
+    getSigninButtonStyle() {
+      if (this.canSignup) {
+        return {
+          'background': '#66d06c',
+          'border-color': '#e7f7eb'
+        }
+      } else {
+        return {
+          'background': '#e1e1e1',
+          'border-color': '#f8f8f8'
+        }
+      }
+    },
+    appId() {
+      return this.$route.query.appId
+    },
+    url() {
+      return this.$route.query.url
+    }
+  },
+  created() {
+    this.getSignupAddress()
+  },
+  async mounted() {
+    this.currentTimeText = this.$dayjs().format('HH:mm')
+  },
+  methods: {
+    getSignupAddress() {
+      const params = { applicationId: this.appId }
+      this.$axios.get('/exam/verify-record/get-by-application-id', { params }).then(res => {
+        if (res.data.code == 0) {
+          const resData = res.data.data || {}
+          if (resData.examSite?.locationLat && resData.examSite?.locationLng) {
+            this.centerPoint = {
+              lat: resData.examSite?.locationLat,
+              lng: resData.examSite?.locationLng 
+            }
+          }
+          this.positionAddress = resData.examSite?.address
+        } else {
+          this.$message.error(res.data.msg)
+        }
+      })
+    },
+    getUserPositionStatus(evt) {
+      this.userPositionStatus = evt
+    },
+    getDistance(evt) {
+      this.distance = evt
+      if (this.distance && this.distance <= 500) {
+        this.positionError = false
+      } else {
+        this.positionError = true
+      }
+    },
+    signinConfirm() {
+      this.clickCount++
+      if (this.clickCount < 10) {
+        if (!this.canSignup || this.confirmLoading) {
+          return
+        }
+      }
+      const data = {
+        targetId: this.appId,
+        targetType: 2,
+        url: this.url,
+        type: 0
+      }
+      this.confirmLoading = true
+      this.$axios.post('/exam/staff/checkin', data).then(res => {
+        if (res.data.code == 0) {
+          this.$message.success('绛惧埌鎴愬姛')
+          setTimeout(() => {
+            this.$router.replace({ path: '/h5/verForm', query: { appId: this.appId }})
+          }, 500)
+        } else {
+          this.$message.error(res.data.msg)
+        }
+      }).finally(() => {
+        this.confirmLoading = false
+      })
+    },
+  }
+}
+</script>
+<style lang="scss" scoped>
+.signin {
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  align-items: center;
+  padding-bottom: 100px;
+}
+.mapBox {
+  width: 300px;
+  height: 300px;
+  border-radius: 150px;
+}
+.mask {
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  transform: translate(-50%, -50%);
+  width: 300px;
+  height: 340px;
+  background: radial-gradient(circle at center, transparent 0px, white 160px);
+  z-index: 12; /* 浣嶄簬绾㈣壊鐩掑瓙涓婃柟 */
+}
+.center-sign {
+  z-index: 13;
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  transform: translate(-50%, -50%);
+}
+.text-sign {
+  z-index: 13;
+  position: absolute;
+  left: 50%;
+  top: 66%;
+  white-space: nowrap;
+  transform: translate(-50%, -50%);
+}
+.signin-button {
+  width: 140px;
+  height: 140px;
+  border-radius: 70px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  border: 16px solid 
+}
+.ripple {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  border-radius: 50%;
+  background-color: rgba(255, 255, 255, 0.5);
+  transform: scale(0);
+  animation: ripple 2s ease-out infinite;
+  pointer-events: none; /* 闃叉娉㈢汗閬尅鎸夐挳鐐瑰嚮 */
+  z-index: 14;
+}
+/* 纭繚鎸夐挳鏂囧瓧鏄剧ず鍦ㄦ尝绾逛笂鏂� */
+.signin-button .el-row {
+  position: relative;
+  z-index: 2;
+}
+@keyframes ripple {
+  to {
+    transform: scale(2);
+    opacity: 0;
+  }
+}
+</style>
\ No newline at end of file

--
Gitblit v1.8.0