Explorar o código

feat(qr): 优化二维码页面样式与功能

- 添加刷新二维码按钮,提升用户体验
- 根据屏幕宽度动态计算二维码尺寸,确保显示效果
- 重设计二维码卡片样式,使用毛玻璃背景和渐变边框
- 增强用户信息展示区域,优化标题和角色徽章样式
- 改进二维码容器装饰,添加角标和交互反馈
- 引入动画效果,提升页面加载和交互体验
- 添加响应式优化,适配小屏幕设备
- 增加深色模式支持,提高视觉舒适度
mcbaiyun hai 1 mes
pai
achega
fbe97a1d36
Modificáronse 1 ficheiros con 169 adicións e 53 borrados
  1. 169 53
      src/pages/public/profile/qr/index.vue

+ 169 - 53
src/pages/public/profile/qr/index.vue

@@ -18,6 +18,9 @@
             v-if="qrData"
           ></canvas>
         </view>
+        <view class="refresh-btn" @click="generateQRCode">
+          <text class="refresh-text">刷新二维码</text>
+        </view>
       </view>
     </view>
   </view>
@@ -86,10 +89,15 @@ const generateQRCode = () => {
   })
   console.log('QR data:', data)
   qrData.value = data
+  // 获取系统信息,计算 rpx 到 px 的转换
+  const systemInfo = uni.getSystemInfoSync()
+  const rpxToPx = systemInfo.windowWidth / 750
+  const qrSizeRpx = 350 // 与 CSS 中的 .qr-canvas 尺寸一致 (rpx)
+  const qrSizePx = Math.floor(qrSizeRpx * rpxToPx) // 转换为像素
   // 使用 weapp-qrcode 生成二维码
   drawQrcode({
-    width: 200,
-    height: 200,
+    width: qrSizePx,
+    height: qrSizePx,
     canvasId: 'qrcode',
     text: data
   })
