// 手机号绑定页面 const app = getApp(); const apiClient = require('../../../utils/api-client.js'); const accountSyncManager = require('../../../utils/account-sync.js'); const authManager = require('../../../utils/auth.js'); Page({ data: { // 表单数据 phoneNumber: '', verifyCode: '', // 状态控制 canSendCode: false, canBind: false, isBinding: false, // 验证码倒计时 codeButtonText: '获取验证码', codeCountdown: 0, codeTimer: null, // 合并相关 showMergeDialog: false, mergeCandidates: [], // 系统适配 statusBarHeight: 44, navBarHeight: 88, windowHeight: 667, safeAreaBottom: 0, // 用户信息 userInfo: null }, onLoad: function (options) { console.log('手机号绑定页面加载'); this.initSystemInfo(); this.initUserInfo(); }, onUnload: function () { // 清理定时器 if (this.data.codeTimer) { clearInterval(this.data.codeTimer); } }, // 初始化系统信息 initSystemInfo() { try { const systemInfo = wx.getSystemInfoSync(); const menuButtonInfo = wx.getMenuButtonBoundingClientRect(); const statusBarHeight = systemInfo.statusBarHeight; const navBarHeight = menuButtonInfo.bottom + menuButtonInfo.top - statusBarHeight; this.setData({ statusBarHeight, navBarHeight, windowHeight: systemInfo.windowHeight, safeAreaBottom: systemInfo.safeArea ? systemInfo.screenHeight - systemInfo.safeArea.bottom : 0 }); } catch (error) { console.error('初始化系统信息失败:', error); } }, // 初始化用户信息 initUserInfo() { const userInfo = authManager.getUserDisplayInfo(); if (userInfo) { this.setData({ userInfo }); } else { console.error('无法获取用户信息,返回上一页'); wx.navigateBack(); } }, // 手机号输入处理 onPhoneInput: function (e) { const value = e.detail.value; this.setData({ phoneNumber: value }); this.validateForm(); }, // 验证码输入处理 onCodeInput: function (e) { const value = e.detail.value; this.setData({ verifyCode: value }); this.validateForm(); }, // 表单验证 validateForm: function () { const { phoneNumber, verifyCode, codeCountdown } = this.data; // 手机号格式验证 const phoneRegex = /^1[3-9]\d{9}$/; const isPhoneValid = phoneRegex.test(phoneNumber); // 验证码验证 const isCodeValid = verifyCode.length === 6; this.setData({ canSendCode: isPhoneValid && codeCountdown === 0, canBind: isPhoneValid && isCodeValid }); }, // 发送验证码 sendVerifyCode: function () { if (!this.data.canSendCode) { return; } const { phoneNumber } = this.data; wx.showLoading({ title: '发送中...', mask: true }); apiClient.sendVerifyCode(phoneNumber) .then(response => { wx.hideLoading(); console.log('验证码发送成功:', response); this.startCodeCountdown(); wx.showToast({ title: '验证码已发送', icon: 'success', duration: 2000 }); }) .catch(error => { wx.hideLoading(); console.error('验证码发送失败:', error); let errorMessage = '发送失败,请重试'; if (error.message) { errorMessage = error.message; } wx.showToast({ title: errorMessage, icon: 'none', duration: 3000 }); }); }, // 开始验证码倒计时 startCodeCountdown: function () { let countdown = 60; this.setData({ codeCountdown: countdown, codeButtonText: `${countdown}s后重发` }); const timer = setInterval(() => { countdown--; if (countdown <= 0) { clearInterval(timer); this.setData({ codeCountdown: 0, codeButtonText: '重新发送', codeTimer: null }); this.validateForm(); } else { this.setData({ codeCountdown: countdown, codeButtonText: `${countdown}s后重发` }); } }, 1000); this.setData({ codeTimer: timer }); }, // 绑定手机号 handleBind: function () { if (!this.data.canBind || this.data.isBinding) { return; } const { phoneNumber, verifyCode } = this.data; this.setData({ isBinding: true }); wx.showLoading({ title: '绑定中...', mask: true }); // 🔥 使用新的分步绑定逻辑 this.attemptBinding(phoneNumber, verifyCode); }, // 🔥 分步绑定逻辑 async attemptBinding(phoneNumber, verifyCode) { try { // 第一步:尝试不自动合并的绑定 console.log('🔄 第一步:尝试绑定(不自动合并)'); const result = await accountSyncManager.bindPhone(phoneNumber, verifyCode, false); // 绑定成功 this.handleBindingSuccess(result); } catch (error) { console.log('🔄 第一步绑定失败:', error.message); if (error.message && error.message.includes('已关联其他账号')) { // 发现冲突,询问用户是否合并 this.showMergeConfirmDialog(phoneNumber, verifyCode); } else { // 其他错误,直接显示 wx.hideLoading(); wx.showToast({ title: error.message || '绑定失败', icon: 'none', duration: 3000 }); this.setData({ isBinding: false }); } } }, // 显示合并确认对话框 showMergeConfirmDialog(phoneNumber, verifyCode) { wx.hideLoading(); wx.showModal({ title: '发现账号冲突', content: `手机号 ${phoneNumber} 已被其他账号使用。\n\n是否同意自动合并账号?合并后将保留当前账号的数据。`, cancelText: '取消绑定', confirmText: '同意合并', success: (res) => { if (res.confirm) { // 用户同意合并 this.performAutoMergeBinding(phoneNumber, verifyCode); } else { // 用户取消 this.setData({ isBinding: false }); } } }); }, // 执行自动合并绑定 async performAutoMergeBinding(phoneNumber, verifyCode) { wx.showLoading({ title: '合并账号中...', mask: true }); try { console.log('🔄 第二步:执行自动合并绑定'); const result = await accountSyncManager.bindPhone(phoneNumber, verifyCode, true); // 合并成功 this.handleBindingSuccess(result); } catch (error) { console.error('🔄 自动合并绑定失败:', error); wx.hideLoading(); wx.showToast({ title: error.message || '合并失败', icon: 'none', duration: 3000 }); this.setData({ isBinding: false }); } }, // 处理绑定成功 handleBindingSuccess(result) { wx.hideLoading(); console.log('✅ 绑定成功:', result); // 重置绑定状态 this.setData({ isBinding: false }); // 根据文档,处理不同的绑定结果 if (result.hasMerged && result.mergeCount > 0) { wx.showToast({ title: `绑定成功!已自动合并 ${result.mergeCount} 个账号`, icon: 'success', duration: 2000 }); } else { wx.showToast({ title: '绑定成功!', icon: 'success', duration: 2000 }); } // 延迟返回上一页,让用户看到成功提示 setTimeout(() => { wx.navigateBack(); }, 2000); }, // 处理账号冲突 async handleAccountConflict() { try { const userInfo = this.data.userInfo; if (!userInfo || !userInfo.customId) { throw new Error('无法获取用户ID'); } console.log('🔍 检测可合并账号 - 详细信息:', { currentUserCustomId: userInfo.customId, phoneNumber: this.data.phoneNumber, currentUserPhone: userInfo.phone }); const mergeInfo = await accountSyncManager.detectMerge(userInfo.customId); console.log('🔍 检测结果详情:', { hasMergeCandidates: mergeInfo.hasMergeCandidates, candidatesCount: mergeInfo.candidates?.length || 0, candidates: mergeInfo.candidates, autoMerged: mergeInfo.autoMerged, mergeCount: mergeInfo.mergeCount }); if (mergeInfo.hasMergeCandidates && mergeInfo.candidates.length > 0) { this.setData({ mergeCandidates: mergeInfo.candidates, showMergeDialog: true }); } else { // 🚨 异常情况:绑定失败但检测不到冲突账号 console.error('🚨 系统异常:绑定失败但检测不到冲突账号'); wx.showModal({ title: '系统检测异常', content: `手机号 ${this.data.phoneNumber} 绑定失败,提示已被其他账号使用,但系统检测不到冲突账号。\n\n可能原因:\n1. 数据库状态异常\n2. 已删除账号的残留数据\n3. 账号状态不一致\n\n建议联系技术支持处理。`, showCancel: true, cancelText: '使用其他手机号', confirmText: '联系客服', success: (res) => { if (res.confirm) { wx.showToast({ title: '请联系客服处理此问题', icon: 'none', duration: 3000 }); } } }); } } catch (error) { console.error('检测可合并账号失败:', error); wx.showToast({ title: '检测账号失败,请重试', icon: 'none', duration: 3000 }); } }, // 关闭合并对话框 closeMergeDialog: function () { this.setData({ showMergeDialog: false, mergeCandidates: [] }); }, // 手动合并指定账号 mergeSpecificAccount: function (e) { const candidateCustomId = e.currentTarget.dataset.customId; this.performMerge(candidateCustomId, '用户手动选择合并'); }, // 自动合并所有账号 autoMergeAll: function () { const { phoneNumber, verifyCode } = this.data; wx.showLoading({ title: '自动合并中...', mask: true }); // 根据文档,使用autoMerge=true参数进行自动合并 accountSyncManager.bindPhone(phoneNumber, verifyCode, true) .then(result => { wx.hideLoading(); console.log('自动合并成功:', result); const mergeCount = result.mergeCount || 0; const message = result.hasMerged ? `绑定成功!已自动合并 ${mergeCount} 个账号` : '绑定成功!'; wx.showToast({ title: message, icon: 'success', duration: 2000 }); this.setData({ showMergeDialog: false }); setTimeout(() => { wx.navigateBack(); }, 2000); }) .catch(error => { wx.hideLoading(); console.error('自动合并失败:', error); wx.showToast({ title: error.message || '自动合并失败', icon: 'none', duration: 3000 }); }); }, // 执行合并操作 async performMerge(secondaryCustomId, mergeReason) { try { const userInfo = this.data.userInfo; if (!userInfo || !userInfo.customId) { throw new Error('无法获取用户ID'); } wx.showLoading({ title: '合并中...', mask: true }); console.log('执行账号合并:', { primary: userInfo.customId, secondary: secondaryCustomId, reason: mergeReason }); const result = await accountSyncManager.mergeAccount( userInfo.customId, secondaryCustomId, mergeReason ); wx.hideLoading(); console.log('账号合并成功:', result); wx.showToast({ title: '账号合并成功!', icon: 'success', duration: 2000 }); this.setData({ showMergeDialog: false }); setTimeout(() => { wx.navigateBack(); }, 2000); } catch (error) { wx.hideLoading(); console.error('账号合并失败:', error); wx.showToast({ title: error.message || '合并失败,请重试', icon: 'none', duration: 3000 }); } }, // 返回上一页 goBack: function () { wx.navigateBack(); } });