Browse Source

更新二维码页面:添加图片加载状态管理,优化样式和用户体验

Xfy
Default User 2 weeks ago
parent
commit
f2d1365a3c
  1. 129
      pages/qrcode/index.js
  2. 60
      pages/qrcode/index.wxml
  3. 232
      pages/qrcode/index.wxss

129
pages/qrcode/index.js

@ -1,22 +1,141 @@
// pages/qrcode/index.js // pages/qrcode/index.js
const API = require('../../utils/api.js');
Page({ Page({
data: { data: {
qrCodeUrl: '' // 二维码图片URL qrCodeUrl: '', // 二维码图片URL
userInfo: {
projectName: '未登录',
name: '未登录',
phoneNumber: '未登录'
},
imageLoading: false,
imageError: false
}, },
onLoad: function (options) { onLoad: function (options) {
// 页面加载时的初始化逻辑 // 页面加载时的初始化逻辑
console.log('二维码页面加载'); console.log('二维码页面加载');
// 这里可以添加生成或获取二维码的逻辑 // 加载用户信息
this.loadUserInfo();
}, },
onShow: function () { onShow: function () {
// 页面显示时的逻辑 // 页面显示时的逻辑
// 重新加载用户信息,确保信息是最新的
this.loadUserInfo();
},
// 加载用户信息
loadUserInfo: function () {
// 从本地存储获取用户信息
const userInfo = wx.getStorageSync('userInfo') || {};
const phoneNumber = userInfo.phoneNumber || wx.getStorageSync('phoneNumber') || '';
if (phoneNumber) {
// 根据电话号码查询personnel表
API.request('/api/personnel/get', 'POST', { phone: phoneNumber }).then(res => {
console.log('查询personnel表结果:', res);
if (res && res.success && res.data && res.data.length > 0) {
const personnelInfo = res.data[0];
this.setData({
userInfo: {
projectName: personnelInfo.projectName || '未提供',
name: personnelInfo.name || '未提供',
phoneNumber: phoneNumber
}
});
} else {
// 如果查询失败,使用本地存储的用户信息
this.setData({
userInfo: {
projectName: '未提供',
name: userInfo.nickName || userInfo.name || '未提供',
phoneNumber: phoneNumber
}
});
}
}).catch(err => {
console.error('查询personnel表失败:', err);
// 如果查询失败,使用本地存储的用户信息
this.setData({
userInfo: {
projectName: '未提供',
name: userInfo.nickName || userInfo.name || '未提供',
phoneNumber: phoneNumber
}
});
});
} else {
// 如果没有电话号码,提示用户登录
wx.showToast({
title: '请先登录',
icon: 'none',
duration: 2000
});
}
}, },
// 示例:生成二维码的函数 // 生成二维码的函数
generateQRCode: function () { generateQRCode: function () {
// 这里可以添加生成二维码的逻辑 // 设置图片加载状态
// 例如,调用API生成二维码并获取URL this.setData({
imageLoading: true,
imageError: false
});
// 生成包含会话ID的URL
const sessionId = 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
// 获取用户信息
const { userInfo } = this.data;
let inviterName = userInfo.name || '';
let inviterPhone = userInfo.phoneNumber || '';
let inviterProjectName = userInfo.projectName || '';
// 构建邀请URL,包含会话ID和邀请者信息
const inviteUrl = `http://8.137.125.67:3008/certificate.html?sessionId=${encodeURIComponent(sessionId)}&inviter=${encodeURIComponent(inviterName)}&inviterPhone=${encodeURIComponent(inviterPhone)}&inviterProjectName=${encodeURIComponent(inviterProjectName)}`;
// 使用api.qrserver.com生成二维码
const qrCodeUrl = `https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=${encodeURIComponent(inviteUrl)}`;
console.log('生成的二维码URL:', qrCodeUrl);
// 更新二维码图片
this.setData({
qrCodeUrl: qrCodeUrl
}, () => {
console.log('二维码URL已更新:', this.data.qrCodeUrl);
// 显示成功提示
wx.showToast({
title: '邀请二维码生成成功!',
icon: 'success',
duration: 2000
});
});
},
// 图片加载成功事件
onImageLoad: function () {
console.log('二维码图片加载成功');
this.setData({
imageLoading: false,
imageError: false
});
},
// 图片加载失败事件
onImageError: function (e) {
console.error('二维码图片加载失败:', e);
this.setData({
imageLoading: false,
imageError: true
});
wx.showToast({
title: '二维码图片加载失败,请重试',
icon: 'none',
duration: 2000
});
} }
}); });

60
pages/qrcode/index.wxml

