智慧教务系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

499 lines
11 KiB

<template>
<view class="container">
<uni-nav-bar fixed status-bar left-icon="left" title="学员详情" @clickLeft="navigateBack"></uni-nav-bar>
<view class="content" v-if="studentInfo">
<view class="student-header">
<view class="avatar-box">
<image :src="studentInfo.avatar || '/static/icon-img/avatar.png'" mode="aspectFill" class="avatar-img"></image>
</view>
<view class="name-box">
<text class="name">{{studentInfo.name}}</text>
<text class="id">ID: {{studentInfo.id}}</text>
</view>
</view>
<view class="card-section">
<view class="section-title">基本信息</view>
<view class="info-card">
<view class="info-item">
<text class="item-label">所属校区</text>
<text class="item-value">{{studentInfo.campus}}</text>
</view>
<view class="info-item">
<text class="item-label">联系电话</text>
<text class="item-value">{{studentInfo.phone}}</text>
</view>
<view class="info-item">
<text class="item-label">年龄</text>
<text class="item-value">{{studentInfo.age}}岁</text>
</view>
<view class="info-item">
<text class="item-label">入学时间</text>
<text class="item-value">{{studentInfo.enrollmentDate}}</text>
</view>
</view>
</view>
<view class="card-section">
<view class="section-title">课程信息</view>
<view class="info-card">
<view class="info-item">
<text class="item-label">剩余课程</text>
<text class="item-value highlight">{{studentInfo.remainingCourses}}节</text>
</view>
<view class="info-item">
<text class="item-label">课程到期时间</text>
<text class="item-value highlight">{{studentInfo.expiryDate}}</text>
</view>
<view class="info-item">
<text class="item-label">已消课程</text>
<text class="item-value">{{studentInfo.completedCourses}}节</text>
</view>
<view class="info-item">
<text class="item-label">报名课程</text>
<text class="item-value">{{studentInfo.courseName}}</text>
</view>
</view>
</view>
<view class="card-section">
<view class="section-title">最近上课记录</view>
<view class="info-card" v-if="studentInfo.recentClasses && studentInfo.recentClasses.length > 0">
<view class="class-item" v-for="(item, index) in studentInfo.recentClasses" :key="index">
<view class="class-date">{{item.date}}</view>
<view class="class-info">
<text class="class-name">{{item.courseName}}</text>
<text class="class-time">{{item.timeSlot}}</text>
</view>
</view>
</view>
<view class="empty-class" v-else>
<text>暂无上课记录</text>
</view>
</view>
<view class="btn-group">
<button class="btn primary" @click="contactStudent">联系学员</button>
<button class="btn secondary" @click="viewSchedule">查看课表</button>
</view>
</view>
<view v-else class="loading-box">
<text>加载中...</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
id: null,
studentInfo: null
}
},
onLoad(options) {
if (options.id) {
this.id = options.id;
this.getStudentDetail();
} else {
uni.showToast({
title: '参数错误',
icon: 'none'
});
setTimeout(() => {
this.navigateBack();
}, 1500);
}
},
methods: {
navigateBack() {
uni.navigateBack();
},
getStudentDetail() {
// 模拟数据,实际开发中应该从API获取
// try {
// const res = await memberApi.getStudentDetail({id: this.id});
// if(res.code == 1) {
// this.studentInfo = res.data || null;
// } else {
// uni.showToast({
// title: res.msg || '获取学员详情失败',
// icon: 'none'
// });
// }
// } catch(error) {
// console.error('获取学员详情失败:', error);
// uni.showToast({
// title: '获取学员详情失败',
// icon: 'none'
// });
// }
// 使用模拟数据
setTimeout(() => {
// 定义一些模拟数据对象
const studentData = {
'1': {
id: '1',
name: '张三',
avatar: '/static/icon-img/avatar.png',
campus: '总部校区',
phone: '13812341000',
age: 11,
enrollmentDate: '2023-01-11',
remainingCourses: 10,
expiryDate: '2023-12-31',
completedCourses: 20,
courseName: '少儿英语基础班',
recentClasses: [
{
date: '2023-09-15',
courseName: '少儿英语基础班',
timeSlot: '15:30-17:00'
},
{
date: '2023-09-08',
courseName: '少儿英语基础班',
timeSlot: '15:30-17:00'
},
{
date: '2023-09-01',
courseName: '少儿英语基础班',
timeSlot: '15:30-17:00'
}
]
},
'2': {
id: '2',
name: '李四',
avatar: '/static/icon-img/avatar.png',
campus: '西区校区',
phone: '13812341001',
age: 12,
enrollmentDate: '2023-01-12',
remainingCourses: 5,
expiryDate: '2023-11-15',
completedCourses: 25,
courseName: '少儿英语进阶班',
recentClasses: [
{
date: '2023-09-14',
courseName: '少儿英语进阶班',
timeSlot: '14:00-15:30'
},
{
date: '2023-09-07',
courseName: '少儿英语进阶班',
timeSlot: '14:00-15:30'
}
]
},
'3': {
id: '3',
name: '王五',
avatar: '/static/icon-img/avatar.png',
campus: '东区校区',
phone: '13812341002',
age: 13,
enrollmentDate: '2023-01-13',
remainingCourses: 15,
expiryDate: '2024-01-20',
completedCourses: 15,
courseName: '少儿英语口语班',
recentClasses: [
{
date: '2023-09-16',
courseName: '少儿英语口语班',
timeSlot: '10:00-11:30'
},
{
date: '2023-09-09',
courseName: '少儿英语口语班',
timeSlot: '10:00-11:30'
},
{
date: '2023-09-02',
courseName: '少儿英语口语班',
timeSlot: '10:00-11:30'
}
]
},
'4': {
id: '4',
name: '赵六',
avatar: '/static/icon-img/avatar.png',
campus: '南区校区',
phone: '13812341003',
age: 10,
enrollmentDate: '2023-02-15',
remainingCourses: 8,
expiryDate: '2023-11-30',
completedCourses: 12,
courseName: '少儿英语基础班',
recentClasses: [
{
date: '2023-09-13',
courseName: '少儿英语基础班',
timeSlot: '16:00-17:30'
},
{
date: '2023-09-06',
courseName: '少儿英语基础班',
timeSlot: '16:00-17:30'
}
]
},
'5': {
id: '5',
name: '刘七',
avatar: '/static/icon-img/avatar.png',
campus: '北区校区',
phone: '13812341004',
age: 14,
enrollmentDate: '2023-03-20',
remainingCourses: 20,
expiryDate: '2024-02-15',
completedCourses: 10,
courseName: '少儿英语进阶班',
recentClasses: [
{
date: '2023-09-12',
courseName: '少儿英语进阶班',
timeSlot: '17:00-18:30'
},
{
date: '2023-09-05',
courseName: '少儿英语进阶班',
timeSlot: '17:00-18:30'
}
]
},
'6': {
id: '6',
name: '陈八',
avatar: '/static/icon-img/avatar.png',
campus: '总部校区',
phone: '13812341005',
age: 9,
enrollmentDate: '2023-04-05',
remainingCourses: 3,
expiryDate: '2023-10-30',
completedCourses: 27,
courseName: '少儿英语口语班',
recentClasses: [
{
date: '2023-09-11',
courseName: '少儿英语口语班',
timeSlot: '14:30-16:00'
},
{
date: '2023-09-04',
courseName: '少儿英语口语班',
timeSlot: '14:30-16:00'
}
]
}
};
// 根据ID获取对应的学员数据
this.studentInfo = studentData[this.id] || {
id: this.id,
name: '未知学员',
avatar: '/static/icon-img/avatar.png',
campus: '未知校区',
phone: '暂无',
age: '暂无',
enrollmentDate: '暂无',
remainingCourses: 0,
expiryDate: '暂无',
completedCourses: 0,
courseName: '暂无',
recentClasses: []
};
}, 500);
},
contactStudent() {
if (this.studentInfo && this.studentInfo.phone) {
uni.makePhoneCall({
phoneNumber: this.studentInfo.phone.replace(/\*/g, '0')
});
}
},
viewSchedule() {
uni.navigateTo({
url: `/pages/coach/student/timetable?id=${this.id}`
});
}
}
}
</script>
<style lang="scss">
.container {
min-height: 100vh;
background-color: #F5F5F5;
}
.content {
padding: 20rpx;
}
.loading-box {
display: flex;
justify-content: center;
align-items: center;
height: 80vh;
color: #999;
font-size: 28rpx;
}
.student-header {
display: flex;
align-items: center;
background-color: #FFFFFF;
border-radius: 12rpx;
padding: 40rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
.avatar-box {
width: 150rpx;
height: 150rpx;
border-radius: 75rpx;
overflow: hidden;
margin-right: 30rpx;
.avatar-img {
width: 100%;
height: 100%;
}
}
.name-box {
display: flex;
flex-direction: column;
.name {
font-size: 36rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.id {
font-size: 24rpx;
color: #999;
}
}
}
.card-section {
margin-bottom: 20rpx;
.section-title {
font-size: 30rpx;
font-weight: bold;
color: #333;
margin: 30rpx 10rpx 20rpx;
}
.info-card {
background-color: #FFFFFF;
border-radius: 12rpx;
padding: 20rpx 30rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.info-item {
display: flex;
justify-content: space-between;
padding: 20rpx 0;
border-bottom: 1px solid #F5F5F5;
&:last-child {
border-bottom: none;
}
.item-label {
color: #666;
font-size: 28rpx;
}
.item-value {
color: #333;
font-size: 28rpx;
&.highlight {
color: #FF6600;
font-weight: bold;
}
}
}
.class-item {
display: flex;
padding: 20rpx 0;
border-bottom: 1px solid #F5F5F5;
&:last-child {
border-bottom: none;
}
.class-date {
width: 180rpx;
font-size: 28rpx;
color: #666;
}
.class-info {
flex: 1;
display: flex;
flex-direction: column;
.class-name {
font-size: 28rpx;
color: #333;
margin-bottom: 10rpx;
}
.class-time {
font-size: 24rpx;
color: #999;
}
}
}
.empty-class {
padding: 40rpx 0;
text-align: center;
color: #999;
font-size: 28rpx;
}
}
.btn-group {
display: flex;
justify-content: space-between;
margin: 40rpx 0;
.btn {
width: 48%;
height: 80rpx;
line-height: 80rpx;
border-radius: 40rpx;
font-size: 30rpx;
&.primary {
background-color: #3B7CF9;
color: #FFFFFF;
}
&.secondary {
background-color: #FFFFFF;
color: #3B7CF9;
border: 1px solid #3B7CF9;
}
}
}
</style>