feat(app): 添加课程页面并优化打卡和计划功能
- 新增 pages/course/course 页面,集成 web-view 显示线上课程列表 - 在 app.json 中注册课程页面并添加底部 tabbar 导航 - 优化打卡页面,添加学号显示和改进成员列表布局 - 重构计划页面,添加内容详情弹层和优化加载逻辑 - 添加阿里云 OSS 上传工具模块用于文件上传功能 - 统一姓名和学号在同一行显示,改善 UI 体验 - 修复多个页面中的绑定事件和样式问题
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<view
|
||||
class="type-tab {{typeIndex === index ? 'active' : ''}}"
|
||||
wx:for="{{types}}"
|
||||
wx:key="index"
|
||||
wx:key="*this"
|
||||
data-index="{{index}}"
|
||||
hover-class="type-tab-hover"
|
||||
bindtap="onTypeChange"
|
||||
@@ -24,7 +24,7 @@
|
||||
<view class="overview-head">
|
||||
<view class="head-title-wrap">
|
||||
<view class="head-title">{{types[typeIndex]}}</view>
|
||||
<view class="head-sub" wx:if="{{isTeacher}}" bindtap="{{periodList.length > 0 ? 'openPeriodPicker' : ''}}" hover-class="{{periodList.length > 0 ? 'head-hover' : ''}}">
|
||||
<view class="head-sub" wx:if="{{isTeacher}}" bindtap="openPeriodPicker" hover-class="{{periodList.length > 0 ? 'head-hover' : 'none'}}">
|
||||
{{periodKey}}
|
||||
<text class="head-arrow" wx:if="{{periodList.length > 0}}"> ▾</text>
|
||||
</view>
|
||||
@@ -93,8 +93,8 @@
|
||||
<view
|
||||
class="group-period-row"
|
||||
wx:if="{{myGroup}}"
|
||||
bindtap="{{periodList.length > 0 ? 'openPeriodPicker' : ''}}"
|
||||
hover-class="{{periodList.length > 0 ? 'head-hover' : ''}}"
|
||||
bindtap="openPeriodPicker"
|
||||
hover-class="{{periodList.length > 0 ? 'head-hover' : 'none'}}"
|
||||
>
|
||||
<text class="group-period-text">{{myGroup}} · {{periodKey}}</text>
|
||||
<text class="head-arrow" wx:if="{{periodList.length > 0}}"> ▾</text>
|
||||
@@ -103,16 +103,22 @@
|
||||
<view class="state-icon">◌</view>
|
||||
<view>加载中...</view>
|
||||
</view>
|
||||
<!-- 学员小组 tab:只展示成员信息,不展示任何人的打卡内容,也不提供详情入口 -->
|
||||
<view class="member-list" wx:elif="{{members.length > 0}}">
|
||||
<view class="member" wx:for="{{members}}" wx:key="user_id" wx:for-item="member">
|
||||
<view class="member-left">
|
||||
<view class="member-avatar {{member.filled ? 'done' : 'unchecked'}}">{{index + 1}}</view>
|
||||
<view class="member-info">
|
||||
<view class="member-name">{{member.name}}</view>
|
||||
<view class="member-meta" wx:if="{{member.filled && member.record}}">{{member.record.checked_at}} 提交</view>
|
||||
<view class="member" wx:for="{{members}}" wx:key="user_id" wx:for-item="member" wx:for-index="mi">
|
||||
<view class="member-row">
|
||||
<view class="member-left">
|
||||
<view class="member-avatar {{member.filled ? 'done' : 'unchecked'}}">{{mi + 1}}</view>
|
||||
<view class="member-info">
|
||||
<view class="member-line">
|
||||
<text class="member-name">{{member.name}}</text>
|
||||
<text class="member-sid" wx:if="{{member.student_id}}">学号 {{member.student_id}}</text>
|
||||
</view>
|
||||
<view class="member-meta" wx:if="{{member.filled && member.record}}">{{member.record.checked_at}} 提交</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="badge {{member.filled ? 'done' : 'unchecked'}}">{{member.filled ? '已完成' : '未完成'}}</view>
|
||||
</view>
|
||||
<view class="badge {{member.filled ? 'done' : 'unchecked'}}">{{member.filled ? '已完成' : '未完成'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="empty" wx:elif="{{!loading && !myGroup}}">
|
||||
@@ -131,7 +137,13 @@
|
||||
<view class="empty-icon">📒</view>
|
||||
<view class="empty-text">暂无{{types[typeIndex]}}记录</view>
|
||||
</view>
|
||||
<view class="history-card" wx:for="{{history}}" wx:key="id">
|
||||
<!-- 卡片直接铺内容:正文 3 行截断、缩略图最多 2 张;全部文字与图片在「查看详情」弹层里看 -->
|
||||
<view
|
||||
class="history-card"
|
||||
wx:for="{{history}}"
|
||||
wx:key="id"
|
||||
wx:for-index="hi"
|
||||
>
|
||||
<view class="history-head">
|
||||
<view class="history-period">{{item.period_key}}</view>
|
||||
<view class="history-status" style="color:{{item.statusColor}};background:{{item.statusBg}}">{{item.status}}</view>
|
||||
@@ -139,8 +151,17 @@
|
||||
<view class="history-meta" wx:if="{{item.checked_at}}">{{item.checked_at}} 提交</view>
|
||||
<view class="history-content" wx:if="{{item.content}}">{{item.content}}</view>
|
||||
<view class="history-thumbs" wx:if="{{item.thumbs.length > 0}}">
|
||||
<image class="history-thumb" wx:for="{{item.thumbs}}" wx:for-item="thumb" wx:key="*this" src="{{thumb}}" mode="aspectFill"></image>
|
||||
<image
|
||||
class="history-thumb"
|
||||
wx:for="{{item.thumbs}}"
|
||||
wx:for-item="thumb"
|
||||
wx:for-index="ti"
|
||||
wx:key="*this"
|
||||
src="{{thumb}}"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
</view>
|
||||
<view class="tap-hint" data-hi="{{hi}}" hover-class="tap-hint-hover" bindtap="openHistoryDetail">查看详情 ›</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
@@ -176,7 +197,7 @@
|
||||
<view class="back" hover-class="back-hover" bindtap="backToOverview">‹ 返回</view>
|
||||
<view class="detail-title-wrap">
|
||||
<view class="head-title">{{selectedGroupName}}</view>
|
||||
<view class="head-sub" bindtap="{{periodList.length > 0 ? 'openPeriodPicker' : ''}}" hover-class="{{periodList.length > 0 ? 'head-hover' : ''}}">
|
||||
<view class="head-sub" bindtap="openPeriodPicker" hover-class="{{periodList.length > 0 ? 'head-hover' : 'none'}}">
|
||||
{{periodKey}} <text class="head-arrow" wx:if="{{periodList.length > 0}}"> ▾</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -187,15 +208,36 @@
|
||||
<view>加载中...</view>
|
||||
</view>
|
||||
<view class="member-list">
|
||||
<view class="member" wx:for="{{members}}" wx:key="user_id" wx:for-item="member">
|
||||
<view class="member-left">
|
||||
<view class="member-avatar {{member.filled ? 'done' : 'unchecked'}}">{{index + 1}}</view>
|
||||
<view class="member-info">
|
||||
<view class="member-name">{{member.name}}</view>
|
||||
<view class="member-meta" wx:if="{{member.filled && member.record}}">{{member.record.checked_at}} 提交</view>
|
||||
<view class="member" wx:for="{{members}}" wx:key="user_id" wx:for-item="member" wx:for-index="mi">
|
||||
<!-- 已提交者整行可点,全文与全部图片在详情弹层里看(未提交者 handler 内部会直接返回) -->
|
||||
<view
|
||||
class="member-row"
|
||||
data-mi="{{mi}}"
|
||||
hover-class="{{member.filled ? 'member-row-hover' : 'none'}}"
|
||||
bindtap="openMemberDetail"
|
||||
>
|
||||
<view class="member-left">
|
||||
<view class="member-avatar {{member.filled ? 'done' : 'unchecked'}}">{{mi + 1}}</view>
|
||||
<view class="member-info">
|
||||
<view class="member-line">
|
||||
<text class="member-name">{{member.name}}</text>
|
||||
<text class="member-sid" wx:if="{{member.student_id}}">学号 {{member.student_id}}</text>
|
||||
</view>
|
||||
<view class="member-meta" wx:if="{{member.filled && member.record}}">{{member.record.checked_at}} 提交</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="badge {{member.filled ? 'done' : 'unchecked'}}">{{member.filled ? '已完成' : '未完成'}}</view>
|
||||
</view>
|
||||
<view class="badge {{member.filled ? 'done' : 'unchecked'}}">{{member.filled ? '已完成' : '未完成'}}</view>
|
||||
<!-- 提示文字是 .member-row 的兄弟节点,必须自己绑事件,否则点它没有任何节点接收
|
||||
(不要挪进 .member-row 里 —— tap 会冒泡到父行导致 openMemberDetail 执行两次,
|
||||
同 tick 连发 setData 会触发 recursive update detected) -->
|
||||
<view
|
||||
class="tap-hint"
|
||||
wx:if="{{member.filled}}"
|
||||
data-mi="{{mi}}"
|
||||
hover-class="tap-hint-hover"
|
||||
bindtap="openMemberDetail"
|
||||
>点击查看详情 ›</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="empty" wx:if="{{!loading && members.length === 0}}">暂无成员</view>
|
||||
@@ -220,4 +262,34 @@
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!-- 内容详情弹层:完整文章 + 全部图片 -->
|
||||
<view class="cd-mask" wx:if="{{contentDetail}}" bindtap="closeContentDetail" catchtouchmove="noop"></view>
|
||||
<view class="cd-panel" wx:if="{{contentDetail}}">
|
||||
<view class="cd-head">
|
||||
<view class="cd-head-text">
|
||||
<view class="cd-title">{{contentDetail.title}}</view>
|
||||
<view class="cd-sub" wx:if="{{contentDetail.sub}}">{{contentDetail.sub}}</view>
|
||||
</view>
|
||||
<view class="cd-close" hover-class="cd-close-hover" bindtap="closeContentDetail">✕</view>
|
||||
</view>
|
||||
<view class="cd-meta" wx:if="{{contentDetail.meta}}">{{contentDetail.meta}}</view>
|
||||
<scroll-view class="cd-body" scroll-y>
|
||||
<view class="cd-content" wx:if="{{contentDetail.content}}">{{contentDetail.content}}</view>
|
||||
<view class="cd-no-content" wx:if="{{!contentDetail.content}}">未填写文字内容</view>
|
||||
<view class="cd-thumbs" wx:if="{{contentDetail.thumbs.length > 0}}">
|
||||
<image
|
||||
class="cd-thumb"
|
||||
wx:for="{{contentDetail.thumbs}}"
|
||||
wx:for-item="pic"
|
||||
wx:for-index="ci"
|
||||
wx:key="*this"
|
||||
src="{{pic}}"
|
||||
mode="widthFix"
|
||||
data-ci="{{ci}}"
|
||||
bindtap="previewDetailImage"
|
||||
></image>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
Reference in New Issue
Block a user