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.
1178 lines
26 KiB
1178 lines
26 KiB
<!--家长端用户信息管理页面-->
|
|
<template>
|
|
<view class="main_box">
|
|
<view class="navbar_section">
|
|
<view class="title">用户信息</view>
|
|
</view>
|
|
|
|
<!-- 家长信息展示 -->
|
|
<view class="parent_info_section">
|
|
<view class="parent_basic_info">
|
|
<view class="parent_name">{{ parentInfo.name || '张家长' }}</view>
|
|
<view class="parent_phone">{{ parentInfo.phone_number || '13800138000' }}</view>
|
|
</view>
|
|
<view class="logout_button" @click="logout">
|
|
<image :src="$util.img('/static/icon-img/logout.png')" class="logout_icon"></image>
|
|
<text class="logout_text">退出</text>
|
|
</view>
|
|
</view>
|
|
|
|
|
|
<!-- 学员卡片展示 -->
|
|
<view class="students_section">
|
|
<view class="students_header">
|
|
<view class="students_title">我的学员</view>
|
|
<view class="add_student_button" @click="showAddStudentDialog">
|
|
<image :src="$util.img('/static/icon-img/add.png')" class="add_icon"></image>
|
|
<text class="add_text">新增学员</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="students_grid" v-if="childrenList.length > 0">
|
|
<view
|
|
v-for="child in childrenList"
|
|
:key="child.id"
|
|
:class="['student_card', selectedChild && selectedChild.id === child.id ? 'selected' : '']"
|
|
@click="selectStudent(child)"
|
|
>
|
|
<view class="student_avatar">
|
|
<image :src="child.avatar || $util.img('/static/icon-img/default-avatar.png')" class="avatar_image"></image>
|
|
</view>
|
|
<view class="student_info">
|
|
<view class="student_name">{{ child.name }}</view>
|
|
<view class="student_details">
|
|
<text class="detail_tag">{{ child.gender === 1 ? '男' : '女' }}</text>
|
|
<text class="detail_tag">{{ Math.floor(child.age) }}岁</text>
|
|
</view>
|
|
<view class="student_campus">{{ child.campus_name || '未分配校区' }}</view>
|
|
<view class="student_courses">剩余 {{ child.remaining_courses || 0 }} 课时</view>
|
|
</view>
|
|
<view class="student_status" :class="child.status === 1 ? 'active' : 'inactive'">
|
|
{{ child.status === 1 ? '正常' : '暂停' }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="empty_students" v-else>
|
|
<image :src="$util.img('/static/icon-img/empty.png')" class="empty_icon"></image>
|
|
<view class="empty_text">暂无学员信息</view>
|
|
<view class="empty_tip">点击右上角"新增学员"添加孩子信息</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 新增学员对话框 -->
|
|
<view class="add_student_dialog" v-if="showAddStudent" @click="closeAddStudentDialog">
|
|
<view class="dialog_content" @click.stop>
|
|
<view class="dialog_header">
|
|
<view class="dialog_title">新增学员</view>
|
|
<view class="dialog_close" @click="closeAddStudentDialog">×</view>
|
|
</view>
|
|
<view class="dialog_form">
|
|
<view class="form_item">
|
|
<view class="form_label">学员姓名</view>
|
|
<input class="form_input" v-model="newStudent.name" placeholder="请输入学员姓名" />
|
|
</view>
|
|
<view class="form_item">
|
|
<view class="form_label">性别</view>
|
|
<view class="gender_selector">
|
|
<view
|
|
:class="['gender_option', newStudent.gender === 1 ? 'selected' : '']"
|
|
@click="newStudent.gender = 1"
|
|
>男</view>
|
|
<view
|
|
:class="['gender_option', newStudent.gender === 2 ? 'selected' : '']"
|
|
@click="newStudent.gender = 2"
|
|
>女</view>
|
|
</view>
|
|
</view>
|
|
<view class="form_item">
|
|
<view class="form_label">出生日期</view>
|
|
<picker mode="date" :value="newStudent.birthday" @change="onBirthdayChange">
|
|
<view class="form_input picker_input">
|
|
{{ newStudent.birthday || '请选择出生日期' }}
|
|
</view>
|
|
</picker>
|
|
</view>
|
|
<view class="form_item">
|
|
<view class="form_label">备注信息</view>
|
|
<textarea class="form_textarea" v-model="newStudent.remark" placeholder="请输入备注信息(选填)"></textarea>
|
|
</view>
|
|
</view>
|
|
<view class="dialog_actions">
|
|
<view class="action_button cancel" @click="closeAddStudentDialog">取消</view>
|
|
<view class="action_button confirm" @click="confirmAddStudent">确认</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 选中孩子信息弹窗 -->
|
|
<view class="child_popup" v-if="showChildPopup" @click="closeChildPopup">
|
|
<view class="popup_content" @click.stop>
|
|
<view class="popup_header">
|
|
<view class="popup_title">选择孩子</view>
|
|
<view class="popup_close" @click="closeChildPopup">×</view>
|
|
</view>
|
|
<view class="popup_children_list">
|
|
<view
|
|
v-for="child in childrenList"
|
|
:key="child.id"
|
|
:class="['popup_child_item', selectedChild && selectedChild.id === child.id ? 'selected' : '']"
|
|
@click="selectChildFromPopup(child)"
|
|
>
|
|
<view class="popup_child_info">
|
|
<view class="popup_child_name">{{ child.name }}</view>
|
|
<view class="popup_child_details">
|
|
<text class="popup_detail_tag">{{ child.gender === 1 ? '男' : '女' }}</text>
|
|
<text class="popup_detail_tag">{{ Math.floor(child.age) }}岁</text>
|
|
</view>
|
|
<view class="popup_child_campus">{{ child.campus_name || '未分配' }}</view>
|
|
<view class="popup_child_class">{{ child.class_name || '未分配' }}</view>
|
|
</view>
|
|
<view class="popup_child_courses">{{ child.remaining_courses || 0 }}课时</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 弹窗底部新增孩子按钮 -->
|
|
<view class="popup_add_child_section">
|
|
<view class="popup_add_child_button" @click="addChildFromPopup">
|
|
<image :src="$util.img('/static/icon-img/add.png')" class="popup_add_icon"></image>
|
|
<text class="popup_add_text">新增孩子</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 当前选中孩子的统计信息 -->
|
|
<view class="selected_child_section" v-if="selectedChild">
|
|
<view class="selected_child_header">
|
|
<view class="selected_child_info">
|
|
<view class="selected_child_name">{{ selectedChild.name }}</view>
|
|
<view class="selected_child_details">
|
|
<text class="selected_detail_tag">{{ selectedChild.gender === 1 ? '男' : '女' }}</text>
|
|
<text class="selected_detail_tag">{{ Math.floor(selectedChild.age) }}岁</text>
|
|
<text class="selected_detail_tag">{{ selectedChild.campus_name || '未分配校区' }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="switch_button" @click="openChildPopup">切换</view>
|
|
</view>
|
|
|
|
<view class="stats_grid">
|
|
<view class="stat_item">
|
|
<view class="stat_number">{{ selectedChild.total_courses || 0 }}</view>
|
|
<view class="stat_label">总课程</view>
|
|
</view>
|
|
<view class="stat_item">
|
|
<view class="stat_number">{{ selectedChild.completed_courses || 0 }}</view>
|
|
<view class="stat_label">已完成</view>
|
|
</view>
|
|
<view class="stat_item">
|
|
<view class="stat_number">{{ selectedChild.remaining_courses || 0 }}</view>
|
|
<view class="stat_label">剩余课时</view>
|
|
</view>
|
|
<view class="stat_item">
|
|
<view class="stat_number">{{ selectedChild.attendance_rate || 0 }}%</view>
|
|
<view class="stat_label">出勤率</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 功能菜单 - 九宫格样式 -->
|
|
<view class="main_section">
|
|
<view class="grid_container">
|
|
<view class="grid_item" @click="viewChildDetail">
|
|
<view class="grid_icon">
|
|
<image :src="$util.img('/static/icon-img/tou.png')" class="icon_image"></image>
|
|
</view>
|
|
<view class="grid_text">孩子详情</view>
|
|
</view>
|
|
|
|
<view class="grid_item" @click="viewCourses">
|
|
<view class="grid_icon">
|
|
<image :src="$util.img('/static/icon-img/kkry.png')" class="icon_image"></image>
|
|
</view>
|
|
<view class="grid_text">课程管理</view>
|
|
</view>
|
|
|
|
<view class="grid_item" @click="viewMaterials">
|
|
<view class="grid_icon">
|
|
<image :src="$util.img('/static/icon-img/liu.png')" class="icon_image"></image>
|
|
</view>
|
|
<view class="grid_text">教学资料</view>
|
|
</view>
|
|
|
|
<view class="grid_item" @click="viewServices">
|
|
<view class="grid_icon">
|
|
<image :src="$util.img('/static/icon-img/notice.png')" class="icon_image"></image>
|
|
</view>
|
|
<view class="grid_text">服务管理</view>
|
|
</view>
|
|
|
|
<view class="grid_item" @click="viewOrders">
|
|
<view class="grid_icon">
|
|
<image :src="$util.img('/static/icon-img/used.png')" class="icon_image"></image>
|
|
</view>
|
|
<view class="grid_text">订单管理</view>
|
|
</view>
|
|
|
|
<view class="grid_item" @click="viewMessages">
|
|
<view class="grid_icon">
|
|
<image :src="$util.img('/static/icon-img/notice.png')" class="icon_image"></image>
|
|
</view>
|
|
<view class="grid_text">消息管理</view>
|
|
</view>
|
|
|
|
<view class="grid_item" @click="viewContracts">
|
|
<view class="grid_icon">
|
|
<image :src="$util.img('/static/icon-img/warn.png')" class="icon_image"></image>
|
|
</view>
|
|
<view class="grid_text">合同管理</view>
|
|
</view>
|
|
|
|
<!-- 空白占位,保持九宫格对齐 -->
|
|
<view class="grid_item empty_item"></view>
|
|
<view class="grid_item empty_item"></view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { mapState, mapMutations } from 'vuex'
|
|
import apiRoute from '@/api/apiRoute.js'
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
parentInfo: {},
|
|
childrenList: [],
|
|
showChildPopup: false,
|
|
loading: false,
|
|
// 新增学员相关
|
|
showAddStudent: false,
|
|
newStudent: {
|
|
name: '',
|
|
gender: 1, // 1=男,2=女
|
|
birthday: '',
|
|
remark: ''
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
...mapState(['selectedChild'])
|
|
},
|
|
onLoad() {
|
|
// 设置用户角色为家长
|
|
this.setUserRole('parent')
|
|
this.loadChildrenList()
|
|
console.log('用户信息页面加载完成')
|
|
},
|
|
|
|
onShow() {
|
|
// 页面显示时刷新数据
|
|
console.log('用户信息页面显示')
|
|
},
|
|
methods: {
|
|
...mapMutations(['SET_USER_ROLE', 'SET_SELECTED_CHILD', 'SET_CHILDREN_LIST']),
|
|
|
|
setUserRole(role) {
|
|
this.SET_USER_ROLE(role)
|
|
},
|
|
|
|
async loadChildrenList() {
|
|
this.loading = true
|
|
try {
|
|
console.log('开始加载孩子列表...')
|
|
const response = await apiRoute.parent_getChildrenList()
|
|
console.log('孩子列表响应:', response)
|
|
|
|
if (response.code === 1) {
|
|
this.childrenList = response.data.data || []
|
|
this.parentInfo = response.data.parent_info || {}
|
|
this.SET_CHILDREN_LIST(this.childrenList)
|
|
|
|
console.log('加载到的孩子列表:', this.childrenList)
|
|
console.log('家长信息:', this.parentInfo)
|
|
|
|
// 如果没有选中的孩子且有孩子列表,默认选中第一个
|
|
if (!this.selectedChild && this.childrenList.length > 0) {
|
|
this.SET_SELECTED_CHILD(this.childrenList[0])
|
|
}
|
|
} else {
|
|
console.error('获取孩子列表失败:', response)
|
|
uni.showToast({
|
|
title: response.msg || '获取孩子列表失败',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
} catch (error) {
|
|
console.error('获取孩子列表失败:', error)
|
|
uni.showToast({
|
|
title: '获取孩子列表失败',
|
|
icon: 'none'
|
|
})
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
},
|
|
|
|
|
|
openChildPopup() {
|
|
this.showChildPopup = true
|
|
},
|
|
|
|
closeChildPopup() {
|
|
this.showChildPopup = false
|
|
},
|
|
|
|
selectChildFromPopup(child) {
|
|
this.SET_SELECTED_CHILD(child)
|
|
console.log('选中孩子:', child)
|
|
this.closeChildPopup()
|
|
},
|
|
|
|
// 从弹窗中新增孩子
|
|
addChildFromPopup() {
|
|
this.closeChildPopup()
|
|
this.showAddStudentDialog()
|
|
},
|
|
|
|
viewChildDetail() {
|
|
if (!this.selectedChild) {
|
|
uni.showToast({
|
|
title: '请先选择孩子',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
this.$navigateToPage(`/pages/parent/user-info/child-detail`, {
|
|
childId: this.selectedChild.id
|
|
})
|
|
},
|
|
|
|
viewCourses() {
|
|
if (!this.selectedChild) {
|
|
uni.showToast({
|
|
title: '请先选择孩子',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
this.$navigateToPage(`/pages/parent/courses/index`, {
|
|
childId: this.selectedChild.id
|
|
})
|
|
},
|
|
|
|
viewMaterials() {
|
|
if (!this.selectedChild) {
|
|
uni.showToast({
|
|
title: '请先选择孩子',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
this.$navigateToPage(`/pages/parent/materials/index`, {
|
|
childId: this.selectedChild.id
|
|
})
|
|
},
|
|
|
|
viewServices() {
|
|
if (!this.selectedChild) {
|
|
uni.showToast({
|
|
title: '请先选择孩子',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
this.$navigateToPage(`/pages/parent/services/index`, {
|
|
childId: this.selectedChild.id
|
|
})
|
|
},
|
|
|
|
viewOrders() {
|
|
if (!this.selectedChild) {
|
|
uni.showToast({
|
|
title: '请先选择孩子',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
this.$navigateToPage(`/pages/parent/orders/index`, {
|
|
childId: this.selectedChild.id
|
|
})
|
|
},
|
|
|
|
viewMessages() {
|
|
if (!this.selectedChild) {
|
|
uni.showToast({
|
|
title: '请先选择孩子',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
this.$navigateToPage(`/pages/parent/messages/index`, {
|
|
childId: this.selectedChild.id
|
|
})
|
|
},
|
|
|
|
viewContracts() {
|
|
if (!this.selectedChild) {
|
|
uni.showToast({
|
|
title: '请先选择孩子',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
this.$navigateToPage(`/pages/parent/contracts/index`, {
|
|
childId: this.selectedChild.id
|
|
})
|
|
},
|
|
|
|
// 退出登录
|
|
logout() {
|
|
uni.showModal({
|
|
title: '确认退出',
|
|
content: '您确定要退出当前账号吗?',
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
// 清除本地存储
|
|
uni.removeStorageSync('token')
|
|
uni.removeStorageSync('userInfo')
|
|
uni.removeStorageSync('userType')
|
|
uni.removeStorageSync('roleInfo')
|
|
uni.removeStorageSync('menuList')
|
|
|
|
// 清空Vuex状态
|
|
this.SET_SELECTED_CHILD(null)
|
|
this.SET_CHILDREN_LIST([])
|
|
this.SET_USER_ROLE('')
|
|
|
|
// 跳转到登录页面
|
|
uni.reLaunch({
|
|
url: '/pages/student/login/login?loginType=member'
|
|
})
|
|
|
|
uni.showToast({
|
|
title: '退出成功',
|
|
icon: 'success'
|
|
})
|
|
}
|
|
}
|
|
})
|
|
},
|
|
|
|
// 选择学员
|
|
selectStudent(child) {
|
|
this.SET_SELECTED_CHILD(child)
|
|
console.log('选中学员:', child)
|
|
},
|
|
|
|
// 显示新增学员对话框
|
|
showAddStudentDialog() {
|
|
this.showAddStudent = true
|
|
// 重置表单
|
|
this.newStudent = {
|
|
name: '',
|
|
gender: 1,
|
|
birthday: '',
|
|
remark: ''
|
|
}
|
|
},
|
|
|
|
// 关闭新增学员对话框
|
|
closeAddStudentDialog() {
|
|
this.showAddStudent = false
|
|
},
|
|
|
|
// 出生日期选择
|
|
onBirthdayChange(e) {
|
|
this.newStudent.birthday = e.detail.value
|
|
},
|
|
|
|
// 确认新增学员
|
|
async confirmAddStudent() {
|
|
// 表单验证
|
|
if (!this.newStudent.name.trim()) {
|
|
uni.showToast({
|
|
title: '请输入学员姓名',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
|
|
if (!this.newStudent.birthday) {
|
|
uni.showToast({
|
|
title: '请选择出生日期',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
|
|
try {
|
|
uni.showLoading({
|
|
title: '添加中...'
|
|
})
|
|
|
|
// 计算年龄
|
|
const today = new Date()
|
|
const birthDate = new Date(this.newStudent.birthday)
|
|
const age = today.getFullYear() - birthDate.getFullYear()
|
|
|
|
const params = {
|
|
name: this.newStudent.name.trim(),
|
|
gender: this.newStudent.gender,
|
|
birthday: this.newStudent.birthday,
|
|
age: age,
|
|
remark: this.newStudent.remark.trim()
|
|
}
|
|
|
|
console.log('新增学员参数:', params)
|
|
|
|
// 调用API新增学员
|
|
const response = await apiRoute.parent_addChild(params)
|
|
|
|
if (response.code === 1) {
|
|
uni.showToast({
|
|
title: '添加成功',
|
|
icon: 'success'
|
|
})
|
|
|
|
// 重新加载学员列表
|
|
await this.loadChildrenList()
|
|
this.closeAddStudentDialog()
|
|
} else {
|
|
uni.showToast({
|
|
title: response.msg || '添加失败',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
} catch (error) {
|
|
console.error('新增学员失败:', error)
|
|
uni.showToast({
|
|
title: '添加失败,请重试',
|
|
icon: 'none'
|
|
})
|
|
} finally {
|
|
uni.hideLoading()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.main_box {
|
|
background: #f8f9fa;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
// 自定义导航栏
|
|
.navbar_section {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background: #29D3B4;
|
|
|
|
.title {
|
|
padding: 40rpx 20rpx;
|
|
|
|
// 小程序端样式
|
|
// #ifdef MP-WEIXIN
|
|
padding: 80rpx 0 20rpx;
|
|
// #endif
|
|
|
|
font-size: 30rpx;
|
|
color: #fff;
|
|
}
|
|
}
|
|
|
|
// 家长信息
|
|
.parent_info_section {
|
|
background: #fff;
|
|
padding: 32rpx;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
|
|
.parent_basic_info {
|
|
flex: 1;
|
|
|
|
.parent_name {
|
|
font-size: 32rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
}
|
|
|
|
.parent_phone {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
margin-top: 8rpx;
|
|
}
|
|
}
|
|
|
|
.logout_button {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
padding: 12rpx 20rpx;
|
|
border-radius: 12rpx;
|
|
background: rgba(255, 76, 76, 0.1);
|
|
|
|
.logout_icon {
|
|
width: 32rpx;
|
|
height: 32rpx;
|
|
margin-bottom: 4rpx;
|
|
}
|
|
|
|
.logout_text {
|
|
font-size: 22rpx;
|
|
color: #ff4c4c;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 学员卡片区域
|
|
.students_section {
|
|
background: #fff;
|
|
margin: 20rpx;
|
|
border-radius: 16rpx;
|
|
padding: 32rpx;
|
|
|
|
.students_header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 24rpx;
|
|
|
|
.students_title {
|
|
font-size: 32rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
}
|
|
|
|
.add_student_button {
|
|
display: flex;
|
|
align-items: center;
|
|
background: #29d3b4;
|
|
color: #fff;
|
|
padding: 12rpx 20rpx;
|
|
border-radius: 20rpx;
|
|
font-size: 24rpx;
|
|
|
|
.add_icon {
|
|
width: 24rpx;
|
|
height: 24rpx;
|
|
margin-right: 8rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.students_grid {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 20rpx;
|
|
|
|
.student_card {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 24rpx;
|
|
border: 2rpx solid #f0f0f0;
|
|
border-radius: 12rpx;
|
|
background: #fafafa;
|
|
transition: all 0.3s;
|
|
|
|
&.selected {
|
|
border-color: #29d3b4;
|
|
background: rgba(41, 211, 180, 0.05);
|
|
}
|
|
|
|
.student_avatar {
|
|
width: 100rpx;
|
|
height: 100rpx;
|
|
border-radius: 50%;
|
|
overflow: hidden;
|
|
margin-right: 20rpx;
|
|
|
|
.avatar_image {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
}
|
|
|
|
.student_info {
|
|
flex: 1;
|
|
|
|
.student_name {
|
|
font-size: 28rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
margin-bottom: 8rpx;
|
|
}
|
|
|
|
.student_details {
|
|
display: flex;
|
|
gap: 12rpx;
|
|
margin-bottom: 8rpx;
|
|
|
|
.detail_tag {
|
|
font-size: 22rpx;
|
|
color: #666;
|
|
background: #f0f0f0;
|
|
padding: 2rpx 8rpx;
|
|
border-radius: 8rpx;
|
|
}
|
|
}
|
|
|
|
.student_campus {
|
|
font-size: 22rpx;
|
|
color: #999;
|
|
margin-bottom: 4rpx;
|
|
}
|
|
|
|
.student_courses {
|
|
font-size: 24rpx;
|
|
color: #29d3b4;
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
|
|
.student_status {
|
|
padding: 8rpx 16rpx;
|
|
border-radius: 12rpx;
|
|
font-size: 22rpx;
|
|
font-weight: 600;
|
|
|
|
&.active {
|
|
background: rgba(76, 175, 80, 0.1);
|
|
color: #4caf50;
|
|
}
|
|
|
|
&.inactive {
|
|
background: rgba(255, 152, 0, 0.1);
|
|
color: #ff9800;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.empty_students {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
padding: 60rpx 20rpx;
|
|
|
|
.empty_icon {
|
|
width: 120rpx;
|
|
height: 120rpx;
|
|
opacity: 0.3;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.empty_text {
|
|
font-size: 28rpx;
|
|
color: #999;
|
|
margin-bottom: 8rpx;
|
|
}
|
|
|
|
.empty_tip {
|
|
font-size: 24rpx;
|
|
color: #ccc;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 新增学员对话框
|
|
.add_student_dialog {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
z-index: 1000;
|
|
|
|
.dialog_content {
|
|
background: #fff;
|
|
border-radius: 16rpx;
|
|
width: 85%;
|
|
max-height: 80vh;
|
|
overflow: hidden;
|
|
|
|
.dialog_header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 32rpx;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
|
|
.dialog_title {
|
|
font-size: 32rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
}
|
|
|
|
.dialog_close {
|
|
font-size: 48rpx;
|
|
color: #999;
|
|
font-weight: 300;
|
|
}
|
|
}
|
|
|
|
.dialog_form {
|
|
padding: 32rpx;
|
|
max-height: 60vh;
|
|
overflow-y: auto;
|
|
|
|
.form_item {
|
|
margin-bottom: 32rpx;
|
|
|
|
.form_label {
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
margin-bottom: 12rpx;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.form_input {
|
|
width: 100%;
|
|
padding: 20rpx;
|
|
border: 2rpx solid #f0f0f0;
|
|
border-radius: 8rpx;
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
background: #fafafa;
|
|
|
|
&.picker_input {
|
|
color: #666;
|
|
}
|
|
}
|
|
|
|
.form_textarea {
|
|
width: 100%;
|
|
min-height: 120rpx;
|
|
padding: 20rpx;
|
|
border: 2rpx solid #f0f0f0;
|
|
border-radius: 8rpx;
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
background: #fafafa;
|
|
resize: none;
|
|
}
|
|
|
|
.gender_selector {
|
|
display: flex;
|
|
gap: 20rpx;
|
|
|
|
.gender_option {
|
|
flex: 1;
|
|
padding: 16rpx;
|
|
text-align: center;
|
|
border: 2rpx solid #f0f0f0;
|
|
border-radius: 8rpx;
|
|
font-size: 28rpx;
|
|
color: #666;
|
|
background: #fafafa;
|
|
|
|
&.selected {
|
|
border-color: #29d3b4;
|
|
background: rgba(41, 211, 180, 0.1);
|
|
color: #29d3b4;
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.dialog_actions {
|
|
display: flex;
|
|
gap: 20rpx;
|
|
padding: 32rpx;
|
|
border-top: 1px solid #f0f0f0;
|
|
|
|
.action_button {
|
|
flex: 1;
|
|
padding: 24rpx;
|
|
text-align: center;
|
|
border-radius: 8rpx;
|
|
font-size: 28rpx;
|
|
font-weight: 600;
|
|
|
|
&.cancel {
|
|
background: #f0f0f0;
|
|
color: #666;
|
|
}
|
|
|
|
&.confirm {
|
|
background: #29d3b4;
|
|
color: #fff;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// 弹窗样式
|
|
.child_popup {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
z-index: 1000;
|
|
|
|
.popup_content {
|
|
background: #fff;
|
|
border-radius: 16rpx;
|
|
width: 80%;
|
|
max-height: 70vh;
|
|
overflow: hidden;
|
|
|
|
.popup_header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 32rpx;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
|
|
.popup_title {
|
|
font-size: 32rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
}
|
|
|
|
.popup_close {
|
|
font-size: 48rpx;
|
|
color: #999;
|
|
font-weight: 300;
|
|
}
|
|
}
|
|
|
|
.popup_children_list {
|
|
max-height: 50vh;
|
|
overflow-y: auto;
|
|
|
|
.popup_child_item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 24rpx 32rpx;
|
|
border-bottom: 1px solid #f8f9fa;
|
|
|
|
&.selected {
|
|
background: rgba(41, 211, 180, 0.1);
|
|
}
|
|
|
|
.popup_child_info {
|
|
flex: 1;
|
|
|
|
.popup_child_name {
|
|
font-size: 28rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
margin-bottom: 8rpx;
|
|
}
|
|
|
|
.popup_child_details {
|
|
display: flex;
|
|
gap: 12rpx;
|
|
margin-bottom: 8rpx;
|
|
|
|
.popup_detail_tag {
|
|
font-size: 22rpx;
|
|
color: #666;
|
|
background: #f0f0f0;
|
|
padding: 2rpx 8rpx;
|
|
border-radius: 8rpx;
|
|
}
|
|
}
|
|
|
|
.popup_child_campus, .popup_child_class {
|
|
font-size: 22rpx;
|
|
color: #999;
|
|
margin-bottom: 4rpx;
|
|
}
|
|
}
|
|
|
|
.popup_child_courses {
|
|
font-size: 24rpx;
|
|
color: #29d3b4;
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
}
|
|
|
|
.popup_add_child_section {
|
|
padding: 32rpx;
|
|
border-top: 1px solid #f0f0f0;
|
|
|
|
.popup_add_child_button {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 24rpx;
|
|
background: rgba(41, 211, 180, 0.1);
|
|
border: 2rpx dashed #29d3b4;
|
|
border-radius: 12rpx;
|
|
transition: all 0.3s;
|
|
|
|
&:active {
|
|
background: rgba(41, 211, 180, 0.2);
|
|
}
|
|
|
|
.popup_add_icon {
|
|
width: 32rpx;
|
|
height: 32rpx;
|
|
margin-right: 12rpx;
|
|
}
|
|
|
|
.popup_add_text {
|
|
font-size: 28rpx;
|
|
color: #29d3b4;
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 选中孩子信息
|
|
.selected_child_section {
|
|
background: #fff;
|
|
margin: 20rpx;
|
|
border-radius: 16rpx;
|
|
padding: 32rpx;
|
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
|
|
|
|
.selected_child_header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 32rpx;
|
|
|
|
.selected_child_info {
|
|
flex: 1;
|
|
|
|
.selected_child_name {
|
|
font-size: 32rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
margin-bottom: 8rpx;
|
|
}
|
|
|
|
.selected_child_details {
|
|
display: flex;
|
|
gap: 12rpx;
|
|
|
|
.selected_detail_tag {
|
|
font-size: 22rpx;
|
|
color: #666;
|
|
background: #f0f0f0;
|
|
padding: 4rpx 12rpx;
|
|
border-radius: 12rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.switch_button {
|
|
background: #29d3b4;
|
|
color: #fff;
|
|
padding: 12rpx 24rpx;
|
|
border-radius: 20rpx;
|
|
font-size: 24rpx;
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
|
|
.stats_grid {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
|
|
.stat_item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 8rpx;
|
|
|
|
.stat_number {
|
|
color: #29D3B4;
|
|
font-size: 48rpx;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.stat_label {
|
|
color: #AAAAAA;
|
|
font-size: 24rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.main_section {
|
|
margin-top: 20rpx;
|
|
background: #f8f9fa;
|
|
padding: 0 24rpx;
|
|
padding-top: 40rpx;
|
|
padding-bottom: 150rpx;
|
|
|
|
.grid_container {
|
|
background: #fff;
|
|
border-radius: 16rpx;
|
|
padding: 40rpx 20rpx;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: space-between;
|
|
|
|
.grid_item {
|
|
width: 30%;
|
|
margin-bottom: 40rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
|
|
&.empty_item {
|
|
// 空白占位项不显示任何内容
|
|
}
|
|
|
|
.grid_icon {
|
|
width: 88rpx;
|
|
height: 88rpx;
|
|
border-radius: 50%;
|
|
background: rgba(41, 211, 180, 0.1);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-bottom: 16rpx;
|
|
|
|
.icon_image {
|
|
width: 48rpx;
|
|
height: 48rpx;
|
|
}
|
|
}
|
|
|
|
.grid_text {
|
|
font-size: 26rpx;
|
|
color: #333;
|
|
text-align: center;
|
|
line-height: 1.2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 箭头图标样式
|
|
.arrow-icon {
|
|
width: 24rpx;
|
|
height: 24rpx;
|
|
opacity: 0.6;
|
|
}
|
|
</style>
|