213 lines
9.7 KiB
Plaintext
213 lines
9.7 KiB
Plaintext
<!-- 顶部打卡卡模板 -->
|
||
<template name="top-card">
|
||
<view class="card top-card {{checked ? 'done-card' : ''}}">
|
||
<view class="status-row">
|
||
<view class="date-chip" bindtap="openWeekPicker" hover-class="{{weekList.length > 0 ? 'date-chip-hover' : 'none'}}">
|
||
<view class="date-week">{{weekday}}</view>
|
||
<view class="date-num">{{dayNum}}<text class="date-arrow" wx:if="{{weekList.length > 0}}"> ▾</text></view>
|
||
</view>
|
||
<view class="status-main">
|
||
<view class="status-title {{checked ? 'done' : 'undone'}}">{{checked ? '已打卡' : '未打卡'}}</view>
|
||
<view class="status-sub">{{checked ? '已完成今日打卡' : '请选择状态完成打卡'}}</view>
|
||
<view class="hero-status" wx:if="{{checked}}">
|
||
<view class="hero-status-dot" style="background-color:{{statusColor}}"></view>
|
||
<text class="hero-status-label" style="color:{{statusColor}}">{{record.status}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="pills-grid {{submitting ? 'disabled' : ''}}">
|
||
<view
|
||
wx:for="{{statusItems}}"
|
||
wx:key="label"
|
||
class="pill {{statusIndex === index ? 'active' : ''}}"
|
||
style="background-color:{{statusIndex === index ? item.color : '#ffffff'}};border-color:{{statusIndex === index ? item.color : '#D8C7B4'}};color:{{statusIndex === index ? '#ffffff' : '#5A4A3A'}}"
|
||
data-index="{{index}}"
|
||
hover-class="pill-hover"
|
||
bindtap="onStatusTap"
|
||
>
|
||
<view class="dot" style="background-color:{{statusIndex === index ? '#ffffff' : item.color}}"></view>
|
||
<text>{{item.label}}</text>
|
||
</view>
|
||
<view class="submitting" wx:if="{{submitting}}">提交中…</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<!-- 成员列表项模板 -->
|
||
<template name="member-item">
|
||
<view class="member {{item.checked ? 'ok' : 'idle'}}">
|
||
<view class="member-avatar {{item.checked ? 'ok' : ''}}">{{item.shortName}}</view>
|
||
<view class="member-info">
|
||
<view class="member-line">
|
||
<text class="member-name">{{item.name}}</text>
|
||
<text class="member-sid" wx:if="{{item.student_id}}">- {{item.student_id}}</text>
|
||
</view>
|
||
<view class="member-meta">{{item.checked ? ('打卡 ' + item.timeText) : ''}}</view>
|
||
</view>
|
||
<view class="member-badge {{item.checked ? 'ok' : 'idle'}}">{{item.checked ? item.record.status : '未打卡'}}</view>
|
||
</view>
|
||
</template>
|
||
|
||
<!-- 加载失败 -->
|
||
<block wx:if="{{loadError}}">
|
||
<view class="page">
|
||
<view class="error-card">
|
||
<view class="error-icon">!</view>
|
||
<view class="error-title">{{loadError}}</view>
|
||
<button class="btn-retry" hover-class="btn-hover" bindtap="onRetry">重新加载</button>
|
||
</view>
|
||
</view>
|
||
</block>
|
||
|
||
<!-- 首次加载骨架屏 -->
|
||
<block wx:if="{{loading && view === 'overview'}}">
|
||
<view class="page">
|
||
<view class="skeleton-card">
|
||
<view class="sk sk-title"></view>
|
||
<view class="sk sk-line w60"></view>
|
||
<view class="sk sk-line w90"></view>
|
||
</view>
|
||
<view class="skeleton-list">
|
||
<view class="sk sk-row" wx:for="{{[1, 2, 3, 4, 5]}}" wx:key="*this"></view>
|
||
</view>
|
||
</view>
|
||
</block>
|
||
|
||
<block wx:elif="{{!loading}}">
|
||
<view class="page fade-in">
|
||
<!-- 老师总览视图 -->
|
||
<block wx:if="{{isTeacher && view === 'overview'}}">
|
||
<!-- 顶部打卡卡 -->
|
||
<template is="top-card" data="{{checked,weekList,weekday,dayNum,statusColor,record,statusItems,statusIndex,submitting}}"></template>
|
||
|
||
<!-- 小组统计列表 -->
|
||
<view class="record-panel">
|
||
<view class="section-title">小组统计</view>
|
||
<scroll-view class="record-scroll" scroll-y refresher-enabled refresher-triggered="{{refreshing}}" bindrefresherrefresh="onRefresh">
|
||
<view class="groups-list">
|
||
<view class="group-card" hover-class="group-card-hover" wx:for="{{groups}}" wx:key="group_name" wx:for-item="group">
|
||
<view class="group-main" data-group="{{group.group_name}}" bindtap="openGroup">
|
||
<view class="group-row">
|
||
<view class="group-avatar">{{index + 1}}</view>
|
||
<view class="group-name">{{group.group_name}}</view>
|
||
<view class="group-counts">
|
||
<text class="count done">已打卡 {{group.checked_count}}</text>
|
||
<text class="count total">{{group.total}}人</text>
|
||
</view>
|
||
<view class="chevron">›</view>
|
||
</view>
|
||
<view class="progress-track">
|
||
<view class="progress-bar" style="width: {{group.percent}}%"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="unassigned" wx:if="{{unassignedCount > 0}}">另有未分组 {{unassignedCount}} 人</view>
|
||
<view class="empty" wx:if="{{groups.length === 0}}">
|
||
<view class="empty-icon">👥</view>
|
||
<view class="empty-text">暂无小组</view>
|
||
</view>
|
||
</view>
|
||
<view class="bottom-space"></view>
|
||
</scroll-view>
|
||
</view>
|
||
</block>
|
||
|
||
<!-- 老师详情视图 -->
|
||
<block wx:elif="{{isTeacher && view === 'detail'}}">
|
||
<view class="detail-head">
|
||
<view class="back" hover-class="back-hover" bindtap="backToOverview">‹ 返回</view>
|
||
<view class="detail-title-wrap">
|
||
<view class="detail-title">{{selectedGroupName}}</view>
|
||
<view class="detail-sub" bindtap="openWeekPicker" hover-class="{{weekList.length > 0 ? 'head-hover' : 'none'}}">
|
||
{{classDate}} <text class="head-arrow" wx:if="{{weekList.length > 0}}"> ▾</text>
|
||
</view>
|
||
</view>
|
||
<view class="detail-progress">{{checkedCount}}/{{total}}</view>
|
||
</view>
|
||
|
||
<scroll-view class="detail-scroll" scroll-y refresher-enabled refresher-triggered="{{refreshing}}" bindrefresherrefresh="onRefresh">
|
||
<view class="state-block" wx:if="{{loading}}">
|
||
<view class="state-icon">◌</view>
|
||
<view>加载中...</view>
|
||
</view>
|
||
<view class="member-list" wx:else>
|
||
<block wx:for="{{members}}" wx:key="user_id" wx:for-item="item">
|
||
<template is="member-item" data="{{item: item}}"></template>
|
||
</block>
|
||
</view>
|
||
<view class="empty" wx:if="{{!loading && members.length === 0}}">暂无成员</view>
|
||
<view class="bottom-space"></view>
|
||
</scroll-view>
|
||
</block>
|
||
|
||
<!-- 学员视图 -->
|
||
<block wx:else>
|
||
<!-- 顶部打卡卡 -->
|
||
<template is="top-card" data="{{checked,weekList,weekday,dayNum,statusColor,record,statusItems,statusIndex,submitting}}"></template>
|
||
|
||
<!-- 记录区:小组/个人 tab -->
|
||
<view class="record-panel">
|
||
<view class="tabs">
|
||
<view class="tab {{tab === 'group' ? 'active' : ''}}" data-tab="group" hover-class="tab-hover" bindtap="switchTab">小组</view>
|
||
<view class="tab {{tab === 'personal' ? 'active' : ''}}" data-tab="personal" hover-class="tab-hover" bindtap="switchTab">个人</view>
|
||
</view>
|
||
<scroll-view class="record-scroll" scroll-y refresher-enabled refresher-triggered="{{refreshing}}" bindrefresherrefresh="onRefresh">
|
||
<view class="record-inner" wx:if="{{tab === 'group'}}">
|
||
<view class="group-head" wx:if="{{groupName}}">
|
||
<view class="group-title">{{groupName}} · {{classDate}}</view>
|
||
<view class="group-progress">{{checkedCount}}/{{total}} 已打卡</view>
|
||
</view>
|
||
<view class="empty" wx:if="{{!groupName}}">
|
||
<view class="empty-icon">👥</view>
|
||
<view class="empty-text">暂无小组,请联系管理员分配</view>
|
||
</view>
|
||
<view class="empty" wx:elif="{{members.length === 0}}">
|
||
<view class="empty-icon">📭</view>
|
||
<view class="empty-text">本周暂无打卡记录</view>
|
||
</view>
|
||
<view class="member-list" wx:else>
|
||
<block wx:for="{{members}}" wx:key="user_id" wx:for-item="item">
|
||
<template is="member-item" data="{{item: item}}"></template>
|
||
</block>
|
||
</view>
|
||
</view>
|
||
<view wx:else class="record-inner">
|
||
<view class="empty" wx:if="{{history.length === 0}}">
|
||
<view class="empty-icon">📒</view>
|
||
<view class="empty-text">暂无个人打卡记录</view>
|
||
</view>
|
||
<view class="history-item" wx:for="{{history}}" wx:key="id">
|
||
<view class="history-head">
|
||
<view class="history-date">{{item.class_date}}</view>
|
||
<view class="history-badge" style="color:{{item.color}};background:{{item.bg}}">{{item.status}}</view>
|
||
</view>
|
||
<view class="history-time">{{item.timeText}}</view>
|
||
</view>
|
||
<view class="history-footer" wx:if="{{history.length > 0}}">
|
||
<text wx:if="{{historyLoading}}">加载中…</text>
|
||
<text wx:elif="{{historyFinished}}">— 已加载全部 —</text>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</block>
|
||
|
||
<!-- 周选择弹层 -->
|
||
<view class="picker-mask" wx:if="{{showWeekPicker}}" bindtap="closeWeekPicker"></view>
|
||
<view class="picker-panel {{showWeekPicker ? 'show' : ''}}" wx:if="{{showWeekPicker}}">
|
||
<view class="picker-title">选择上课周</view>
|
||
<scroll-view class="picker-list" scroll-y>
|
||
<view
|
||
class="picker-item {{item === classDate ? 'active' : ''}}"
|
||
wx:for="{{weekList}}"
|
||
wx:key="*this"
|
||
data-date="{{item}}"
|
||
bindtap="onWeekSelect"
|
||
>
|
||
<text>{{item}}</text>
|
||
<text class="picker-check" wx:if="{{item === classDate}}">✓</text>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</view>
|
||
</block> |