From a32100e31b93bc378b11ab93617a9c40b081ad70 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期三, 15 四月 2026 16:44:03 +0800
Subject: [PATCH] 移除核验部分+登录注册接口对接

---
 src/views/main/appraisalPlan/index.vue      |   37 ++
 src/views/main/index.vue                    |   26 ++
 src/router/main/appraisalPlan/index.js      |    5 
 src/router/main/score/index.js              |    3 
 src/views/main/components/CustomLoading.vue |   86 +++++++
 src/views/login/index.vue                   |  140 ++++++++++--
 src/router/main/examTicket/index.js         |    3 
 src/router/index.js                         |   19 +
 src/views/main/components/MyFooter.vue      |    6 
 src/config/property.js                      |    9 
 /dev/null                                   |   28 --
 src/router/main/home/index.js               |    3 
 src/views/main/components/MyHeader.vue      |   35 +-
 src/router/main/certificate/index.js        |    3 
 src/views/main/center/index.vue             |   24 +
 src/main.js                                 |    3 
 src/stores/session.js                       |   12 +
 src/router/main/notice/index.js             |    6 
 src/utils/ruleGenerator.js                  |  166 +++++++++++++-
 src/assets/json/idCardTypeItems.json        |   10 
 src/router/main/center/index.js             |    3 
 21 files changed, 510 insertions(+), 117 deletions(-)

diff --git a/src/assets/json/idCardTypeItems.json b/src/assets/json/idCardTypeItems.json
new file mode 100644
index 0000000..5446057
--- /dev/null
+++ b/src/assets/json/idCardTypeItems.json
@@ -0,0 +1,10 @@
+[
+  {
+    "label": "灞呮皯韬唤璇�",
+    "value": 1
+  },
+  {
+    "label": "鍙版腐婢宠瘉浠跺眳姘戞潵寰�鍐呭湴閫氳璇�",
+    "value": 2
+  }
+]
\ No newline at end of file
diff --git a/src/config/property.js b/src/config/property.js
index 683394a..4efa8be 100644
--- a/src/config/property.js
+++ b/src/config/property.js
@@ -1,3 +1,10 @@
 export default {
-  
+  sex: {
+    key_1: '鐢�',
+    key_0: '濂�' 
+  },
+  idCardType: {
+    key_1: '灞呮皯韬唤璇�',
+    key_2: '鍙版腐婢宠瘉浠跺眳姘戞潵寰�鍐呭湴閫氳璇�'
+  }
 }
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
index 06305e4..0673633 100644
--- a/src/main.js
+++ b/src/main.js
@@ -50,7 +50,8 @@
 app.component('UploadBtn', UploadBtn)
 
 app.use(ElementPlus, {
-  locale: zhCn
+  locale: zhCn,
+  
 })
 const pinia = createPinia()
 pinia.use(piniaPluginPersistedstate)
diff --git a/src/router/h5/router.js b/src/router/h5/router.js
deleted file mode 100644
index 5c23388..0000000
--- a/src/router/h5/router.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const router = [
-  {
-    path: '/h5',
-    name: 'h5椤甸潰',
-    component: () => import('@/views/h5/index.vue'),
-    children: [
-      {
-        path: 'verify',
-        name: '鑰冪偣鏍搁獙',
-        component: () => import('@/views/h5/verify/index.vue'),
-      },
-      {
-        path: 'verForm',
-        name: '鎻愪氦鑰冪偣鏍搁獙',
-        component: () => import('@/views/h5/verify/form.vue'),
-      },
-      {
-        path: 'noVerAccess',
-        name: '鏍搁獙鏃犳潈闄�',
-        component: () => import('@/views/h5/verify/noAccess.vue'),
-      },
-      {
-        path: 'signup',
-        name: '绛惧埌',
-        component: () => import('@/views/h5/signup/index.vue'),
-      },
-      {
-        path: 'face',
-        name: '浜鸿劯楠岃瘉',
-        component: () => import('@/views/h5/faceAuth/index.vue'),
-      },
-    ],
-  },
-  {
-    path: '/h5/login',
-    name: '韬唤楠岃瘉鐧诲綍',
-    component: () => import('@/views/h5/login/index.vue'),
-  },
-  {
-    path: '/h5/redirect',
-    name: '閲嶅畾鍚�',
-    component: () => import('@/views/h5/login/redirect.vue'),
-  },
-  {
-    path: '/h5/bind',
-    name: '缁戝畾鎵嬫満鍙�',
-    component: () => import('@/views/h5/login/bind.vue'),
-  },
-]
-export default router
diff --git a/src/router/index.js b/src/router/index.js
index 899675b..7eb7e39 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -2,11 +2,11 @@
 import authPage from '@/router/auth/index.js'
 import errorPage from '@/router/error/index.js'
 import mainPage from '@/router/main/index.js'
-import h5 from '@/router/h5/router.js'
-
+import { useLoginStore } from '@/stores/login.js'
+import { useSessionStore } from '@/stores/session.js'
 const router = createRouter({
   history: createWebHistory(import.meta.env.BASE_URL),
-  routes: [...mainPage, ...authPage, ...errorPage, ...h5],
+  routes: [...mainPage, ...authPage, ...errorPage],
 })
 
 router.beforeEach((to, from, next) => {
@@ -17,7 +17,18 @@
       next({ path: '/error/404', query: { errorUrl: to.path } })
     }
   } else {
-    next()
+    if (to.meta.loginRequired) {
+      const { userInfo } = useSessionStore()
+      const { setLoginDialogVisible } = useLoginStore()
+      if (userInfo.id) {
+        next()
+      } else {
+        setLoginDialogVisible(true)
+        next(false)
+      }
+    } else {
+      next()
+    }
   }
 })
 
diff --git a/src/router/main/appraisalPlan/index.js b/src/router/main/appraisalPlan/index.js
index ea8d59e..bb10740 100644
--- a/src/router/main/appraisalPlan/index.js
+++ b/src/router/main/appraisalPlan/index.js
@@ -4,6 +4,11 @@
     name: '璇勪环璁″垝',
     component: () => import('@/views/main/appraisalPlan/index.vue'),
   },
+  {
+    path: 'appraisalPlan/signup/:id',
+    name: '璇勪环璁″垝鎶ュ悕',
+    component: () => import('@/views/main/appraisalPlan/index.vue'),
+  },
 ]
 
 export default appraisalPlan
\ No newline at end of file
diff --git a/src/router/main/center/index.js b/src/router/main/center/index.js
index 1a3fdc6..3e878b3 100644
--- a/src/router/main/center/index.js
+++ b/src/router/main/center/index.js
@@ -3,6 +3,9 @@
     path: 'center',
     name: '涓汉涓績',
     component: () => import('@/views/main/center/index.vue'),
+    meta: {
+      loginRequired: false
+    }
   },
 ]
 
diff --git a/src/router/main/certificate/index.js b/src/router/main/certificate/index.js
index 4983dfe..88a54d7 100644
--- a/src/router/main/certificate/index.js
+++ b/src/router/main/certificate/index.js
@@ -3,6 +3,9 @@
     path: 'certificate',
     name: '璇佷功鏌ヨ',
     component: () => import('@/views/main/certificate/index.vue'),
+    meta: {
+      loginRequired: true
+    }
   },
 ]
 
diff --git a/src/router/main/examTicket/index.js b/src/router/main/examTicket/index.js
index 24ccd43..f3325cb 100644
--- a/src/router/main/examTicket/index.js
+++ b/src/router/main/examTicket/index.js
@@ -3,6 +3,9 @@
     path: 'examTicket',
     name: '鍑嗚�冭瘉鏌ヨ',
     component: () => import('@/views/main/examTicket/index.vue'),
+    meta: {
+      loginRequired: true
+    }
   },
 ]
 
diff --git a/src/router/main/home/index.js b/src/router/main/home/index.js
index 2b753c4..0c7c832 100644
--- a/src/router/main/home/index.js
+++ b/src/router/main/home/index.js
@@ -3,6 +3,9 @@
     path: 'home',
     name: '棣栭〉',
     component: () => import('@/views/main/home/index.vue'),
+    meta: {
+      loginRequired: false
+    }
   },
 ]
 
diff --git a/src/router/main/notice/index.js b/src/router/main/notice/index.js
index f8777d2..aebc190 100644
--- a/src/router/main/notice/index.js
+++ b/src/router/main/notice/index.js
@@ -3,11 +3,17 @@
     path: 'noticeList',
     name: '鍏憡鍒楄〃',
     component: () => import('@/views/main/notice/list.vue'),
+    meta: {
+      loginRequired: false
+    }
   },
   {
     path: 'noticeDetail/:id',
     name: '鍏憡璇︽儏',
     component: () => import('@/views/main/notice/detail.vue'),
+    meta: {
+      loginRequired: false
+    }
   },
 ]
 
diff --git a/src/router/main/score/index.js b/src/router/main/score/index.js
index f932815..00836cd 100644
--- a/src/router/main/score/index.js
+++ b/src/router/main/score/index.js
@@ -3,6 +3,9 @@
     path: 'score',
     name: '鎴愮哗鏌ヨ',
     component: () => import('@/views/main/score/index.vue'),
+    meta: {
+      loginRequired: true
+    }
   },
 ]
 
diff --git a/src/stores/session.js b/src/stores/session.js
index b5ae635..e4d8b04 100644
--- a/src/stores/session.js
+++ b/src/stores/session.js
@@ -1,7 +1,17 @@
 import { ref } from 'vue'
 import { defineStore } from 'pinia'
 export const useSessionStore = defineStore('session', () => {
-  const userInfo = ref({})
+  const userInfo = ref({
+    id: '',
+    nickName: '',
+    idCard: '',
+    idCardType: '',
+    mobile: '',
+    sex: '',
+    avatar: '',
+    idCardFrontImg: '',
+    idCardBackImg: ''
+  })
 
   function setUserInfo(data) {
     userInfo.value = data
diff --git a/src/utils/ruleGenerator.js b/src/utils/ruleGenerator.js
index a7a9c7a..7a7aed7 100644
--- a/src/utils/ruleGenerator.js
+++ b/src/utils/ruleGenerator.js
@@ -3,7 +3,7 @@
 export const ruleGenerator = {
   // 蹇呭~瀛楁
   required(message = '姝ゅ瓧娈典负蹇呭~椤�') {
-    return { required: true, message, trigger: 'blur' }
+    return { required: true, message, trigger: ['blur', 'change'] }
   },
   
   // 闀垮害闄愬埗
@@ -35,7 +35,7 @@
           callback(new Error('璇疯緭鍏ユ纭殑鎵嬫満鍙风爜'))
         }
       },
-      trigger: ['blur', 'change']
+      trigger: ['blur']
     }
   },
   //楠岃瘉鐮侀獙璇�
@@ -65,21 +65,7 @@
       trigger: ['blur', 'change']
     }
   },
-
-  // 澶氶�夋楠岃瘉
-  checkbox(message) {
-    return { 
-      validator: (rule, value, callback) => {
-        if (!value) {
-          callback(new Error(message));
-        } else {
-          callback();
-        }
-      }, 
-      trigger: 'change' 
-    }
-  },
-
+  
   // 閭楠岃瘉
   email() {
     return {
@@ -93,5 +79,149 @@
       },
       trigger: 'blur'
     }