@ -1,14 +1,58 @@
<view class="container"> <view class="container">
<view class="qrcode-container"> <view class="user-info">
<text class="qrcode-title">二维码</text> <view class="user-info-header">
<view class="qrcode-content"> <text class="user-info-title">登录信息</text>
<!-- 这里可以添加二维码图片 --> </view>
<view wx:if="{{qrCodeUrl}}" class="qrcode-image"> <view class="user-info-content">
<image src="{{qrCodeUrl}}" mode="aspectFit"></image> <text class="user-info-item">职位:<text class="user-info-value">{{userInfo.projectName}}</text></text>
<text class="user-info-item">姓名:<text class="user-info-value">{{userInfo.name}}</text></text>
<text class="user-info-item">电话:<text class="user-info-value">{{userInfo.phoneNumber}}</text></text>
</view>
</view>
<view class="header">
<text class="header-title">生成邀请二维码</text>
<text class="header-subtitle">创建一个二维码,邀请他人填写合格证信息</text>
</view>
<view class="info-box">
<text class="info-box-title">使用说明</text>
<text class="info-box-item">1. 点击下方按钮生成邀请二维码</text>
<text class="info-box-item">2. 将生成的二维码分享给需要填写信息的人</text>
<text class="info-box-item">3. 对方扫描二维码后,填写完整的合格证信息并提交</text>
<text class="info-box-item">4. 您可以扫描下方二维码查看和导出已填写的信息</text>
</view>
<view class="qr-container">
<text class="qr-container-title">📝 邀请二维码</text>
<view wx:if="{{qrCodeUrl}}" class="qrcode-image">
<image
src="{{qrCodeUrl}}"
mode="aspectFit"
bindload="onImageLoad"
binderror="onImageError"
></image>
<view wx:if="{{imageLoading}}" class="image-loading">
<text>加载中...</text>
</view> </view>
<view wx:else class="qrcode-placeholder"> <view wx:if="{{imageError}}" class="image-error">
<text class="placeholder-text">二维码将显示在这里</text> <text>加载失败,请重试</text>
</view> </view>
</view> </view>
<view wx:else class="qrcode-placeholder">
<text class="placeholder-text">二维码将显示在这里</text>
</view>
<view class="qr-info">
<text class="qr-info-title">作用:邀请他人填写合格证信息</text>
<text class="qr-info-subtitle">扫描此二维码进入信息填写页面</text>
</view>
</view>
<view class="action-buttons">
<button class="action-btn primary" bindtap="generateQRCode">生成邀请二维码</button>
</view>
<view class="footer">
<text class="footer-text">技术支持:四川又鸟蛋贸易有限公司</text>
</view> </view>
</view> </view>

232
pages/qrcode/index.wxss

@ -1,41 +1,121 @@
.container { .container {
display: flex; max-width: 480px;
flex-direction: column; margin: 0 auto;
align-items: center; background-color: white;
justify-content: center;
min-height: 100vh; min-height: 100vh;
background-color: #f5f5f5; padding: 20px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
.user-info {
background-color: #f8f9fa;
border-radius: 8px;
padding: 15px;
margin-bottom: 20px;
width: 100%;
box-sizing: border-box;
} }
.qrcode-container { .user-info-header {
width: 90%;
max-width: 400rpx;
background-color: #ffffff;
border-radius: 16rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
padding: 40rpx;
display: flex; display: flex;
flex-direction: column; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 10px;
} }
.qrcode-title { .user-info-title {
font-size: 32rpx; font-size: 16px;
font-weight: bold; font-weight: bold;
color: #333333; color: #333;
margin-bottom: 40rpx;
} }
.qrcode-content { .logout-btn {
width: 100%; padding: 6px 12px;
display: flex; font-size: 14px;
flex-direction: column; background-color: #6c757d;
align-items: center; color: white;
border: none;
border-radius: 4px;
}
.user-info-content {
font-size: 14px;
color: #666;
}
.user-info-item {
margin-bottom: 8px;
display: block;
}
.user-info-value {
font-weight: 500;
}
.header {
text-align: center;
margin-bottom: 30px;
padding-top: 20px;
}
.header-title {
font-size: 24px;
color: #28a745;
font-weight: bold;
margin-bottom: 10px;
display: block;
}
.header-subtitle {
font-size: 16px;
color: #666;
display: block;
}
.info-box {
background-color: #f8f9fa;
border-radius: 8px;
padding: 15px;
margin: 20px 0;
}
.info-box-title {
font-size: 18px;
color: #333;
font-weight: bold;
margin-bottom: 10px;
display: block;
}
.info-box-item {
font-size: 14px;
color: #666;
line-height: 1.5;
margin-bottom: 8px;
display: block;
}
.qr-container {
text-align: center;
margin: 30px 0;
}
.qr-container-title {
color: #28a745;
font-weight: bold;
margin-bottom: 15px;
display: block;
} }
.qrcode-image { .qrcode-image {
width: 300rpx; width: 300px;
height: 300rpx; height: 300px;
margin: 0 auto;
background-color: white;
padding: 15px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
position: relative;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -46,18 +126,110 @@
height: 100%; height: 100%;
} }
.qrcode-placeholder { .image-loading,
width: 300rpx; .image-error {
height: 300rpx; position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.8);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
border-radius: 10px;
}
.image-loading text,
.image-error text {
color: #666;
font-size: 14px;
}
.qrcode-placeholder {
width: 300px;
height: 300px;
margin: 0 auto;
background-color: #f0f0f0; background-color: #f0f0f0;
border-radius: 8rpx; border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
} }
.placeholder-text { .placeholder-text {
font-size: 24rpx; font-size: 14px;
color: #999999; color: #999;
text-align: center; text-align: center;
} }
.qr-info {
margin-top: 15px;
padding: 10px;
background-color: #e6f7ee;
border-radius: 8px;
}
.qr-info-title {
color: #28a745;
font-weight: 500;
margin-bottom: 5px;
display: block;
}
.qr-info-subtitle {
color: #666;
font-size: 14px;
display: block;
}
.action-buttons {
display: flex;
flex-direction: column;
gap: 15px;
margin-top: 30px;
}
.action-btn {
padding: 15px;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 500;
text-align: center;
transition: background-color 0.3s;
}
.action-btn.primary {
background-color: #28a745;
color: white;
}
.action-btn.primary:hover {
background-color: #218838;
}
.footer {
text-align: center;
margin-top: 40px;
padding: 20px 0;
font-size: 14px;
color: #999;
border-top: 1px solid #f0f0f0;
}
@media (max-width: 480px) {
.container {
max-width: 100%;
padding: 15px;
}
.header-title {
font-size: 20px;
}
.qrcode-image {
max-width: 250px;
max-height: 250px;
}
}

Loading…
Cancel
Save