findme-miniprogram-frontend/subpackages/qr/qr-code/qr-code.js
2025-12-27 17:16:03 +08:00

834 lines
23 KiB
JavaScript
Raw Permalink 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.

// Get application instance
const app = getApp();
const apiClient = require('../../../utils/api-client.js'); // Import your API client
const friendAPI = require('../../../utils/friend-api.js'); // Import friend API for loading target user info
// Page configuration
Page({
// Page data
data: {
username: '加载中...', // User name (loading state)
userId: '加载中...', // User ID (loading state)
qrCodeUrl: '', // QR code image URL
isDarkMode: false, // Whether in dark mode
isLoading: true, // Loading state
userInfo: null, // Store complete user info
isTestData: false, // Flag to indicate if using test data
},
// Test/fallback user data to prevent crashes
getTestUserData: function() {
return {
user: {
id: 'test_123456',
customId: 'TEST001',
nickname: 'Test User',
phone: '13800138000',
avatar: 'https://via.placeholder.com/100x100/4CAF50/white?text=T',
gender: 1,
birthday: '1990-01-01',
location: 'Test City',
signature: 'This is a test user for development',
isActive: true,
createdAt: '2024-01-01T00:00:00Z',
updatedAt: '2024-01-01T00:00:00Z'
},
token: 'test_token_123456789',
refreshToken: 'test_refresh_token_123456789',
expiresAt: Date.now() + (7 * 24 * 60 * 60 * 1000), // 7 days from now
permissions: ['basic', 'location', 'social'],
settings: {
locationPrivacy: 'friends',
showPhone: false,
allowSearch: true
}
};
},
// Page load lifecycle function
onLoad: function(options) {
// 接收传入的 customId 参数(如果是从用户预览页或好友详情页跳转过来的)
const targetCustomId = options?.customId || null;
// Check theme settings first
const isDarkMode = wx.getStorageSync('isDarkMode') || false;
this.setData({
isDarkMode: isDarkMode
});
// Load user information
this.loadUserInfo(targetCustomId);
},
// Load user information with guaranteed fallback
loadUserInfo: function(targetCustomId) {
// Show loading
wx.showLoading({
title: '加载中...',
mask: true
});
// 如果传入了 targetCustomId说明要显示陌生人或好友的二维码
if (targetCustomId) {
this.loadTargetUserInfo(targetCustomId);
return;
}
// 否则显示当前用户的二维码
// Start with test data immediately to ensure something always works
const testUserData = this.getTestUserData();
this.setData({
username: testUserData.user.nickname,
userId: testUserData.user.customId,
userInfo: testUserData,
isLoading: false,
isTestData: true
});
// Generate QR code immediately with test data
this.generateQRCodeWithData(testUserData);
// Hide loading
wx.hideLoading();
// Show test data notification
wx.showToast({
title: '使用测试数据',
icon: 'none',
duration: 2000
});
// Try to get real data in background (optional)
this.tryLoadRealUserData();
},
// 加载目标用户(陌生人或好友)的信息
loadTargetUserInfo: async function(targetCustomId) {
console.log('📱 开始加载目标用户信息, customId:', targetCustomId);
if (!targetCustomId) {
console.error('❌ targetCustomId 为空');
wx.hideLoading();
wx.showModal({
title: '参数错误',
content: '用户ID不存在',
showCancel: false,
confirmText: '确定',
success: () => {
wx.navigateBack();
}
});
return;
}
try {
// 先尝试获取好友详情(如果是好友)
try {
console.log('🔍 尝试获取好友详情, customId:', targetCustomId);
const detail = await friendAPI.getFriendDetail(targetCustomId);
if (detail && detail.code === 0 && detail.data) {
console.log('✅ 获取好友详情成功');
const userData = detail.data;
// 格式化用户信息,匹配二维码生成所需的格式
const formattedUserInfo = {
user: {
customId: userData.customId || targetCustomId,
nickname: userData.nickname || userData.remark || '用户',
avatar: userData.avatar || '',
id: userData.id || userData.customId
}
};
this.setData({
username: formattedUserInfo.user.nickname,
userId: formattedUserInfo.user.customId,
userInfo: formattedUserInfo,
isLoading: false,
isTestData: false
});
// 使用现有逻辑生成二维码
this.generateQRCodeWithData(formattedUserInfo);
wx.hideLoading();
console.log('✅ 好友二维码生成完成');
return;
}
} catch (err) {
// 不是好友,继续走搜索流程
console.log('⚠️ 获取好友详情失败(可能不是好友),尝试搜索用户:', err.message || err);
}
// 如果不是好友,使用搜索接口
console.log('🔍 使用搜索接口查找用户, customId:', targetCustomId);
const resp = await friendAPI.searchUsers(targetCustomId, 'custom_id', 1, 1);
const user = resp?.data?.users?.[0];
if (!user) {
console.error('❌ 未找到用户信息');
wx.hideLoading();
wx.showModal({
title: '加载失败',
content: '未找到该用户信息',
showCancel: false,
confirmText: '确定',
success: () => {
wx.navigateBack();
}
});
return;
}
console.log('✅ 搜索到用户信息:', user);
// 格式化用户信息
const formattedUserInfo = {
user: {
customId: user.customId || targetCustomId,
nickname: user.nickname || '用户',
avatar: user.avatar || '',
id: user.id || user.customId
}
};
this.setData({
username: formattedUserInfo.user.nickname,
userId: formattedUserInfo.user.customId,
userInfo: formattedUserInfo,
isLoading: false,
isTestData: false
});
// 使用现有逻辑生成二维码
this.generateQRCodeWithData(formattedUserInfo);
wx.hideLoading();
console.log('✅ 陌生人二维码生成完成');
} catch (error) {
console.error('❌ 加载目标用户信息失败:', error);
wx.hideLoading();
wx.showModal({
title: '加载失败',
content: error.message || '无法加载用户信息,请稍后重试',
showCancel: false,
confirmText: '确定',
success: () => {
wx.navigateBack();
}
});
}
},
// Try to load real user data in background (won't break if fails)
tryLoadRealUserData: async function() {
try {
// Try local storage first
let userInfo = wx.getStorageSync('userInfo');
// Try API if no local data
if (!userInfo || !userInfo.user) {
const response = await apiClient.getUserInfo();
if (response && response.code === 0 && response.data) {
userInfo = response.data;
wx.setStorageSync('userInfo', userInfo);
}
}
// If we got real data, update the UI
if (userInfo && userInfo.user) {
this.setData({
username: userInfo.user.nickname || userInfo.user.customId || '真实用户',
userId: userInfo.user.customId || userInfo.user.id || 'REAL001',
userInfo: userInfo,
isTestData: false
});
// Regenerate QR code with real data
this.generateQRCodeWithData(userInfo);
wx.showToast({
title: '已加载真实数据',
icon: 'success',
duration: 1500
});
}
} catch (error) {
// Do nothing - we already have test data working
}
},
// Generate QR code with provided user data (guaranteed to work)
generateQRCodeWithData: function(userData) {
if (!userData || !userData.user) {
console.error('未提供用于生成二维码的用户数据');
return;
}
// Create QR code data object
// const qrData = {
// type: 'user_card',
// username: userData.user.nickname || userData.user.customId,
// customId: userData.user.customId,
// nickname: userData.user.nickname,
// avatar: userData.user.avatar,
// isTestData: this.data.isTestData,
// timestamp: Date.now()
// };
// Convert to JSON string for QR code
const qrCodeData = "FINDME:" + userData.user.customId;//JSON.stringify(qrData);
// Generate QR code URL using online service (guaranteed to work)
try {
const encodedData = encodeURIComponent(qrCodeData);
const qrCodeUrl = `https://api.qrserver.com/v1/create-qr-code/?size=300x300&format=png&data=${encodedData}`;
this.setData({
qrCodeUrl: qrCodeUrl
});
} catch (error) {
console.error('生成二维码失败 URL', error);
// Ultimate fallback - use a simple text-based QR code
const simpleData = `${userData.user.nickname}-${userData.user.customId}`;
const encodedSimpleData = encodeURIComponent(simpleData);
const fallbackUrl = `https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=${encodedSimpleData}`;
this.setData({
qrCodeUrl: fallbackUrl
});
}
},
// Navigate back
navigateBack: function() {
wx.navigateBack({
delta: 1
});
},
// Show menu
showMenu: function() {
// Different menu options based on whether user is logged in or using test data
const menuItems = ['保存图片', '分享二维码', '刷新数据'];
if (this.data.isTestData) {
menuItems.push('前往登录');
}
menuItems.push('Settings');
wx.showActionSheet({
itemList: menuItems,
success: (res) => {
switch (res.tapIndex) {
case 0:
this.saveQRCode();
break;
case 1:
this.shareQRCode();
break;
case 2:
this.refreshUserInfo();
break;
case 3:
if (this.data.isTestData) {
this.goToLogin();
} else {
this.goToSettings();
}
break;
case 4:
if (!this.data.isTestData) {
this.goToSettings();
}
break;
}
}
});
},
// Navigate to login page
goToLogin: function() {
wx.navigateTo({
url: '/pages/login/login'
});
},
// Navigate to settings page
goToSettings: function() {
wx.navigateTo({
url: '/subpackages/settings/settingss/settingss'
});
},
// Force test data (for debugging) - only works when not logged in
forceTestData: function() {
// Check if user is actually logged in
const userInfo = wx.getStorageSync('userInfo');
if (userInfo && userInfo.user && userInfo.token) {
wx.showModal({
title: 'Cannot Use Test Data',
content: 'You are currently logged in. Please log out first to use test data.',
showCancel: false,
confirmText: 'OK'
});
return;
}
const testUserData = this.getTestUserData();
this.setData({
username: testUserData.user.nickname,
userId: testUserData.user.customId,
userInfo: testUserData,
isTestData: true,
qrCodeUrl: '' // Clear current QR code
});
this.generateQRCodeWithData(testUserData);
wx.showToast({
title: 'Test data loaded',
icon: 'success'
});
},
// Refresh user info
refreshUserInfo: function() {
this.setData({
isLoading: true,
username: '令人耳目一新……',
userId: '请稍等...',
qrCodeUrl: ''
});
// Try to reload user info (will use real data if available, test data if not)
this.loadUserInfo();
},
// Refresh QR code
refreshQRCode: function() {
if (!this.data.userInfo) {
this.loadUserInfo();
return;
}
wx.showLoading({
title: '正在刷新二维码...'
});
// Clear current QR code
this.setData({
qrCodeUrl: ''
});
// Regenerate with current data
setTimeout(() => {
this.generateQRCodeWithData(this.data.userInfo);
wx.hideLoading();
wx.showToast({
title: '二维码已刷新',
icon: 'success'
});
}, 500);
},
// QR code image load success
onQRCodeLoad: function() {
},
// QR code image load error
onQRCodeError: function(e) {
console.error('二维码图片加载失败:', e);
// Try to regenerate with simpler data
if (this.data.userInfo) {
const userData = this.data.userInfo;
const simpleData = `${userData.user.nickname || 'User'}-${userData.user.customId || 'ID'}`;
const encodedData = encodeURIComponent(simpleData);
const fallbackUrl = `https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=${encodedData}`;
this.setData({
qrCodeUrl: fallbackUrl
});
}
},
// Save QR code to album
saveQRCode: function() {
if (!this.data.qrCodeUrl) {
wx.showToast({
title: '没有二维码可以保存',
icon: 'none'
});
return;
}
// Download and save
wx.downloadFile({
url: this.data.qrCodeUrl,
success: (res) => {
if (res.statusCode === 200) {
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
wx.showToast({
title: '保存成功',
icon: 'success'
});
},
fail: (error) => {
console.error('保存二维码失败:', error);
wx.showToast({
title: '保存失败',
icon: 'none'
});
}
});
}
},
fail: (error) => {
console.error('二维码下载失败:', error);
wx.showToast({
title: '下载失败'+error.errMsg,
icon: 'none'
});
}
});
},
// Share QR code
shareQRCode: function() {
if (!this.data.qrCodeUrl) {
wx.showToast({
title: '没有可分享的二维码',
icon: 'none'
});
return;
}
wx.downloadFile({
url: this.data.qrCodeUrl,
success: (res) => {
if (res.statusCode === 200) {
wx.showShareImageMenu({
path: res.tempFilePath,
success: () => {
},
fail: (error) => {
console.error('分享失败:', error);
wx.showToast({
title: '分享失败',
icon: 'none'
});
}
});
}
},
fail: (error) => {
console.error('无法下载共享:', error);
wx.showToast({
title: '分享失败',
icon: 'none'
});
}
});
},
// Enhanced scan QR code with better error handling
scanQRCode: function() {
wx.navigateTo({
url: '/subpackages/qr/qr-scan/qr-scan',
})
// Check camera permission first
// wx.getSetting({
// success: (res) => {
// if (res.authSetting['scope.camera'] === false) {
// wx.showModal({
// title: '需要相机权限',
// content: '扫描二维码需要使用相机,请允许访问相机',
// showCancel: true,
// cancelText: '取消',
// confirmText: '去设置',
// success: (modalRes) => {
// if (modalRes.confirm) {
// wx.openSetting();
// }
// }
// });
// return;
// }
// // Proceed with scanning
// wx.scanCode({
// // onlyFromCamera: true,
// scanType: ['qrCode'],
// success: (res) => {
// try {
// const scannedData = JSON.parse(res.result);
// if (scannedData.type === 'user_card') {
// this.handleUserCardScan(scannedData);
// } else {
// this.handleGenericScan(res.result);
// }
// } catch (error) {
// this.handleGenericScan(res.result);
// }
// },
// fail: (error) => {
// console.error('扫描失败:', error);
// if (error.errMsg.includes('cancel')) {
// // User cancelled scanning
// } else {
// wx.showToast({
// title: '扫描失败,请重试',
// icon: 'none'
// });
// }
// }
// });
// }
// });
},
// Handle user card QR code scan (Enhanced version)
handleUserCardScan: function(userData) {
const isTestData = userData.isTestData || false;
const dataType = isTestData ? ' (Test Data)' : '';
// Check if trying to scan own QR code
if (this.data.userInfo &&
(userData.userId === this.data.userInfo.user.customId ||
userData.userId === this.data.userInfo.user.id)) {
wx.showModal({
title: '提示',
content: '不能添加自己为好友',
showCancel: false,
confirmText: '知道了'
});
return;
}
wx.showModal({
title: `扫描到用户${dataType}`,
content: `用户名: ${userData.username}\n用户ID: ${userData.userId}${isTestData ? '\n\n注意这是测试数据' : ''}`,
showCancel: true,
cancelText: '取消',
confirmText: isTestData ? '知道了' : '添加好友',
success: (res) => {
if (res.confirm && !isTestData) {
this.addFriend(userData);
} else if (res.confirm && isTestData) {
wx.showToast({
title: '无法添加测试用户',
icon: 'none'
});
}
}
});
},
// Add friend functionality using your existing API
addFriend: async function(userData) {
// Show loading
wx.showLoading({
title: '添加中...',
mask: true
});
try {
// Check if user is logged in
const currentUserInfo = wx.getStorageSync('userInfo');
if (!currentUserInfo || !currentUserInfo.token) {
wx.hideLoading();
wx.showModal({
title: '未登录',
content: '请先登录后再添加好友',
showCancel: true,
cancelText: '取消',
confirmText: '去登录',
success: (res) => {
if (res.confirm) {
wx.navigateTo({
url: '/pages/login/login'
});
}
}
});
return;
}
// Use your existing API method
const response = await apiClient.addFriend(
userData.userId, // targetId
'通过扫描二维码添加' // message
);
wx.hideLoading();
if (response && response.code === 0) {
// Success
wx.showModal({
title: '添加成功',
content: `已成功添加 ${userData.username} 为好友`,
showCancel: false,
confirmText: '确定',
success: () => {
// Navigate to friends list or chat
wx.showActionSheet({
itemList: ['查看好友列表', '开始聊天'],
success: (actionRes) => {
if (actionRes.tapIndex === 0) {
wx.navigateTo({
url: '/pages/social/friends/friends'
});
} else if (actionRes.tapIndex === 1) {
wx.navigateTo({
url: `/pages/message/chat/chat?userId=${userData.userId}&username=${userData.username}`
});
}
}
});
}
});
// Update local friends list if you have one cached
this.updateLocalFriendsList(userData);
} else if (response && (response.code === 40001 || response.message?.includes('已经是好友'))) {
// User already a friend (adjust code based on your backend response)
wx.showModal({
title: '提示',
content: `${userData.username} 已经是您的好友了`,
showCancel: true,
cancelText: '知道了',
confirmText: '开始聊天',
success: (res) => {
if (res.confirm) {
wx.navigateTo({
url: `/pages/message/chat/chat?userId=${userData.userId}&username=${userData.username}`
});
}
}
});
} else if (response && (response.code === 40002 || response.message?.includes('等待确认'))) {
// Friend request sent (pending approval)
wx.showToast({
title: '好友请求已发送,等待对方确认',
icon: 'none',
duration: 3000
});
} else if (response && (response.code === 40404 || response.message?.includes('用户不存在'))) {
// User not found
wx.showModal({
title: '用户不存在',
content: '该用户可能已注销或不存在',
showCancel: false,
confirmText: '知道了'
});
} else {
// Other error
const errorMsg = response?.message || '添加好友失败';
wx.showToast({
title: errorMsg,
icon: 'none',
duration: 2000
});
}
} catch (error) {
wx.hideLoading();
console.error('添加好友出错:', error);
// Handle specific error messages
let errorMsg = '添加好友失败';
if (error.message) {
if (error.message.includes('目标用户ID不能为空')) {
errorMsg = '用户ID无效';
} else if (error.message.includes('好友申请留言不能超过100字符')) {
errorMsg = '申请留言过长';
} else {
errorMsg = error.message;
}
}
wx.showModal({
title: '添加失败',
content: errorMsg,
showCancel: true,
cancelText: '取消',
confirmText: '重试',
success: (res) => {
if (res.confirm) {
this.addFriend(userData);
}
}
});
}
},
// Update local friends list cache
updateLocalFriendsList: function(newFriend) {
try {
let friendsList = wx.getStorageSync('friendsList') || [];
// Check if friend already exists
const existingIndex = friendsList.findIndex(friend =>
friend.userId === newFriend.userId || friend.customId === newFriend.userId
);
if (existingIndex === -1) {
// Add new friend to local cache
friendsList.push({
userId: newFriend.userId,
customId: newFriend.userId,
nickname: newFriend.username,
avatar: newFriend.avatar || '',
addedAt: new Date().toISOString(),
status: 'accepted' // or 'pending' if requires approval
});
wx.setStorageSync('friendsList', friendsList);
}
} catch (error) {
console.error('更新本地好友列表失败:', error);
}
},
// Handle generic QR code scan
handleGenericScan: function(result) {
wx.showModal({
title: '二维码结果',
content: result,
showCancel: false,
confirmText: 'OK'
});
}
});