智慧教务系统UniApp前端项目(使用中2025-0517)
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.
 
 
 
 
 

796 lines
19 KiB

<template>
<view class="main_box">
<view class="main_section">
<!--最近课程-->
<view class="section_3">
<view class="title_box">
<view class="top_box">
<text>最近课程</text>
<view></view>
</view>
<view class="line"></view>
</view>
<view class="ul" v-if="infoData.course_list && infoData.course_list.length > 0">
<!-- 上课中-->
<view class="li" v-for="(v,k) in infoData.course_list" :key="k" @click="openViewCourseInfoList(v)">
<view class="top_box">
<view class="title">课程:{{ v.courses_name }}</view>
<view class="title">时间:{{ v.date_time }} {{ v.time_slot.split(',')[0] }}-{{ v.time_slot.split(',')[1] }}
</view>
<view class="title">地点:{{ v.address }}</view>
</view>
<view class="botton_box" v-if="v.status == 1">
<view class="box">
<view>已签到学生({{ v.sign_count }}/{{ v.students_count }})</view>
<view>
查看
<fui-icon size="35" color="#fff" name="arrowright"></fui-icon>
</view>
</view>
<!-- <view class="box">-->
<!-- <view>尚未发布作业</view>-->
<!-- <view></view>-->
<!-- </view>-->
</view>
<view class="botton_box" v-else>
<view class="box">
<view>应到学生({{ v.students_count }})</view>
<view>
查看
<fui-icon size="35" color="#fff" name="arrowright"></fui-icon>
</view>
</view>
</view>
<view
v-if="v.status == 1"
class="tag"
style="background:#fad24e;">上课中
</view>
<view
v-else
class="tag"
style="background:#1cd188;">待上课
</view>
</view>
</view>
<!-- 没有数据时的占位区域 -->
<view class="empty-placeholder" v-else>
<image src="/static/icon-img/empty.png" mode="aspectFit"></image>
<text>暂无课程数据</text>
</view>
</view>
<!--作业批改-->
<view class="section_4">
<view class="title_box">
<view class="top_box">
<text>作业批改</text>
<view @click="openObjListView()">全部</view>
</view>
<view class="line"></view>
</view>
<view class="ul" v-if="infoData.task_list && infoData.task_list.length > 0">
<view class="li" v-for="(v,k) in infoData.task_list" :key="k" @click="openViewWorkDetails(v)">
<view class="left_box">
<view class="date_box">
<text>{{v.wc_count}}</text>
<text>/</text>
<text>{{v.student_count}}</text>
</view>
<view class="ratio">
完成率:{{v.rate}}%
</view>
</view>
<view class="center_box">
<view>班级:{{v.class_name}}</view>
<view>时间:{{v.send_time}}</view>
<view>课程:{{v.courses_name}}
</view>
</view>
<view class="right_box">
<!-- <view class="tag" style="background:#fad24e;">上课中</view>-->
<view class="tag" style="background:#1cd188;">待批改</view>
</view>
</view>
</view>
<!-- 没有数据时的占位区域 -->
<view class="empty-placeholder" v-else>
<image src="/static/icon-img/empty.png" mode="aspectFit"></image>
<text>暂无作业数据</text>
</view>
</view>
<!--我的服务列表-->
<view class="section_6">
<view class="title_box">
<view class="top_box">
<text>我的服务</text>
<view @click="openServiceListView()">全部</view>
</view>
<view class="line"></view>
</view>
<view class="service-list" v-if="serviceList && serviceList.length > 0">
<view class="service-item" v-for="(item, index) in serviceList" :key="index" @click="viewServiceDetail(item)">
<view class="service-info">
<view class="service-name">{{item.name}}</view>
<view class="service-desc">{{item.description}}</view>
<view class="service-time">创建时间:{{item.create_time}}</view>
</view>
<view class="service-status" :class="{'active': item.status === 1}">
{{item.status === 1 ? '进行中' : '已结束'}}
</view>
</view>
</view>
<!-- 没有数据时的占位区域 -->
<view class="empty-placeholder" v-else>
<image src="/static/icon-img/empty.png" mode="aspectFit"></image>
<text>暂无服务数据</text>
</view>
</view>
</view>
<!-- 底部导航-->
<AQTabber/>
</view>
</template>
<script>
import memberApi from '@/api/member.js';
import AQTabber from "@/components/AQ/AQTabber.vue"
export default {
components: {
AQTabber,
},
data() {
return {
//首页数据
infoData:{
course_list:[],//课程列表
task_list:[],//作业批改
},
serviceList: [], // 我的服务列表
}
},
onLoad() {
this.init() // 页面加载时初始化
},
onShow() {
this.init() // 每次显示页面时初始化
},
methods: {
//初始化
async init(){
await this.getInfo()
await this.getServiceList() // 获取服务列表
},
//获取首页信息
async getInfo(){
// 注释掉API调用,使用模拟数据
// let res = await memberApi.jlIndex({})
// if(res.code != 1){
// uni.showToast({
// title: res.msg,
// icon: 'none'
// })
// return
// }
// this.infoData = res.data
// 使用模拟数据
this.infoData = {
course_list: [
{
id: 1,
courses_name: '少儿英语基础班',
date_time: '2025-07-20',
time_slot: '15:30,17:00',
address: '总部校区 305教室',
status: 0,
sign_count: 0,
students_count: 15
},
{
id: 2,
courses_name: '少儿英语进阶班',
date_time: '2025-07-21',
time_slot: '14:00,15:30',
address: '西区校区 203教室',
status: 1,
sign_count: 12,
students_count: 18
},
{
id: 3,
courses_name: '少儿英语口语班',
date_time: '2025-07-22',
time_slot: '10:00,11:30',
address: '东区校区 102教室',
status: 0,
sign_count: 0,
students_count: 10
}
],
task_list: [
{
id: 1,
wc_count: 8,
student_count: 15,
rate: 53,
class_name: '英语基础1班',
send_time: '2025-07-18',
courses_name: '少儿英语基础班'
},
{
id: 2,
wc_count: 15,
student_count: 18,
rate: 83,
class_name: '英语进阶2班',
send_time: '2025-07-17',
courses_name: '少儿英语进阶班'
}
]
}
},
// 获取服务列表
async getServiceList() {
// 注释掉API调用,使用模拟数据
// try {
// // 这里替换为实际的API调用
// let res = await memberApi.serviceList({})
// if(res.code == 1){
// this.serviceList = res.data || []
// } else {
// uni.showToast({
// title: res.msg || '获取服务列表失败',
// icon: 'none'
// })
// }
// } catch (error) {
// console.error('获取服务列表失败:', error)
// uni.showToast({
// title: '获取服务列表失败',
// icon: 'none'
// })
// }
// 使用模拟数据
this.serviceList = [
{
id: 1,
name: '一对一辅导服务',
description: '针对学生个人情况定制的一对一辅导计划,帮助学生快速提高成绩。',
create_time: '2025-07-15',
status: 1
},
{
id: 2,
name: '小组课程服务',
description: '3-5人小组课程,提供互动学习环境,培养学生团队协作能力。',
create_time: '2025-07-20',
status: 0
},
{
id: 3,
name: '课后辅导服务',
description: '针对课后作业和复习提供专业辅导,巩固课堂所学知识。',
create_time: '2025-07-01',
status: 1
}
]
},
//打开-发布作业页
openObjAddView(){
this.$navigateTo({
url: '/pages/coach/job/add'
})
},
//打开作业列表页
openObjListView(){
this.$navigateTo({
url: '/pages/coach/job/list'
})
},
//跳转页面-课程详情
openViewCourseInfoList(item){
let id = item.id
this.$navigateTo({
url: `/pages/coach/course/info_list?id=${id}`
})
},
//跳转页面-作业详情
openViewWorkDetails(item){
let id = item.id
this.$navigateTo({
url: `/pages/coach/student/work_details?id=${id}`
})
},
// 打开服务列表页面
openServiceListView() {
this.$navigateTo({
url: '/pages/coach/my/service_list'
})
},
// 查看服务详情
viewServiceDetail(item) {
let id = item.id
this.$navigateTo({
url: `/pages/coach/my/service_detail?id=${id}`
})
},
// 跳转到我的学员列表页面
goToStudentList() {
this.$navigateTo({
url: '/pages/coach/student/student_list'
})
},
// 跳转到班级列表页面
goToClassList() {
this.$navigateTo({
url: '/pages/coach/class/list'
})
},
}
}
</script>
<style lang="less" scoped>
.main_box{
background: #292929 ;
}
//自定义导航栏
.navbar_section{
padding: 0 40rpx;
display: flex;
justify-content: space-between;
align-items: center;
background: #29d3b4;
view{
width: 30%;
text-align: center;
}
.left{
text-align: left;
}
.title{
padding: 40rpx 0rpx;
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0rpx;
// #endif
font-size: 30rpx;
color: #fff;
}
.right{
padding: 20rpx 0;
/* H5端样式 */
// #ifdef H5
padding: 40rpx 0 20rpx;
// #endif
/* 小程序端样式 */
// #ifdef MP-WEIXIN
padding: 80rpx 0 20rpx;
// #endif
font-size: 26rpx;
color: #fff;
text-align: right;
}
}
.main_section{
min-height: 100vh;
background: #292929 100%;
padding: 0 24rpx;
padding-top: 40rpx;
padding-bottom: 150rpx;
font-size: 28rpx;
/* 空数据占位区域样式 */
.empty-placeholder {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60rpx 0;
image {
width: 200rpx;
height: 200rpx;
margin-bottom: 20rpx;
}
text {
color: #999;
font-size: 28rpx;
}
}
.section_1{
background: #FFFFFF 100%;
height: 264rpx;
border-radius: 14rpx;
margin: 28rpx auto;
padding: 28rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
font-size: 28rpx;
.top{
display: flex;
justify-content: space-between;
align-items: center;
.user{
display: flex;
align-items: center;
gap: 20rpx;
.pic{
width: 144rpx;
height: 144rpx;
border-radius: 50%;
image{
width: 100%;
height: 100%;
}
}
}
.right{
display: flex;
flex-direction: column;
gap: 20rpx;
view{
display: flex;
gap: 10rpx;
.title{
width: 148rpx;
text-align: right;
}
}
}
}
.bottom{
padding: 0 44rpx;
}
}
.section_2{
border-radius: 60rpx;
padding: 28rpx 36rpx;
background: #29D3B4 100%;
color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
.left_box{
display: flex;
view{
display: flex;
flex-direction: column;
text{}
}
view:nth-child(1){
padding-right: 10rpx;
border-right: 2px solid #fff;
}
view:nth-child(2){
padding-left: 10rpx;
}
}
.rigth_box{
view{
width: 106rpx;
height: 50rpx;
line-height: 50rpx;
text-align: center;
border-radius: 25rpx;
background: #32baa1;
font-size: 24rpx;
}
}
}
.section_3{
margin-top: 36rpx;
color: #fff;
font-size: 24rpx;
.title_box{
display: flex;
flex-direction: column;
.top_box{
display: flex;
justify-content: space-between;
align-items: center;
text{
font-size: 30rpx;
}
}
.line{
width: 90rpx;
height: 2px;
background: #29D3B4;
}
}
.ul{
margin-top: 30rpx;
display: flex;
flex-direction: column;
gap: 20rpx;
.li{
border: 1px solid #00E5BB;
position: relative;
border-radius: 22rpx;
background: #434544 100%;
padding: 14rpx 20rpx;
padding-bottom: 44rpx;
display: flex;
flex-direction: column;
.top_box{
padding-bottom: 18rpx;
border-bottom: 1px dashed #F2F2F2;
display: flex;
flex-direction: column;
gap: 18rpx;
.title{}
}
.botton_box{
padding-top: 18rpx;
display: flex;
flex-direction: column;
gap: 18rpx;
color: #D7D7D7;
.box{
display: flex;
justify-content: space-between;
view{
display: flex;
align-items: center;
}
}
}
.tag{
position:absolute;
top: 0rpx;
right: 0rpx;
padding: 10rpx;
width: 102rpx;
text-align: center;
font-size: 24rpx;
border-bottom-left-radius: 20rpx;
border-top-right-radius: 20rpx;
}
}
}
}
.section_4{
margin-top: 36rpx;
color: #fff;
font-size: 24rpx;
.title_box{
display: flex;
flex-direction: column;
.top_box{
display: flex;
justify-content: space-between;
align-items: center;
text{
font-size: 30rpx;
}
}
.line{
width: 90rpx;
height: 2px;
background: #29D3B4;
}
}
.ul{
margin-top: 30rpx;
display: flex;
flex-direction: column;
gap: 20rpx;
.li{
position: relative;
border-radius: 22rpx;
background: #434544 100%;
padding: 32rpx 0;
display: flex;
align-items: center;
.left_box{
margin-left: 28rpx;
width: 146rpx;
display: flex;
flex-direction: column;
gap: 10rpx;
.date_box{
display: flex;
font-size: 48rpx;
text:nth-child(1){
color: #29D3B4;
}
}
.ratio{
color: #AAAAAA;
}
}
.center_box{
margin-left: 52rpx;
display: flex;
flex-direction: column;
gap: 10rpx;
}
.right_box{
.tag{
position:absolute;
top: 0rpx;
right: 0rpx;
padding: 10rpx;
width: 102rpx;
text-align: center;
font-size: 24rpx;
border-bottom-left-radius: 20rpx;
border-top-right-radius: 20rpx;
}
}
}
}
}
.section_5{
margin-top: 36rpx;
color: #fff;
font-size: 24rpx;
.title_box{
display: flex;
flex-direction: column;
.top_box{
display: flex;
justify-content: space-between;
align-items: center;
text{
font-size: 30rpx;
}
}
.line{
width: 90rpx;
height: 2px;
background: #29D3B4;
}
}
.quick-links {
margin-top: 30rpx;
display: flex;
justify-content: space-around;
.quick-link-item {
display: flex;
flex-direction: column;
align-items: center;
background: #434544;
border-radius: 20rpx;
padding: 30rpx 20rpx;
width: 30%;
.quick-link-icon {
margin-bottom: 20rpx;
}
.quick-link-text {
font-size: 28rpx;
color: #fff;
}
}
}
}
.section_6{
margin-top: 36rpx;
color: #fff;
font-size: 24rpx;
.title_box{
display: flex;
flex-direction: column;
.top_box{
display: flex;
justify-content: space-between;
align-items: center;
text{
font-size: 30rpx;
}
}
.line{
width: 90rpx;
height: 2px;
background: #29D3B4;
}
}
.service-list{
margin-top: 30rpx;
display: flex;
flex-direction: column;
gap: 20rpx;
.service-item{
position: relative;
border-radius: 22rpx;
background: #434544 100%;
padding: 24rpx 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
border-left: 4rpx solid #29D3B4;
.service-info{
flex: 1;
display: flex;
flex-direction: column;
gap: 12rpx;
.service-name{
font-size: 30rpx;
color: #fff;
font-weight: 500;
}
.service-desc{
font-size: 24rpx;
color: #D7D7D7;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.service-time{
font-size: 22rpx;
color: #AAAAAA;
margin-top: 6rpx;
}
}
.service-status{
padding: 8rpx 20rpx;
border-radius: 30rpx;
background: #666;
color: #fff;
font-size: 24rpx;
text-align: center;
&.active {
background: #29D3B4;
}
}
}
}
}
}
</style>