-  }
+  },
+
+  // 澶т簬绛変簬0鐨勬鏁存暟楠岃瘉
+  positiveInteger(min = 0) {
+    return {
+      validator: (rule, value, callback) => {
+        if (!value) {
+          callback()
+        } else {
+          // 妫�鏌ユ槸鍚︿负姝f暣鏁颁笖澶т簬绛変簬min
+          const num = Number(value)
+          const isPositiveInteger = Number.isInteger(num) && num >= min && num >= 0
+          if (isPositiveInteger) {
+            callback()
+          } else {
+            callback(new Error(min === 0 ? '璇疯緭鍏ュぇ浜庣瓑浜�0鐨勬鏁存暟' : `璇疯緭鍏ュぇ浜庣瓑浜�${min}鐨勬鏁存暟`))
+          }
+        }
+      },
+      trigger: ['blur', 'change']
+    }
+  },
+
+  // 韬唤璇佸彿楠岃瘉
+  idCard() {
+    return {
+      validator: (rule, value, callback) => {
+        if (!value) {
+          callback()
+          return
+        }
+
+        // 18浣嶈韩浠借瘉姝e垯琛ㄨ揪寮�
+        const reg18 = /^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/
+        // 15浣嶈韩浠借瘉姝e垯琛ㄨ揪寮忥紙鑰佸紡锛�
+        const reg15 = /^[1-9]\d{5}\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}$/
+
+        if (reg18.test(value)) {
+          // 18浣嶈韩浠借瘉鏍¢獙鐮侀獙璇�
+          const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
+          const checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
+          let sum = 0
+          for (let i = 0; i < 17; i++) {
+            sum += parseInt(value[i]) * weights[i]
+          }
+          const checkCode = checkCodes[sum % 11]
+          if (checkCode.toUpperCase() === value[17].toUpperCase()) {
+            callback()
+          } else {
+            callback(new Error('璇疯緭鍏ユ纭殑韬唤璇佸彿鐮�'))
+          }
+        } else if (reg15.test(value)) {
+          // 15浣嶈韩浠借瘉鏍¢獙閫氳繃
+          callback()
+        } else {
+          callback(new Error('璇疯緭鍏ユ纭殑韬唤璇佸彿鐮�'))
+        }
+      },
+      trigger: ['blur', 'change']
+    }
+  },
+
+  // 缁熶竴绀句細淇$敤浠g爜楠岃瘉
+  creditCode() {
+    return {
+      validator: (rule, value, callback) => {
+        if (!value) {
+          callback()
+          return
+        }
+
+        // 缁熶竴绀句細淇$敤浠g爜鐢�18浣嶅瓧绗︾粍鎴愶細1浣嶇櫥璁扮鐞嗛儴闂ㄤ唬鐮� + 1浣嶆満鏋勭被鍒唬鐮� + 6浣嶇櫥璁扮鐞嗘満鍏宠鏀垮尯鍒掔爜 + 9浣嶄富浣撹瘑鍒爜锛堢粍缁囨満鏋勪唬鐮侊級 + 1浣嶆牎楠岀爜
+        const reg = /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/
+
+        if (!reg.test(value)) {
+          callback(new Error('璇疯緭鍏ユ纭殑缁熶竴绀句細淇$敤浠g爜'))
+          return
+        }
+
+        // 鏍¢獙鐮佽绠�
+        const weights = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28]
+        const checkCodes = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'T', 'U', 'W', 'X', 'Y']
+
+        let sum = 0
+        for (let i = 0; i < 17; i++) {
+          const char = value[i]
+          // 灏嗗瓧绗﹁浆鎹负瀵瑰簲鐨勬暟鍊�
+          const num = char >= '0' && char <= '9' ? parseInt(char) : char.charCodeAt(0) - 55
+          sum += num * weights[i]
+        }
+
+        const mod = 31
+        const remainder = sum % mod
+        const checkCode = checkCodes[(mod - remainder) % mod]
+
+        if (checkCode === value[17].toUpperCase()) {
+          callback()
+        } else {
+          callback(new Error('璇疯緭鍏ユ纭殑缁熶竴绀句細淇$敤浠g爜'))
+        }
+      },
+      trigger: ['blur', 'change']
+    }
+  },
+
+  // 閲戦楠岃瘉锛堜繚鐣�2浣嶅皬鏁帮級
+  money(min = 0) {
+    return {
+      validator: (rule, value, callback) => {
+        if (!value) {
+          callback()
+          return
+        }
+
+        // 閲戦姝e垯锛氭暣鏁伴儴鍒嗕笉闄愪綅鏁帮紝灏忔暟閮ㄥ垎鏈�澶�2浣�
+        const reg = /^(0|[1-9]\d*)(\.\d{1,2})?$/
+
+        if (!reg.test(value)) {
+          callback(new Error('璇疯緭鍏ユ纭殑閲戦'))
+          return
+        }
+
+        const num = parseFloat(value)
+        if (num < min) {
+          callback(new Error(`閲戦涓嶈兘灏忎簬${min}`))
+        } else {
+          callback()
+        }
+      },
+      trigger: ['blur', 'change']
+    }
+  },
+    // 澶氶�夋楠岃瘉
+  checkbox(message) {
+    return { 
+      validator: (rule, value, callback) => {
+        if (!value) {
+          callback(new Error(message));
+        } else {
+          callback();
+        }
+      }, 
+      trigger: 'change' 
+    }
+  },
 }
