update:教练查看体测报告
This commit is contained in:
parent
4f4599ef6f
commit
6e67f91a10
3
app.json
3
app.json
@ -71,7 +71,8 @@
|
||||
"teacher/report-detail/report-detail",
|
||||
"user/apply-school/apply-school",
|
||||
"user/redeem-class/redeem-class",
|
||||
"parent/fitness-detail/fitness-detail"
|
||||
"parent/fitness-detail/fitness-detail",
|
||||
"teacher/student-fitness-detail/student-fitness-detail"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
@ -38,6 +38,12 @@ Page({
|
||||
cWidth: 330,
|
||||
cHeight: 280,
|
||||
pixelRatio: 2,
|
||||
// 体测报告
|
||||
activeTab: 0, // 0-课堂报告 1-体测报告
|
||||
fitnessClassList: [], // 体测班级列表
|
||||
nowFitnessClass: {}, // 当前体测班级
|
||||
fitnessStudentList: [], // 体测学生列表
|
||||
fitnessLoading: false,
|
||||
},
|
||||
|
||||
|
||||
@ -50,12 +56,55 @@ Page({
|
||||
})
|
||||
if (wx.getStorageSync('roleId') && wx.getStorageSync('roleId') == 4) {
|
||||
await this.getTrainClass(true)
|
||||
await this.getFitnessClasses()
|
||||
} else {
|
||||
await this.getClass()
|
||||
}
|
||||
wx.hideLoading()
|
||||
},
|
||||
|
||||
// 切换 Tab
|
||||
switchTab(e) {
|
||||
const tab = e.currentTarget.dataset.tab
|
||||
this.setData({ activeTab: tab })
|
||||
},
|
||||
|
||||
// 获取体测班级列表
|
||||
async getFitnessClasses() {
|
||||
const res = await getClassList()
|
||||
if (res && res.data && res.data.length > 0) {
|
||||
this.setData({
|
||||
fitnessClassList: res.data,
|
||||
nowFitnessClass: res.data[0]
|
||||
}, () => {
|
||||
this.getFitnessStudents()
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
// 体测班级切换
|
||||
fitnessPicker(e) {
|
||||
const nowFitnessClass = this.data.fitnessClassList[Number(e.detail.value)]
|
||||
this.setData({ nowFitnessClass }, () => {
|
||||
this.getFitnessStudents()
|
||||
})
|
||||
},
|
||||
|
||||
// 获取体测学生列表
|
||||
async getFitnessStudents() {
|
||||
if (!this.data.nowFitnessClass.classId) return
|
||||
this.setData({ fitnessLoading: true })
|
||||
const res = await getStudentList({
|
||||
pageIndex: 1,
|
||||
pageSize: 200,
|
||||
classId: this.data.nowFitnessClass.classId
|
||||
})
|
||||
this.setData({
|
||||
fitnessStudentList: (res && res.data && res.data.datas) ? res.data.datas : (res && res.data ? res.data : []),
|
||||
fitnessLoading: false
|
||||
})
|
||||
},
|
||||
|
||||
clickCouse(e) {
|
||||
this.setData({
|
||||
clickCouse: e.currentTarget.dataset.item
|
||||
@ -115,7 +164,7 @@ Page({
|
||||
pageIndex: this.data.page,
|
||||
PageSize: 20,
|
||||
})
|
||||
if(!this.data.nowCourse.id){
|
||||
if(!this.data.nowCourse.id && res.data.datas.length > 0){
|
||||
const detail = await getClassRoomReportDetails(res.data.datas[0].id)
|
||||
this.setData({
|
||||
nowCourseDetail:this.data.nowCourse.id ? this.data.nowCourseDetail: detail.data
|
||||
@ -133,6 +182,7 @@ Page({
|
||||
|
||||
//获取项目列表
|
||||
async getProject() {
|
||||
if(!this.data.nowClass || !this.data.nowClass.gradeId) return
|
||||
const res = await getProjectList(this.data.nowClass.gradeId)
|
||||
this.setData({
|
||||
projectList: res.data,
|
||||
@ -142,6 +192,7 @@ Page({
|
||||
|
||||
//获取学生列表 刷新 加载更多
|
||||
async getStudent(isRefresh) {
|
||||
if (!this.data.nowClass || !this.data.nowClass.classId) return
|
||||
if (!this.data.hasMore && !isRefresh) return //非刷新且没有
|
||||
const res = await getTongji({
|
||||
ClassId: this.data.nowClass.classId,
|
||||
@ -294,9 +345,14 @@ Page({
|
||||
wx.navigateTo({
|
||||
url: '/subpackage/teacher/report-detail/report-detail?id='+this.data.nowCourse.id +'&studentNo='+e.currentTarget.dataset.item.studentNo,
|
||||
})
|
||||
// wx.navigateTo({
|
||||
// url: '/subpackage/teacher/report-list/report-list?studentNo='+e.currentTarget.dataset.item.studentNo,
|
||||
// })
|
||||
},
|
||||
|
||||
// 体测报告 - 跳转学生体测详情
|
||||
goFitnessDetail(e) {
|
||||
const item = e.currentTarget.dataset.item
|
||||
wx.navigateTo({
|
||||
url: '/subpackage/teacher/student-fitness-detail/student-fitness-detail?studentNo=' + item.studentNo + '&classId=' + this.data.nowFitnessClass.classId
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@ -59,6 +59,18 @@
|
||||
</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}}">
|
||||
<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="" />
|
||||
</view>
|
||||
@ -90,21 +102,6 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- <view class="tp">
|
||||
<view class="table-t">
|
||||
<view class="no-b no-r">最大心率</view>
|
||||
<view class="no-b no-r">最小心率</view>
|
||||
<view class="no-b no-r">平均心率</view>
|
||||
<view class="no-b">中高强度时长(分钟)</view>
|
||||
</view>
|
||||
<view class="table-t">
|
||||
<view class="no-r">{{nowCourseDetail.maxHR || '- -'}}</view>
|
||||
<view class="no-r">{{nowCourseDetail.minHR || '- -'}}</view>
|
||||
<view class="no-r">{{nowCourseDetail.avgHR || '- -'}}</view>
|
||||
<view>{{nowCourseDetail.highIntensity || '- -'}}</view>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<view class="title">
|
||||
<view class="title-before"></view>学生列表
|
||||
</view>
|
||||
@ -114,9 +111,7 @@
|
||||
<image src="{{item.photo == '' ? 'https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/room/avater.png': item.photo}}" class="img" />
|
||||
{{item.studentName}}
|
||||
<image class="sex" src="https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/report-icon/sex_{{item.sex}}.png" mode=""/>
|
||||
<!-- {{item.age}}岁 -->
|
||||
</view>
|
||||
|
||||
<mp-icon icon="arrow" size="{{13}}" color="#8c8c8c"></mp-icon>
|
||||
</view>
|
||||
|
||||
@ -131,7 +126,6 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 加载更多提示 -->
|
||||
<view wx:if="{{haveMore}}" class="loading">加载中...</view>
|
||||
<view wx:if="{{!haveMore}}" class="no-more">没有更多数据了</view>
|
||||
</scroll-view>
|
||||
@ -141,5 +135,58 @@
|
||||
<button type="primary" bind:tap="sureClickCouse">确定</button>
|
||||
</view>
|
||||
</mp-half-screen-dialog>
|
||||
</block>
|
||||
|
||||
<!-- 体测报告 -->
|
||||
<block wx:if="{{activeTab === 1}}">
|
||||
<!-- 班级选择器 -->
|
||||
<view class="fitness-header">
|
||||
<view class="fitness-class-picker">
|
||||
<picker range="{{fitnessClassList}}" range-key="name" bindchange="fitnessPicker">
|
||||
<view class="fitness-picker-btn">
|
||||
<image src="https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/teacher/downn-b.png" class="picker-icon" />
|
||||
<text>{{nowFitnessClass.name || '请选择班级'}}</text>
|
||||
<image src="https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/teacher/downn-b.png" class="picker-arrow" />
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="fitness-count-badge">
|
||||
<text>共 {{fitnessStudentList.length}} 人</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载中 -->
|
||||
<view wx:if="{{fitnessLoading}}" class="fitness-loading">
|
||||
<view class="loading-dot"></view>
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
|
||||
<!-- 学生列表 -->
|
||||
<view wx:elif="{{fitnessStudentList.length > 0}}">
|
||||
<view class="fitness-student-card" wx:for="{{fitnessStudentList}}" wx:key="studentNo" bindtap="goFitnessDetail" data-item="{{item}}">
|
||||
<view class="fsc-avatar-wrap">
|
||||
<image class="fsc-avatar" src="{{item.photo || 'https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/room/avater.png'}}" mode="aspectFill" />
|
||||
</view>
|
||||
<view class="fsc-info">
|
||||
<view class="fsc-name-row">
|
||||
<text class="fsc-name">{{item.studentName || item.name}}</text>
|
||||
<image wx:if="{{item.sex}}" class="fsc-sex" src="https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/report-icon/sex_{{item.sex}}.png" mode="aspectFit" />
|
||||
</view>
|
||||
<view class="fsc-meta">
|
||||
<text wx:if="{{item.studentNo}}" class="fsc-no">学号:{{item.studentNo}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="fsc-arrow">
|
||||
<mp-icon icon="arrow" size="{{14}}" color="#26A5F6"></mp-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view wx:elif="{{!fitnessLoading}}" class="fitness-empty">
|
||||
<view class="fitness-empty-icon">📋</view>
|
||||
<text>暂无学生数据</text>
|
||||
</view>
|
||||
</block>
|
||||
</block>
|
||||
</view>
|
||||
@ -1,4 +1,180 @@
|
||||
/* pages/teacher/count/count.wxss */
|
||||
|
||||
/* ===== Tab 切换 ===== */
|
||||
.report-tabs {
|
||||
display: flex;
|
||||
margin: 24rpx 30rpx 0;
|
||||
background-color: #EAF4FF;
|
||||
border-radius: 60rpx;
|
||||
padding: 6rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.report-tab-item {
|
||||
flex: 1;
|
||||
height: 68rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 54rpx;
|
||||
font-size: 28rpx;
|
||||
color: #26A5F6;
|
||||
transition: all 0.25s;
|
||||
}
|
||||
|
||||
.report-tab-active {
|
||||
background: linear-gradient(135deg, #26A5F6 0%, #1478D4 100%);
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
box-shadow: 0 4rpx 16rpx rgba(38, 165, 246, 0.35);
|
||||
}
|
||||
|
||||
/* ===== 体测报告 header ===== */
|
||||
.fitness-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 30rpx 30rpx 16rpx;
|
||||
}
|
||||
|
||||
.fitness-class-picker {
|
||||
flex: 1;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.fitness-picker-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 72rpx;
|
||||
background: linear-gradient(135deg, #26A5F6 0%, #1478D4 100%);
|
||||
border-radius: 50rpx;
|
||||
padding: 0 24rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(38, 165, 246, 0.3);
|
||||
}
|
||||
|
||||
.fitness-picker-btn text {
|
||||
color: #fff;
|
||||
font-size: 26rpx;
|
||||
font-weight: bold;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.picker-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.picker-arrow {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
filter: brightness(10);
|
||||
}
|
||||
|
||||
.fitness-count-badge {
|
||||
background-color: #EAF4FF;
|
||||
border: 2rpx solid #26A5F6;
|
||||
border-radius: 30rpx;
|
||||
padding: 8rpx 24rpx;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fitness-count-badge text {
|
||||
font-size: 24rpx;
|
||||
color: #26A5F6;
|
||||
}
|
||||
|
||||
/* ===== 体测学生卡片 ===== */
|
||||
.fitness-student-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
margin: 18rpx 30rpx;
|
||||
padding: 24rpx 28rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(38, 165, 246, 0.08);
|
||||
border-left: 6rpx solid #26A5F6;
|
||||
}
|
||||
|
||||
.fsc-avatar-wrap {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #74C7FF 0%, #26A5F6 100%);
|
||||
padding: 4rpx;
|
||||
box-sizing: border-box;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.fsc-avatar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
border: 3rpx solid #fff;
|
||||
background-color: #e8f5ff;
|
||||
}
|
||||
|
||||
.fsc-info {
|
||||
flex: 1;
|
||||
margin-left: 24rpx;
|
||||
}
|
||||
|
||||
.fsc-name-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fsc-name {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.fsc-sex {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
|
||||
.fsc-meta {
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.fsc-no {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.fsc-arrow {
|
||||
flex-shrink: 0;
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
|
||||
/* ===== 加载中 ===== */
|
||||
.fitness-loading {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 80rpx 0;
|
||||
color: #26A5F6;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
/* ===== 空状态 ===== */
|
||||
.fitness-empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 120rpx 0 60rpx;
|
||||
color: #bbb;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.fitness-empty-icon {
|
||||
font-size: 80rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.card{
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 10rpx rgb(223, 222, 222);
|
||||
|
||||
@ -0,0 +1,148 @@
|
||||
// subpackage/teacher/student-fitness-detail/student-fitness-detail.js
|
||||
import uCharts from '../../../utils/chart/u-charts';
|
||||
import { getReport } from '../../../utils/serve/parent';
|
||||
|
||||
var uChartsInstance = {};
|
||||
|
||||
const UNIT_MAP = {
|
||||
'BMI': 'kg/m²',
|
||||
'肺活量': 'ml',
|
||||
'坐位体前屈': 'cm',
|
||||
'立定跳远': 'cm',
|
||||
'一分钟跳绳': '个',
|
||||
'一分钟仰卧起坐': '个',
|
||||
};
|
||||
|
||||
Page({
|
||||
data: {
|
||||
fitnessItems: [],
|
||||
fitnessReport: [],
|
||||
radarCWidth: 300,
|
||||
radarCHeight: 300,
|
||||
pixelRatio: 2,
|
||||
showFitnessPopup: false,
|
||||
selectedFitnessItem: null,
|
||||
studentNo: '',
|
||||
readyFired: false,
|
||||
},
|
||||
|
||||
async onLoad(options) {
|
||||
wx.showLoading({ title: '加载中' });
|
||||
this.setData({ studentNo: options.studentNo || '' });
|
||||
try {
|
||||
const res = await getReport({ studentNo: options.studentNo });
|
||||
const list = (res.data && res.data.categoryScoreList) || [];
|
||||
const fitnessItems = list.map(item => ({
|
||||
...item,
|
||||
unit: UNIT_MAP[item.name] || '',
|
||||
}));
|
||||
this.setData({
|
||||
fitnessReport: list,
|
||||
fitnessItems,
|
||||
}, () => {
|
||||
// 如果 onReady 已经触发,数据到位后立即绘图
|
||||
if (this.data.readyFired) {
|
||||
this.drawRadarChart(this);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
this.setData({ fitnessItems: [] });
|
||||
}
|
||||
wx.hideLoading();
|
||||
},
|
||||
|
||||
onReady() {
|
||||
const info = wx.getWindowInfo();
|
||||
const pixelRatio = info.pixelRatio;
|
||||
const radarCWidth = info.windowWidth * 0.86;
|
||||
const radarCHeight = info.windowWidth * 0.86;
|
||||
this.setData({ radarCWidth, radarCHeight, pixelRatio, readyFired: true }, () => {
|
||||
// 如果数据已经加载完,直接绘图;否则等 onLoad 回调里触发
|
||||
if (this.data.fitnessReport && this.data.fitnessReport.length > 0) {
|
||||
this.drawRadarChart(this);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
drawRadarChart(that) {
|
||||
const list = that.data.fitnessReport || [];
|
||||
const categories = list.map(i => i.name);
|
||||
const prevData = list.map(i => i.prevScore || 0);
|
||||
const currentData = list.map(i => i.lastScore || 0);
|
||||
|
||||
const query = wx.createSelectorQuery().in(that);
|
||||
query.select('#radarCanvas').fields({ node: true, size: true }).exec(res => {
|
||||
if (!res[0]) return;
|
||||
const canvas = res[0].node;
|
||||
const ctx = canvas.getContext('2d');
|
||||
canvas.width = (res[0].width + 20) * that.data.pixelRatio;
|
||||
canvas.height = (res[0].height + 20) * that.data.pixelRatio;
|
||||
uChartsInstance['radarCanvas'] = new uCharts({
|
||||
type: 'radar',
|
||||
context: ctx,
|
||||
width: that.data.radarCWidth * that.data.pixelRatio,
|
||||
height: that.data.radarCHeight * that.data.pixelRatio,
|
||||
categories,
|
||||
series: [
|
||||
{ name: '上次成绩', data: prevData, color: '#4A90E2' },
|
||||
{ name: '本次成绩', data: currentData, color: '#E74C3C' },
|
||||
],
|
||||
pixelRatio: that.data.pixelRatio,
|
||||
animation: true,
|
||||
background: 'rgba(0,0,0,0)',
|
||||
color: ['#4A90E2', '#E74C3C'],
|
||||
padding: [0, 0, 0, 10],
|
||||
legend: {
|
||||
show: true,
|
||||
position: 'bottom',
|
||||
float: 'center',
|
||||
fontSize: 12,
|
||||
lineHeight: 11,
|
||||
margin: 5,
|
||||
itemGap: 20,
|
||||
},
|
||||
extra: {
|
||||
radar: {
|
||||
gridType: 'radar',
|
||||
gridColor: '#CCCCCC',
|
||||
gridCount: 4,
|
||||
opacity: 0.15,
|
||||
gridEvenShow: true,
|
||||
gridOddShow: true,
|
||||
labelShow: true,
|
||||
labelColor: '#333',
|
||||
fontSize: 13,
|
||||
labelPointShow: false,
|
||||
max: 100,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
showFitnessScore(e) {
|
||||
const item = e.currentTarget.dataset.item;
|
||||
this.setData({ selectedFitnessItem: item, showFitnessPopup: true });
|
||||
},
|
||||
|
||||
closeFitnessPopup() {
|
||||
this.setData({ showFitnessPopup: false, selectedFitnessItem: null });
|
||||
},
|
||||
|
||||
goFitnessDetail() {
|
||||
const item = this.data.selectedFitnessItem;
|
||||
if (!item) return;
|
||||
this.setData({ showFitnessPopup: false });
|
||||
wx.setStorageSync('fitnessDetailItem', item);
|
||||
wx.navigateTo({
|
||||
url: '/subpackage/parent/fitness-detail/fitness-detail',
|
||||
});
|
||||
},
|
||||
|
||||
onShow() {},
|
||||
onHide() {},
|
||||
onUnload() {},
|
||||
onPullDownRefresh() {},
|
||||
onReachBottom() {},
|
||||
onShareAppMessage() {},
|
||||
})
|
||||
@ -0,0 +1,9 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"mp-bar": "weui-miniprogram/navigation-bar/navigation-bar",
|
||||
"mp-icon": "weui-miniprogram/icon/icon"
|
||||
},
|
||||
"backgroundColorContent": "#f0f7ff",
|
||||
"backgroundColor": "#f0f7ff",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
<!--subpackage/teacher/student-fitness-detail/student-fitness-detail.wxml-->
|
||||
<view class="page-wrap" style="padding: 0 30rpx; padding-bottom: 300rpx; box-sizing: border-box;">
|
||||
<mp-bar background="linear-gradient(190deg, #49a5fc 0%, #f5f8ff 700rpx, #f5f8ff 100%)" title="体测报告" color="#fff" back="{{true}}"></mp-bar>
|
||||
|
||||
<!-- 体测报告主体 -->
|
||||
<view class="fitness-card">
|
||||
<view class="fitness-chart-title">体测成绩对比</view>
|
||||
<view class="radar-wrap" style="width:{{radarCWidth}}px;height:{{radarCHeight}}px;">
|
||||
<canvas
|
||||
type="2d"
|
||||
id="radarCanvas"
|
||||
canvas-id="radarCanvas"
|
||||
style="width:{{radarCWidth}}px;height:{{radarCHeight}}px;"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 六项指标卡片 -->
|
||||
<view class="fitness-grid">
|
||||
<view
|
||||
class="fitness-item"
|
||||
wx:for="{{fitnessItems}}"
|
||||
wx:key="categoryValue"
|
||||
data-item="{{item}}"
|
||||
bind:tap="showFitnessScore"
|
||||
>
|
||||
<image src="{{item.imgUrl}}" class="fitness-icon" mode="aspectFit" />
|
||||
<view class="fitness-name">{{item.name}}</view>
|
||||
<view class="fitness-score">{{item.lastScore}}<text class="fitness-unit"> {{item.unit}}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view wx:if="{{fitnessItems.length === 0}}" class="empty-tip">暂无体测数据</view>
|
||||
|
||||
<!-- 成绩弹窗遮罩 -->
|
||||
<view class="popup-mask" wx:if="{{showFitnessPopup}}" bind:tap="closeFitnessPopup"></view>
|
||||
|
||||
<!-- 成绩弹窗 -->
|
||||
<view class="score-popup {{showFitnessPopup ? 'popup-show' : ''}}">
|
||||
<view class="popup-header">
|
||||
<image src="{{selectedFitnessItem.imgUrl}}" class="popup-icon" mode="aspectFit" />
|
||||
<text class="popup-title">{{selectedFitnessItem.name}}</text>
|
||||
<view class="popup-close" bind:tap="closeFitnessPopup">✕</view>
|
||||
</view>
|
||||
|
||||
<view class="score-rows">
|
||||
<view class="score-row">
|
||||
<view class="score-label">本次成绩</view>
|
||||
<view class="score-value score-highlight">{{selectedFitnessItem.lastScore}}<text class="score-unit"> {{selectedFitnessItem.unit}}</text></view>
|
||||
</view>
|
||||
<view class="score-row">
|
||||
<view class="score-label">上次成绩</view>
|
||||
<view class="score-value">{{selectedFitnessItem.prevScore}}<text class="score-unit"> {{selectedFitnessItem.unit}}</text></view>
|
||||
</view>
|
||||
<view class="score-divider"></view>
|
||||
<view class="score-row">
|
||||
<view class="score-label">班级平均</view>
|
||||
<view class="score-value">{{selectedFitnessItem.classAvgScore}}<text class="score-unit"> {{selectedFitnessItem.unit}}</text></view>
|
||||
</view>
|
||||
<view class="score-row">
|
||||
<view class="score-label">机构平均</view>
|
||||
<view class="score-value">{{selectedFitnessItem.schoolAvgScore}}<text class="score-unit"> {{selectedFitnessItem.unit}}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="popup-btn" bind:tap="goFitnessDetail">查看详细趋势</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,377 @@
|
||||
/* subpackage/teacher/student-fitness-detail/student-fitness-detail.wxss */
|
||||
|
||||
/* ===== 成绩弹窗 ===== */
|
||||
.popup-mask {
|
||||
position: fixed;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
background: rgba(0,0,0,0.45);
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.score-popup {
|
||||
position: fixed;
|
||||
left: 0; right: 0; bottom: 0;
|
||||
background: #fff;
|
||||
border-radius: 36rpx 36rpx 0 0;
|
||||
padding: 36rpx 40rpx 60rpx;
|
||||
z-index: 9999;
|
||||
transform: translateY(100%);
|
||||
transition: transform 0.3s ease;
|
||||
box-shadow: 0 -8rpx 40rpx rgba(73,165,252,0.18);
|
||||
}
|
||||
|
||||
.popup-show {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.popup-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 36rpx;
|
||||
}
|
||||
|
||||
.popup-icon {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
margin-right: 20rpx;
|
||||
border-radius: 50%;
|
||||
/* background: linear-gradient(135deg, #8dcfff, #49a5fc); */
|
||||
/* padding: 14rpx; */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.popup-title {
|
||||
flex: 1;
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
color: #18394D;
|
||||
}
|
||||
|
||||
.popup-close {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
border-radius: 50%;
|
||||
background: #f0f4f8;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.score-rows {
|
||||
background: #f7fbff;
|
||||
border-radius: 20rpx;
|
||||
padding: 8rpx 30rpx;
|
||||
margin-bottom: 36rpx;
|
||||
}
|
||||
|
||||
.score-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 24rpx 0;
|
||||
border-bottom: 1rpx solid #eef2f8;
|
||||
}
|
||||
|
||||
.score-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.score-divider {
|
||||
height: 2rpx;
|
||||
background: linear-gradient(90deg, transparent, #d0e8ff, transparent);
|
||||
margin: 4rpx 0;
|
||||
}
|
||||
|
||||
.score-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.score-value {
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.score-highlight {
|
||||
color: #1d78e8;
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.score-unit {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.popup-btn {
|
||||
background: linear-gradient(135deg, #49a5fc, #1d78e8);
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 28rpx 0;
|
||||
border-radius: 50rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
box-shadow: 0 6rpx 20rpx rgba(73,165,252,0.4);
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
/* ===== 体测报告卡片 ===== */
|
||||
.fitness-card {
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding: 30rpx 20rpx 10rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(73,165,252,0.12);
|
||||
margin-bottom: 30rpx;
|
||||
margin-top: 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fitness-chart-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #18394D;
|
||||
margin-bottom: 16rpx;
|
||||
position: relative;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.fitness-chart-title::before,
|
||||
.fitness-chart-title::after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 60rpx;
|
||||
height: 4rpx;
|
||||
background: linear-gradient(90deg, transparent, #49a5fc);
|
||||
vertical-align: middle;
|
||||
margin-right: 16rpx;
|
||||
border-radius: 2rpx;
|
||||
}
|
||||
|
||||
.fitness-chart-title::after {
|
||||
background: linear-gradient(90deg, #49a5fc, transparent);
|
||||
margin-right: 0;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
|
||||
.radar-wrap {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ===== 六项指标网格 ===== */
|
||||
.fitness-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.fitness-item {
|
||||
width: calc(33.33% - 14rpx);
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(73,165,252,0.12);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 30rpx 10rpx 24rpx;
|
||||
box-sizing: border-box;
|
||||
active-opacity: 0.7;
|
||||
}
|
||||
|
||||
.fitness-item:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
.fitness-icon {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
}
|
||||
|
||||
.fitness-name {
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.fitness-score {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #1d78e8;
|
||||
}
|
||||
|
||||
.fitness-unit {
|
||||
font-size: 20rpx;
|
||||
color: #999;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* ===== 空状态 ===== */
|
||||
.empty-tip {
|
||||
text-align: center;
|
||||
padding: 80rpx 0;
|
||||
color: #bbb;
|
||||
font-size: 26rpx;
|
||||
|
||||
flex-wrap: wrap;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.meta-tag {
|
||||
background-color: rgba(255, 255, 255, 0.25);
|
||||
border-radius: 20rpx;
|
||||
padding: 4rpx 18rpx;
|
||||
font-size: 22rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.score-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 20rpx;
|
||||
padding: 16rpx 28rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.score-num {
|
||||
font-size: 52rpx;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
|
||||
/* ===== 章节标题 ===== */
|
||||
.section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 36rpx 30rpx 16rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.title-bar {
|
||||
width: 6rpx;
|
||||
height: 28rpx;
|
||||
border-radius: 6rpx;
|
||||
background: linear-gradient(180deg, #26A5F6, #1478D4);
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
/* ===== 成绩表格 ===== */
|
||||
.table-card {
|
||||
background-color: #fff;
|
||||
border-radius: 24rpx;
|
||||
margin: 0 30rpx 40rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4rpx 20rpx rgba(38, 165, 246, 0.1);
|
||||
}
|
||||
|
||||
.table-row {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1.5fr 1fr 1.2fr;
|
||||
align-items: center;
|
||||
padding: 0 24rpx;
|
||||
min-height: 90rpx;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
background: linear-gradient(90deg, #EAF4FF, #f5faff);
|
||||
font-size: 24rpx;
|
||||
font-weight: bold;
|
||||
color: #26A5F6;
|
||||
min-height: 72rpx;
|
||||
border-bottom: 2rpx solid #e8f3ff;
|
||||
}
|
||||
|
||||
.row-even {
|
||||
background-color: #fff;
|
||||
border-bottom: 2rpx solid #f5f5f5;
|
||||
}
|
||||
|
||||
.row-odd {
|
||||
background-color: #f8fcff;
|
||||
border-bottom: 2rpx solid #f5f5f5;
|
||||
}
|
||||
|
||||
.col-name {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
padding-right: 10rpx;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.col {
|
||||
font-size: 25rpx;
|
||||
color: #555;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.col-score {
|
||||
font-weight: bold;
|
||||
color: #26A5F6;
|
||||
}
|
||||
|
||||
.col-rank {
|
||||
text-align: center;
|
||||
border-radius: 20rpx;
|
||||
font-size: 22rpx;
|
||||
padding: 4rpx 0;
|
||||
}
|
||||
|
||||
.col-rank.rank-1 {
|
||||
color: #1aad19;
|
||||
background-color: #e8f9e8;
|
||||
}
|
||||
|
||||
.col-rank.rank-2 {
|
||||
color: #26A5F6;
|
||||
background-color: #eaf4ff;
|
||||
}
|
||||
|
||||
.col-rank.rank-3 {
|
||||
color: #ff9900;
|
||||
background-color: #fff7e8;
|
||||
}
|
||||
|
||||
.col-rank.rank-4 {
|
||||
color: #e64340;
|
||||
background-color: #fff0f0;
|
||||
}
|
||||
|
||||
/* ===== 空状态 ===== */
|
||||
.empty {
|
||||
text-align: center;
|
||||
padding: 80rpx 0;
|
||||
color: #bbb;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
/* ===== 加载骨架 ===== */
|
||||
.skeleton {
|
||||
padding: 24rpx 30rpx;
|
||||
}
|
||||
|
||||
.sk-header {
|
||||
height: 160rpx;
|
||||
background: linear-gradient(90deg, #dbeeff 25%, #c8e5ff 50%, #dbeeff 75%);
|
||||
border-radius: 24rpx;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.sk-row {
|
||||
height: 80rpx;
|
||||
background: linear-gradient(90deg, #f0f0f0 25%, #e8e8e8 50%, #f0f0f0 75%);
|
||||
border-radius: 12rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user