miniprogramme/pages/account-sync/phone-binding/phone-binding.js
2025-09-12 16:08:17 +08:00

490 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 手机号绑定页面
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();
}
});