- Change VITE_API_URL in .env from localhost:3000 to localhost:3001 for backend access. - Update index.html to replace favicon with logo.png and ensure proper HTML structure. - Add new dependencies for WangEditor in package.json and package-lock.json to support rich text editing features.
250 lines
11 KiB
Plaintext
250 lines
11 KiB
Plaintext
<!--挑战赛页面 - 全新设计-->
|
||
<view class="page-container">
|
||
<!-- 顶部装饰背景 -->
|
||
<view class="hero-bg">
|
||
<view class="hero-pattern"></view>
|
||
</view>
|
||
|
||
<!-- 主要内容 -->
|
||
<view class="main-content">
|
||
<!-- 页面标题 -->
|
||
<view class="page-header">
|
||
<text class="page-title">发起挑战</text>
|
||
<text class="page-subtitle">扫描对手会员码,开启对决</text>
|
||
</view>
|
||
|
||
<!-- 当前门店 -->
|
||
<view class="store-bar" wx:if="{{currentStore}}" bindtap="goToStore">
|
||
<image class="store-icon" src="/images/icon-store.svg" mode="aspectFit"></image>
|
||
<text class="store-name">{{currentStore.storeName}}</text>
|
||
<text class="store-arrow">›</text>
|
||
</view>
|
||
|
||
<!-- 未登录或非天梯用户提示 -->
|
||
<view class="notice-card animate-fadeInUp" wx:if="{{!ladderUser}}">
|
||
<view class="notice-icon">
|
||
<image class="notice-icon-img" src="/images/icon-challenge.svg" mode="aspectFit"></image>
|
||
</view>
|
||
<view class="notice-content">
|
||
<text class="notice-title">暂未开通天梯</text>
|
||
<text class="notice-desc">请联系门店工作人员加入天梯系统</text>
|
||
</view>
|
||
<view class="notice-action" bindtap="refreshLadderInfo">
|
||
<text class="refresh-text">刷新</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 比赛功能区 -->
|
||
<block wx:else>
|
||
<!-- 用户信息卡片 -->
|
||
<view class="user-card animate-fadeInUp">
|
||
<view class="user-card-inner">
|
||
<view class="user-avatar-box">
|
||
<image class="user-avatar" src="{{userInfo.avatar || '/images/avatar-default.svg'}}" mode="aspectFill"></image>
|
||
</view>
|
||
<view class="user-info-box">
|
||
<view class="user-name-row">
|
||
<text class="user-name">{{ladderUser.realName}}</text>
|
||
<view class="user-level lv{{ladderUser.level}}">{{ladderUser.levelName || 'Lv' + ladderUser.level}}</view>
|
||
</view>
|
||
<view class="user-stats-row">
|
||
<view class="mini-stat">
|
||
<text class="mini-stat-value">{{ladderUser.powerScore}}</text>
|
||
<text class="mini-stat-label">战力分</text>
|
||
</view>
|
||
<view class="mini-stat">
|
||
<text class="mini-stat-value win">{{ladderUser.winCount || 0}}</text>
|
||
<text class="mini-stat-label">胜场</text>
|
||
</view>
|
||
<view class="mini-stat">
|
||
<text class="mini-stat-value">{{ladderUser.matchCount || 0}}</text>
|
||
<text class="mini-stat-label">总场次</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 扫码入口 - 并排展示 -->
|
||
<view class="scan-grid animate-fadeInUp" style="animation-delay: 0.1s">
|
||
<view class="scan-card challenge" bindtap="startChallenge">
|
||
<view class="scan-icon-wrapper">
|
||
<image class="scan-icon-img" src="/images/icon-challenge.svg" mode="aspectFit"></image>
|
||
</view>
|
||
<text class="scan-title">挑战赛</text>
|
||
<text class="scan-desc">1v1 对决</text>
|
||
<view class="scan-badge">不服就干</view>
|
||
</view>
|
||
|
||
<view class="scan-card ranking" bindtap="joinRankingMatch">
|
||
<view class="scan-icon-wrapper">
|
||
<image class="scan-icon-img" src="/images/icon-ranking.svg" mode="aspectFit"></image>
|
||
</view>
|
||
<text class="scan-title">排位赛</text>
|
||
<text class="scan-desc">多人竞技</text>
|
||
<view class="scan-badge accent">扫码加入</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 正在进行中的比赛(当前比赛信息) -->
|
||
<view class="ongoing-card animate-fadeInUp" style="animation-delay: 0.12s" wx:if="{{ongoingMatches.length > 0}}">
|
||
<view class="ongoing-header">
|
||
<view class="ongoing-header-left">
|
||
<image class="ongoing-icon-img" src="/images/icon-history.svg" mode="aspectFit"></image>
|
||
<text class="ongoing-title">当前比赛</text>
|
||
</view>
|
||
<view class="ongoing-count">{{ongoingMatches.length}}</view>
|
||
</view>
|
||
<view class="ongoing-list">
|
||
<view class="ongoing-item {{item.type === 1 ? 'challenge' : 'ranking'}}"
|
||
wx:for="{{ongoingMatches}}"
|
||
wx:key="id"
|
||
bindtap="goToMatchDetail"
|
||
data-match="{{item}}">
|
||
<view class="ongoing-item-header">
|
||
<view class="match-type-tag {{item.type === 1 ? 'challenge' : 'ranking'}}">
|
||
<text>{{item.typeName}}</text>
|
||
</view>
|
||
<view class="match-status-tag {{item.status === 0 ? 'waiting' : 'playing'}}">
|
||
{{item.statusName}}
|
||
</view>
|
||
</view>
|
||
<view class="ongoing-item-body">
|
||
<block wx:if="{{item.type === 1}}">
|
||
<!-- 挑战赛:显示对手信息 -->
|
||
<view class="opponent-info" wx:if="{{item.opponent}}">
|
||
<image class="opponent-avatar" src="{{item.opponent.avatar || '/images/avatar-default.svg'}}" mode="aspectFill"></image>
|
||
<view class="opponent-detail">
|
||
<text class="opponent-name">VS {{item.opponent.realName}}</text>
|
||
<view class="opponent-stats">
|
||
<text class="opponent-level">Lv{{item.opponent.level}}</text>
|
||
<text class="opponent-power">战力 {{item.opponent.powerScore}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</block>
|
||
<block wx:else>
|
||
<!-- 排位赛:显示比赛信息 -->
|
||
<view class="ranking-info">
|
||
<view class="ranking-name">{{item.name || '排位赛'}}</view>
|
||
<view class="ranking-meta">
|
||
<text class="ranking-stage">{{item.stageName}}</text>
|
||
<text class="ranking-players">{{item.playerCount}}人参赛</text>
|
||
</view>
|
||
<view class="current-opponent" wx:if="{{item.opponent}}">
|
||
<text class="current-label">当前对手:</text>
|
||
<text class="current-name">{{item.opponent.realName}}</text>
|
||
</view>
|
||
<view class="my-status {{item.myStatus}}">
|
||
<text wx:if="{{item.myStatus === 'waiting'}}">等待中</text>
|
||
<text wx:elif="{{item.myStatus === 'playing'}}">比赛中</text>
|
||
<text wx:else>已完成</text>
|
||
</view>
|
||
</view>
|
||
</block>
|
||
</view>
|
||
<view class="ongoing-item-footer">
|
||
<text class="match-weight" wx:if="{{item.weight > 1}}">权重 ×{{item.weight}}</text>
|
||
<text class="enter-btn">查看详情 ›</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 最近比赛(近10场,可进入更多) -->
|
||
<view class="recent-card animate-fadeInUp" style="animation-delay: 0.14s" wx:if="{{recentMatches.length > 0}}">
|
||
<view class="recent-header">
|
||
<view class="recent-header-left">
|
||
<image class="recent-icon-img" src="/images/icon-records.svg" mode="aspectFit"></image>
|
||
<text class="recent-title">最近比赛</text>
|
||
</view>
|
||
<view class="recent-actions" bindtap="goToRecentMatches">
|
||
<text class="recent-more-pill">最近7天</text>
|
||
</view>
|
||
</view>
|
||
<view class="recent-list">
|
||
<view class="recent-item" wx:for="{{recentMatches}}" wx:key="id" bindtap="goToMatchDetail" data-match="{{item}}">
|
||
<view class="recent-item-inner">
|
||
<view class="recent-line-1">
|
||
<text class="recent-name">{{item.name || (item.typeName + (item.matchCode || ''))}}</text>
|
||
<text class="recent-type-tag {{item.type === 1 ? 'challenge' : 'ranking'}}">{{item.typeName}}</text>
|
||
</view>
|
||
<view class="recent-line-2">
|
||
<text class="recent-store" wx:if="{{item.storeName}}">{{item.storeName}}</text>
|
||
<text class="recent-stage" wx:if="{{item.showStage}}">{{item.stageName}}</text>
|
||
<text class="recent-status status-{{item.statusType}}">{{item.statusName}}</text>
|
||
</view>
|
||
<view class="recent-line-3">
|
||
<text class="recent-time">{{item.timeText}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 待确认比赛 -->
|
||
<view class="pending-card animate-fadeInUp" style="animation-delay: 0.15s" wx:if="{{pendingGames.length > 0}}">
|
||
<view class="pending-header">
|
||
<text class="pending-title">待确认比分</text>
|
||
<view class="pending-count">{{pendingGames.length}}</view>
|
||
</view>
|
||
<view class="pending-list">
|
||
<view class="pending-item" wx:for="{{pendingGames}}" wx:key="id" bindtap="confirmGame" data-game="{{item}}">
|
||
<view class="game-info">
|
||
<text class="vs-tag">VS</text>
|
||
<text class="opponent-name">{{item.opponentName}}</text>
|
||
</view>
|
||
<text class="game-score">{{item.myScore}} : {{item.opponentScore}}</text>
|
||
<view class="confirm-btn">确认</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</block>
|
||
|
||
<!-- 战力值规则 -->
|
||
<view class="rules-card animate-fadeInUp" style="animation-delay: 0.2s">
|
||
<view class="rules-header">
|
||
<view class="rules-icon">
|
||
<image class="rules-icon-img" src="/images/icon-info.svg" mode="aspectFit"></image>
|
||
</view>
|
||
<text class="rules-title">战力值规则</text>
|
||
</view>
|
||
<view class="rules-grid">
|
||
<view class="rule-item">
|
||
<view class="rule-icon win">↑</view>
|
||
<view class="rule-text">
|
||
<text class="rule-label">胜方</text>
|
||
<text class="rule-value positive">+15 基础分</text>
|
||
</view>
|
||
</view>
|
||
<view class="rule-item">
|
||
<view class="rule-icon lose">↓</view>
|
||
<view class="rule-text">
|
||
<text class="rule-label">败方</text>
|
||
<text class="rule-value negative">-5 基础分</text>
|
||
</view>
|
||
</view>
|
||
<view class="rule-item">
|
||
<view class="rule-icon bonus">★</view>
|
||
<view class="rule-text">
|
||
<text class="rule-label">以下克上</text>
|
||
<text class="rule-value">额外 +10%</text>
|
||
</view>
|
||
</view>
|
||
<view class="rule-item">
|
||
<view class="rule-icon shield">
|
||
<image class="rule-icon-img" src="/images/icon-shield.svg" mode="aspectFit"></image>
|
||
</view>
|
||
<view class="rule-text">
|
||
<text class="rule-label">新手保护</text>
|
||
<text class="rule-value">输分减半</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="rules-note">
|
||
提示:同一对手30天内仅限挑战1次
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|