ltx d17f43135d feat: 完善多角色赛事服务功能
- 新增参赛者、裁判、检录员角色识别及角色化首页与个人中心
- 新增裁判注册、身份认证提示、赛事执裁报名及报名记录查询
- 新增检录工作台,支持检录任务、轮次状态与运动员检录操作
- 新增赛事成绩查询页面及成绩详情展示
- 封装成绩、检录和裁判报名接口,补充请求参数清理逻辑
- 新增检录 Tab 图标、页面路由及本地开发配置
- 新增 Git 忽略规则,排除依赖、构建缓存、日志和本地工具文件
2026-08-07 11:28:38 +08:00

163 lines
9.4 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-home">
<scroll-view wx:if="{{isChecker}}" class="home-scroll checker-home" scroll-y="{{true}}" enhanced show-scrollbar="{{false}}" refresher-enabled="{{true}}" refresher-triggered="{{refresherTriggered}}" bindrefresherrefresh="onRefresherRefresh">
<view class="checker-hero">
<view class="checker-hero-top">
<view class="checker-live"><view class="checker-live-dot"></view><text>检录任务</text></view>
<text class="checker-venue">{{checkerContext.venue || '等待分配场地'}}</text>
</view>
<text class="checker-event">{{checkerContext.eventName || '当前暂无检录任务'}}</text>
<text class="checker-welcome">检录员工作台</text>
</view>
<view wx:if="{{checkerContext}}" class="checker-task-card">
<view class="checker-task-head">
<view><text class="checker-task-label">当前检次</text><text class="checker-task-round">{{checkerContext.currentCheckinName || checkerContext.roundName}} · 共 {{checkerContext.totalCheckins || checkerContext.totalRounds}} 检</text></view>
<view class="checker-task-status">进行中</view>
</view>
<view class="checker-group-box">
<text class="checker-task-label">检录范围</text>
<text class="checker-group-name">全部运动员</text>
<text class="checker-group-order">后一检仅接收已通过前一检的运动员</text>
</view>
<button class="checker-enter-btn" bindtap="goToCheckin">进入检录工作台</button>
</view>
<view wx:elif="{{checkerLoading}}" class="checker-empty">正在加载检录任务...</view>
<view wx:else class="checker-empty">当前暂无检录任务,下拉可刷新</view>
</scroll-view>
<scroll-view wx:else class="home-scroll" scroll-y="{{true}}" enhanced show-scrollbar="{{false}}" lower-threshold="100" bindscrolltolower="onScrollToLower" refresher-enabled="{{true}}" refresher-threshold="{{80}}" refresher-default-style="black" refresher-triggered="{{refresherTriggered}}" bindrefresherrefresh="onRefresherRefresh">
<swiper class="banner" indicator-dots="{{banners.length > 1}}" autoplay="{{banners.length > 1}}" interval="4000" circular="{{banners.length > 1}}" indicator-color="rgba(255,255,255,0.55)" indicator-active-color="#1a57b2">
<block wx:for="{{banners}}" wx:key="_bannerKey">
<swiper-item>
<view class="banner-item" bindtap="onBannerTap" data-linktype="{{item.linkType}}" data-eventid="{{item.eventId}}" data-linkurl="{{item.linkUrl}}">
<image class="banner-image" src="{{item.imageUrl}}" mode="aspectFill" />
</view>
</swiper-item>
</block>
</swiper>
<view class="sticky-header">
<view class="search-wrap">
<image class="search-img" src="https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/event_miniapp/search-left.png" />
<input class="search-input" placeholder="搜索关键字" placeholder-class="search-ph" value="{{keyword}}" confirm-type="search" bindconfirm="onSearch" bindinput="onKeywordInput" />
<view class="search-btn" bindtap="onSearch">
<mp-icon icon="search" size="22" color="#ffffff" />
<text class="search-btn-text">搜索</text>
</view>
</view>
<view class="section-tabs">
<view class="section-tab {{sectionTab === 'list' ? 'is-active' : ''}}" data-tab="list" bindtap="onSectionTab">
<text class="section-tab-text">{{isReferee ? '报名执裁' : '赛事报名'}}</text>
<image class="section-tab-img" wx:if="{{sectionTab === 'list'}}" src="https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/event_miniapp/home-title-b.png" />
</view>
<view class="section-tab {{sectionTab === 'registered' ? 'is-active' : ''}}" data-tab="registered" bindtap="onSectionTab">
<text class="section-tab-text">{{isReferee ? '已报名执裁' : '已报赛事'}}</text>
<image class="section-tab-img" wx:if="{{sectionTab === 'registered'}}" src="https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/event_miniapp/home-title-b.png" />
</view>
</view>
<view class="status-filters" wx:if="{{sectionTab === 'list'}}">
<view class="status-pill {{status === 1 ? 'is-on' : ''}}" data-status="1" bindtap="onStatusTap">
报名中
</view>
<view class="status-pill {{status === 3 ? 'is-1' : ''}}" data-status="3" bindtap="onStatusTap">
比赛中
</view>
<view class="status-pill {{status === 4 ? 'is-2' : ''}}" data-status="4" bindtap="onStatusTap">
已结束
</view>
</view>
</view>
<view class="list-section">
<block wx:if="{{sectionTab === 'registered' && !loggedIn}}">
<view class="login-hint">
<text class="login-hint-text">登录后可查看{{isReferee ? '已报名执裁赛事' : '已报名赛事'}}</text>
<button class="login-hint-btn" type="primary" bindtap="goLogin">去登录</button>
</view>
</block>
<!-- 首屏加载骨架 -->
<block wx:elif="{{isFirstLoad && rows.length === 0}}">
<view class="skeleton-card" wx:for="{{[1,2,3]}}" wx:key="*this">
<view class="skeleton-cover"></view>
<view class="skeleton-body">
<view class="skeleton-line skeleton-line--long"></view>
<view class="skeleton-line skeleton-line--short"></view>
<view class="skeleton-line skeleton-line--mid"></view>
</view>
</view>
</block>
<block wx:elif="{{rows.length === 0 && !loading}}">
<view class="empty">暂无数据</view>
</block>
<block wx:for="{{rows}}" wx:key="rowKey">
<view class="event-card" wx:if="{{sectionTab === 'registered' || (status == 0 || item.eventStatus == status)}}" bindtap="onEventTap" data-id="{{item.id}}">
<view class="event-card-media">
<image class="event-card-cover" src="{{item.coverImage}}" mode="aspectFill" />
<view class="addr-pill" wx:if="{{item.address}}">{{item.address}}</view>
<view class="status-pill-top status-pill-top-{{item.eventStatus}}">
{{item.eventStatusText}}
</view>
</view>
<view class="event-card-body">
<view class="title-row">
<text class="event-title">{{item.eventName || '-'}}</text>
<view class="format-tag" wx:if="{{item.eventFormatText}}">
{{item.eventFormatText}}
</view>
</view>
<block wx:if="{{sectionTab === 'list'}}">
<view class="meta-line">
报名时间:{{item.registrationStartText}}~{{item.registrationEndText}}
</view>
<view class="meta-line">比赛时间:{{item.matchStartText}}~{{item.matchEndText}}</view>
</block>
<block wx:else>
<view class="meta-line">{{isReferee ? '报名执裁时间' : '报名时间'}}:{{item.registrationTimeText}}</view>
<view class="meta-line" wx:if="{{isReferee && item.matchStartText}}">比赛时间:{{item.matchStartText}}~{{item.matchEndText}}</view>
<view class="meta-line" wx:if="{{item.projectCount != null}}">
已报项目:{{item.projectCount}} 项
</view>
<view class="meta-line" wx:if="{{item.isNeedMaterial && item.materialRangeText}}">
素材上传时间:{{item.materialRangeText}}
</view>
</block>
</view>
<view class="card-actions" wx:if="{{sectionTab === 'registered' && isReferee}}" catchtap>
<view class="action-btn action-btn--referee" catchtap>已报名执裁</view>
</view>
<view class="card-actions" wx:elif="{{sectionTab === 'registered'}}" catchtap>
<view wx:if="{{item.isNeedMaterial}}" class="action-btn action-btn--ghost" catchtap="onUploadMaterialTap" data-registrationid="{{item.registrationId}}" data-matstarttime="{{item.matStartTime}}" data-matendtime="{{item.matEndTime}}" data-materialrangetext="{{item.materialRangeText}}">
上传素材
</view>
<block wx:if="{{item.paymentStatus === 1}}">
<view class="action-btn action-btn--paid" catchtap>已支付</view>
</block>
<block wx:else>
<view class="action-btn action-btn--ghost" catchtap="onUploadVoucherTap" data-registrationid="{{item.registrationId}}">
上传付款凭证
</view>
</block>
<!-- <view class="action-btn action-btn--ghost" catchtap>更改参赛人</view> -->
<view
class="action-btn {{item.canCancel ? 'action-btn--danger' : 'action-btn--disabled'}}"
catchtap="onCancelRegistrationTap"
data-registrationid="{{item.registrationId}}"
data-cancancel="{{item.canCancel}}"
>
取消报名
</view>
</view>
</view>
</block>
<!-- 底部状态:加载更多 / 没有更多 -->
<view wx:if="{{loading && rows.length > 0}}" class="loading">
<view class="loading-dots">
<view class="loading-dot"></view>
<view class="loading-dot"></view>
<view class="loading-dot"></view>
</view>
</view>
<view wx:elif="{{!hasMore && rows.length > 0}}" class="loading">没有更多了</view>
</view>
</scroll-view>
</view>