\ No newline at end of file
diff --git a/src/views/h5/faceAuth/components/auditDialog.vue b/src/views/h5/faceAuth/components/auditDialog.vue
deleted file mode 100644
index 9662901..0000000
--- a/src/views/h5/faceAuth/components/auditDialog.vue
+++ /dev/null
@@ -1,156 +0,0 @@
-<template>
-  <el-dialog
-    v-model="dialogFlag"
-    width="80%"
-    style="max-width: 500px;"
-    align-center
-    :show-close="status!='auditing'"
-    :close-on-click-modal="false"
-    :close-on-press-escape="false"
-  >
-    <div class="p-7 pt-0" style="display: flex; flex-direction: column; align-items: center;">
-      <div class="image_box" v-if="['unStart', 'auditing'].includes(status)">
-        <el-image :src="base64" style="width: 100%;" fit="cover"></el-image>
-        <div v-if="status=='auditing'" class="scan-line"></div>
-      </div>
-      <el-row justify="center" v-else-if="['success', 'fail'].includes(status)">
-        <el-image :src="$getImageUrl(`/h5/face_${status}.png`)"></el-image>
-        <el-row>
-          <el-text class="text-lg">浜鸿劯楠岃瘉{{ status=='success'?'':'涓�' }}閫氳繃</el-text>
-        </el-row>
-        <el-row class="mt-2">
-          <el-text v-if="status=='success'">绯荤粺宸叉垚鍔熷鏍告偍鐨勮韩浠�</el-text>
-          <el-text v-else-if="status=='fail'">璇烽噸鏂伴獙璇佹偍鐨勮韩浠�</el-text>
-        </el-row>
-      </el-row>
-      <el-row justify="center" class="mt-5" v-if="status=='auditing'">
-        <el-text>姝e湪瀹℃牳涓紝璇疯�愬績绛夊緟...</el-text>
-      </el-row>
-      <el-button
-        v-if="status=='unStart'"
-        @click="submitAudit" 
-        :loading="status=='auditing'" 
-        type="primary"
-        size="large" class="mt-5" 
-        style="width: 100%;"
-      >
-        鎻愪氦瀹℃牳
-      </el-button>
-      <el-button
-        v-else-if="status=='success'"
-        @click="handlerSuccess"
-        type="primary" 
-        size="large" class="mt-5" 
-        style="width: 100%;"
-      >
-        瀹屾垚楠岃瘉
-      </el-button>
-      <el-button
-        v-else-if="status=='fail'"
-        @click="dialogFlag=false"
-        type="primary" 
-        size="large" class="mt-5" 
-        style="width: 100%;"
-      >
-        纭畾
-      </el-button>
-    </div>
-  </el-dialog>
-</template>
-
-<script>
-import { uploadByBase64 } from '@/utils/tool.js';
-
-export default {
-  components: {},
-  data() {
-    return {
-      dialogFlag: false,
-      status: '',
-      url: ''
-    }
-  },
-  props: {
-    modelValue: {
-      type: Boolean,
-      default: false
-    },
-    base64: {
-      type: String,
-      default: ''
-    }
-  },
-  computed: {
-    
-  },
-  created() {
-    
-  },
-  watch: {
-    modelValue(val) {
-      this.dialogFlag = val
-      if (val) {
-        this.status = 'unStart'
-      }
-    },
-    dialogFlag(val) {
-      this.$emit('update:modelValue', val)
-    }
-  },
-  methods: {
-    async submitAudit() {
-      this.status = 'auditing'
-      this.url = await uploadByBase64(this.base64 ,'浜鸿劯鐓х墖')
-      if (!this.url) {
-        this.status = 'fail'
-        return
-      }
-      const params = { faceImgPath: this.url  }
-      this.$axios.get('/system/auth/staff/checkin/face-match', { params }).then(res => {
-        if (res.data.code == 0) {
-          this.status = res.data.data ? 'success' : 'fail'
-        } else {
-          this.status = 'fail'
-          this.$message.error(res.data.msg || "浜鸿劯姣斿澶辫触")
-        }
-      }).catch(() => {
-        this.status = 'fail'
-      })
-    },
-    handlerSuccess() {
-      this.dialogFlag = false
-      this.$emit('handlerSuccess', this.url)
-    }
-  }
-}
-</script>
-<style scoped lang="scss">
-.image_box {
-  position: relative;
-  width: 90%;
-  max-width: 300px;
-  aspect-ratio: 1/1;
-  border-radius: 50% 50%;
-  overflow: hidden;
-  display: flex;
-  justify-content: center;
-  border: 5px solid #5693f4;
-}
-/* 鎵弿绾� */
-.scan-line {
-  position: absolute;
-  left: 0px;
-  right: 0px;
-  height: 50px;
-  background: linear-gradient(0deg, #5693f4, transparent);
-  animation: scan 2s ease-in-out infinite;
-  /* 鍒濆浣嶇疆璁惧湪椤堕儴 */
-  top: -50px;
-}
-
-@keyframes scan {
-  0% { top: -50px; }
-  100% { top: 100%; } /* 绉诲姩鍒板簳閮� */
-}
-
-</style>
\ No newline at end of file
diff --git a/src/views/h5/faceAuth/components/camera.vue b/src/views/h5/faceAuth/components/camera.vue
deleted file mode 100644
index 21bec1c..0000000
--- a/src/views/h5/faceAuth/components/camera.vue
+++ /dev/null
@@ -1,263 +0,0 @@
-<template>
-  <div ref="cameraBox" class="camera_box" :style="cameraStyle" v-show="isCameraOpening">
-    <video ref="videoEl" :width="videoWidth" :height="videoHeight" autoplay></video>
-    <canvas ref="canvasEl" :width="videoWidth" :height="videoHeight" style="display:none;"></canvas>
-    
-    <el-row justify="center" class="btn_box">
-      <el-button plain text @click="closeCamera()">
-        <Icon icon="material-symbols:cancel" width="28" height="28"  style="color: #FA5252" />
-      </el-button>
-      <el-button plain text @click="startRecordImage()">
-        <Icon icon="ant-design:camera-filled" width="28" height="28"  style="color: #FA5252" />
-      </el-button>
-    </el-row>
-  </div>
-</template>
-
-<script>
-export default {
-  data () {
-    return {
-      recorderOptions: { // recorder 閰嶇疆椤�
-        mimeType: 'video/webm;codecs=vp8,opus'
-      },
-      isCameraOpening: false,
-    }
-  },
-  computed: {
-    videoWidth: function () {
-      return 400
-    },
-    videoHeight: function(){
-      return (this.videoWidth * 3) / 4
-    },
-    cameraStyle: function(){
-      return {
-        width: `${this.videoWidth}px`,
-        height: `${this.videoHeight}px`
-      }
-    },
-  },
-  beforeUnmount(){
-    this.closeCamera()
-  },
-  mounted () {
-    this.initNavigatorMedia()
-    this.openCamera()
-  },
-  methods: {
-    initNavigatorMedia: function(){
-      // 鑾峰彇濯掍綋灞炴�э紝鏃х増鏈祻瑙堝櫒鍙兘涓嶆敮鎸乵ediaDevices锛岃缃竴涓┖瀵硅薄
-      if (navigator.mediaDevices === undefined) {
-        navigator.mediaDevices = {};
-      }
-      // 浣跨敤getUserMedia锛屽洜涓哄畠浼氳鐩栫幇鏈夌殑灞炴�с��
-      // 杩欓噷锛屽鏋滅己灏慻etUserMedia灞炴�э紝灏辨坊鍔犲畠銆�
-      if (navigator.mediaDevices.getUserMedia === undefined) {
-        this.initGetUserMedia()
-      }
-    },
-    initGetUserMedia: function(){
-      navigator.mediaDevices.getUserMedia = (constraints) => {
-        // 棣栧厛鑾峰彇鐜板瓨鐨刧etUserMedia(濡傛灉瀛樺湪)
-        let getUserMedia =
-          navigator.webkitGetUserMedia ||
-          navigator.mozGetUserMedia ||
-          navigator.getUserMedia;
-        // 鏈変簺娴忚鍣ㄤ笉鏀寔锛屼細杩斿洖閿欒淇℃伅
-        // 淇濇寔鎺ュ彛涓�鑷�
-        if (!getUserMedia) {//涓嶅瓨鍦ㄥ垯鎶ラ敊
-          return Promise.reject(
-            new Error("getUserMedia is not implemented in this browser")
-          );
-        }
-        // 鍚﹀垯锛屼娇鐢≒romise灏嗚皟鐢ㄥ寘瑁呭埌鏃х殑navigator.getUserMedia
-        return new Promise((resolve, reject) => {
-          getUserMedia.call(navigator, constraints, resolve, reject);
-        });
-      };
-    },
-    openCamera: function(){ // 鎵撳紑鎽勫儚澶�
-      navigator.mediaDevices.getUserMedia({
-        audio: false,
-        video: {
-          width: this.videoWidth,
-          height: this.videoHeight,
-        }
-      }).then((stream) => {
-        this.isCameraOpening = true
-        this.mediaStream = stream
-        this.initVideoSrcObject()
-      }).catch(err => {
-        console.log(`${err.name}锛�${err.message}`);
-        this.closeCamera()
-        this.mediaErrorHandler(err)
-      });
-    },
-    closeCamera() { // 鍏抽棴鎽勫儚澶�
-      if (!this.isCameraOpening) return false
-
-      this.isCameraOpening = false
-
-      if (this.mediaStream) {
-        let tracks = this.mediaStream.getTracks()
-        tracks.forEach(track => track.stop());
-      }
-
-      if (this.mediaRecorder) this.mediaRecorder.stop();
-      this.$emit('close')
-    },
-    initVideoSrcObject: function(){ // 鍒濆鍖� 瑙嗛褰曞埗 鐨� video srcObject
-      // 鏃х殑娴忚鍣ㄥ彲鑳芥病鏈塻rcObject
-      if ("srcObject" in this.$refs.videoEl) {
-        this.$refs.videoEl.srcObject = this.mediaStream;
-        this.initVideoMoveListener()
-      } else {
-        console.log('娴忚鍣ㄤ笉鏀寔')
-      }
-    },
-    initVideoMoveListener: function(){ // 鍒濆鍖� 瑙嗛绐楀彛 鐨� 绉诲姩浜嬩欢
-      let eventState = {}
-      let startMoving = (e) => { // 寮�濮嬬Щ鍔ㄧ殑鍥炶皟
-        e.preventDefault()
-        e.stopPropagation()
-        eventState = {
-          left: this.$refs.cameraBox.offsetLeft,
-          top: this.$refs.cameraBox.offsetTop,
-          x: e.clientX,
-          y: e.clientY
-        }
-        document.addEventListener('mousemove', moving)
-        document.addEventListener('mouseup', endMoving)
-      }
-      let moving = (e) => { // 绉诲姩鐨勫洖璋�
-        e.preventDefault()
-        e.stopPropagation()
-
-        let margin = 10
-        let left = e.clientX - (eventState.x - eventState.left)
-        let top = e.clientY - (eventState.y - eventState.top)
-        let maxLeft = document.documentElement.clientWidth - this.videoWidth - margin
-        let maxTop = document.documentElement.clientHeight - this.videoHeight - margin
-
-        // 闄愬埗绉诲姩鎴浘鍖哄煙涓嶈兘绉诲埌鍙鍖哄煙澶�
-        if (left < 10) left = margin
-        if (top < 10) top = margin
-        if (left > maxLeft) left = maxLeft
-        if (top > maxTop) top = maxTop
-
-        this.$refs.cameraBox.style.left = `${left}px`
-        this.$refs.cameraBox.style.top = `${top}px`
-      }
-      let endMoving = (e) => { // 缁撴潫绉诲姩鐨勫洖璋�
-        e.preventDefault()
-        document.removeEventListener('mousemove', moving)
-        document.removeEventListener('mouseup', endMoving)
-      }
-      this.$refs.cameraBox.addEventListener('mousedown', startMoving)
-    },
-    initUploadChunk: async function(blobs){ // 鍒濆鍖栦笂浼犱换鍔�
-      let tmpBlob = new Blob(blobs, { 'type': this.recorderOptions.mimeType });
-      // let file = new File(blobs, fileName, { type: 'video/webm' });
-      let file = null
-      try {
-        // 瑙e喅 Webm 瑙嗛 duration 闂
-        file = await fixWebmMetaInfo(tmpBlob)
-      } catch (error) {
-        file = tmpBlob
-        console.log(error)
-      }
-
-      let path = await uploadChunk(file, '瀛︿範瑙嗛', 'webm')
-      if (!path) return false
-
-      if (this.recordingFlag || this.recordCameraFlag) {
-        this.$store.commit('authCamera/recordVideoUrl', path)
-        this.$store.commit('authCamera/faceCaptureAll', { flag: false, imgList: this.faceCaptureAllImgList })
-      } else {
-        this.$store.commit('authCamera/biopsyVideoUrl', path)
-      }
-    },
-    startRecordImage() { // 寮�濮嬪綍鍒跺浘鍍忥紙鎷嶇収锛�
-      if (!this.$refs.canvasEl) return false
-
-      this.drawImage()
-      // this.closeCamera()
-    },
-    drawImage: function(){ // 缁樺埗鍥剧墖
-      this.$refs.canvasEl.getContext('2d').drawImage(
-        this.$refs.videoEl,
-        0,
-        0,
-        this.videoWidth,
-        this.videoHeight
-      );
-      this.uploadBase64()
-    },
-    async uploadBase64(){ // 涓婁紶鍥剧墖
-      let base64 = this.$refs.canvasEl.toDataURL("image/png", 1);
-      if (base64) {
-        this.$emit('handlerSuccess', base64)
-        this.closeCamera()
-      } else {
-        this.$message.error('鎷嶆憚澶辫触')
-      }
-    },
-    uploadErrorHandler: function (evt) { // 涓婁紶澶辫触鍥炶皟
-      console.log(JSON.stringify(evt.target))
-    },
-    mediaErrorHandler: function(){ // 寮�鍚憚鍍忓ご鎴栧綍鍒跺睆骞曞紓甯稿鐞�
-      this.$message.error('褰撳墠娴忚鍣ㄤ笉鏀寔锛岃鏇存崲娴忚鍣�')
-    },
-  }
-};
-</script>
-
-<style lang="scss" scoped>
-.camera_box{
-  position: fixed;
-  bottom: 10px;
-  right: 10px;
-  z-index: 300;
-}
-.status_box{
-  position: absolute;
-  left: 0;
-  right: 0;
-  padding: 6px;
-  margin-top: -38px;
-  font-size: 0.8rem;
-  color: white;
-  background: rgba(0,0,0,0.4);
-  .normal > span,
-  .abnormal > span{
-    width: 6px;
-    height: 6px;
-    border-radius: 28px;
-    display: inline-block;
-    margin-right: 5px;
-  }
-  .normal > span{
-    background-color: #00E63C;
-  }
-  .abnormal > span{
-    background-color: #FF3232;
-  }
-}
-.btn_box{
-  background: rgba(0,0,0,0.4);
-  margin-top: -63px;
-  padding-top: 10px;
-  padding-bottom: 7px;
-  position: absolute;
-  left: 0;
-  right: 0;
-}
-.duration{
-  position: absolute;
-  top: 0;
-  right: 0;
-  color: white;
-  text-shadow: 1px 1px 1px black, 1px -1px 1px black, -1px -1px 1px black, -1px 1px 1px black;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/h5/faceAuth/index.vue b/src/views/h5/faceAuth/index.vue
deleted file mode 100644
index 32f2e91..0000000
--- a/src/views/h5/faceAuth/index.vue
+++ /dev/null
@@ -1,197 +0,0 @@
-<template>
-  <div class="p-7 py-4 face">
-    <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">
-        <el-image :src="$getImageUrl(`/h5/face_default.png`)" style="width: 300px;"></el-image>
-      </el-row>
-      <!-- <video id="video" width="400" height="300" autoplay></video> -->
-      <el-row justify="center">
-        <el-text class="text-xl">璇锋媿鎽勭収鐗囧畬鎴愪汉鑴歌璇�</el-text>
-      </el-row>
-      <el-row class="my-7">
-        <el-text class="text-info text-center">
-          鎻愮ず锛氫汉鑴搁獙璇佸皢浼氳繘琛岀郴缁熷鏍革紝涓虹‘淇濇偍鑳藉揩閫熼�氳繃楠岃瘉锛岃鍕胯。鐫�鏆撮湶锛岄厤鍚堢郴缁熸寚绀哄畬鎴愰獙璇併��
-        </el-text>
-      </el-row>
-      <el-row class="pt-7">
-        <el-text class="text-xl">鎷嶆憚椤荤煡</el-text>
-      </el-row>
-      <el-row justify="space-between" class="mt-3">
-        <div v-for="(tip,index) in tipItems" :key="`tip${index}`">
-          <el-image :src="$getImageUrl(`/h5/face_tip_${index+1}.png`)" style="width: 70px;"></el-image>
-        </div>
-      </el-row>
-    </div>
-    <el-row justify="center" class="mb-7">
-      <el-button @click="startCapture" type="primary" style="width: 100%;" size="large">寮�濮嬫媿鎽�</el-button>
-    </el-row>
-
-    <camera 
-      v-if="openCameraFlag"
-      @close="openCameraFlag=false"
-      @handlerSuccess="shootSuccess"
-    ></camera>
-
-    <auditDialog
-      v-model="auditDialogFlag"
-      :base64="base64"
-      @handlerSuccess="auditSuccess"
-    >
-    </auditDialog>
-  </div>
-</template>
-
-<script>
-import camera from '@/views/h5/faceAuth/components/camera.vue';
-import {isWeixin} from '@/utils/UA.js'
-import auditDialog from '@/views/h5/faceAuth/components/auditDialog.vue';
-import { useSessionStore } from '@/stores/session.js'
-import { storeToRefs } from 'pinia';
-import { chooseImage } from '@/utils/wxjssdk.js'
-export default {
-  components: {
-    camera,
-    auditDialog
-  },
-  setup() {
-    const { userInfo } = storeToRefs(useSessionStore()) 
-    return { userInfo } 
-  },
-  data() {
-    return {
-      tipItems: [
-        { label: '鏍囧噯鎷嶆憚' },
-        { label: '閬尅鑴搁儴' },
-        { label: '鎷嶆憚涓嶅叏' },
-        { label: '鍏夌嚎涓嶈冻' },
-      ],
-      openCameraFlag: false,
-      base64: '',
-      auditDialogFlag: false
-    }
-  },
-  computed: {
-    getSigninButtonStyle() {
-      if (this.positionStatus == 'success') {
-        return {
-          'background': '#66d06c',
-          'border-color': '#e7f7eb'
-        }
-      } else {
-        return {
-          'background': '#e1e1e1',
-          'border-color': '#f8f8f8'
-        }
-      }
-    },
-    appId() {
-      return this.$route.query.appId
-    }
-  },
-  async mounted() {
-    this.currentTimeText = this.$dayjs().format('HH:mm')
-  },
-  methods: {
-    getUserPositionStatus(evt) {
-      this.userPositionStatus = evt
-    },
-    async startCapture() {
-      if (isWeixin) {
-        let photo = await chooseImage()
-        photo = photo.startsWith('data:image') ? photo : ('data:image/jpg;base64,' + photo)
-        this.shootSuccess(photo)
-      } else {
-        this.openCameraFlag = true
-      }
-    },
-    shootSuccess(evt) {
-      this.base64 = evt
-      if (this.base64) {
-        this.auditDialogFlag = true
-      }
-    },
-    auditSuccess(evt) {
-      this.$router.replace({ path: '/h5/signup', query: { appId: this.appId, url: evt } })
-    },
-  }
-}
-</script>
-<style lang="scss" scoped>
-.face {
-  height: 100vh;
-  display: flex;
-  flex-direction: column;
-  justify-content: space-between;
-  max-width: 700px;
-  margin: 0 auto;
-  overflow: auto;
-}
-.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
diff --git a/src/views/h5/index.vue b/src/views/h5/index.vue
deleted file mode 100644
index fd2c39d..0000000
--- a/src/views/h5/index.vue
+++ /dev/null
@@ -1,34 +0,0 @@
-<template>
-  <div v-if="userInfo.id">
-    <router-view></router-view>
-  </div>
-</template>
-<script>
-import { useSessionStore } from '@/stores/session.js'
-import { storeToRefs } from 'pinia';
-export default {
-  setup() {
-    const { setUserInfo } = useSessionStore()
-    const { userInfo } = storeToRefs(useSessionStore())
-    return { setUserInfo, userInfo }
-  },
-  data() {
-    return {}
-  },
-  created() {
-    if (this.$route.path == '/h5/verify' && this.$route.query.appId) {
-      localStorage.setItem('verify_url', this.$route.fullPath)
-    }
-    this.getUserInfo()
-  },
-  methods: {
-    getUserInfo() {
-      this.$axios.get('/system/auth/staff/profile').then(res => {
-        if (res.data.code == 0) {
-          this.setUserInfo(res.data.data || {})
-        }
-      })
-    },
-  }
-}
-</script>
\ No newline at end of file
diff --git a/src/views/h5/login/bind.vue b/src/views/h5/login/bind.vue
deleted file mode 100644
index ede5d35..0000000
--- a/src/views/h5/login/bind.vue
+++ /dev/null
@@ -1,140 +0,0 @@
-<template>
-  <div class="login">
-    <el-form ref="form" :model="form">
-      <el-form-item :rules="[$rules.required('璇疯緭鍏ョ粦瀹氭墜鏈哄彿') , $rules.phone()]" prop="mobile">
-        <el-input v-model="form.mobile" placeholder="璇疯緭鍏ョ粦瀹氭墜鏈哄彿" style="width: 100%" size="large" />
-      </el-form-item>
-      <el-form-item prop="code" :rules="[$rules.required('璇疯緭鍏ラ獙璇佺爜'), $rules.code()]">
-        <el-input 
-          v-model="form.code" 
-          placeholder="璇疯緭鍏ラ獙璇佺爜" 
-          style="width: 100%" size="large"
-        >
-          <template #append>
-            <el-row style="width: 70px;justify-content: center;">
-              <el-button 
-                v-if="countdown == 180"
-                style="color: var(--el-color-primary);"
-                class="cursor-p" 
-                :loading="sendCodeLoading"
-                @click="sendCode()"
-              >
-                鑾峰彇楠岃瘉鐮�
-              </el-button>
-              <el-text v-else>{{ countdown }}s</el-text>
-            </el-row>
-          </template>
-        </el-input>
-      </el-form-item>
-    </el-form>
-    <el-button @click="login()" :loading="loginLoading" type="primary" size="large" class="mt-2" style="width: 100%">缁戝畾骞剁櫥褰�</el-button>
-  </div>
-</template>
-<script>
-import { tokenUtils } from '@/utils/axios.js';
-import { useLoginStore } from '@/stores/login.js'
-import { storeToRefs } from 'pinia';
-export default {
-  setup() {
-    const { lastRouteInfo } = storeToRefs(useLoginStore())
-    return { lastRouteInfo }
-  },
-  data() {
-    return {
-      form: {
-        mobile: '',
-        code: '',
-      },
-      countdown: 180,
-      sendCodeLoading: false,
-      loginLoading: false,
-      countdownInterval: null
-    }
-  },
-  created() {
-  },
-  computed: {
-    state() {
-      return this.$route.query.state
-    },
-    openid() {
-      return this.$route.query.openid
-    },
-    wxCode() {
-      return this.$route.query.code
-    }
-  },
-  mounted() {
-    document.title = this.$route.name
-  },
-  methods: {
-    startCountdownInterval() {
-      this.clearCountdownInterval()
-      this.countdown--
-      this.countdownInterval = setInterval(() => {
-        if (this.countdown > 0) {
-          this.countdown--
-        } else {
-          this.countdown = 180
-          this.clearCountdownInterval()
-        }
-      }, 1000)
-    },
-    clearCountdownInterval() {
-      clearInterval(this.countdownInterval)
-      this.countdownInterval = null
-    },
-    async sendCode() {
-      const validate = await this.$refs.form.validateField('mobile')
-      if (validate) {
-        const data = {
-          captchaVerification: '',
-          mobile: this.form.mobile,
-          scene: 31,
-        }
-        this.sendCodeLoading = true
-        this.$axios.post('/system/auth/send-sms-code', data).then(res => {
-          if (res.data.code == 0) {
-            this.startCountdownInterval()
-            this.$message.success('宸插彂閫侀獙璇佺爜锛岃娉ㄦ剰鏌ユ敹')
-          } else {
-            this.$message.error(res.data.msg || '鑾峰彇楠岃瘉鐮佸け璐�')
-          }
-        }).finally(() => {
-          this.sendCodeLoading = false
-        })
-      }
-    },
-    login() {
-      const data = {
-        mobile: this.form.mobile,
-        code: this.form.code,
-        state: this.state,
-        openid: this.openid,
-        wxCode: this.wxCode
-      }
-      this.loginLoading = true
-      this.$axios.post('/system/auth/staff/checkin/bind', data).then(async res => {
-        if (res.data.code == 0) {
-          const resData = res.data.data
-          tokenUtils.setTokens(resData.accessToken, resData.refreshToken)
-          this.$message.success('缁戝畾鎴愬姛')
-          const path = localStorage.getItem('verify_url')
-          if (path) {
-            this.$router.replace(path)
-          }
-        } else {
-          this.$message.error(res.data.msg || '鐧诲綍澶辫触')
-        }
-      }).finally(() => {
-        this.loginLoading = false
-      })
-    },
-  }
-}
-</script>
-<style scoped>
-.login {
-  padding: 40px 20px 20px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/h5/login/index.vue b/src/views/h5/login/index.vue
deleted file mode 100644
index 86af36f..0000000
--- a/src/views/h5/login/index.vue
+++ /dev/null
@@ -1,141 +0,0 @@
-<template>
-  <div class="login" v-if="loginType == 'mobilePhone'">
-    <el-form ref="form" :model="form">
-      <el-form-item :rules="[$rules.required('璇疯緭鍏ユ墜鏈哄彿') , $rules.phone()]" prop="mobile">
-        <el-input v-model="form.mobile" placeholder="璇疯緭鍏ユ墜鏈哄彿" style="width: 100%" size="large" />
-      </el-form-item>
-      <el-form-item prop="code" :rules="[$rules.required('璇疯緭鍏ラ獙璇佺爜'), $rules.code()]">
-        <el-input 
-          v-model="form.code" 
-          placeholder="璇疯緭鍏ラ獙璇佺爜" 
-          style="width: 100%" size="large"
-        >
-          <template #append>
-            <el-row style="width: 70px;justify-content: center;">
-              <el-button 
-                v-if="countdown == 180"
-                style="color: var(--el-color-primary);"
-                class="cursor-p" 
-                :loading="sendCodeLoading"
-                @click="sendCode()"
-              >
-                鑾峰彇楠岃瘉鐮�
-              </el-button>
-              <el-text v-else>{{ countdown }}s</el-text>
-            </el-row>
-          </template>
-        </el-input>
-      </el-form-item>
-    </el-form>
-    <el-button @click="login()" :loading="loginLoading" type="primary" size="large" class="mt-2" style="width: 100%">鐧诲綍</el-button>
-  </div>
-</template>
-<script>
-import { tokenUtils } from '@/utils/axios.js';
-import { useLoginStore } from '@/stores/login.js'
-import { storeToRefs } from 'pinia';
-import { isWeixin } from '@/utils/UA.js'
-export default {
-  setup() {
-    const { lastRouteInfo } = storeToRefs(useLoginStore())
-    return { lastRouteInfo }
-  },
-  data() {
-    return {
-      loginType: '', //mobilePhone銆亀eixin
-      form: {
-        mobile: '',
-        code: '',
-      },
-      countdown: 180,
-      sendCodeLoading: false,
-      loginLoading: false,
-      countdownInterval: null
-    }
-  },
-  created() {
-    
-    tokenUtils.clearTokens()
-    this.loginType = isWeixin ? 'weixin' : 'mobilePhone'
-    if (isWeixin) {
-      this.loginType = 'weixin'
-      localStorage.removeItem('weChatRedirectCount')
-      this.$router.replace({ path: '/h5/redirect' })
-    }
-  },
-  computed: {
-    appId() {
-      return this.$route.query.appId
-    }
-  },
-  mounted() {
-    document.title = this.$route.name
-  },
-  methods: {
-    startCountdownInterval() {
-      this.clearCountdownInterval()
-      this.countdown--
-      this.countdownInterval = setInterval(() => {
-        if (this.countdown > 0) {
-          this.countdown--
-        } else {
-          this.countdown = 180
-          this.clearCountdownInterval()
-        }
-      }, 1000)
-    },
-    clearCountdownInterval() {
-      clearInterval(this.countdownInterval)
-      this.countdownInterval = null
-    },
-    async sendCode() {
-      const validate = await this.$refs.form.validateField('mobile')
-      if (validate) {
-        const data = {
-          captchaVerification: '',
-          mobile: this.form.mobile,
-          scene: 31,
-        }
-        this.sendCodeLoading = true
-        this.$axios.post('/system/auth/send-sms-code', data).then(res => {
-          if (res.data.code == 0) {
-            this.startCountdownInterval()
-            this.$message.success('宸插彂閫侀獙璇佺爜锛岃娉ㄦ剰鏌ユ敹')
-          } else {
-            this.$message.error(res.data.msg || '鑾峰彇楠岃瘉鐮佸け璐�')
-          }
-        }).finally(() => {
-          this.sendCodeLoading = false
-        })
-      }
-    },
-    login() {
-      const data = {
-        mobile: this.form.mobile,
-        code: this.form.code,
-      }
-      this.loginLoading = true
-      this.$axios.post('/system/auth/staff/checkin/sms-login', data).then(async res => {
-        if (res.data.code == 0) {
-          const resData = res.data.data
-          tokenUtils.setTokens(resData.accessToken, resData.refreshToken)
-          this.$message.success('鐧诲綍鎴愬姛')
-          const path = localStorage.getItem('verify_url')
-          if (path) {
-            this.$router.replace(path)
-          }
-        } else {
-          this.$message.error(res.data.msg || '鐧诲綍澶辫触')
-        }
-      }).finally(() => {
-        this.loginLoading = false
-      })
-    },
-  }
-}
-</script>
-<style scoped>
-.login {
-  padding: 40px 20px 20px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/h5/login/redirect.vue b/src/views/h5/login/redirect.vue
deleted file mode 100644
index 31ac4a7..0000000
--- a/src/views/h5/login/redirect.vue
+++ /dev/null
@@ -1,245 +0,0 @@
-<template>
-  <div class="wx-login-container">
-    <div class="loading-wrapper">
-      <div class="wechat-icon">
-        <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
-          <path d="M717.5 595.8c-15.7 8.3-32.6 13.9-50.4 15.7-12.6 1.3-25.3-0.4-37.6-2.9-19-3.8-36.9-10.8-53.5-20.7-3.6-2.2-7.2-4.4-10.7-6.8-19.5-13.6-36.5-29.9-50.8-49-6.5-8.6-12.1-17.9-16.9-27.5-4.8-9.7-8.3-19.8-10.6-30.3-2.2-10.1-3.2-20.3-3-30.6 0.1-5.3 0.4-10.5 1.1-15.8 1.7-12.6 5.1-24.7 10.1-36.3 6.1-14.1 14.2-27 24.4-38.5 13.9-15.6 30.4-28.1 49.3-37.2 12.9-6.3 26.5-10.6 40.6-12.8 14.1-2.2 28.4-2.2 42.6 0.1 14.2 2.3 27.8 6.7 40.7 13.1 18.9 9.2 35.4 21.7 49.3 37.3 10.2 11.5 18.3 24.5 24.4 38.5 5 11.6 8.4 23.8 10.1 36.3 0.7 5.3 1 10.5 1.1 15.8 0.2 10.3-0.8 20.5-3 30.6-2.3 10.5-5.8 20.6-10.6 30.3-4.8 9.6-10.4 18.9-16.9 27.5-14.3 19.1-31.3 35.4-50.8 49-3.5 2.4-7.1 4.6-10.7 6.8-16.6 9.9-34.5 16.9-53.5 20.7-12.3 2.5-25 4.2-37.6 2.9z" fill="#07C160"/>
-          <path d="M395.6 380.4c0 54.7 26.5 103.5 67.6 134.4-3.6 9.8-7.9 19.2-12.8 28.1-4.9 8.9-10.4 17.4-16.6 25.4-6.2 8-13.1 15.4-20.6 22.2-7.5 6.8-15.7 12.8-24.4 17.9-8.7 5.1-18 9.3-27.6 12.5-9.6 3.2-19.6 5.3-29.8 6.3-10.2 1-20.5 0.9-30.6-0.4-10.1-1.3-20-3.8-29.4-7.4-9.4-3.6-18.3-8.3-26.6-14-8.3-5.7-15.9-12.2-22.7-19.6-6.8-7.4-12.7-15.5-17.6-24.3-4.9-8.8-8.8-18.2-11.5-28-2.7-9.8-4.2-19.9-4.5-30.2-0.3-10.3 0.8-20.5 3.2-30.5 2.4-10 6.1-19.6 10.9-28.7 4.8-9.1 10.7-17.5 17.5-25.2 6.8-7.7 14.5-14.5 22.9-20.4 8.4-5.9 17.5-10.8 27.1-14.6 9.6-3.8 19.7-6.4 30-7.9 10.3-1.5 20.8-1.8 31.2-0.7 10.4 1.1 20.6 3.6 30.3 7.4 9.7 3.8 18.8 8.8 27.1 15 8.3 6.2 15.8 13.4 22.4 21.5 6.6 8.1 12.2 16.9 16.6 26.3 4.4 9.4 7.6 19.3 9.5 29.6z" fill="#07C160"/>
-        </svg>
-      </div>
-      12222222223333
-      <div class="sub-text" v-if="!errorFlag">
-        寰俊鎺堟潈涓�
-        <span class="dots">
-          <span class="dot"></span>
-          <span class="dot"></span>
-          <span class="dot"></span>
-        </span>
-      </div>
-      <div v-else class="sub-text">鎺堟潈澶辫触</div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { tokenUtils } from '@/utils/axios.js';
-import { useLoginStore } from '@/stores/login.js'
-import { storeToRefs } from 'pinia';
-export default {
-  setup() {
-    const { lastRouteInfo } = storeToRefs(useLoginStore())
-    return { lastRouteInfo }
-  },
-  data() {
-    return {
-      redirectCount: 0,
-      errorMessage: ''
-    }
-  },
-  watch() {
-
-  },
-  computed: {
-    code() {
-      return this.$route.query.code
-    },
-    state() {
-      return this.$route.query.state
-    }
-  },
-  created() {
-    if (this.code && this.state) {
-      this.authSuccess()
-    } else {
-      this.redirectUrl()
-      this.redirectCount = localStorage.getItem('weChatRedirectCount') || 0
-      this.redirectCount = Number(this.redirectCount) + 1
-      localStorage.setItem('weChatRedirectCount', redirectCount)
-    }
-  },
-  methods: {
-    redirectUrl() {
-      if (this.redirectCount > 1) {
-        this.errorFlag = true
-        return
-      }
-      const params = {
-        targetId: '',
-        redirectUrl: encodeURIComponent(window.location.href),
-      }
-      this.$axios.get('/system/auth/staff/checkin/wx-auth-redirect', { params }).then(res => {
-        if (res.data.code == 0) {
-          window.location.replace(res.data.data)
-        } else {
-          this.errorFlag = true
-          this.$message.error(res.data.msg)
-        }
-      })
-    },
-    authSuccess() {
-      const params = {
-        targetId: '',
-        code: this.code,
-        state: this.state
-      }
-      this.$axios.get('/system/auth/staff/checkin/auth-success/null', { params }).then(res => {
-        if (res.data.code == 0) {
-          const resData = res.data.data || {}
-          if (resData.userId) {
-            tokenUtils.setTokens(resData.accessToken, resData.refreshToken)
-            const path = localStorage.getItem('verify_url')
-            if (path) {
-              this.$router.replace(path)
-            } else {
-              this.$router.replace('/h5/noVerAccess')
-            }
-          } else {
-            this.$router.replace({ 
-              path: '/h5/bind', 
-              query: { 
-                state: resData.state, 
-                openid: resData.openid,
-                code: resData.code
-              } 
-            })
-          }
-        } else {
-          this.$message.error(res.data.msg)
-        }
-      })
-    }
-  }
-}
-</script>
-
-<style scoped>
-.wx-login-container {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  min-height: 100vh;
-  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
-}
-
-.loading-wrapper {
-  text-align: center;
-  padding: 60px 40px;
-}
-
-.wechat-icon {
-  width: 100px;
-  height: 100px;
-  margin: 0 auto 30px;
-  animation: iconPulse 2s ease-in-out infinite;
-}
-
-.wechat-icon svg {
-  width: 100%;
-  height: 100%;
-  filter: drop-shadow(0 8px 16px rgba(7, 193, 96, 0.3));
-}
-
-@keyframes iconPulse {
-  0%, 100% {
-    transform: scale(1);
-  }
-  50% {
-    transform: scale(1.1);
-  }
-}
-
-.loading-text {
-  font-size: 28px;
-  font-weight: 600;
-  color: #333;
-  margin-bottom: 16px;
-  display: inline-block;
-}
-
-.text-item {
-  display: inline-block;
-  opacity: 0;
-  animation: textFadeIn 0.5s ease-out forwards;
-}
-
-.text-item:nth-child(1) {
-  animation-delay: 0.2s;
-}
-
-.text-item:nth-child(2) {
-  animation-delay: 0.4s;
-}
-
-.text-item:nth-child(3) {
-  animation-delay: 0.6s;
-}
-
-.text-item:nth-child(4) {
-  animation-delay: 0.8s;
-}
-
-@keyframes textFadeIn {
-  from {
-    opacity: 0;
-    transform: translateY(20px);
-  }
-  to {
-    opacity: 1;
-    transform: translateY(0);
-  }
-}
-
-.dots {
-  display: inline-block;
-  margin-left: 8px;
-  vertical-align: middle;
-}
-
-.dot {
-  display: inline-block;
-  width: 6px;
-  height: 6px;
-  background: #07C160;
-  border-radius: 50%;
-  margin: 0 3px;
-  animation: dotBounce 1.4s ease-in-out infinite both;
-}
-
-.dot:nth-child(1) {
-  animation-delay: -0.32s;
-}
-
-.dot:nth-child(2) {
-  animation-delay: -0.16s;
-}
-
-.dot:nth-child(3) {
-  animation-delay: 0;
-}
-
-@keyframes dotBounce {
-  0%, 80%, 100% {
-    transform: scale(0);
-    opacity: 0.5;
-  }
-  40% {
-    transform: scale(1);
-    opacity: 1;
-  }
-}
-
-.sub-text {
-  font-size: 18px;
-  color: #999;
-  animation: fadeInOut 2s ease-in-out infinite;
-}
-
-@keyframes fadeInOut {
-  0%, 100% {
-    opacity: 0.5;
-  }
-  50% {
-    opacity: 1;
-  }
-}
-</style>
diff --git a/src/views/h5/signup/BaiduMap.vue b/src/views/h5/signup/BaiduMap.vue
deleted file mode 100644
index 68d0b3d..0000000
--- a/src/views/h5/signup/BaiduMap.vue
+++ /dev/null
@@ -1,133 +0,0 @@
-<template>
-  <div class="map-wrapper">
-    <div ref="mapContainer" class="map-container"></div>
-  </div>
-</template>
-
-<script>
-let baiduMapPromise = null;
-
-function loadBaiduMapScript() {
-  const ak = 'H4IN9QhFD5mC72tJEvbZysO7SKf0vDMa';
-  if (window.BMapGL) {
-    return Promise.resolve();
-  }
-  if (baiduMapPromise) {
-    return baiduMapPromise;
-  }
-  baiduMapPromise = new Promise((resolve, reject) => {
-    window.__baidu_map_callback = function() {
-      delete window.__baidu_map_callback; // 娓呯悊鍏ㄥ眬鍥炶皟
-      resolve();
-    };
-    const script = document.createElement('script');
-    script.type = 'text/javascript';
-    script.src = `//api.map.baidu.com/api?type=webgl&v=1.0&ak=${ak}&callback=__baidu_map_callback`;
-    script.onerror = (error) => {
-      delete window.__baidu_map_callback;
-      baiduMapPromise = null; // 鍏佽閲嶈瘯
-      reject(error);
-    };
-    document.body.appendChild(script);
-  });
-  return baiduMapPromise;
-}
-export default {
-  name: 'BaiduMap',
-  props: {
-    center: {
-      type: Object,
-      default: () => ({ lng: 0, lat: 0 })
-    },
-  },
-  data() {
-    return {
-      map: null,
-      zoom: 17,
-      userPosition: null
-    };
-  },
-  mounted() {
-    this.loadMap();
-  },
-  beforeUnmount() {
-    if (this.map) {
-      this.map.destroy();
-      this.map = null;
-    }
-  },
-  watch: {
-    center: {
-      handler: function(val) {
-        const newPoint = new BMapGL.Point(val.lng, val.lat);
-        this.map.map.setCenter(newPoint)
-      },
-      deep: true
-    }
-  },
-  methods: {
-    loadMap() {
-      loadBaiduMapScript()
-        .then(() => {
-          this.initMap();
-        })
-        .catch(err => {
-          this.$emit('getMapStatus', 'fail')
-          console.error('鍦板浘鑴氭湰鍔犺浇澶辫触:', err);
-        });
-    },
-    initMap() {
-      const container = this.$refs.mapContainer;
-      if (!container) return;
-      const map = new BMapGL.Map(container);
-      const point = new BMapGL.Point(this.center.lng, this.center.lat);
-      map.centerAndZoom(point, this.zoom);
-      map.enableScrollWheelZoom();
-      this.map = map;
-      this.$emit('ready', map);
-      this.$emit('getMapStatus', 'success')
-      this.getUserPosition()
-    },
-    async getUserPosition() {
-      const geolocation = new BMapGL.Geolocation();
-      let that = this
-      geolocation.getCurrentPosition(function(r){
-        if(this.getStatus() == BMAP_STATUS_SUCCESS){
-            // 瀹氫綅鎴愬姛锛宺.point 鍗充负鑾峰彇鍒扮殑鐧惧害鍧愭爣锛圔D09ll锛�
-            let pt = r.point;
-            that.userPosition = {
-              lng: pt.lng,
-              lat: pt.lat
-            }
-            that.$emit('getUserPositionStatus', 'success')
-            that.diffDistance()
-        } else {
-          that.$emit('getUserPositionStatus', 'fail')
-        }
-      });
-    },
-    diffDistance() { //娴嬭窛
-      if (!this.map || !this.userPosition) return
-      const userPoint = new BMapGL.Point(this.userPosition.lng, this.userPosition.lat); // 鐐笰鍧愭爣
-      const centerPoint = new BMapGL.Point(this.center.lng, this.center.lat); // 鐐笲鍧愭爣
-      const distance = this.map.getDistance(userPoint,centerPoint)
-      this.$emit('getDistance', Math.floor(distance))
-    }
-  }
-};
-</script>
-
-<style scoped>
-.map-wrapper {
-  width: 100%;
-  height: 100%;
-  margin: 0;
-  padding: 0;
-}
-.map-container {
-  width: 100%;
-  height: 100%;
-  margin: 0;
-  padding: 0;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/h5/signup/index.vue b/src/views/h5/signup/index.vue
deleted file mode 100644
index f80cf0c..0000000
--- a/src/views/h5/signup/index.vue
+++ /dev/null
@@ -1,251 +0,0 @@
-<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
diff --git a/src/views/h5/verify/form.vue b/src/views/h5/verify/form.vue
deleted file mode 100644
index 91c57d1..0000000
--- a/src/views/h5/verify/form.vue
+++ /dev/null
@@ -1,233 +0,0 @@
-<template>
-  <div>
-    <el-row class="p-3 m-0" justify="space-between" align="middle">
-      <el-col :span="4"></el-col>
-      <el-col :span="16">
-        <el-row justify="center">
-          <el-text class="text-lg font-bold text-center">
-            {{ title }}
-          </el-text>
-        </el-row>
-      </el-col>
-      <el-col :span="4">
-        <el-row justify="center">
-          <el-button
-            v-if="!isVerified"
-            text style="color: var(--el-color-primary);" 
-            :loading="saveLoading" @click="tempSave()"
-            class="mx-4"
-          >
-            鏆傚瓨
-          </el-button>
-        </el-row>
-      </el-col>
-    </el-row>
-    
-    <el-divider class="m-0" style="flex-shrink: 0;"></el-divider>
-    <el-scrollbar :height="`${mainHeight}px`" class="p-2 m-0 mt-1" min-size="none">
-      <div v-if="pdfUrl" :style="{width: '100%', height: `${mainHeight - 100}px`}">
-        <PdfPreview v-if="pdfUrl" :url="pdfUrl"></PdfPreview>
-      </div>
-      <el-text v-if="pdfUrlError" class="ml-2 text-info">鑰冪偣鐢虫姤鏂囦欢鍔犺浇澶辫触...</el-text>
-      <div class="p-2 my-4">
-        <el-form ref="verifyForm" :model="form">
-          <el-form-item label="*浠ヤ笂鐢虫姤鍐呭鏄惁灞炲疄" prop="isVerified">
-            <el-radio-group v-model="form.isContentTrue" :disabled="isVerified">
-              <el-radio :value="1">鏄�</el-radio>
-              <el-radio :value="0">鍚�</el-radio>
-            </el-radio-group>
-          </el-form-item>
-          <el-form-item label="*璇ヨ�冪偣鏍搁獙鏄惁閫氳繃" prop="isPass">
-            <el-radio-group v-model="form.isSitePass" :disabled="isVerified">
-              <el-radio :value="1">鏄�</el-radio>
-              <el-radio :value="0">鍚�</el-radio>
-            </el-radio-group>
-          </el-form-item>
-          <el-row><el-text>涓撳璇勪及鎰忚</el-text></el-row>
-          <el-form-item class="mt-1">
-            <el-input
-              v-model="form.suggestion"
-              :rows="3"
-              type="textarea"
-              placeholder="璇峰~鍐欒瘎浼版剰瑙�"
-              :disabled="isVerified"
-            />
-          </el-form-item>
-          <el-row><el-text>*鐜板満宸ヤ綔鐓х墖</el-text></el-row>
-          <el-row>
-            <UploadBtn 
-              v-model="form.image" 
-              :disabled="isVerified" 
-              :accept="['pdf', 'jpg']" 
-              :limitFileCount="10" 
-              listType="picture-card"
-            ></UploadBtn>
-          </el-row>
-          
-          <Signature v-model="form.signatureUrl" :disabled="isVerified" :isRequire="true"></Signature>
-
-          <el-button
-            v-if="!isVerified"
-            @click="submitVerify" 
-            type="primary" size="large" 
-            class="my-7" style="width: 100%;"
-            :loading="submitLoading"
-          >鎻愪氦鏍搁獙缁撴灉
-          </el-button>
-          <el-button
-            v-if="isVerified"
-            disabled
-            type="primary" size="large" 
-            class="my-7" style="width: 100%;"
-          >鏍搁獙缁撴灉宸叉彁浜�
-          </el-button>
-        </el-form>
-      </div>
-    </el-scrollbar>
-  </div>
-</template>
-<script>
-import PdfPreview from '@/views/main/components/PdfPreview.vue'
-import { useWindowSize } from '@/utils/hook.js'
-import Signature from '@/views/main/components/Signature.vue';
-import { useSessionStore } from '@/stores/session.js'
-import { storeToRefs } from 'pinia';
-
-export default {
-  components: {
-    PdfPreview,
-    Signature
-  },
-  setup() {
-    const { height } = useWindowSize()
-    const { userInfo } = storeToRefs(useSessionStore())
-    return { pageHeight: height, userInfo }
-  },
-  data() {
-    return {
-      title: '',
-      pdfUrl: '',
-      form: {
-        id: '',
-        isContentTrue: 0,
-        isSitePass: 0,
-        suggestion: '',
-        image: [],
-        signatureUrl: ''
-      },
-      isVerified: false,
-      saveLoading: false,
-      submitLoading: false,
-      pdfUrlError: false
-    }
-  },
-  computed: {
-    mainHeight() {
-      return this.pageHeight - 80
-    },
-    appId() {
-      return this.$route.query.appId
-    }
-  },
-  async created() {
-    this.getVerifyDetail()
-  },
-  mounted() {
-    document.title = '鑰冪偣鏍搁獙'
-  },
-  methods: {
-    getVerifyDetail() {
-      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 || {}
-          this.pdfUrl = resData.examSiteVerifyFile ? this.$qxueyou.qxyRes + resData.examSiteVerifyFile : ''
-          this.title = resData.organizationName + '-' + resData.examSite.siteName + '鑰冪偣鏍搁獙'
-          if (resData.id) {
-            this.form.isContentTrue  = resData.isContentTrue
-            this.form.isSitePass = resData.isSitePass
-            this.form.suggestion = resData.evaluationOpinion
-            resData.sitePhotos?.forEach(ele => {
-              this.form.image.push({ name: '', url: ele })
-            })
-            this.form.signatureUrl = resData.signatureUrl
-            this.isVerified = resData.isVerified
-          }
-          if (!this.pdfUrl) {
-            this.pdfUrlError = false
-          }
-        } else {
-          this.$message.error('鑾峰彇鏍搁獙淇℃伅澶辫触')
-        }
-      })
-    },
-    tempSave() {
-      const data = {
-        applicationId: this.appId,
-        id: this.form.id,
-        userId: this.userInfo.id,
-        name: this.userInfo.name,
-        mobile: this.userInfo.mobile,
-        idNumber: this.userInfo.idCard,
-        isContentTrue: this.form.isContentTrue,
-        isSitePass: this.form.isSitePass,
-        evaluationOpinion: this.form.suggestion,
-        sitePhotos: this.form.image.map(ele => ele.url),
-        signatureUrl: this.form.signatureUrl,
-      }
-      this.saveLoading = true
-      this.$axios.put(`/exam/verify-record/save`, data).then(res => {
-        if (res.data.code == 0) {
-          this.$message.success('淇濆瓨鎴愬姛')
-          this.getVerifyDetail()
-        } else {
-          this.$message.error(res.data.msg)
-        }
-      }).finally(() => {
-        this.saveLoading = false
-      })
-    },
-    submitVerify() {
-      if (this.form.image.length==0) {
-        this.$message.error('璇蜂笂浼犵幇鍦哄伐浣滅収鐗�')
-        return
-      }
-      if (!this.form.signatureUrl) {
-        this.$message.error('璇峰~鍐欑鍚�')
-        return
-      }
-      this.$messageBox.confirm('鎻愪氦涔嬪悗涓嶅彲鍐嶇紪杈戞牳楠岋紝纭鎻愪氦鍚�', '鎻愮ず', 
-      { confirmButtonText: '纭畾', cancelButtonText: '鍙栨秷', type: 'tip' }).then(res => {
-        if (res == 'confirm') { 
-          this.submitLoading = true
-          const data = {
-            applicationId: this.appId,
-            isContentTrue: this.form.isContentTrue,
-            isSitePass: this.form.isSitePass,
-            evaluationOpinion: this.form.suggestion,
-            sitePhotos: this.form.image.map(ele => ele.url),
-            signatureUrl: this.form.signatureUrl,
-          }
-          this.$axios.post('/exam/verify-record/verify', data).then(res => {
-            if (res.data.code == 0) {
-              this.$message.success('鎻愪氦鏍搁獙鎴愬姛')
-              this.isVerified = true
-            } else {
-              this.$message.error(res.data.msg || '鎻愪氦鏍搁獙澶辫触')
-            }
-          }).finally(() => {
-            this.submitLoading = false
-          })
-        }
-      })
-    },
-    onPagesLoaded(msg) {
-      console.log(msg)
-    },
-    onError(msg) {
-      console.log(msg)
-    },
-    onPageChange() {}
-  }
-}
-</script>
\ No newline at end of file
diff --git a/src/views/h5/verify/index.vue b/src/views/h5/verify/index.vue
deleted file mode 100644
index 6c4bc70..0000000
--- a/src/views/h5/verify/index.vue
+++ /dev/null
@@ -1,80 +0,0 @@
-<template>
-  <div></div>
-</template>
-<script>
-export default {
-  components: {},
-  data() {
-    return {}
-  },
-  computed: {
-    appId() {
-      return this.$route.query.appId
-    }
-  },
-  async created() {
-    const canVerify = await this.getCanVerify()
-    if (!canVerify) {
-      this.$router.replace('/h5/noVerAccess')
-      return
-    }
-    const getCheckIsSubmit = await this.getCheckIsSubmit()
-    if (getCheckIsSubmit) {
-      this.$router.replace({ path: '/h5/verForm', query: { appId: this.appId }})
-    } else {
-      this.$router.replace({ path: '/h5/face', query: { appId: this.appId }})
-    }
-  },
-  mounted() {
-    document.title = '鑰冪偣鏍搁獙'
-  },
-  methods: {
-    getCanVerify() {
-      return new Promise((resolve) => {
-        const params = {
-          applicationId: this.appId
-        }
-        this.$axios.get('/exam/verify-record/can-verify', { params }).then(res => {
-          if (res.data.code == 0) {
-            resolve(res.data.data)
-          } else {
-            resolve(false)
-          }
-        }, () => {
-          resolve(false)
-        })
-      })
-    },
-    getCheckIsSubmit() {
-      return new Promise((resolve) => {
-        const params = { applicationId: this.appId }
-        this.$axios.get('/exam/verify-record/get-by-application-id', { params }).then(res => {
-          if (res.data.code == 0) {
-            resolve(res.data.data.isVerified)
-          } else {
-            resolve(false)
-          }
-        }, () => {
-          resolve(false)
-        })
-      })
-    },
-    getCheckinExist() {
-      return new Promise((resolve) => {
-        const params = {
-          targetId: this.appId
-        }
-        this.$axios.get('/exam/staff/checkin/exist', { params }).then(res => {
-          if (res.data.code == 0) {
-            resolve(res.data.data)
-          } else {
-            resolve(false)
-          }
-        }, () => {
-          resolve(false)
-        })
-      })
-    },
-  }
-}
-</script>
\ No newline at end of file
diff --git a/src/views/h5/verify/noAccess.vue b/src/views/h5/verify/noAccess.vue
deleted file mode 100644
index 05aef8d..0000000
--- a/src/views/h5/verify/noAccess.vue
+++ /dev/null
@@ -1,28 +0,0 @@
-<template>
-  <div class="content">
-    <el-image style="width: 150px" fit="contain" :src="$getImageUrl('/h5/noVerify.png')"></el-image>
-    <el-row style="margin-top: 40px;">
-      <el-text class="text-center">鎮ㄩ潪鏈�冪偣璧勮川瀹℃牳鐨勬牳楠屽憳锛屾棤娉曟牳楠岋紝璇疯仈绯诲伐浣滀汉鍛樼‘璁ゃ��</el-text>
-    </el-row>
-  </div>
-</template>
-<script>
-export default {
-  data() {
-    return {
-
-    }
-  }
-}
-</script>
-<style lang="scss" scoped>
-.content {
-  padding: 60px;
-  width: 100%;
-  height: 100%;
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-  align-items: center;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/login/index.vue b/src/views/login/index.vue
index edaec00..120f1d5 100644
--- a/src/views/login/index.vue
+++ b/src/views/login/index.vue
@@ -32,11 +32,17 @@
             </template>
           </el-input>
         </el-form-item>
-        <el-form-item prop="agreement" style="height: 30px;">
+        <!-- <el-form-item prop="agreement" style="height: 30px;">
           <el-checkbox v-model="form.agreement" label="鍚屾剰xxx鏈嶅姟鍗忚" size="large" />
-        </el-form-item>
+        </el-form-item> -->
 
-        <el-button class="mt-1" @click="submitLogin()" :loading="loginLoading" type="primary" size="large" style="width: 100%;">
+        <el-button 
+          class="mt-3" 
+          @click="submitLogin()" 
+          :loading="loginLoading" 
+          type="primary" size="large" 
+          style="width: 100%;"
+        >
           <el-text class="text-lg text-white">鐧诲綍</el-text>
         </el-button>
       </el-form>
@@ -55,8 +61,18 @@
             <el-radio :value="0">濂�</el-radio>
           </el-radio-group>
         </el-form-item>
-        <el-form-item prop="idCard">
-          <el-input v-model="form.idCard" placeholder="璇疯緭鍏ヨ韩浠借瘉鍙�" />
+        <el-form-item prop="idCardType">
+          <el-select v-model="form.idCardType" placeholder="璇佷欢绫诲瀷">
+            <el-option
+              v-for="item in idCardTypeItems"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="idCard" :rules="[$rules.required('璇疯緭鍏ヨ瘉浠跺彿鐮�'), form.idCardType == 1 ? $rules.idCard('璇疯緭鍏ユ纭殑韬唤璇佸彿'): '' ]">
+          <el-input v-model="form.idCard" placeholder="璇疯緭鍏ヨ瘉浠跺彿鐮�" />
         </el-form-item>
         <el-form-item prop="mobile">
           <el-input v-model="form.mobile" placeholder="璇疯緭鍏ユ墜鏈哄彿" />
@@ -79,11 +95,17 @@
             </template>
           </el-input>
         </el-form-item>
-        <el-form-item prop="agreement" style="height: 30px;">
+        <!-- <el-form-item prop="agreement" style="height: 30px;">
           <el-checkbox v-model="form.agreement" label="鍚屾剰xxx鏈嶅姟鍗忚" size="large" />
-        </el-form-item>
+        </el-form-item> -->
 
-        <el-button class="mt-1" @click="submitRegister()" type="primary" size="large" style="width: 100%;">
+        <el-button 
+          class="mt-5"
+          :loading="registerLoading"
+          @click="submitRegister()" 
+          type="primary" size="large" 
+          style="width: 100%;"
+        >
           <el-text class="text-lg text-white">娉ㄥ唽</el-text>
         </el-button>
       </el-form>
@@ -91,7 +113,7 @@
       <el-row class="mt-7" justify="center">
         <el-button v-if="loginType!='register'" text type="primary" @click="changeLoginType('register')">娉ㄥ唽璐﹀彿</el-button>
         <el-divider v-if="loginType!='register'" direction="vertical" class="m-0 mt-1 mx-4" style="height: 24px !important" />
-        <el-button v-if="loginType!='qrCode'" text type="primary" @click="changeLoginType('qrCode')">浜岀淮鐮佺櫥褰�</el-button>
+        <el-button v-if="loginType!='qrCode'" text type="primary" @click="changeLoginType('qrCode')">寰俊鎵爜鐧诲綍</el-button>
         <el-divider v-if="loginType=='register'" direction="vertical" class="m-0 mt-1 mx-4" style="height: 24px !important" />
         <el-button v-if="loginType!='mobile'" text type="primary" @click="changeLoginType('mobile')">鎵嬫満鍙风櫥褰�</el-button>
       </el-row>
@@ -103,6 +125,8 @@
 import { useLoginStore } from '@/stores/login.js'
 import { useSessionStore } from '@/stores/session.js'
 import { storeToRefs } from 'pinia';
+import idCardTypeItems from '@/assets/json/idCardTypeItems.json'
+import { tokenUtils } from '@/utils/axios.js';
 export default {
   components: {},
   setup() {
@@ -116,14 +140,15 @@
       form: {
         name: '',
         sex: 1,
+        idCardType: 1,
         idCard: '',
-        mobile: '13537719675',
+        mobile: '',
         code: '',
         agreement: false
       },
+      idCardTypeItems: idCardTypeItems,
       rules: {
         name: [ this.$rules.required('璇疯緭鍏ュ鍚�') ],
-        idCard: [ this.$rules.required('璇疯緭鍏ヨ韩浠借瘉鍙�') ],
         mobile: [ this.$rules.required('璇疯緭鍏ユ墜鏈哄彿'), this.$rules.phone() ],
         code: [ this.$rules.required('璇峰~鍐欓獙璇佺爜'), this.$rules.code() ],
         agreement: [ this.$rules.checkbox('璇烽槄璇诲苟鍕鹃�夊悓鎰忓崗璁�') ]
@@ -131,7 +156,8 @@
       countdown: 180,
       countdownInterval: null,
       sendCodeLoading: false,
-      loginLoading: false
+      loginLoading: false,
+      registerLoading: false
     }
   },
   computed: {
@@ -151,15 +177,45 @@
     this.clearCountdownInterval()
   },
   watch: {
-    
+    loginDialogVisible: function(val) {
+      if (!val) {
+        this.clearCountdownInterval()
+      }
+    }
   },
   methods: {
     async sendCode() {
       try {
-        await this.$refs.accountForm.validateField('mobile')
-        this.startCountdownInterval()
-        this.$message.success('宸插彂閫侀獙璇佺爜锛岃娉ㄦ剰鏌ユ敹')
+        let ref = null
+        let scene = 0
+        if (this.loginType == 'mobile') {
+          ref = this.$refs.accountForm
+          scene = 33
+        } else if (this.loginType == 'register') {
+          ref = this.$refs.registerForm
+          scene = 32
+        }
+        const validate = await ref.validateField('mobile')
+        if (validate) {
+          const data = {
+            captchaVerification: '',
+            mobile: this.form.mobile,
+            scene: scene,
+          }
+          this.sendCodeLoading = true
+          this.$axios.post('/system/auth/send-sms-code', data).then(res => {
+            if (res.data.code == 0) {
+              this.startCountdownInterval()
+              this.$message.success('宸插彂閫侀獙璇佺爜锛岃娉ㄦ剰鏌ユ敹')
+            } else {
+              this.$message.error(res.data.msg || '鑾峰彇楠岃瘉鐮佸け璐�')
+            }
+          }).finally(() => {
+            this.sendCodeLoading = false
+          })
+        }
       } catch (error) {
+        console.log(error)
         this.$message.error('璇疯緭鍏ユ墜鏈哄彿鐮�')
       }
     },
@@ -183,29 +239,57 @@
       try {
         await this.$refs.accountForm.validate()
         this.loginLoading = true
-        setTimeout(() => {
-          localStorage.setItem('accessToken', '123456')
-          this.getUserInfo()
-          this.$message.success('鐧诲綍鎴愬姛')
-          this.loginDialogVisible = false
+        const data = {
+          mobile: this.form.mobile,
+          code: this.form.code
+        }
+        this.$axios.post('/system/kw/examinee/login', data).then(res => {
+          if (res.data.code == 0) {
+            const resData = res.data.data || {}
+              tokenUtils.setTokens(resData.accessToken, resData.refreshToken)
+              this.getUserInfo()
+              this.$message.success('鐧诲綍鎴愬姛')
+              this.loginDialogVisible = false
+          } else {
+            this.$message.error(res.data.msg)
+          }
+        }).finally(() => {
           this.loginLoading = false
-
-        }, 1000)
+        })
       } catch (error) {
         console.log()
       }
     },
     getUserInfo() {
-      this.setUserInfo({
-        id: '123456',
-        username: '榛勫┓濠�',
+      this.$axios.get('/system/kw/examinee/profile').then(res => {
+        if (res.data.code == 0) {
+          const resData = res.data.data || {}
+          this.setUserInfo(resData)
+        } else {
+          this.$message.error(res.data.msg)
+        }
       })
     },
     async submitRegister() {
       try {
-        await this.$refs.registerForm.validate()
+        const validate = await this.$refs.registerForm.validate()
+        if (validate) {
+          const data = { ...this.form }
+          this.$axios.post('/system/kw/examinee/register', data).then(res => {
+            if (res.data.code == 0) {
+              const resData = res.data.data || {}
+              tokenUtils.setTokens(resData.accessToken, resData.refreshToken)
+              this.getUserInfo()
+              this.$message.success('娉ㄥ唽鎴愬姛')
+              this.loginDialogVisible = false
+            } else {
+              this.$message.error(res.data.msg)
+            }
+          })
+        }
       } catch (error) {
-        console.log()
+        console.log(error)
+        this.$message.error('璇锋鏌ュ繀濉瓧娈�')
       }
     },
     changeLoginType(type) {
diff --git a/src/views/main/appraisalPlan/index.vue b/src/views/main/appraisalPlan/index.vue
index b7f0a51..3c96cd2 100644
--- a/src/views/main/appraisalPlan/index.vue
+++ b/src/views/main/appraisalPlan/index.vue
@@ -227,10 +227,28 @@
   computed: {
     filterList() {
       return this.planList.slice((this.filter.pageNo-1)*this.filter.pageSize, this.filter.pageNo*this.filter.pageSize)
+    },
+    query() {
+      return this.$route.query
+    }
+  },
+  watch: {
+    signupDialogVisible: {
+      handler: function(val) {
+        if (!val) {
+          this.$router.replace({ path: this.$route.path })
+        }
+      }
     }
   },
   created() {
     this.getPlanList()
+    
+  },
+  mounted() {
+    if (this.query.signupDialogFlag == '1') {
+      this.signup({ id: this.query.appraisalId })
+    }
   },
   methods: {
     getPlanList() {
@@ -331,13 +349,18 @@
       }, 400)
     },
     signup(item) {
-      if (this.userInfo.id) {
-        this.signupDialogVisible = true
-        this.currentPlan = item
-      } else {
-        this.loginDialogVisible = true
-        this.$message.primary('璇峰厛鐧诲綍')
-      }
+      this.signupDialogVisible = true
+      this.currentPlan = item
+      this.$router.replace({ path: this.$route.path, query: { appraisalId: item.id, signupDialogFlag: 1 } })
+      // if (this.userInfo.id) {
+      //   this.signupDialogVisible = true
+      //   this.currentPlan = item
+      //   this.$router.replace({ path: this.$route.path, query: { appraisalId: item.id, signupDialogFlag: 1 } })
+      // }
+      // else {
+      //   this.loginDialogVisible = true
+      //   this.$message.primary('璇峰厛鐧诲綍')
+      // }
     }
   }
 }
diff --git a/src/views/main/center/index.vue b/src/views/main/center/index.vue
index c2c52c9..3b78f86 100644
--- a/src/views/main/center/index.vue
+++ b/src/views/main/center/index.vue
@@ -32,25 +32,28 @@
             <el-col :span="22">
               <div v-if="activeTab=='toExam'" class="p-4 px-6">
                 <el-row align="middle">
-                  <el-text class="font-medium">濮撳悕锛歿{ form.name }}</el-text>
+                  <el-text class="font-medium">濮撳悕锛歿{ userInfo.nickname }}</el-text>
                   <el-button text class="ml-2">
                     <Icon icon="ix:pen-filled" width="18" height="18"  style="color: black" />
                   </el-button>
                 </el-row>
                 <el-row align="middle">
-                  <el-text class="font-medium">鎬у埆锛歿{ form.gender }}</el-text>
+                  <el-text class="font-medium">鎬у埆锛歿{ sexText }}</el-text>
                   <el-button text class="ml-2">
                     <Icon icon="ix:pen-filled" width="18" height="18"  style="color: black" />
                   </el-button>
                 </el-row>
                 <el-row align="middle">
