yingsa/miniprogram/pages/user/index.wxml
ethanfly e0713c3fd8 feat: 实现天梯排行数字大屏页面并统一品牌名称为英飒俱乐部
- 新增无需登录的数字大屏页面,包含蓝色和橙色主题
- 在管理后台仪表盘添加大屏入口快速按钮
- 扩展天梯排名接口,支持大屏显示模式(绕过最低参赛场次限制)
- 统一将项目品牌名称从“影杀/羽动俱乐部”更新为“英飒俱乐部”
- 更新相关配置文件、文档和界面中的品牌名称
- 添加公开数据接口用于获取门店列表和天梯排名
2026-01-30 00:59:26 +08:00

229 lines
9.7 KiB
Plaintext
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.

<!-- 个人中心页面 - 运动感设计 -->
<view class="page-container">
<!-- 顶部装饰背景 -->
<view class="hero-bg">
<view class="hero-pattern"></view>
</view>
<!-- 用户信息区域 -->
<view class="user-section">
<!-- 已登录状态 -->
<block wx:if="{{userInfo && userInfo.phone}}">
<view class="profile-card animate-fadeInUp">
<view class="avatar-wrapper" bindtap="onTapAvatar">
<image class="avatar-xl" src="{{userInfo.avatar || '/images/avatar-default.svg'}}" mode="aspectFill"></image>
<view class="avatar-ring"></view>
<view class="avatar-edit-badge">
<text class="edit-icon">✏️</text>
</view>
</view>
<view class="user-info">
<text class="nickname">{{userInfo.nickname || '新用户'}}</text>
<view class="user-stats">
<view class="stat-item">
<text class="stat-value">{{userInfo.totalPoints || 0}}</text>
<text class="stat-label">积分</text>
</view>
<view class="stat-divider"></view>
<view class="stat-item">
<text class="stat-value highlight">{{ladderUser.powerScore || 0}}</text>
<text class="stat-label">战力</text>
</view>
<view class="stat-divider" wx:if="{{ladderUser}}"></view>
<view class="stat-item" wx:if="{{ladderUser}}">
<text class="stat-value">{{ladderUser.matchCount || 0}}</text>
<text class="stat-label">场次</text>
</view>
</view>
</view>
</view>
<!-- 会员码卡片 -->
<view class="member-card" bindtap="showMemberCode">
<view class="member-card-bg"></view>
<view class="member-card-content">
<view class="member-icon">
<image src="/images/icon-qrcode.svg" mode="aspectFit"></image>
</view>
<view class="member-info">
<text class="member-title">我的会员码</text>
<text class="member-code">{{userInfo.memberCode}}</text>
</view>
<view class="member-action">
<text class="action-text">查看</text>
<text class="action-arrow"></text>
</view>
</view>
<view class="scan-hint">出示给对方扫码挑战</view>
</view>
</block>
<!-- 未登录状态 -->
<block wx:else>
<view class="login-card animate-fadeInUp">
<view class="login-avatar-wrapper">
<image class="login-avatar" src="/images/avatar-default.svg" mode="aspectFill"></image>
<view class="login-avatar-pulse"></view>
</view>
<view class="login-content">
<text class="login-title">开启你的运动之旅</text>
<text class="login-subtitle">授权手机号,加入英飒俱乐部</text>
</view>
<button class="login-btn-primary" open-type="getPhoneNumber" bindgetphonenumber="onGetPhoneNumber">
<text class="btn-icon">📱</text>
<text class="btn-text">手机号快捷登录</text>
</button>
</view>
</block>
</view>
<!-- 天梯信息卡片 -->
<view class="ladder-section animate-fadeInUp" style="animation-delay: 0.2s" wx:if="{{ladderUser}}">
<view class="section-header">
<text class="section-title">天梯战绩</text>
<text class="section-badge">{{currentStore.storeName}}</text>
</view>
<view class="ladder-stats">
<view class="ladder-stat-item">
<view class="stat-icon lv{{ladderUser.level}}">
<text>{{ladderUser.levelName || 'Lv' + ladderUser.level}}</text>
</view>
<text class="stat-name">{{ladderUser.realName}}</text>
</view>
<view class="ladder-progress">
<view class="progress-info">
<text class="progress-label">战力值</text>
<text class="progress-value">{{ladderUser.powerScore}}</text>
</view>
<view class="progress-bar">
<view class="progress-fill" style="width: {{ladderUser.powerScore / 30}}%;"></view>
</view>
</view>
<view class="ladder-record">
<view class="record-item">
<text class="record-value win">{{ladderUser.winCount || 0}}</text>
<text class="record-label">胜场</text>
</view>
<view class="record-item">
<text class="record-value">
{{(ladderUser.matchCount || 0) - (ladderUser.winCount || 0)}}
</text>
<text class="record-label">负场</text>
</view>
<view class="record-item">
<text class="record-value rate">
{{(ladderUser.matchCount > 0 && ladderUser.winCount !== null && ladderUser.winCount !== undefined) ? Math.round((Number(ladderUser.winCount) || 0) / Number(ladderUser.matchCount) * 100) : 0}}%
</text>
<text class="record-label">胜率</text>
</view>
</view>
</view>
</view>
<!-- 未加入天梯提示 -->
<view class="notice-card animate-fadeInUp" style="animation-delay: 0.2s" wx:elif="{{userInfo && userInfo.phone}}">
<view class="notice-icon">🏸</view>
<view class="notice-content">
<text class="notice-title">尚未加入天梯系统</text>
<text class="notice-desc">请联系门店工作人员,开启你的天梯之旅</text>
</view>
</view>
<!-- 功能菜单 -->
<view class="menu-section animate-fadeInUp" style="animation-delay: 0.3s">
<view class="menu-grid">
<view class="menu-item" bindtap="goTo" data-url="/pages/match/history/index">
<view class="menu-icon history">
<image src="/images/icon-history.svg" mode="aspectFit"></image>
</view>
<text class="menu-text">比赛记录</text>
</view>
<view class="menu-item" bindtap="goTo" data-url="/pages/points/records/index">
<view class="menu-icon points">
<image src="/images/icon-points.svg" mode="aspectFit"></image>
</view>
<text class="menu-text">积分记录</text>
</view>
<view class="menu-item" bindtap="goTo" data-url="/pages/points/order/index">
<view class="menu-icon order">
<image src="/images/icon-order.svg" mode="aspectFit"></image>
</view>
<text class="menu-text">兑换订单</text>
</view>
<view class="menu-item" bindtap="goTo" data-url="/pages/store/index">
<view class="menu-icon store">
<image src="/images/icon-store.svg" mode="aspectFit"></image>
</view>
<text class="menu-text">切换门店</text>
</view>
</view>
</view>
</view>
<!-- 会员码弹窗 -->
<view class="qrcode-overlay {{showQrcode ? 'show' : ''}}" bindtap="hideQrcode">
<view class="qrcode-modal {{showQrcode ? 'show' : ''}}" catchtap="preventBubble">
<view class="modal-header">
<text class="modal-title">我的会员码</text>
<view class="modal-close" bindtap="hideQrcode">×</view>
</view>
<view class="qrcode-wrapper">
<view class="qrcode-border">
<!-- 加载中 -->
<view class="qrcode-loading" wx:if="{{qrcodeLoading}}">
<view class="loading-spinner"></view>
<text class="loading-text">生成中...</text>
</view>
<!-- 二维码图片 -->
<image wx:else class="qrcode-image" src="{{qrcodeImage}}" mode="aspectFit" show-menu-by-longpress="{{true}}"></image>
</view>
<view class="qrcode-corners">
<view class="corner tl"></view>
<view class="corner tr"></view>
<view class="corner bl"></view>
<view class="corner br"></view>
</view>
</view>
<view class="qrcode-info">
<text class="code-label">会员码</text>
<text class="code-value">{{userInfo.memberCode}}</text>
</view>
<view class="qrcode-tips">
<view class="tip-item">
<text class="tip-icon">📱</text>
<text class="tip-text">请出示给对方扫描发起挑战</text>
</view>
</view>
</view>
</view>
<!-- 完善资料弹窗 -->
<view class="profile-overlay {{showProfileModal ? 'show' : ''}}" bindtap="closeProfileModal">
<view class="profile-modal {{showProfileModal ? 'show' : ''}}" catchtap="preventBubble">
<view class="profile-modal-header">
<text class="profile-modal-title">{{isEditMode ? '修改资料' : '完善个人资料'}}</text>
<view class="profile-modal-close" bindtap="closeProfileModal">×</view>
</view>
<view class="profile-modal-body">
<!-- 提示信息 -->
<view class="profile-tips" wx:if="{{!isEditMode}}">
<text class="tips-icon">💡</text>
<text class="tips-text">完善资料后,好友可以更容易找到你</text>
</view>
<!-- 头像选择 -->
<view class="profile-avatar-section">
<text class="profile-label">头像</text>
<button class="avatar-choose-btn" open-type="chooseAvatar" bindchooseavatar="onChooseAvatarNew">
<image class="profile-avatar-preview" src="{{profileForm.avatar || '/images/avatar-default.svg'}}" mode="aspectFill"></image>
<view class="avatar-choose-badge">
<text class="choose-icon">📷</text>
</view>
</button>
<text class="avatar-tip">点击更换头像</text>
</view>
<!-- 昵称输入 -->
<view class="profile-nickname-section">
<text class="profile-label">昵称</text>
<input class="nickname-input" type="nickname" placeholder="请输入昵称" value="{{profileForm.nickname}}" bindinput="onNicknameInput" maxlength="20" />
</view>
</view>
<view class="profile-modal-footer">
<button class="profile-btn-cancel" bindtap="closeProfileModal">
{{isEditMode ? '取消' : '跳过'}}
</button>
<button class="profile-btn-confirm" bindtap="saveProfile">保存</button>
</view>
</view>
</view>