@@ -120,106 +128,214 @@ onShow(() => {
 }
 
 .qr-card {
-  background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
-  border-radius: 24rpx;
-  padding: 50rpx;
-  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
+  background: rgba(255, 255, 255, 0.95);
+  backdrop-filter: blur(20px);
+  border-radius: 32rpx;
+  padding: 60rpx 40rpx;
+  box-shadow: 
+    0 20rpx 40rpx rgba(0, 0, 0, 0.1),
+    0 8rpx 16rpx rgba(0, 0, 0, 0.05),
+    inset 0 1rpx 0 rgba(255, 255, 255, 0.6);
   display: flex;
   flex-direction: column;
   align-items: center;
-  max-width: 550rpx;
-  width: 85%;
+  max-width: 600rpx;
+  width: 90%;
   position: relative;
   overflow: hidden;
+  border: 1rpx solid rgba(255, 255, 255, 0.2);
+  animation: cardEntrance 0.6s ease-out;
 }
 
-.qr-card::before {
+/* 渐变边框效果 */
+.qr-card::after {
   content: '';
   position: absolute;
   top: 0;
   left: 0;
   right: 0;
-  height: 8rpx;
-  background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
-  border-radius: 24rpx 24rpx 0 0;
+  bottom: 0;
+  border-radius: 32rpx;
+  padding: 2rpx;
+  background: linear-gradient(135deg, #667eea, #764ba2, #f093fb);
+  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
+  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
+  -webkit-mask-composite: xor;
+  mask-composite: exclude;
+  pointer-events: none;
 }
 
 .user-info {
   text-align: center;
-  margin-bottom: 50rpx;
+  margin-bottom: 60rpx;
   position: relative;
+  width: 100%;
 }
 
 .title-row {
   display: flex;
-  justify-content: center;
+  justify-content: space-between;
   align-items: center;
-  margin-bottom: 20rpx;
+  margin-bottom: 30rpx;
+  background: linear-gradient(135deg, #f8f9fa, #e9ecef);
+  padding: 20rpx 30rpx;
+  border-radius: 20rpx;
+  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
 }
 
 .card-title {
-  flex: 1;
-  text-align: center;
-  font-size: 40rpx;
-  font-weight: bold;
+  font-size: 36rpx;
+  font-weight: 700;
   color: #2c3e50;
-  text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.1);
+  text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
 }
 
 .role-badge {
-  margin-left: auto;
-  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  background: linear-gradient(135deg, #667eea, #764ba2);
   color: white;
-  padding: 8rpx 14rpx;
-  border-radius: 16rpx;
+  padding: 12rpx 20rpx;
+  border-radius: 20rpx;
   font-size: 24rpx;
-  font-weight: 500;
-  box-shadow: 0 2rpx 8rpx rgba(102, 126, 234, 0.3);
-}
-
-.user-info::after {
-  content: '';
-  position: absolute;
-  bottom: -20rpx;
-  left: 50%;
-  transform: translateX(-50%);
-  width: 80rpx;
-  height: 4rpx;
-  background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
-  border-radius: 2rpx;
+  font-weight: 600;
+  box-shadow: 0 4rpx 12rpx rgba(102, 126, 234, 0.3);
+  border: 1rpx solid rgba(255, 255, 255, 0.2);
 }
 
 .user-name {
-  font-size: 56rpx;
-  font-weight: bold;
+  font-size: 48rpx;
+  font-weight: 700;
   color: #2c3e50;
   display: block;
-  margin-bottom: 12rpx;
-  text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.1);
+  margin: 20rpx 0;
+  background: linear-gradient(135deg, #2c3e50, #4a6572);
+  -webkit-background-clip: text;
+  background-clip: text;
+  -webkit-text-fill-color: transparent;
+  text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
 }
 
 .qr-desc {
-  font-size: 32rpx;
-  color: #95a5a6;
+  font-size: 28rpx;
+  color: #6c757d;
   font-weight: 400;
   display: block;
-  margin-top: 10rpx;
+  margin-top: 15rpx;
+  line-height: 1.5;
+  padding: 0 20rpx;
 }
 
 .qr-container {
   display: flex;
   justify-content: center;
   align-items: center;
-  padding: 30rpx;
-  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
-  border-radius: 16rpx;
-  border: 2rpx solid #dee2e6;
-  box-shadow: inset 0 2rpx 4rpx rgba(0, 0, 0, 0.05);
+  padding: 40rpx;
+  background: linear-gradient(135deg, #f8f9fa, #e9ecef);
+  border-radius: 24rpx;
+  border: 1rpx solid rgba(255, 255, 255, 0.5);
+  box-shadow: 
+    inset 0 2rpx 4rpx rgba(255, 255, 255, 0.8),
+    0 8rpx 20rpx rgba(0, 0, 0, 0.1);
+  position: relative;
+  overflow: hidden;
+  transition: all 0.3s ease;
+}
+
+/* 二维码装饰角 */
+.qr-container::before,
+.qr-container::after {
+  content: '';
+  position: absolute;
+  width: 40rpx;
+  height: 40rpx;
+  border: 4rpx solid #667eea;
+}
+
+.qr-container::before {
+  top: 10rpx;
+  left: 10rpx;
+  border-right: none;
+  border-bottom: none;
+}
+
+.qr-container::after {
+  bottom: 10rpx;
+  right: 10rpx;
+  border-left: none;
+  border-top: none;
+}
+
+.qr-container:active {
+  transform: scale(0.98);
+  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
 }
 
 .qr-canvas {
-  width: 400rpx;
-  height: 400rpx;
-  border-radius: 8rpx;
+  opacity: 0.75;
+  border-radius: 12rpx;
+  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+  border: 1rpx solid rgba(0, 0, 0, 0.1);
+}
+
+@keyframes cardEntrance {
+  0% {
+    opacity: 0;
+    transform: translateY(30rpx) scale(0.95);
+  }
+  100% {
+    opacity: 1;
+    transform: translateY(0) scale(1);
+  }
+}
+
+/* 响应式优化 */
+/* 针对不同屏幕尺寸的适配 */
+@media (max-width: 375px) {
+  .qr-card {
+    padding: 40rpx 30rpx;
+    width: 95%;
+  }
+  
+  .user-name {
+    font-size: 40rpx;
+  }
+  
+  .qr-canvas {
+    width: 350rpx;
+    height: 350rpx;
+  }
+}
+
+/* 深色模式支持 */
+@media (prefers-color-scheme: dark) {
+  .qr-card {
+    background: rgba(40, 40, 40, 0.95);
+    color: #ffffff;
+  }
+  
+  .card-title, .user-name {
+    color: #ffffff;
+  }
+  
+  .qr-desc {
+    color: #b0b0b0;
+  }
+}
+
+/* 添加刷新按钮(可选) */
+.refresh-btn {
+  margin-top: 40rpx;
+  padding: 20rpx 40rpx;
+  background: linear-gradient(135deg, #667eea, #764ba2);
+  color: white;
+  border-radius: 25rpx;
+  font-size: 28rpx;
+  font-weight: 500;
+  box-shadow: 0 4rpx 12rpx rgba(102, 126, 234, 0.3);
+  transition: all 0.3s ease;
+}
+
+.refresh-btn:active {
+  transform: scale(0.95);
+  box-shadow: 0 2rpx 6rpx rgba(102, 126, 234, 0.4);
 }
 </style>