Initial Commit
This commit is contained in:
commit
1d71a02738
237 changed files with 64293 additions and 0 deletions
484
pages/qr-code/qr-code.js
Normal file
484
pages/qr-code/qr-code.js
Normal file
|
|
@ -0,0 +1,484 @@
|
|||
// Get application instance
|
||||
const app = getApp();
|
||||
const apiClient = require('../../utils/api-client.js'); // Import your API client
|
||||
|
||||
// Page configuration
|
||||
Page({
|
||||
// Page data
|
||||
data: {
|
||||
username: 'Loading...', // User name (loading state)
|
||||
userId: 'Loading...', // 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() {
|
||||
console.log('QR Code page loaded');
|
||||
|
||||
// Check theme settings first
|
||||
const isDarkMode = wx.getStorageSync('isDarkMode') || false;
|
||||
this.setData({
|
||||
isDarkMode: isDarkMode
|
||||
});
|
||||
|
||||
// Load user information
|
||||
this.loadUserInfo();
|
||||
},
|
||||
|
||||
// Load user information with guaranteed fallback
|
||||
loadUserInfo: function() {
|
||||
console.log('Starting to load user info...');
|
||||
|
||||
// Show loading
|
||||
wx.showLoading({
|
||||
title: 'Loading...',
|
||||
mask: true
|
||||
});
|
||||
|
||||
// Start with test data immediately to ensure something always works
|
||||
const testUserData = this.getTestUserData();
|
||||
console.log('Using test user data:', testUserData);
|
||||
|
||||
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: 'Using test data',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
|
||||
// Try to get real data in background (optional)
|
||||
this.tryLoadRealUserData();
|
||||
},
|
||||
|
||||
// Try to load real user data in background (won't break if fails)
|
||||
tryLoadRealUserData: async function() {
|
||||
try {
|
||||
console.log('Attempting to load real user data...');
|
||||
|
||||
// Try local storage first
|
||||
let userInfo = wx.getStorageSync('userInfo');
|
||||
|
||||
// Try API if no local data
|
||||
if (!userInfo || !userInfo.user) {
|
||||
console.log('No local user info, trying API...');
|
||||
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) {
|
||||
console.log('Got real user data, updating UI...');
|
||||
this.setData({
|
||||
username: userInfo.user.nickname || userInfo.user.customId || 'Real User',
|
||||
userId: userInfo.user.customId || userInfo.user.id || 'REAL001',
|
||||
userInfo: userInfo,
|
||||
isTestData: false
|
||||
});
|
||||
|
||||
// Regenerate QR code with real data
|
||||
this.generateQRCodeWithData(userInfo);
|
||||
|
||||
wx.showToast({
|
||||
title: 'Real data loaded',
|
||||
icon: 'success',
|
||||
duration: 1500
|
||||
});
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.log('Failed to load real data, staying with test data:', error);
|
||||
// Do nothing - we already have test data working
|
||||
}
|
||||
},
|
||||
|
||||
// Generate QR code with provided user data (guaranteed to work)
|
||||
generateQRCodeWithData: function(userData) {
|
||||
console.log('Generating QR code with data:', userData);
|
||||
|
||||
if (!userData || !userData.user) {
|
||||
console.error('No user data provided for QR generation');
|
||||
return;
|
||||
}
|
||||
|
||||
// Create QR code data object
|
||||
const qrData = {
|
||||
type: 'user_card',
|
||||
userId: userData.user.customId || userData.user.id,
|
||||
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()
|
||||
};
|
||||
|
||||
console.log('QR data object created:', qrData);
|
||||
|
||||
// Convert to JSON string for QR code
|
||||
const qrCodeData = JSON.stringify(qrData);
|
||||
console.log('QR code data string length:', qrCodeData.length);
|
||||
|
||||
// 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}`;
|
||||
|
||||
console.log('Generated QR code URL:', qrCodeUrl);
|
||||
|
||||
this.setData({
|
||||
qrCodeUrl: qrCodeUrl
|
||||
});
|
||||
|
||||
console.log('QR code URL set in data');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to generate QR code 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
|
||||
});
|
||||
|
||||
console.log('Using fallback QR code URL:', fallbackUrl);
|
||||
}
|
||||
},
|
||||
|
||||
// Navigate back
|
||||
navigateBack: function() {
|
||||
wx.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
},
|
||||
|
||||
// Show menu
|
||||
showMenu: function() {
|
||||
wx.showActionSheet({
|
||||
itemList: ['Save Image', 'Share QR Code', 'Refresh Data', 'Use Test Data', 'Settings'],
|
||||
success: (res) => {
|
||||
switch (res.tapIndex) {
|
||||
case 0:
|
||||
this.saveQRCode();
|
||||
break;
|
||||
case 1:
|
||||
this.shareQRCode();
|
||||
break;
|
||||
case 2:
|
||||
this.refreshUserInfo();
|
||||
break;
|
||||
case 3:
|
||||
this.forceTestData();
|
||||
break;
|
||||
case 4:
|
||||
wx.navigateTo({
|
||||
url: '/pages/settings/settings'
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Force test data (for debugging)
|
||||
forceTestData: function() {
|
||||
console.log('Forcing test data...');
|
||||
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() {
|
||||
console.log('Refreshing user info...');
|
||||
this.setData({
|
||||
isLoading: true,
|
||||
username: 'Refreshing...',
|
||||
userId: 'Please wait...',
|
||||
qrCodeUrl: ''
|
||||
});
|
||||
|
||||
// Always start with test data, then try real data
|
||||
this.loadUserInfo();
|
||||
},
|
||||
|
||||
// Refresh QR code
|
||||
refreshQRCode: function() {
|
||||
console.log('Refreshing QR code...');
|
||||
|
||||
if (!this.data.userInfo) {
|
||||
console.log('No user info available, loading test data...');
|
||||
this.loadUserInfo();
|
||||
return;
|
||||
}
|
||||
|
||||
wx.showLoading({
|
||||
title: 'Refreshing QR code...'
|
||||
});
|
||||
|
||||
// Clear current QR code
|
||||
this.setData({
|
||||
qrCodeUrl: ''
|
||||
});
|
||||
|
||||
// Regenerate with current data
|
||||
setTimeout(() => {
|
||||
this.generateQRCodeWithData(this.data.userInfo);
|
||||
wx.hideLoading();
|
||||
|
||||
wx.showToast({
|
||||
title: 'QR code refreshed',
|
||||
icon: 'success'
|
||||
});
|
||||
}, 500);
|
||||
},
|
||||
|
||||
// QR code image load success
|
||||
onQRCodeLoad: function() {
|
||||
console.log('QR code image loaded successfully');
|
||||
},
|
||||
|
||||
// QR code image load error
|
||||
onQRCodeError: function(e) {
|
||||
console.error('QR code image failed to load:', e);
|
||||
|
||||
// Try to regenerate with simpler data
|
||||
if (this.data.userInfo) {
|
||||
console.log('Retrying QR generation with simpler data...');
|
||||
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: 'No QR code to save',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Saving QR code:', this.data.qrCodeUrl);
|
||||
|
||||
// Download and save
|
||||
wx.downloadFile({
|
||||
url: this.data.qrCodeUrl,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
wx.saveImageToPhotosAlbum({
|
||||
filePath: res.tempFilePath,
|
||||
success: () => {
|
||||
wx.showToast({
|
||||
title: 'Saved successfully',
|
||||
icon: 'success'
|
||||
});
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('Failed to save QR code:', error);
|
||||
wx.showToast({
|
||||
title: 'Save failed',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('Failed to download QR code:', error);
|
||||
wx.showToast({
|
||||
title: 'Download failed',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Share QR code
|
||||
shareQRCode: function() {
|
||||
if (!this.data.qrCodeUrl) {
|
||||
wx.showToast({
|
||||
title: 'No QR code to share',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Sharing QR code:', this.data.qrCodeUrl);
|
||||
|
||||
wx.downloadFile({
|
||||
url: this.data.qrCodeUrl,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
wx.showShareImageMenu({
|
||||
path: res.tempFilePath,
|
||||
success: () => {
|
||||
console.log('Share successful');
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('Share failed:', error);
|
||||
wx.showToast({
|
||||
title: 'Share failed',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('Failed to download for sharing:', error);
|
||||
wx.showToast({
|
||||
title: 'Share failed',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Scan QR code
|
||||
scanQRCode: function() {
|
||||
console.log('Starting QR code scan...');
|
||||
|
||||
wx.scanCode({
|
||||
onlyFromCamera: true,
|
||||
scanType: ['qrCode'],
|
||||
success: (res) => {
|
||||
console.log('Scan successful:', res.result);
|
||||
|
||||
try {
|
||||
const scannedData = JSON.parse(res.result);
|
||||
|
||||
if (scannedData.type === 'user_card') {
|
||||
this.handleUserCardScan(scannedData);
|
||||
} else {
|
||||
this.handleGenericScan(res.result);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Not JSON data, treating as text');
|
||||
this.handleGenericScan(res.result);
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('Scan failed:', error);
|
||||
wx.showToast({
|
||||
title: 'Scan failed',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Handle user card QR code scan
|
||||
handleUserCardScan: function(userData) {
|
||||
console.log('Scanned user card:', userData);
|
||||
|
||||
const isTestData = userData.isTestData || false;
|
||||
const dataType = isTestData ? ' (Test Data)' : '';
|
||||
|
||||
wx.showModal({
|
||||
title: `User Card Scanned${dataType}`,
|
||||
content: `Username: ${userData.username}\nUser ID: ${userData.userId}${isTestData ? '\n\nNote: This is test data' : ''}`,
|
||||
showCancel: true,
|
||||
cancelText: 'Cancel',
|
||||
confirmText: isTestData ? 'OK' : 'Add Friend',
|
||||
success: (res) => {
|
||||
if (res.confirm && !isTestData) {
|
||||
wx.showToast({
|
||||
title: 'Add friend feature coming soon',
|
||||
icon: 'none'
|
||||
});
|
||||
} else if (res.confirm && isTestData) {
|
||||
wx.showToast({
|
||||
title: 'Cannot add test user',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Handle generic QR code scan
|
||||
handleGenericScan: function(result) {
|
||||
console.log('Generic scan result:', result);
|
||||
|
||||
wx.showModal({
|
||||
title: 'QR Code Result',
|
||||
content: result,
|
||||
showCancel: false,
|
||||
confirmText: 'OK'
|
||||
});
|
||||
}
|
||||
});
|
||||
8
pages/qr-code/qr-code.json
Normal file
8
pages/qr-code/qr-code.json
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"navigationBarTitleText": "我的二维码",
|
||||
"navigationBarTextStyle": "white",
|
||||
"backgroundColor": "#000000",
|
||||
"disableScroll": false,
|
||||
"navigationStyle": "custom",
|
||||
"pageOrientation": "portrait"
|
||||
}
|
||||
92
pages/qr-code/qr-code.wxml
Normal file
92
pages/qr-code/qr-code.wxml
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
<!-- 页面根容器,设置整体样式 -->
|
||||
<view class="qr-code-container">
|
||||
<!-- 自定义导航栏 -->
|
||||
<view class="nav-bar">
|
||||
<!-- 返回按钮 -->
|
||||
<view class="back-btn" bindtap="navigateBack">
|
||||
<text class="back-icon">↩</text>
|
||||
</view>
|
||||
<!-- 菜单按钮 -->
|
||||
<view class="menu-btn" bindtap="showMenu">
|
||||
<text class="menu-icon">⋯</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 主体内容区域 -->
|
||||
<view class="main-content">
|
||||
<!-- 用户信息区域 -->
|
||||
<view class="user-info">
|
||||
<!-- 用户名显示 -->
|
||||
<text class="username">{{username}}</text>
|
||||
<!-- 用户ID显示 -->
|
||||
<text class="user-id">ID: {{userId}}</text>
|
||||
<!-- 加载状态指示器 -->
|
||||
<view wx:if="{{isLoading}}" class="loading-indicator">
|
||||
<text class="loading-text">Loading...</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 二维码容器 -->
|
||||
<view class="qr-code-box">
|
||||
<!-- 加载状态 -->
|
||||
<view wx:if="{{isLoading}}" class="qr-loading">
|
||||
<text class="loading-text">Generating QR Code...</text>
|
||||
</view>
|
||||
|
||||
<!-- 二维码图片显示 -->
|
||||
<image
|
||||
wx:elif="{{qrCodeUrl}}"
|
||||
class="qr-code-image"
|
||||
src="{{qrCodeUrl}}"
|
||||
mode="aspectFit"
|
||||
bindload="onQRCodeLoad"
|
||||
binderror="onQRCodeError"
|
||||
></image>
|
||||
|
||||
<!-- 错误状态 -->
|
||||
<view wx:else class="qr-error">
|
||||
<text class="error-text">QR Code unavailable</text>
|
||||
<button class="retry-btn" bindtap="generateQRCode">Retry</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 刷新二维码按钮 -->
|
||||
<view class="refresh-btn" bindtap="refreshQRCode" hover-class="btn-hover">
|
||||
<!-- 刷新图标 -->
|
||||
<text class="refresh-icon">🔄</text>
|
||||
<!-- 刷新按钮文字 -->
|
||||
<text class="refresh-text">换一换</text>
|
||||
</view>
|
||||
|
||||
<!-- 用户信息卡片(可选显示更多信息) -->
|
||||
<view wx:if="{{userInfo && userInfo.user}}" class="user-details">
|
||||
<view wx:if="{{userInfo.user.avatar}}" class="user-avatar">
|
||||
<image class="avatar-img" src="{{userInfo.user.avatar}}" mode="aspectFill"></image>
|
||||
</view>
|
||||
<view class="user-meta">
|
||||
<text class="user-nickname">{{userInfo.user.nickname || 'No nickname'}}</text>
|
||||
<text class="user-custom-id">{{userInfo.user.customId || 'No custom ID'}}</text>
|
||||
<!-- Test data indicator -->
|
||||
<text wx:if="{{isTestData}}" class="test-indicator">🧪 Test Data</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="action-buttons">
|
||||
<!-- 保存二维码按钮 -->
|
||||
<view class="action-btn" bindtap="saveQRCode">
|
||||
<!-- 下载图标 -->
|
||||
<image class="action-icon" src="/images/download.svg" mode="aspectFit"></image>
|
||||
</view>
|
||||
<!-- 扫描二维码按钮 -->
|
||||
<view class="action-btn" bindtap="scanQRCode">
|
||||
<!-- 扫描图标 -->
|
||||
<image class="action-icon" src="/images/scan.svg" mode="aspectFit"></image>
|
||||
</view>
|
||||
<!-- 分享二维码按钮 -->
|
||||
<view class="action-btn" bindtap="shareQRCode">
|
||||
<!-- 分享图标 -->
|
||||
<image class="action-icon" src="/images/share.svg" mode="aspectFit"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
167
pages/qr-code/qr-code.wxss
Normal file
167
pages/qr-code/qr-code.wxss
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/* 全局渐变背景 */
|
||||
.qr-code-container {
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #7b4397 0%, #dc2430 50%, #007bb5 100%);
|
||||
color: #ffffff;
|
||||
padding-bottom: 100rpx;
|
||||
}
|
||||
|
||||
/* 导航栏样式 */
|
||||
.nav-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 100rpx 30rpx 30rpx;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.back-icon {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.right-buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.menu-btn {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
font-size: 24rpx;
|
||||
color: #ffffff;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
.theme-toggle {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 主体内容样式 */
|
||||
.main-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 80rpx 30rpx 50rpx;
|
||||
}
|
||||
|
||||
/* 用户信息样式 */
|
||||
.user-info {
|
||||
text-align: center;
|
||||
margin-bottom: 70rpx;
|
||||
}
|
||||
|
||||
.username {
|
||||
font-size: 44rpx;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
margin-bottom: 15rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.user-id {
|
||||
font-size: 30rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* 二维码容器样式 */
|
||||
.qr-code-box {
|
||||
width: 520rpx;
|
||||
height: 520rpx;
|
||||
background-color: #000000;
|
||||
border-radius: 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 20rpx 40rpx rgba(0, 0, 0, 0.3);
|
||||
margin-bottom: 40rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.qr-code-image {
|
||||
width: 420rpx;
|
||||
height: 420rpx;
|
||||
position: relative;
|
||||
background: linear-gradient(135deg, #ff6b6b, #feca57, #48dbfb, #1dd1a1, #5f27cd);
|
||||
padding: 10rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
/* 刷新按钮样式 */
|
||||
.refresh-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 40rpx;
|
||||
padding: 18rpx 50rpx;
|
||||
margin-bottom: 120rpx;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.refresh-icon {
|
||||
color: #ffffff;
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
|
||||
.refresh-text {
|
||||
font-size: 30rpx;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/* 底部操作按钮区域样式 */
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
width: 100%;
|
||||
padding: 0 60rpx;
|
||||
position: fixed;
|
||||
bottom: 80rpx;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.2);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
.action-icon {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
opacity: 0.9;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue