update:教师体测报告

This commit is contained in:
ltx 2026-07-13 15:32:38 +08:00
parent 0351b1fdbd
commit 3efa7b0ad8
5 changed files with 225 additions and 53 deletions

View File

@ -31,6 +31,8 @@ Page({
rank: {}, rank: {},
isTrainer: false, isTrainer: false,
courseList: [], //教练课堂记录 courseList: [], //教练课堂记录
coursePage: 1,
courseHasMore: true,
nowCourse: {}, nowCourse: {},
showDialog: false, showDialog: false,
clickCouse: {}, //选中的教练课程 clickCouse: {}, //选中的教练课程
@ -55,11 +57,17 @@ Page({
wx.showLoading({ wx.showLoading({
title: '', title: '',
}) })
if (wx.getStorageSync('roleId') && wx.getStorageSync('roleId') == 4) { const isTrainer = wx.getStorageSync('roleId') && wx.getStorageSync('roleId') == 4
this.setData({
isTrainer,
activeTab: isTrainer ? 0 : 1
})
if (isTrainer) {
await this.getTrainClass(true) await this.getTrainClass(true)
await this.getFitnessClasses() await this.getFitnessClasses()
} else { } else {
await this.getClass() await this.getClass()
await this.getTrainClass(true)
} }
wx.hideLoading() wx.hideLoading()
}, },
@ -122,7 +130,9 @@ Page({
const avgHeart = d.avgHR || 0 const avgHeart = d.avgHR || 0
const highDuration = `${d.highIntensity || 0}分钟` const highDuration = `${d.highIntensity || 0}分钟`
const highRatio = `${d.highIntensityDurationRatio || 0}%` const highRatio = `${d.highIntensityDurationRatio || 0}%`
return { ...d, heartRange, avgHeart, highDuration, highRatio, _moderateHR: moderateHR, _highHR: highHR } const heartRateTrend = d.heartRateTrend || { axisX: [], axisY: [] }
const studentTrainingRecordList = d.studentTrainingRecordList || []
return { ...d, heartRateTrend, studentTrainingRecordList, heartRange, avgHeart, highDuration, highRatio, _moderateHR: moderateHR, _highHR: highHR }
}, },
clickCouse(e) { clickCouse(e) {
@ -174,35 +184,40 @@ Page({
//获取教练课堂记录 刷新 加载更多 //获取教练课堂记录 刷新 加载更多
async getTrainClass(isRefresh) { async getTrainClass(isRefresh) {
const that = this const that = this
let refresh = isRefresh && isRefresh.type != "scrolltolower" const refresh = isRefresh && isRefresh.type != "scrolltolower"
console.log(isRefresh) const pageIndex = refresh ? 1 : this.data.coursePage
console.log('aaaaaaaaaaa',refresh) if (!this.data.courseHasMore && !refresh) return
if (!this.data.hasMore && !refresh) return //非刷新且没有
if (refresh) this.setData({ courseLoading: true }) if (refresh) this.setData({ courseLoading: true })
const res = await getClassRoomRecord({ const res = await getClassRoomRecord({
pageIndex: this.data.page, pageIndex,
PageSize: 20, PageSize: 20,
}) })
if(res.data.datas.length > 0){ const courseList = res && res.data && res.data.datas ? res.data.datas : []
const detail = await getClassRoomReportDetails(this.data.nowCourse.id ? this.data.nowCourse.id : res.data.datas[0].id) const total = res && res.data && res.data.total ? res.data.total : 0
const nextCourse = (!this.data.nowCourse.id || refresh) ? courseList[0] : this.data.nowCourse
if (nextCourse && nextCourse.id) {
const needReloadDetail = refresh || !this.data.nowCourseDetail || this.data.nowCourseDetail.courseId !== nextCourse.id
const detail = needReloadDetail ? await getClassRoomReportDetails(nextCourse.id) : null
this.setData({ this.setData({
nowCourseDetail: this.data.nowCourse.id ? this.data.nowCourseDetail: this._buildCourseDetail(detail.data), nowCourse: nextCourse,
nowCourseDetail: needReloadDetail ? { ...this._buildCourseDetail(detail.data), courseId: nextCourse.id } : this.data.nowCourseDetail,
courseLoading: false, courseLoading: false,
},()=>{ },()=>{
that.drawCharts(that) that.drawCharts(that)
}) })
} else { } else if (refresh) {
if (refresh) this.setData({ courseLoading: false }) this.setData({ courseLoading: false, nowCourseDetail: {} })
} }
this.setData({ this.setData({
courseList: refresh ? res.data.datas : [...this.data.courseList, ...res.data.datas], courseList: refresh ? courseList : [...this.data.courseList, ...courseList],
page: this.data.page + 1, coursePage: pageIndex + 1,
hasMore: res.data.total > (this.data.page) * 20, courseHasMore: total > pageIndex * 20,
nowCourse: (!!this.data.nowCourse && !this.data.nowCourse.id) || refresh ? res.data.datas[0] : this.data.nowCourse, nowCourse: nextCourse || {},
}) })
}, },
//获取项目列表
async getProject() { async getProject() {
if(!this.data.nowClass || !this.data.nowClass.gradeId) return if(!this.data.nowClass || !this.data.nowClass.gradeId) return
const res = await getProjectList(this.data.nowClass.gradeId) const res = await getProjectList(this.data.nowClass.gradeId)
@ -254,8 +269,9 @@ Page({
drawCharts(that) { drawCharts(that) {
if (!that.data.nowCourse.id || !that.data.nowCourseDetail || !that.data.nowCourseDetail.heartRateTrend) return
const query = wx.createSelectorQuery().in(that); const query = wx.createSelectorQuery().in(that);
console.log('重新绘图',that.data.nowCourseDetail) console.log('????',that.data.nowCourseDetail)
query.select('#mycanvas').fields({ query.select('#mycanvas').fields({
node: true, node: true,
size: true size: true
@ -424,7 +440,7 @@ Page({
* 页面相关事件处理函数--监听用户下拉动作 * 页面相关事件处理函数--监听用户下拉动作
*/ */
async onPullDownRefresh() { async onPullDownRefresh() {
this.setData({ page: 1, hasMore: true }) this.setData({ page: 1, hasMore: true, coursePage: 1, courseHasMore: true })
if (this.data.isTrainer) { if (this.data.isTrainer) {
if (this.data.activeTab === 0) { if (this.data.activeTab === 0) {
await this.getTrainClass(true) await this.getTrainClass(true)
@ -433,6 +449,7 @@ Page({
} }
} else { } else {
await this.getClass() await this.getClass()
await this.getTrainClass(true)
} }
wx.stopPullDownRefresh() wx.stopPullDownRefresh()
app.showToast('刷新成功') app.showToast('刷新成功')

View File

@ -2,7 +2,17 @@
<view class="page-content"> <view class="page-content">
<mp-bar background="linear-gradient(190deg, #49a5fc 0%, #f7f7f7 800rpx, #f7f7f7 100%)" title="统计" color="#fff" back="{{false}}"></mp-bar> <mp-bar background="linear-gradient(190deg, #49a5fc 0%, #f7f7f7 800rpx, #f7f7f7 100%)" title="统计" color="#fff" back="{{false}}"></mp-bar>
<block wx:if="{{!isTrainer}}"> <!-- Tab switch -->
<view class="report-tabs">
<view class="report-tab-item {{activeTab === 0 ? 'report-tab-active' : ''}}" bindtap="switchTab" data-tab="{{0}}">
<text>课堂报告</text>
</view>
<view class="report-tab-item {{activeTab === 1 ? 'report-tab-active' : ''}}" bindtap="switchTab" data-tab="{{1}}">
<text>体测报告</text>
</view>
</view>
<block wx:if="{{!isTrainer && activeTab === 1}}">
<view class="card card1"> <view class="card card1">
<view class="all-item"> <view class="all-item">
<view class="num">{{total}}</view> <view class="num">{{total}}</view>
@ -55,23 +65,16 @@
<mp-icon icon="arrow" size="{{13}}" color="#8c8c8c"></mp-icon> <mp-icon icon="arrow" size="{{13}}" color="#8c8c8c"></mp-icon>
</view> </view>
<view wx:if="{{studentList.length == 0}}" class="nothing">暂无数据 ~~</view> <view wx:if="{{studentList.length == 0}}" class="report-empty">
<view class="report-empty-icon">暂无</view>
<text>暂无体测报告数据</text>
</view>
</block> </block>
<block wx:else>
<!-- Tab 切换 -->
<view class="report-tabs">
<view class="report-tab-item {{activeTab === 0 ? 'report-tab-active' : ''}}" bindtap="switchTab" data-tab="{{0}}">
<text>课堂报告</text>
</view>
<view class="report-tab-item {{activeTab === 1 ? 'report-tab-active' : ''}}" bindtap="switchTab" data-tab="{{1}}">
<text>体测报告</text>
</view>
</view>
<!-- 课堂报告 --> <!-- 课堂报告 -->
<block wx:if="{{activeTab === 0}}"> <block wx:if="{{activeTab === 0}}">
<view class="tab-item pickerY" bind:tap="showDialog">{{nowCourse.startingEndingTime}}
<view class="tab-item pickerY" bind:tap="showDialog">{{nowCourse.startingEndingTime || '暂无课堂记录'}}
<image src="https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/teacher/downn-b.png" mode="" /> <image src="https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/teacher/downn-b.png" mode="" />
</view> </view>
@ -96,8 +99,16 @@
</view> </view>
</block> </block>
<!-- 正式内容 --> <!-- empty -->
<block wx:else> <block wx:if="{{!courseLoading && !nowCourse.id}}">
<view class="report-empty">
<view class="report-empty-icon">暂无</view>
<text>暂无课堂报告数据</text>
</view>
</block>
<!-- content -->
<block wx:if="{{!courseLoading && nowCourse.id}}">
<view class="title"> <view class="title">
<view class="title-before"></view>心率统计 <view class="title-before"></view>心率统计
</view> </view>
@ -146,6 +157,7 @@
<view class="title-before"></view>学生列表 <view class="title-before"></view>学生列表
</view> </view>
<view wx:if="{{nowCourseDetail.studentTrainingRecordList && nowCourseDetail.studentTrainingRecordList.length > 0}}">
<view class="card" wx:for="{{nowCourseDetail.studentTrainingRecordList}}" wx:key="studentNo" data-item="{{item}}" bind:tap="goStudentList"> <view class="card" wx:for="{{nowCourseDetail.studentTrainingRecordList}}" wx:key="studentNo" data-item="{{item}}" bind:tap="goStudentList">
<view class="left"> <view class="left">
<image src="{{item.photo == '' ? 'https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/room/avater.png': item.photo}}" class="img" /> <image src="{{item.photo == '' ? 'https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/room/avater.png': item.photo}}" class="img" />
@ -154,6 +166,11 @@
</view> </view>
<mp-icon icon="arrow" size="{{13}}" color="#8c8c8c"></mp-icon> <mp-icon icon="arrow" size="{{13}}" color="#8c8c8c"></mp-icon>
</view> </view>
</view>
<view wx:if="{{!nowCourseDetail.studentTrainingRecordList || nowCourseDetail.studentTrainingRecordList.length == 0}}" class="report-empty report-empty-small">
<view class="report-empty-icon">暂无</view>
<text>暂无学生课堂数据</text>
</view>
</block> </block>
<mp-half-screen-dialog bindbuttontap="buttontap" show="{{showDialog}}" title="课堂记录"> <mp-half-screen-dialog bindbuttontap="buttontap" show="{{showDialog}}" title="课堂记录">
@ -167,8 +184,8 @@
</view> </view>
</view> </view>
</view> </view>
<view wx:if="{{haveMore}}" class="loading">加载中...</view> <view wx:if="{{courseHasMore}}" class="loading">加载中...</view>
<view wx:if="{{!haveMore}}" class="no-more">没有更多数据了</view> <view wx:if="{{!courseHasMore}}" class="no-more">没有更多数据了</view>
</scroll-view> </scroll-view>
</view> </view>
<view slot="footer" class="footer"> <view slot="footer" class="footer">
@ -179,7 +196,7 @@
</block> </block>
<!-- 体测报告 --> <!-- 体测报告 -->
<block wx:if="{{activeTab === 1}}"> <block wx:if="{{isTrainer && activeTab === 1}}">
<!-- 班级选择器 --> <!-- 班级选择器 -->
<view class="fitness-header"> <view class="fitness-header">
<view class="fitness-class-picker"> <view class="fitness-class-picker">
@ -224,10 +241,9 @@
</view> </view>
<!-- 空状态 --> <!-- 空状态 -->
<view wx:elif="{{!fitnessLoading}}" class="fitness-empty"> <view wx:elif="{{!fitnessLoading}}" class="report-empty">
<view class="fitness-empty-icon">📋</view> <view class="report-empty-icon">暂无</view>
<text>暂无学生数据</text> <text>暂无体测报告数据</text>
</view> </view>
</block> </block>
</block>
</view> </view>

View File

@ -612,3 +612,142 @@
font-size: 38rpx; font-size: 38rpx;
} }
/* ===== page polish ===== */
.page-content {
min-height: 100vh;
/* background: #f5f8fb; */
padding-bottom: 48rpx;
box-sizing: border-box;
}
.section-title {
display: flex;
align-items: center;
margin: 44rpx 30rpx 18rpx;
font-size: 32rpx;
font-weight: 700;
color: #1f2d3d;
}
.section-title-line {
width: 8rpx;
height: 30rpx;
border-radius: 8rpx;
margin-right: 14rpx;
background: linear-gradient(180deg, #26A5F6 0%, #7bd46d 100%);
}
.card {
border-radius: 18rpx;
box-shadow: 0 10rpx 30rpx rgba(31, 45, 61, 0.07);
border: 1rpx solid rgba(38, 165, 246, 0.06);
}
.card1 {
margin-top: 24rpx;
padding: 44rpx 28rpx;
background: linear-gradient(135deg, #ffffff 0%, #eef8ff 100%);
}
.all-item {
min-width: 96rpx;
text-align: center;
}
.all-item view {
line-height: 1.35;
}
.tab {
padding: 0 30rpx;
gap: 16rpx;
}
.tab picker {
flex: 1;
}
.tab-item {
min-width: 0;
height: 62rpx;
padding: 0 18rpx;
box-shadow: 0 6rpx 18rpx rgba(38, 165, 246, 0.08);
}
.pickerY {
width: auto;
margin: 18rpx 30rpx 0;
height: 68rpx;
font-size: 26rpx;
font-weight: 600;
}
.title {
margin-top: 42rpx;
color: #1f2d3d;
}
.canvasCard {
padding: 28rpx 24rpx 18rpx;
}
.charts {
margin: 0 auto;
}
.stat-grid {
justify-content: space-between;
}
.stat-card {
border-radius: 18rpx;
min-height: 150rpx;
}
.fitness-student-card {
border-radius: 18rpx;
box-shadow: 0 10rpx 26rpx rgba(31, 45, 61, 0.08);
}
.loading-dot {
width: 18rpx;
height: 18rpx;
border-radius: 50%;
margin-bottom: 16rpx;
background: #26A5F6;
box-shadow: -28rpx 0 0 rgba(38, 165, 246, 0.35), 28rpx 0 0 rgba(38, 165, 246, 0.35);
}
.report-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 34rpx 30rpx;
min-height: 300rpx;
background: #fff;
border-radius: 18rpx;
box-shadow: 0 10rpx 30rpx rgba(31, 45, 61, 0.07);
color: #9aa7b2;
font-size: 26rpx;
}
.report-empty-small {
min-height: 180rpx;
}
.report-empty-icon {
width: 96rpx;
height: 96rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20rpx;
background: #eef8ff;
color: #26A5F6;
font-size: 24rpx;
font-weight: 600;
}

View File

@ -19,7 +19,7 @@
<view class="item title"> <view class="item title">
<view class="name">项目</view> <view class="name">项目</view>
<text>成绩(最好)</text> <text>成绩(最新)</text>
<text>分数</text> <text>分数</text>
<text>等级</text> <text>等级</text>
</view> </view>

View File

@ -1,7 +1,7 @@
const ipAddress = "https://wechatapi.yuedongsports.com/"; // 根据实际情况修改 // const ipAddress = "https://wechatapi.yuedongsports.com/"; // 根据实际情况修改
// const ipAddress = "https://wechatapi-qa.yuedongsports.com/"; // 根据实际情况修改 const ipAddress = "https://wechatapi-qa.yuedongsports.com/"; // 根据实际情况修改
// const ipAddress = "http://192.168.0.146:9993/"; // 根据实际情况修改 // const ipAddress = "http://192.168.0.146:9993/"; // 根据实际情况修改
// const ipAddress = "http://localhost:9993/"; // 根据实际情况修改 // const ipAddress = "http://localhost:9995/"; // 根据实际情况修改
function getToken() { function getToken() {
return wx.getStorageSync('token'); // 获取存储的 token return wx.getStorageSync('token'); // 获取存储的 token