Page({ data: { realName: '', idNumber: '', canProceed: false, idError: '', showConfirm: false }, // 简易中国二代身份证校验:格式+生日+校验位 isValidChineseID(id) { if (!id || typeof id !== 'string') return false; const upper = id.trim().toUpperCase(); if (!/^\d{17}[\dX]$/.test(upper)) return false; // 校验生日是否合法 const y = parseInt(upper.slice(6, 10), 10); const m = parseInt(upper.slice(10, 12), 10); const d = parseInt(upper.slice(12, 14), 10); const date = new Date(y, m - 1, d); if (!(date.getFullYear() === y && date.getMonth() + 1 === m && date.getDate() === d)) return false; // 校验位 const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; const parity = ['1','0','X','9','8','7','6','5','4','3','2']; let sum = 0; for (let i = 0; i < 17; i++) { sum += parseInt(upper[i], 10) * weights[i]; } const code = parity[sum % 11]; return code === upper[17]; }, onRealNameInput(e) { const realName = e.detail.value || ''; this.setData({ realName }, this.updateProceedState); }, onIdNumberInput(e) { // 仅保留数字与X,统一为大写 const raw = (e.detail.value || '').toString(); const cleaned = raw.replace(/[^0-9xX]/g, '').toUpperCase(); const idNumber = cleaned; this.setData({ idNumber }, () => { // 输入中先不显示错误,但实时控制按钮可用 this.updateProceedState(false); }); }, updateProceedState(showError = true) { const { realName, idNumber } = this.data; const trimmed = (idNumber || '').trim(); const valid = this.isValidChineseID(trimmed); const ok = realName.trim().length > 0 && valid; const idError = !trimmed ? '' : (valid ? '' : '身份证格式不正确,请输入18位二代身份证'); this.setData({ canProceed: ok, idError: showError ? idError : '' }); }, onIdBlur() { // 失去焦点时显示错误 this.updateProceedState(true); }, onNext() { const { realName, idNumber, canProceed } = this.data; if (!realName.trim()) { wx.showToast({ title: '请输入真实姓名', icon: 'none' }); return; } if (!this.isValidChineseID((idNumber || '').trim())) { this.setData({ idError: '身份证格式不正确,请输入18位二代身份证' }); wx.showToast({ title: '身份证格式不正确', icon: 'none' }); return; } if (!canProceed) { wx.showToast({ title: '请完善信息', icon: 'none' }); return; } // 打开确认弹框 this.setData({ showConfirm: true }); }, onConfirmCancel() { this.setData({ showConfirm: false }); }, async onConfirmAgree() { this.setData({ showConfirm: false }); wx.navigateTo({ url: `/subpackages/realname/faceid-webview?url=${encodeURIComponent('')}` }); return; // try { const apiClient = require('../../../utils/api-client.js'); const response = await apiClient.post('/api/faceid/create', { realName: this.data.realName, idNumber: this.data.idNumber, redirectUrl: encodeURIComponent('/subpackages/realname/faceid-webview') }); // 期望后端返回 { code:0, data: { certUrl: 'https://...' } } const certUrl = response?.data?.certUrl || response?.certUrl; if (certUrl) { wx.navigateTo({ url: `/subpackages/realname/faceid-webview?url=${encodeURIComponent(certUrl)}` }); } else { wx.showToast({ title: response?.message || '创建认证会话失败', icon: 'none' }); } } catch (error) { console.error('创建FaceID会话失败:', error); wx.showToast({ title: error?.message || '网络异常,请稍后重试', icon: 'none' }); } } });