-                  <el-text class="font-medium">鎵嬫満鍙凤細{{ form.mobilePhone }}</el-text>
+                  <el-text class="font-medium">鎵嬫満鍙凤細{{ userInfo.mobile }}</el-text>
                   <el-button text class="ml-2">
                     <Icon icon="ix:pen-filled" width="18" height="18"  style="color: black" />
                   </el-button>
                 </el-row>
+                <el-row align="middle" class="my-1">
+                  <el-text class="font-medium">璇佷欢绫诲瀷锛歿{ idCardTypeText }}</el-text>
+                </el-row>
                 <el-row align="middle">
-                  <el-text class="font-medium">韬唤璇佸彿锛歿{ form.idCard }}</el-text>
+                  <el-text class="font-medium">璇佷欢姝e弽闈細{{ userInfo.idCard }}</el-text>
                   <el-button text class="ml-2">
                     <Icon icon="ix:pen-filled" width="18" height="18"  style="color: black" />
                   </el-button>
@@ -59,13 +62,13 @@
                   <el-text class="font-medium">韬唤璇佹鍙嶉潰锛�</el-text>
                 </el-row>
                 <el-row>
-                  <UploadIdCard v-model="form.idCardFace" :accept="['jpg', 'png']" type="face"></UploadIdCard>
-                  <UploadIdCard v-model="form.idCardEmblem" :accept="['jpg', 'png']" type="emblem"></UploadIdCard>
+                  <UploadIdCard v-model="userInfo.idCardFace" :accept="['jpg', 'png']" type="face"></UploadIdCard>
+                  <UploadIdCard v-model="userInfo.idCardEmblem" :accept="['jpg', 'png']" type="emblem"></UploadIdCard>
                 </el-row>
                 <el-row align="middle" class="mt-2">
                   <el-text class="font-medium">璇佷功/鍑嗚�冭瘉澶村儚锛�</el-text>
                 </el-row>
