diff --git a/.env.development b/.env.development index 4029ed4..e9a402f 100644 --- a/.env.development +++ b/.env.development @@ -1,8 +1,8 @@ # 开发环境标识(Vite 内置变量,无需修改) NODE_ENV = development -# 开发环境接口基础地址(对应你配置的 http://18.167.120.9:8085/api) -VITE_API_BASE_URL = http://18.167.120.9:8085/api +# 开发环境接口基础地址(对应你配置的 https://adminapi.nplus.top/api) +VITE_API_BASE_URL = https://adminapi.nplus.top/api # 请求超时时间(毫秒) VITE_REQUEST_TIMEOUT = 10000 diff --git a/.env.production b/.env.production index 7184e14..61f9fd9 100644 --- a/.env.production +++ b/.env.production @@ -2,7 +2,7 @@ NODE_ENV = production # 生产环境接口基础地址 -VITE_API_BASE_URL = http://18.167.120.9:8085/api +VITE_API_BASE_URL = https://adminapi.nplus.top/api # 请求超时时间(毫秒) VITE_REQUEST_TIMEOUT = 10000 diff --git a/package.json b/package.json index df1e679..f29f8fd 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "crypto-js": "^4.2.0", "dayjs": "^1.11.20", "element-plus": "^2.13.2", + "face-api.js": "^0.22.2", "file-saver": "^2.0.5", "mqtt": "^5.15.1", "pinia": "^3.0.4", @@ -42,6 +43,7 @@ "@types/file-saver": "^2.0.7", "@types/node": "^24.10.13", "@types/xlsx": "^0.0.36", + "@vitejs/plugin-basic-ssl": "^2.3.0", "@vitejs/plugin-vue": "^6.0.4", "@vue/eslint-config-typescript": "^14.7.0", "@vue/tsconfig": "^0.8.1", diff --git a/public/models/face/face_landmark_68_model-shard1 b/public/models/face/face_landmark_68_model-shard1 new file mode 100644 index 0000000..fcaca47 Binary files /dev/null and b/public/models/face/face_landmark_68_model-shard1 differ diff --git a/public/models/face/face_landmark_68_model-weights_manifest.json b/public/models/face/face_landmark_68_model-weights_manifest.json new file mode 100644 index 0000000..0fe2707 --- /dev/null +++ b/public/models/face/face_landmark_68_model-weights_manifest.json @@ -0,0 +1 @@ +[{"weights":[{"name":"dense0/conv0/filters","shape":[3,3,3,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004853619781194949,"min":-0.5872879935245888}},{"name":"dense0/conv0/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004396426443960153,"min":-0.7298067896973853}},{"name":"dense0/conv1/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00635151559231328,"min":-0.5589333721235686}},{"name":"dense0/conv1/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009354315552057004,"min":-1.2628325995276957}},{"name":"dense0/conv1/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0029380727048013726,"min":-0.5846764682554731}},{"name":"dense0/conv2/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0049374802439820535,"min":-0.6171850304977566}},{"name":"dense0/conv2/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009941946758943446,"min":-1.3421628124573652}},{"name":"dense0/conv2/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0030300481062309416,"min":-0.5272283704841838}},{"name":"dense0/conv3/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005672684837790097,"min":-0.7431217137505026}},{"name":"dense0/conv3/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010712201455060173,"min":-1.5639814124387852}},{"name":"dense0/conv3/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0030966934035806097,"min":-0.3839899820439956}},{"name":"dense1/conv0/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0039155554537679636,"min":-0.48161332081345953}},{"name":"dense1/conv0/pointwise_filter","shape":[1,1,32,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01023082966898002,"min":-1.094698774580862}},{"name":"dense1/conv0/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0027264176630506327,"min":-0.3871513081531898}},{"name":"dense1/conv1/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004583378632863362,"min":-0.5454220573107401}},{"name":"dense1/conv1/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00915846403907327,"min":-1.117332612766939}},{"name":"dense1/conv1/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003091680419211294,"min":-0.5966943209077797}},{"name":"dense1/conv2/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005407439727409214,"min":-0.708374604290607}},{"name":"dense1/conv2/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00946493943532308,"min":-1.2399070660273235}},{"name":"dense1/conv2/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004409168514550901,"min":-0.9788354102303}},{"name":"dense1/conv3/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004478132958505668,"min":-0.6493292789833219}},{"name":"dense1/conv3/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.011063695888893277,"min":-1.2501976354449402}},{"name":"dense1/conv3/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003909627596537272,"min":-0.6646366914113363}},{"name":"dense2/conv0/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003213915404151468,"min":-0.3374611174359041}},{"name":"dense2/conv0/pointwise_filter","shape":[1,1,64,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010917326048308728,"min":-1.4520043644250609}},{"name":"dense2/conv0/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002800439152063108,"min":-0.38085972468058266}},{"name":"dense2/conv1/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0050568851770139206,"min":-0.6927932692509071}},{"name":"dense2/conv1/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01074961213504567,"min":-1.3222022926106174}},{"name":"dense2/conv1/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0030654204242369708,"min":-0.5487102559384177}},{"name":"dense2/conv2/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00591809165244009,"min":-0.917304206128214}},{"name":"dense2/conv2/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01092823346455892,"min":-1.366029183069865}},{"name":"dense2/conv2/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002681120470458386,"min":-0.36463238398234055}},{"name":"dense2/conv3/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0048311497650894465,"min":-0.5797379718107336}},{"name":"dense2/conv3/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.011227761062921263,"min":-1.4483811771168429}},{"name":"dense2/conv3/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0034643323982463162,"min":-0.3360402426298927}},{"name":"dense3/conv0/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003394978887894574,"min":-0.49227193874471326}},{"name":"dense3/conv0/pointwise_filter","shape":[1,1,128,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010051267287310432,"min":-1.2765109454884247}},{"name":"dense3/conv0/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003142924752889895,"min":-0.4588670139219247}},{"name":"dense3/conv1/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00448304671867221,"min":-0.5872791201460595}},{"name":"dense3/conv1/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.016063522357566685,"min":-2.3613377865623026}},{"name":"dense3/conv1/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00287135781026354,"min":-0.47664539650374765}},{"name":"dense3/conv2/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006002906724518421,"min":-0.7923836876364315}},{"name":"dense3/conv2/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.017087187019048954,"min":-1.6061955797906016}},{"name":"dense3/conv2/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003124481205846749,"min":-0.46242321846531886}},{"name":"dense3/conv3/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006576311588287353,"min":-1.0193282961845398}},{"name":"dense3/conv3/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.015590153955945782,"min":-1.99553970636106}},{"name":"dense3/conv3/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004453541601405424,"min":-0.6546706154065973}},{"name":"fc/weights","shape":[256,136],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010417488509533453,"min":-1.500118345372817}},{"name":"fc/bias","shape":[136],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0025084222648658005,"min":0.07683877646923065}}],"paths":["face_landmark_68_model-shard1"]}] \ No newline at end of file diff --git a/public/models/face/tiny_face_detector_model-shard1 b/public/models/face/tiny_face_detector_model-shard1 new file mode 100644 index 0000000..a3f113a Binary files /dev/null and b/public/models/face/tiny_face_detector_model-shard1 differ diff --git a/public/models/face/tiny_face_detector_model-weights_manifest.json b/public/models/face/tiny_face_detector_model-weights_manifest.json new file mode 100644 index 0000000..7d3b222 --- /dev/null +++ b/public/models/face/tiny_face_detector_model-weights_manifest.json @@ -0,0 +1 @@ +[{"weights":[{"name":"conv0/filters","shape":[3,3,3,16],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009007044399485869,"min":-1.2069439495311063}},{"name":"conv0/bias","shape":[16],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005263455241334205,"min":-0.9211046672334858}},{"name":"conv1/depthwise_filter","shape":[3,3,16,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004001977630690033,"min":-0.5042491814669441}},{"name":"conv1/pointwise_filter","shape":[1,1,16,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.013836609615999109,"min":-1.411334180831909}},{"name":"conv1/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0015159862590771096,"min":-0.30926119685173037}},{"name":"conv2/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002666276225856706,"min":-0.317286870876948}},{"name":"conv2/pointwise_filter","shape":[1,1,32,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.015265831292844286,"min":-1.6792414422128714}},{"name":"conv2/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0020280554598453,"min":-0.37113414915168985}},{"name":"conv3/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006100742489683862,"min":-0.8907084034938438}},{"name":"conv3/pointwise_filter","shape":[1,1,64,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.016276211832083907,"min":-2.0508026908425725}},{"name":"conv3/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003394414279975143,"min":-0.7637432129944072}},{"name":"conv4/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006716050119961009,"min":-0.8059260143953211}},{"name":"conv4/pointwise_filter","shape":[1,1,128,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.021875603993733724,"min":-2.8875797271728514}},{"name":"conv4/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0041141652009066415,"min":-0.8187188749804216}},{"name":"conv5/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008423839597141042,"min":-0.9013508368940915}},{"name":"conv5/pointwise_filter","shape":[1,1,256,512],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.030007277283014035,"min":-3.8709387695088107}},{"name":"conv5/bias","shape":[512],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008402082966823203,"min":-1.4871686851277068}},{"name":"conv8/filters","shape":[1,1,512,25],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.028336129469030042,"min":-4.675461362389957}},{"name":"conv8/bias","shape":[25],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002268134028303857,"min":-0.41053225912299807}}],"paths":["tiny_face_detector_model-shard1"]}] \ No newline at end of file diff --git a/src/api/modules/livenessVerification.ts b/src/api/modules/livenessVerification.ts new file mode 100644 index 0000000..ec816ee --- /dev/null +++ b/src/api/modules/livenessVerification.ts @@ -0,0 +1,40 @@ +import { request } from '@/api' + + + + +/** + * 上传实时照片 + */ +export async function uploadCard(params: any): Promise { + return request.post('/aws/uploadCard', params, { + headers: { + 'Content-Type': 'multipart/form-data', // 表单上传必须的头 + }, + }) +} + +/** + * 上传实时照片 + */ +export async function uploadLivePhoto(params: any): Promise { + return request.post('/aws/uploadLivePhoto', params, { + headers: { + 'Content-Type': 'multipart/form-data', // 表单上传必须的头 + } + }) +} + +/** + * 活体检测 + */ +export async function checkLiveness(): Promise { + return request.post('/aws/checkLiveness') +} + +/** + * 验证身份照片 + */ +export async function verifyCard(): Promise { + return request.post('/aws/verifyCard') +} \ No newline at end of file diff --git a/src/router/index.ts b/src/router/index.ts index 39dfb2f..6ab41a4 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -70,6 +70,18 @@ const routes = [ }, ], }, + { + path: '/realName', + name: '实名认证', + component: () => import('@/views/realName/index.vue'), + meta: { requiresAuth: true, title: '实名认证', keepAlive: false }, + }, + { + path: '/livenessVerification', + name: '活体认证', + component: () => import('@/views/livenessVerification/index.vue'), + meta: { requiresAuth: true, title: '活体认证', keepAlive: false }, + }, { path: '/:pathMatch(.*)*', redirect: () => { diff --git a/src/stores/modules/user.ts b/src/stores/modules/user.ts index 21dce0c..36dadd0 100644 --- a/src/stores/modules/user.ts +++ b/src/stores/modules/user.ts @@ -1,201 +1,218 @@ -import { getStorage, setStorage, removeStorage } from '@/utils/storage'; -import { loginApi, registerApi, logoutApi, forgotPasswordApi, changePasswordApi, sendCodeApi } from '@/api/modules/user'; -import type { LoginParams, RegisterParams, ForgotPasswordParams, ChangePasswordParams, SendCodeParams } from '@/api/types/user'; -import type { UserInfo, MenuItem, PermissionItem } from '@/stores/types/user'; -import { formatMenuToElMenu, type ElMenuItem } from '@/utils/menuFormat'; +import { getStorage, setStorage, removeStorage } from '@/utils/storage' +import { + loginApi, + registerApi, + logoutApi, + forgotPasswordApi, + changePasswordApi, + sendCodeApi, +} from '@/api/modules/user' +import type { + LoginParams, + RegisterParams, + ForgotPasswordParams, + ChangePasswordParams, + SendCodeParams, +} from '@/api/types/user' +import type { UserInfo, MenuItem, PermissionItem } from '@/stores/types/user' +import { formatMenuToElMenu, type ElMenuItem } from '@/utils/menuFormat' import { handleRouter, setRouter } from '@/router/handleRouter.ts' // 定义用户 Store export const useUserStore = defineStore('user', () => { - const router = useRouter(); + const router = useRouter() // ========== 状态定义(与后端返回数据对应) ========== // 用户/菜单和权限状态 - const userInfo = ref(getStorage('userInfo') || null); - const token = ref(getStorage('token') || ''); - const menusInfo = ref(getStorage('menusInfo') || []); - const permissionsInfo = ref(getStorage('permissionsInfo') || []); + const userInfo = ref(getStorage('userInfo') || null) + const token = ref(getStorage('token') || '') + const menusInfo = ref(getStorage('menusInfo') || []) + const permissionsInfo = ref(getStorage('permissionsInfo') || []) // ========== 计算属性 ========== - const isLoggedIn = computed(() => !!token.value); + const isLoggedIn = computed(() => !!token.value) // const permissionKeys = computed(() => permissions.value.map(item => item.name)); // 格式化后的 el-menu 数据(自动更新) - const sideMenu = computed(() => formatMenuToElMenu(menusInfo.value)); -/** - * 设置用户信息 - * 作用:根据后端返回数据设置用户状态 + 本地存储 - */ -const setUserInfo = (set: any) => { - token.value = set.user.token; - userInfo.value = set.user; - menusInfo.value = set.menus_info; - permissionsInfo.value = set.permissions_info; + const sideMenu = computed(() => formatMenuToElMenu(menusInfo.value)) + /** + * 设置用户信息 + * 作用:根据后端返回数据设置用户状态 + 本地存储 + */ + const setUserInfo = (set: any) => { + token.value = set.user.token + userInfo.value = set.user + menusInfo.value = set.menus_info + permissionsInfo.value = set.permissions_info - const btnAuth = (set.permissions_info || []).map((item: any) => item.code).filter((item: any) => item) + const btnAuth = (set.permissions_info || []) + .map((item: any) => item.code) + .filter((item: any) => item) - // 保存到本地存储 - setStorage('token', set.user.token); - setStorage('userInfo', set.user); - setStorage('menusInfo', set.menus_info); - setStorage('permissionsInfo', set.permissions_info); - setStorage('btnAuth', btnAuth) - - setRouter() - -}; - -/** - * 清空用户信息(核心复用方法) - * 作用:重置所有用户相关状态 + 清除本地存储 - */ -const clearUserInfo = () => { - // 重置 Pinia 中的状态 - token.value = ''; - userInfo.value = null; - menusInfo.value = []; - permissionsInfo.value = []; - - // 清除本地存储的用户数据 - removeStorage('token'); - removeStorage('userInfo'); - removeStorage('menusInfo'); - removeStorage('permissionsInfo'); - removeStorage('device_no'); - console.log('用户信息已清空'); -}; - -/** - * 登录方法 - * @param params 登录参数 - */ -const login = async (params: LoginParams) => { - try { - const res = await loginApi(params); - if (res.isUserNotExist) { - // 用户不存在,跳转到注册页面 - router.push('/user/register'); - return; - } - setUserInfo(res); - // 跳转到首页 - router.push('/'); - } catch (error) { - console.error('登录失败', error); - - throw error; + // 保存到本地存储 + setStorage('token', set.user.token) + setStorage('userInfo', set.user) + setStorage('menusInfo', set.menus_info) + setStorage('permissionsInfo', set.permissions_info) + setStorage('btnAuth', btnAuth) + setRouter() } -}; -/** + /** + * 清空用户信息(核心复用方法) + * 作用:重置所有用户相关状态 + 清除本地存储 + */ + const clearUserInfo = () => { + // 重置 Pinia 中的状态 + token.value = '' + userInfo.value = null + menusInfo.value = [] + permissionsInfo.value = [] + + // 清除本地存储的用户数据 + removeStorage('token') + removeStorage('userInfo') + removeStorage('menusInfo') + removeStorage('permissionsInfo') + removeStorage('device_no') + console.log('用户信息已清空') + } + + /** + * 登录方法 + * @param params 登录参数 + */ + const login = async (params: LoginParams) => { + try { + const res = await loginApi(params) + if (res.isUserNotExist) { + // 用户不存在,跳转到注册页面 + router.push('/user/register') + return + } + setUserInfo(res) + // 跳转到首页 + if (res.user.real_check !== 1) { + router.push('/') + } else { + router.push('/realName') + } + } catch (error) { + console.error('登录失败', error) + + throw error + } + } + + /** * 注册方法 * @param params 登录参数 */ -const register = async (params: RegisterParams) => { - try { - const res = await registerApi(params); - //跳转登录页面 - router.push('/user/login'); - } catch (error) { - console.error('注册失败', error); - throw error; + const register = async (params: RegisterParams) => { + try { + const res = await registerApi(params) + //跳转登录页面 + router.push('/user/login') + } catch (error) { + console.error('注册失败', error) + throw error + } } -}; -/** - * 退出登录 - */ -const logout = async (params: { device_no: string }) => { - try { - await logoutApi(params); - } catch (error) { - console.error('退出登录接口调用失败', error); - } finally { - clearUserInfo(); + /** + * 退出登录 + */ + const logout = async (params: { device_no: string }) => { + try { + await logoutApi(params) + } catch (error) { + console.error('退出登录接口调用失败', error) + } finally { + clearUserInfo() - // 跳转到登录页面 - router.push('/user/login'); + // 跳转到登录页面 + router.push('/user/login') + } } -}; -/** - * 忘记密码 - */ -const forgotPassword = async (params: ForgotPasswordParams) => { - try { - await forgotPasswordApi(params); - // 跳转登录页面 - router.push('/user/login'); - } catch (error) { - console.error('重置密码失败', error); - throw error; + /** + * 忘记密码 + */ + const forgotPassword = async (params: ForgotPasswordParams) => { + try { + await forgotPasswordApi(params) + // 跳转登录页面 + router.push('/user/login') + } catch (error) { + console.error('重置密码失败', error) + throw error + } } -}; -/** - * 修改密码 - */ -const changePassword = async (params: ChangePasswordParams) => { - try { - await changePasswordApi(params); - // 跳转登录页面 - clearUserInfo(); - router.push('/user/login'); - } catch (error) { - console.error('修改密码失败', error); - throw error; + /** + * 修改密码 + */ + const changePassword = async (params: ChangePasswordParams) => { + try { + await changePasswordApi(params) + // 跳转登录页面 + clearUserInfo() + router.push('/user/login') + } catch (error) { + console.error('修改密码失败', error) + throw error + } } -}; -/** - * 发送验证码 - */ -const sendCode = async (params: SendCodeParams) => { - try { - const res = await sendCodeApi(params); - } catch (error) { - console.error('发送验证码失败', error); - throw error; + /** + * 发送验证码 + */ + const sendCode = async (params: SendCodeParams) => { + try { + const res = await sendCodeApi(params) + } catch (error) { + console.error('发送验证码失败', error) + throw error + } + } + /** + * 切换账户 + */ + const switchAccount = async () => { + clearUserInfo() + router.push('/user/login') } -}; -/** - * 切换账户 - */ -const switchAccount = async () => { - clearUserInfo(); - router.push('/user/login'); -}; -/** - * 更新用户信息 - * @param data 要更新的用户信息 - */ -const updateUserInfo = (data: Partial) => { - if (userInfo.value) { - // 合并更新用户信息 - userInfo.value = { ...userInfo.value, ...data }; - // 更新本地存储 - setStorage('userInfo', userInfo.value); + /** + * 更新用户信息 + * @param data 要更新的用户信息 + */ + const updateUserInfo = (data: Partial) => { + if (userInfo.value) { + // 合并更新用户信息 + userInfo.value = { ...userInfo.value, ...data } + // 更新本地存储 + setStorage('userInfo', userInfo.value) + } } -}; -return { - // 状态 - token, - userInfo, - menusInfo, - permissionsInfo, - // 计算属性 - isLoggedIn, - sideMenu, - // 方法(箭头函数) - login, - setUserInfo, - register, - logout, - forgotPassword, - changePassword, - sendCode, - switchAccount, - updateUserInfo -}; -}); + return { + // 状态 + token, + userInfo, + menusInfo, + permissionsInfo, + // 计算属性 + isLoggedIn, + sideMenu, + // 方法(箭头函数) + login, + setUserInfo, + register, + logout, + forgotPassword, + changePassword, + sendCode, + switchAccount, + updateUserInfo, + } +}) diff --git a/src/views/livenessVerification/index.vue b/src/views/livenessVerification/index.vue new file mode 100644 index 0000000..804c904 --- /dev/null +++ b/src/views/livenessVerification/index.vue @@ -0,0 +1,235 @@ + + + + + diff --git a/src/views/realName/index.vue b/src/views/realName/index.vue new file mode 100644 index 0000000..3e43e7b --- /dev/null +++ b/src/views/realName/index.vue @@ -0,0 +1,1015 @@ + + + + + diff --git a/vite.config.ts b/vite.config.ts index e5ba6a7..e3106da 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -3,6 +3,7 @@ import { loadEnv, defineConfig, ConfigEnv } from 'vite' import type { UserConfig } from 'vite' import vue from '@vitejs/plugin-vue' import vueDevTools from 'vite-plugin-vue-devtools' +import basicSsl from '@vitejs/plugin-basic-ssl' // 自动导入插件 import AutoImport from 'unplugin-auto-import/vite' @@ -37,6 +38,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { dts: 'src/components.d.ts', dirs: ['src/components'], }), + basicSsl(), ], resolve: { alias: { @@ -84,6 +86,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { host: true, port: 9999, open: true, + https: true, proxy: { '/api': { target: env.VITE_API_BASE_URL,