-                <UploadBtn v-model="form.certificateAvatar" listType="picture-card" :accept="['jpg', 'png']" ></UploadBtn>
+                <UploadBtn v-model="userInfo.certificateAvatar" listType="picture-card" :accept="['jpg', 'png']" ></UploadBtn>
 
                 <el-row class="mt-5">
                   <el-text>缁戝畾寰俊锛氭殏鏈粦瀹氬井淇�</el-text>
@@ -121,7 +124,12 @@
     }
   },
   computed: {
-    
+    sexText() {
+      return this.$property.sex[`key_${this.userInfo.sex}`]
+    },
+    idCardTypeText() {
+      return this.$property.idCardType[`key_${this.userInfo.idCardType}`]
+    }
   },
   watch: {
     activeTab: {
diff --git a/src/views/main/components/CustomLoading.vue b/src/views/main/components/CustomLoading.vue
new file mode 100644
index 0000000..f6ccac9
--- /dev/null
+++ b/src/views/main/components/CustomLoading.vue
@@ -0,0 +1,86 @@
+<template>
+  <div class="loading-content">
+    <div class="loading-spinner">
+      <div class="spinner-ring"></div>
+      <div class="spinner-ring"></div>
+      <div class="spinner-ring"></div>
+    </div>
+    <div class="loading-text">鍔犺浇涓�...</div>
+  </div>
+</template>
+
+<style>
+.loading-container {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.loading-content {
+  text-align: center;
+}
+
+.loading-spinner {
+  position: relative;
+  width: 60px;
+  height: 60px;
+  margin: 0 auto 16px;
+}
+
+.spinner-ring {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  border: 3px solid transparent;
+  border-top-color: #007aff;
+  border-radius: 50%;
+  animation: spin 1.2s linear infinite;
+}
+
+.spinner-ring:nth-child(1) {
+  animation-delay: 0s;
+}
+
+.spinner-ring:nth-child(2) {
+  width: 80%;
+  height: 80%;
+  top: 10%;
+  left: 10%;
+  animation-delay: 0.15s;
+  border-top-color: #66b1ff;
+}
+
+.spinner-ring:nth-child(3) {
+  width: 60%;
+  height: 60%;
+  top: 20%;
+  left: 20%;
+  animation-delay: 0.3s;
+  border-top-color: #a0cfff;
+}
+
+@keyframes spin {
+  from {
+    transform: rotate(0deg);
+  }
+  to {
+    transform: rotate(360deg);
+  }
+}
+
+.loading-text {
+  font-size: 14px;
+  color: #666;
+  animation: pulse 1.5s ease-in-out infinite;
+}
+
+@keyframes pulse {
+  0%, 100% {
+    opacity: 0.6;
+  }
+  50% {
+    opacity: 1;
+  }
+}
+
+</style>
\ No newline at end of file
diff --git a/src/views/main/components/MyFooter.vue b/src/views/main/components/MyFooter.vue
index 5c60bf3..1dadf86 100644
--- a/src/views/main/components/MyFooter.vue
+++ b/src/views/main/components/MyFooter.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="custom-footer">
-    <el-row justify="center">
+    <!-- <el-row justify="center">
       <el-select 
         v-for="(item,index) in selectList"
         v-model="item.value" 
@@ -16,7 +16,7 @@
           :value="item.value"
         />
       </el-select>
-    </el-row>
+    </el-row> -->
     <el-row>
       <el-text class="text-white font-medium text-default">
         漏2025 娣卞湷甯備紒楣呯綉缁滅鎶�鏈夐檺鍏徃 绮CP澶�15026064鍙仿�  绮ゅ叕缃戝畨澶� 44030502007327 鍙�
@@ -58,7 +58,7 @@
 <style scoped>
 .custom-footer {
   width: 100%;
-  min-height: 185px !important;
+  min-height: 60px !important;
   display: flex;
   padding: 20px;
   flex-direction: column;
diff --git a/src/views/main/components/MyHeader.vue b/src/views/main/components/MyHeader.vue
index 4d65e5f..745435d 100644
--- a/src/views/main/components/MyHeader.vue
+++ b/src/views/main/components/MyHeader.vue
@@ -5,7 +5,7 @@
       <el-dropdown v-if="userInfo.id" placement="bottom">
         <el-row  align="middle">
           <Icon icon="fa:user-circle" width="22" height="22" class="mr-2"  style="color: #fff" />
-          <el-text class="text-white cursor-p text-lg font-bold">榛勫┓濠�</el-text>
+          <el-text class="text-white cursor-p text-lg font-bold">{{ userInfo.nickname }}</el-text>
           <Icon icon="flowbite:caret-down-solid" width="22" height="22" class="ml-2"  style="color: #fff" />
         </el-row>
         <template #dropdown>
@@ -15,8 +15,8 @@
           </el-dropdown-menu>
         </template>
       </el-dropdown>
-      <el-button  v-else color="#007AFF">
-        <el-text class="text-white cursor-p text-lg font-bold" @click="login">鐧� 褰�</el-text>
+      <el-button @click="login" v-else color="#007AFF">
+        <el-text class="text-white cursor-p text-lg font-bold">鐧� 褰�</el-text>
       </el-button>
     </el-row>
   </div>
@@ -26,7 +26,7 @@
 import { useSessionStore } from '@/stores/session.js' 
 import { useLoginStore } from '@/stores/login.js'
 import { storeToRefs } from 'pinia';
-
+import { tokenUtils } from '@/utils/axios.js'
 export default {
   setup() {
     const { loginDialogVisible } = storeToRefs(useLoginStore())
@@ -36,13 +36,13 @@
   },
   data() {
     return {
-      
     }
   },
   created() {
-    const token =  localStorage.getItem('accessToken')
-    if (token) {
+    if (tokenUtils.getAccessToken()) {
       this.getUserInfo()
+    } else {
+      this.$emit('getUserInfoFlag')
     }
   },
   methods: {
@@ -50,12 +50,16 @@
       this.loginDialogVisible = true
     },
     getUserInfo() {
-      setTimeout(() => {
-        this.setUserInfo({
-          id: '12345',
-          username: '榛勫┓濠�'
-        })
-      }, 1000)
+      this.$axios.get('/system/kw/examinee/profile').then(res => {
+        if (res.data.code == 0) {
+          const resData = res.data.data || {}
+          this.setUserInfo(resData)
+        } else {
+          this.$message.error(res.data.msg)
+        }
+      }).finally(() => {
+        this.$emit('getUserInfoFlag')
+      })
     },
     gotoCenter() {
       this.$router.push('/main/center')
@@ -64,9 +68,12 @@
       this.$messageBox.confirm('纭畾瑕侀��鍑虹櫥褰曞悧', '鎻愮ず', 
       { confirmButtonText: '纭畾', cancelButtonText: '鍙栨秷', type: 'error' }).then(res => {
         if (res == 'confirm') {
-          localStorage.removeItem('accessToken')
+          tokenUtils.clearTokens()
           this.setUserInfo({})
           this.$message.success('閫�鍑虹櫥褰�')
+          if (this.$route.meta.loginRequired) {
+            this.$router.replace('/main/home')
+          }
         }
       })
     }
diff --git a/src/views/main/index.vue b/src/views/main/index.vue
index 6372498..c7fc6de 100644
--- a/src/views/main/index.vue
+++ b/src/views/main/index.vue
@@ -1,15 +1,17 @@
 <template>
   <el-container direction="vertical" style="height: 100vh;">
     <el-header class="p-0">
-      <MyHeader></MyHeader>
+      <MyHeader @getUserInfoFlag="getUserInfoFlag=true"></MyHeader>
     </el-header>
     <el-main :style="{height: mainHeight}" class="custom-main p-0" >
-      <div>
+      <div v-if="getUserInfoFlag">
         <router-view></router-view>
+      </div>
+      <div v-else :style="{'min-height': `${height-150}px`}" class="loading-container">
+        <CustomLoading />
       </div>
       <MyFooter></MyFooter>
     </el-main>
-
     <LoginDialog />
   </el-container>
 </template>
@@ -18,21 +20,37 @@
 import MyHeader from '@/views/main/components/MyHeader.vue'
 import MyFooter from '@/views/main/components/MyFooter.vue'
 import LoginDialog from '@/views/login/index.vue'
+import CustomLoading from '@/views/main/components/CustomLoading.vue'
 export default {
   components: {
     MyHeader,
     MyFooter,
-    LoginDialog
+    LoginDialog,
+    CustomLoading
   },
   setup() {
     const { height } = useWindowSize()
     return { height }
   },
+  data() {
+    return {
+      getUserInfoFlag: false
+    }
+  },
   computed: {
     mainHeight: function() {
       return `${this.height - 60}px`
     }
+  },
+  created() {
+    this.getUserInfo()
+  },
+  methods: {
+    getUserInfo() {
+      
+    }
   }
+
 }
 </script>
 

--
Gitblit v1.8.0