51 changed files with 322 additions and 18962 deletions
@ -1,263 +0,0 @@ |
|||||
<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.todo_list && infoData.todo_list.length > 0"> |
|
||||
<view class="li" v-for="(v,k) in infoData.todo_list" :key="k" @click="openViewTodoDetail(v)"> |
|
||||
<view class="top_box"> |
|
||||
<view class="title">任务:{{ v.title }}</view> |
|
||||
<view class="title">创建时间:{{ v.create_time }}</view> |
|
||||
<view class="title">截止时间:{{ v.deadline }}</view> |
|
||||
</view> |
|
||||
<view class="botton_box"> |
|
||||
<view class="box"> |
|
||||
<view>优先级:{{ v.priority_text }}</view> |
|
||||
<view> |
|
||||
查看 |
|
||||
<fui-icon size="35" color="#fff" name="arrowright"></fui-icon> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view |
|
||||
v-if="v.status == 'pending'" |
|
||||
class="tag" |
|
||||
style="background:#007ACC;">待处理 |
|
||||
</view> |
|
||||
<view |
|
||||
v-if="v.status == 'processing'" |
|
||||
class="tag" |
|
||||
style="background:#fad24e;">处理中 |
|
||||
</view> |
|
||||
<view |
|
||||
v-if="v.status == 'completed'" |
|
||||
class="tag" |
|
||||
style="background:#29d3b4;">已完成 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view v-else class="empty_box"> |
|
||||
<image src="/static/images/empty.png" mode="aspectFit"></image> |
|
||||
<text>暂无待办事项</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!--统计数据--> |
|
||||
<view class="section_3"> |
|
||||
<view class="title_box"> |
|
||||
<view class="top_box"> |
|
||||
<text>数据统计</text> |
|
||||
<view></view> |
|
||||
</view> |
|
||||
<view class="line"></view> |
|
||||
</view> |
|
||||
<view class="stats_grid"> |
|
||||
<view class="stat_item" @click="openViewStats('students')"> |
|
||||
<view class="stat_number">{{ infoData.student_count || 0 }}</view> |
|
||||
<view class="stat_label">学员总数</view> |
|
||||
</view> |
|
||||
<view class="stat_item" @click="openViewStats('courses')"> |
|
||||
<view class="stat_number">{{ infoData.course_count || 0 }}</view> |
|
||||
<view class="stat_label">课程总数</view> |
|
||||
</view> |
|
||||
<view class="stat_item" @click="openViewStats('teachers')"> |
|
||||
<view class="stat_number">{{ infoData.teacher_count || 0 }}</view> |
|
||||
<view class="stat_label">教师总数</view> |
|
||||
</view> |
|
||||
<view class="stat_item" @click="openViewStats('classes')"> |
|
||||
<view class="stat_number">{{ infoData.class_count || 0 }}</view> |
|
||||
<view class="stat_label">班级总数</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
infoData: { |
|
||||
todo_list: [], |
|
||||
student_count: 0, |
|
||||
course_count: 0, |
|
||||
teacher_count: 0, |
|
||||
class_count: 0 |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
onShow() { |
|
||||
this.init() |
|
||||
}, |
|
||||
methods: { |
|
||||
async init() { |
|
||||
try { |
|
||||
// 获取教务首页数据 |
|
||||
const res = await apiRoute.getAcademicHomeData(); |
|
||||
if (res && res.code === 1) { |
|
||||
this.infoData = res.data; |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.error('获取教务数据失败:', error); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 打开待办事项详情 |
|
||||
openViewTodoDetail(item) { |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/academic/todo/detail?id=${item.id}` |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
// 打开统计页面 |
|
||||
openViewStats(type) { |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/academic/stats/index?type=${type}` |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box { |
|
||||
width: 100%; |
|
||||
background-color: #f5f5f5; |
|
||||
min-height: 100vh; |
|
||||
padding-bottom: 140rpx; |
|
||||
} |
|
||||
|
|
||||
.main_section { |
|
||||
padding: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.section_3 { |
|
||||
margin-bottom: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.title_box { |
|
||||
.top_box { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
margin-bottom: 20rpx; |
|
||||
|
|
||||
text { |
|
||||
font-size: 36rpx; |
|
||||
font-weight: bold; |
|
||||
color: #007ACC; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.line { |
|
||||
height: 4rpx; |
|
||||
background: linear-gradient(to right, #007ACC, #4DA6FF); |
|
||||
border-radius: 2rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.ul { |
|
||||
margin-top: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.li { |
|
||||
background: #fff; |
|
||||
border-radius: 20rpx; |
|
||||
padding: 30rpx; |
|
||||
margin-bottom: 20rpx; |
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 122, 204, 0.1); |
|
||||
position: relative; |
|
||||
|
|
||||
.top_box { |
|
||||
.title { |
|
||||
font-size: 28rpx; |
|
||||
color: #333; |
|
||||
margin-bottom: 15rpx; |
|
||||
line-height: 1.4; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.botton_box { |
|
||||
margin-top: 20rpx; |
|
||||
|
|
||||
.box { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
background: #007ACC; |
|
||||
color: #fff; |
|
||||
padding: 20rpx 30rpx; |
|
||||
border-radius: 15rpx; |
|
||||
font-size: 26rpx; |
|
||||
margin-bottom: 10rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.tag { |
|
||||
position: absolute; |
|
||||
top: 30rpx; |
|
||||
right: 30rpx; |
|
||||
padding: 10rpx 20rpx; |
|
||||
border-radius: 20rpx; |
|
||||
color: #fff; |
|
||||
font-size: 22rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.empty_box { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
padding: 100rpx 0; |
|
||||
|
|
||||
image { |
|
||||
width: 200rpx; |
|
||||
height: 200rpx; |
|
||||
margin-bottom: 30rpx; |
|
||||
opacity: 0.5; |
|
||||
} |
|
||||
|
|
||||
text { |
|
||||
color: #999; |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.stats_grid { |
|
||||
display: grid; |
|
||||
grid-template-columns: 1fr 1fr; |
|
||||
gap: 20rpx; |
|
||||
margin-top: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.stat_item { |
|
||||
background: #fff; |
|
||||
border-radius: 20rpx; |
|
||||
padding: 40rpx 30rpx; |
|
||||
text-align: center; |
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 122, 204, 0.1); |
|
||||
|
|
||||
.stat_number { |
|
||||
font-size: 48rpx; |
|
||||
font-weight: bold; |
|
||||
color: #007ACC; |
|
||||
margin-bottom: 10rpx; |
|
||||
} |
|
||||
|
|
||||
.stat_label { |
|
||||
font-size: 26rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,638 +0,0 @@ |
|||||
<!--班级-详情--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<!--自定义导航栏--> |
|
||||
<!-- <view class="navbar_section">--> |
|
||||
<!-- <view class="title">班级详情</view>--> |
|
||||
<!-- </view>--> |
|
||||
|
|
||||
<view class="main_section"> |
|
||||
<view class="section_1"> |
|
||||
<view class="left"> |
|
||||
<image class="pic" :src="classInfo.head_coach_head_img"></image> |
|
||||
<view class="name">{{classInfo.head_coach_name}}</view> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="item"> |
|
||||
班级:{{classInfo.class_name}} |
|
||||
</view> |
|
||||
|
|
||||
<view class="item"> |
|
||||
校区:{{classInfo.campus_name}} |
|
||||
</view> |
|
||||
|
|
||||
<!-- <view class="item"> |
|
||||
<!-- 课程:篮球少儿课 |
|
||||
<!-- </view>--> |
|
||||
|
|
||||
<view class="item"> |
|
||||
人数:{{classInfo.classPersonnelRel.length}}人 |
|
||||
</view> |
|
||||
<!-- |
|
||||
<view class="item"> |
|
||||
|
|
||||
时间:{{classInfo.start_date}} - {{classInfo.end_date}} |
|
||||
</view> --> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- <view class="section_2">--> |
|
||||
<!-- <view class="title_box">--> |
|
||||
<!-- <view>最近课程</view>--> |
|
||||
<!-- </view>--> |
|
||||
<!-- <view class="tag_list">--> |
|
||||
<!-- <view class="item" @click="openViewCourseInfo({id:1})">--> |
|
||||
<!-- <view class="title">--> |
|
||||
<!-- 篮球少儿课--> |
|
||||
<!-- </view>--> |
|
||||
<!-- <view>--> |
|
||||
<!-- 2020.05.30 15:30 - 17:30--> |
|
||||
<!-- </view>--> |
|
||||
<!-- </view>--> |
|
||||
<!-- <view class="item" @click="openViewCourseInfo({id:2})">--> |
|
||||
<!-- <view class="title">--> |
|
||||
<!-- 篮球少儿课--> |
|
||||
<!-- </view>--> |
|
||||
<!-- <view>--> |
|
||||
<!-- 2020.05.30 15:30 - 17:30--> |
|
||||
<!-- </view>--> |
|
||||
<!-- </view>--> |
|
||||
<!-- </view>--> |
|
||||
<!-- </view>--> |
|
||||
|
|
||||
<view class="section_3"> |
|
||||
<view class="btn_box"> |
|
||||
<view :class="['btn', tabType=='1'?'select':'']" @click="tabChange(1)"> |
|
||||
班级成员 |
|
||||
</view> |
|
||||
<view :class="['btn', tabType=='2'?'select':'']" @click="tabChange(2)"> |
|
||||
课程计划 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 班级成员列表--> |
|
||||
<view class="section_4" v-if="tabType=='1'"> |
|
||||
<view class="ul"> |
|
||||
<view class="li" v-for="(v,k) in classInfo.classPersonnelRel" :key="k" |
|
||||
@click="openViewStudentInfo(v)"> |
|
||||
<view class="left"> |
|
||||
<view class="box_1"> |
|
||||
<image class="pic" :src="$util.img(v.student.customerResources.member.headimg)"></image> |
|
||||
<view class="tag_box" v-if="v.expire"> |
|
||||
即将到期 |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="box_2"> |
|
||||
<view class="name">{{ v.student.name }}</view> |
|
||||
<view class="date">课程截止时间:{{ $util.formatToDateTime(v.end_date, 'Y-m-d') }}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="item"> |
|
||||
<view>{{ v.studentCoursesInfo.use_gift_hours + v.studentCoursesInfo.use_gift_hours }} |
|
||||
</view> |
|
||||
<view>已上课时</view> |
|
||||
</view> |
|
||||
<view class="item"> |
|
||||
<view> |
|
||||
{{ (v.studentCoursesInfo.total_hours + v.studentCoursesInfo.gift_hours) - (v.studentCoursesInfo.use_gift_hours + v.studentCoursesInfo.use_gift_hours) }} |
|
||||
</view> |
|
||||
<view>剩余课时</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!--课程计划--> |
|
||||
<scroll-view v-if="tabType=='2'" class="section_5" scroll-y="true" :lower-threshold="lowerThreshold" |
|
||||
@scrolltolower="loadMoreData" style="height: 65vh;"> |
|
||||
<view class="ul"> |
|
||||
<view class="li" v-for="(v,k) in courseList" :key="k" @click="openViewCourseInfo(v)"> |
|
||||
<view class="top_box"> |
|
||||
<view class="title"> |
|
||||
课程:{{v.course.course_name}} |
|
||||
</view> |
|
||||
<view class="title"> |
|
||||
时间:{{v.course_date}} |
|
||||
</view> |
|
||||
<view class="title"> |
|
||||
地点:{{v.campus_name}} |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="bottom_box"> |
|
||||
<view class="item"> |
|
||||
<view class="left">应到学员({{v.student.length}})</view> |
|
||||
<view class="right"> |
|
||||
查看 |
|
||||
<fui-icon size="35" color="#fff" name="arrowright"></fui-icon> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="item"> |
|
||||
<view class="left">已签到学生({{v.student_courses.length}}/{{v.student.length}})</view> |
|
||||
<view class="right"> |
|
||||
查看 |
|
||||
<fui-icon size="35" color="#fff" name="arrowright"></fui-icon> |
|
||||
</view> |
|
||||
</view> |
|
||||
<!-- <view class="item">--> |
|
||||
<!-- <view class="left">作业完成率(80%)</view>--> |
|
||||
<!-- <view class="right">--> |
|
||||
<!-- 查看--> |
|
||||
<!-- <fui-icon size="35" color="#fff" name="arrowright"></fui-icon>--> |
|
||||
<!-- </view>--> |
|
||||
<!-- </view>--> |
|
||||
</view> |
|
||||
|
|
||||
<view class="tag" v-if="isCourseFuture(v.student_courses[0].start_date)" |
|
||||
style="background-color:#20CAAF;"> |
|
||||
未开始 |
|
||||
</view> |
|
||||
<view class="tag" v-if="isNowBetween(v.student_courses[0].start_date, v.student_courses[0].end_date)" |
|
||||
style="background-color:#fad24e;"> |
|
||||
上课中 |
|
||||
</view> |
|
||||
<view class="tag" v-if="!isCourseFuture(v.student_courses[0].end_date)" style="background-color:#e2e2e2;"> |
|
||||
已结束 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</scroll-view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 底部导航--> |
|
||||
<!-- <AQTabber/>--> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import memberApi from '@/api/member.js'; |
|
||||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
class_id: '', //班级id |
|
||||
classInfo: {}, //班级数据 |
|
||||
classMemberList: {}, //班级成员 |
|
||||
|
|
||||
tabType: '1', //1=班级成员,2=课程计划 |
|
||||
|
|
||||
|
|
||||
loading: false, //加载状态 |
|
||||
lowerThreshold: 100, //距离底部多远触发 |
|
||||
isReachedBottom: false, //防止重复加载|true=不可加载|false=可加载 |
|
||||
|
|
||||
//筛选条件 |
|
||||
filteredData: { |
|
||||
page: 1, //当前页码 |
|
||||
limit: 10, //每页返回数据条数 |
|
||||
total: 10, //数据总条数 |
|
||||
class_id: '', //班级id |
|
||||
}, |
|
||||
courseList: [], //课程计划数据 |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
this.class_id = options.class_id //课程id |
|
||||
}, |
|
||||
onShow() { |
|
||||
this.init() |
|
||||
}, |
|
||||
//下拉刷新 |
|
||||
async onPullDownRefresh() { |
|
||||
//重置为第一页 |
|
||||
await this.loadData() |
|
||||
await this.getCourseList() |
|
||||
}, |
|
||||
methods: { |
|
||||
|
|
||||
async init() { |
|
||||
// member/course_list//课程列表 |
|
||||
// member/class_info//班级详情+成员详情 |
|
||||
this.getClassInfo() //获取班级详情 |
|
||||
await this.getCourseList() //获取课程列表 |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
isNowBetween(start_date, end_date) { |
|
||||
const now = new Date(); |
|
||||
const start = new Date(start_date); |
|
||||
const end = new Date(end_date); |
|
||||
|
|
||||
return now >= start && now <= end; |
|
||||
}, |
|
||||
|
|
||||
isCourseFuture(courseDate) { |
|
||||
const courseTime = new Date(courseDate).getTime(); |
|
||||
const nowTime = new Date().getTime(); |
|
||||
return courseTime > nowTime; |
|
||||
}, |
|
||||
|
|
||||
//教练端-获取班级详情 |
|
||||
async getClassInfo() { |
|
||||
let res = await apiRoute.jlClassInfo({ |
|
||||
class_id: this.class_id |
|
||||
}) //班级详情 |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
console.log('获取班级列表', res.data) |
|
||||
this.classInfo = res.data |
|
||||
this.classMemberList = res.data.students_list |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
//加载更过(下一页) |
|
||||
loadMoreData() { |
|
||||
//判断是否加载 |
|
||||
if (!this.isReachedBottom) { |
|
||||
this.isReachedBottom = true; //设置为不可请求状态 |
|
||||
this.getCourseList(); |
|
||||
} |
|
||||
}, |
|
||||
//重置为第一页 |
|
||||
async loadData() { |
|
||||
this.isReachedBottom = false; // 重置状态,以便下次触发加载更多 |
|
||||
|
|
||||
this.filteredData.page = 1 //当前页码 |
|
||||
this.filteredData.limit = 10 //每页返回数据条数 |
|
||||
this.filteredData.total = 10 //数据总条数 |
|
||||
}, |
|
||||
//教练端-获取课程列表 |
|
||||
async getCourseList() { |
|
||||
|
|
||||
let data = { |
|
||||
...this.filteredData |
|
||||
} |
|
||||
data.class_id = this.class_id |
|
||||
|
|
||||
console.log(12123, this.courseList) |
|
||||
|
|
||||
if (data.page == 1) { |
|
||||
this.courseList = [] |
|
||||
} |
|
||||
|
|
||||
//判断是否还有数据 |
|
||||
if ((this.filteredData.page - 1) * this.filteredData.limit >= this.filteredData.total) { |
|
||||
this.loading = false |
|
||||
uni.showToast({ |
|
||||
title: '暂无更多', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
let res = await apiRoute.classCourseList(data) |
|
||||
this.loading = false |
|
||||
this.isReachedBottom = false; |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
|
|
||||
this.courseList = this.courseList.concat(res.data.data) // 使用 concat 方法 将新数据追加到数组中 |
|
||||
|
|
||||
this.filteredData.total = res.data.total |
|
||||
console.log('获取课程列表', this.courseList) |
|
||||
this.filteredData.page++ |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
|
|
||||
|
|
||||
//切换tab |
|
||||
tabChange(tabType) { |
|
||||
this.tabType = tabType |
|
||||
}, |
|
||||
|
|
||||
//打开课程详情 |
|
||||
openViewCourseInfo(item) { |
|
||||
let id = item.id |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/coach/course/info_list?id=${id}` |
|
||||
}) |
|
||||
}, |
|
||||
//打开学员详情页 |
|
||||
openViewStudentInfo(item) { |
|
||||
let students_id = item.student.id |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/coach/student/info?students_id=${students_id}` |
|
||||
}) |
|
||||
}, |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box { |
|
||||
background: #292929; |
|
||||
} |
|
||||
|
|
||||
//自定义导航栏 |
|
||||
.navbar_section { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
background: #292929; |
|
||||
|
|
||||
.title { |
|
||||
padding: 40rpx 0rpx; |
|
||||
|
|
||||
/* 小程序端样式 */ |
|
||||
// #ifdef MP-WEIXIN |
|
||||
padding: 80rpx 0rpx; |
|
||||
// #endif |
|
||||
|
|
||||
|
|
||||
font-size: 30rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.main_section { |
|
||||
min-height: 100vh; |
|
||||
background: #292929 100%; |
|
||||
padding: 0 24rpx; |
|
||||
padding-top: 40rpx; |
|
||||
padding-bottom: 150rpx; |
|
||||
font-size: 24rpx; |
|
||||
color: #FFFFFF; |
|
||||
|
|
||||
.section_1 { |
|
||||
background: #333333; |
|
||||
border-radius: 16rpx; |
|
||||
padding: 34rpx 64rpx; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 38rpx; |
|
||||
|
|
||||
.left { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
gap: 12rpx; |
|
||||
|
|
||||
.pic { |
|
||||
width: 92rpx; |
|
||||
height: 92rpx; |
|
||||
border-radius: 50%; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.right { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 12rpx; |
|
||||
|
|
||||
.item {} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.section_2 { |
|
||||
margin-top: 42rpx; |
|
||||
|
|
||||
.title_box { |
|
||||
font-size: 32rpx; |
|
||||
} |
|
||||
|
|
||||
.tag_list { |
|
||||
margin-top: 26rpx; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 26rpx; |
|
||||
|
|
||||
.item { |
|
||||
padding-left: 20rpx; |
|
||||
width: 330rpx; |
|
||||
height: 162rpx; |
|
||||
border: 1px solid #00e5bb; |
|
||||
border-radius: 10rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
justify-content: center; |
|
||||
gap: 10rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//按钮切换 |
|
||||
.section_3 { |
|
||||
margin-top: 54rpx; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
|
|
||||
.btn_box { |
|
||||
width: 698rpx; |
|
||||
border-radius: 8rpx; |
|
||||
background-color: rgba(22, 132, 252, 1); |
|
||||
border: 1rpx solid rgba(22, 132, 252, 1); |
|
||||
|
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
overflow: hidden; |
|
||||
|
|
||||
.btn { |
|
||||
width: 100%; |
|
||||
height: 76rpx; |
|
||||
line-height: 76rpx; |
|
||||
text-align: center; |
|
||||
color: #fff; |
|
||||
font-size: 26rpx; |
|
||||
} |
|
||||
|
|
||||
.select { |
|
||||
color: #1684fc; |
|
||||
background-color: #fff; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
//班级成员列表 |
|
||||
.section_4 { |
|
||||
margin-top: 40rpx; |
|
||||
|
|
||||
.ul { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 10rpx; |
|
||||
|
|
||||
.li { |
|
||||
padding: 20rpx 0; |
|
||||
padding-bottom: 40rpx; |
|
||||
border-bottom: 2px solid #D7D7D7; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
|
|
||||
.left { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 30rpx; |
|
||||
|
|
||||
.box_1 { |
|
||||
padding-left: 20rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
position: relative; |
|
||||
|
|
||||
.pic { |
|
||||
width: 84rpx; |
|
||||
height: 84rpx; |
|
||||
border-radius: 50%; |
|
||||
} |
|
||||
|
|
||||
.tag_box { |
|
||||
position: absolute; |
|
||||
bottom: -30rpx; |
|
||||
width: 120rpx; |
|
||||
height: 38rpx; |
|
||||
background-color: #F59A23; |
|
||||
border-radius: 4rpx; |
|
||||
line-height: 35rpx; |
|
||||
text-align: center; |
|
||||
font-size: 20rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.box_2 { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 20rpx; |
|
||||
|
|
||||
.name { |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
|
|
||||
.date { |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.right { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 14rpx; |
|
||||
|
|
||||
.item { |
|
||||
border: 1px solid #00E5BB; |
|
||||
border-radius: 10rpx; |
|
||||
width: 102rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
|
|
||||
view { |
|
||||
text-align: center; |
|
||||
height: 50rpx; |
|
||||
line-height: 50rpx; |
|
||||
} |
|
||||
|
|
||||
view:nth-child(1) { |
|
||||
font-size: 32rpx; |
|
||||
background-color: #fff; |
|
||||
color: #00e5bb; |
|
||||
} |
|
||||
|
|
||||
view:nth-child(2) { |
|
||||
font-size: 20rpx; |
|
||||
background-color: #00e5bb; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
//课程计划 |
|
||||
.section_5 { |
|
||||
margin-top: 36rpx; |
|
||||
|
|
||||
.ul { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 30rpx; |
|
||||
|
|
||||
.li { |
|
||||
position: relative; |
|
||||
border-radius: 10rpx; |
|
||||
background-color: rgba(63, 63, 67, 1); |
|
||||
border: 2rpx solid rgba(0, 229, 187, 1); |
|
||||
padding: 20rpx 14rpx; |
|
||||
|
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
|
|
||||
.top_box { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 10rpx; |
|
||||
|
|
||||
.title { |
|
||||
color: rgba(255, 255, 255, 1); |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.bottom_box { |
|
||||
padding-top: 10rpx; |
|
||||
margin-top: 20rpx; |
|
||||
border-top: 1px dashed #F2F2F2; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 10rpx; |
|
||||
|
|
||||
.item { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: space-between; |
|
||||
|
|
||||
color: rgba(215, 215, 215, 1); |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.tag { |
|
||||
position: absolute; |
|
||||
right: 0rpx; |
|
||||
top: 0rpx; |
|
||||
width: 110rpx; |
|
||||
height: 60rpx; |
|
||||
line-height: 58rpx; |
|
||||
border-radius: 0rpx 8rpx 0rpx 24rpx; |
|
||||
background-color: rgba(32, 202, 175, 1); |
|
||||
color: rgba(255, 255, 255, 1); |
|
||||
font-size: 24rpx; |
|
||||
text-align: center; |
|
||||
border: 0rpx solid rgba(121, 121, 121, 1); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
} |
|
||||
</style> |
|
||||
@ -1,299 +0,0 @@ |
|||||
<!--班级-列表--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<!--自定义导航栏--> |
|
||||
<view class="navbar_section"> |
|
||||
<view class="title">班级</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="main_section"> |
|
||||
<view class="section_1"> |
|
||||
<fui-input class="input_item" borderTop clearable="true" placeholder="搜索" v-model="filteredData.name" @confirm="search" @input="search"></fui-input> |
|
||||
</view> |
|
||||
|
|
||||
<view class="section_2"> |
|
||||
<scroll-view |
|
||||
class="ul" |
|
||||
scroll-y="true" |
|
||||
:lower-threshold="lowerThreshold" |
|
||||
@scrolltolower="loadMoreData" |
|
||||
style="height: 65vh;" |
|
||||
> |
|
||||
<view |
|
||||
class="li" |
|
||||
v-for="(v,k) in tableList" |
|
||||
:key="k" |
|
||||
@click="openViewClassInfo(v)" |
|
||||
> |
|
||||
<view class="left"> |
|
||||
<image class="pic" :src="v.head_coach_head_img"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="box_1"> |
|
||||
<view class="name"> |
|
||||
{{v.class_name}} |
|
||||
</view> |
|
||||
<view class="btn_box"> |
|
||||
<view v-if="v.end_count">{{v.end_count}}人即将到期</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="box_2"> |
|
||||
<view class="user_list" v-for="(v2,k2) in v.classPersonnelRel" :key="k2"> |
|
||||
<image |
|
||||
:src="$util.img(v2.student.customerResources.member.headimg)"></image> |
|
||||
</view> |
|
||||
<view class="num">{{v.students_count}}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</scroll-view> |
|
||||
</view> |
|
||||
|
|
||||
</view> |
|
||||
|
|
||||
<!-- 底部导航--> |
|
||||
<AQTabber/> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import memberApi from '@/api/member.js'; |
|
||||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
loading:false,//加载状态 |
|
||||
lowerThreshold: 100,//距离底部多远触发 |
|
||||
isReachedBottom: false,//防止重复加载|true=不可加载|false=可加载 |
|
||||
|
|
||||
//筛选条件 |
|
||||
filteredData:{ |
|
||||
page:1,//当前页码 |
|
||||
limit:10,//每页返回数据条数 |
|
||||
total:10,//数据总条数 |
|
||||
name: '',//班级名称 |
|
||||
}, |
|
||||
tableList:[],//聊天数据列表 |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) {}, |
|
||||
onShow(){ |
|
||||
this.init()//初始化 |
|
||||
}, |
|
||||
methods: { |
|
||||
//初始化 |
|
||||
async init(){ |
|
||||
this.getList() |
|
||||
}, |
|
||||
|
|
||||
//加载更多(下一页) |
|
||||
loadMoreData() { |
|
||||
//判断是否加载 |
|
||||
if (!this.isReachedBottom) { |
|
||||
this.isReachedBottom = true;//设置为不可请求状态 |
|
||||
this.getList(); |
|
||||
} |
|
||||
}, |
|
||||
//重置为第一页 |
|
||||
async resetFilteredData() { |
|
||||
this.isReachedBottom = false; // 重置状态,以便下次触发加载更多 |
|
||||
|
|
||||
this.filteredData.page = 1//当前页码 |
|
||||
this.filteredData.limit = 10//每页返回数据条数 |
|
||||
this.filteredData.total = 10//数据总条数 |
|
||||
}, |
|
||||
//获取列表 |
|
||||
async getList(){ |
|
||||
this.loading = true |
|
||||
|
|
||||
let data = {...this.filteredData} |
|
||||
|
|
||||
console.log(111,(this.filteredData.page * this.filteredData.limit) ,(this.filteredData.total)) |
|
||||
|
|
||||
//判断是否还有数据 |
|
||||
if ((this.filteredData.page - 1) * this.filteredData.limit >= this.filteredData.total) { |
|
||||
this.loading = false |
|
||||
uni.showToast({ |
|
||||
title: '暂无更多', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
if(data.page == 1){ |
|
||||
this.tableList = [] |
|
||||
} |
|
||||
|
|
||||
let res = await apiRoute.jlClassList(data) |
|
||||
this.loading = false |
|
||||
this.isReachedBottom = false; |
|
||||
if (res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.tableList = this.tableList.concat(res.data.data); // 使用 concat 方法 将新数据追加到数组中 |
|
||||
|
|
||||
console.log('列表',this.tableList) |
|
||||
this.filteredData.total = res.data.total |
|
||||
this.filteredData.page++ |
|
||||
}, |
|
||||
|
|
||||
async search(e){ |
|
||||
await this.resetFilteredData() |
|
||||
this.filteredData.name = e |
|
||||
await this.getList() |
|
||||
}, |
|
||||
|
|
||||
//打开班级详情页 |
|
||||
openViewClassInfo(item){ |
|
||||
let class_id = item.id |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/coach/class/info?class_id=${class_id}` |
|
||||
}) |
|
||||
}, |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
|
|
||||
.main_box{ |
|
||||
background: #292929 ; |
|
||||
} |
|
||||
|
|
||||
//自定义导航栏 |
|
||||
.navbar_section{ |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
background: #292929; |
|
||||
.title{ |
|
||||
padding: 40rpx 0rpx; |
|
||||
|
|
||||
/* 小程序端样式 */ |
|
||||
// #ifdef MP-WEIXIN |
|
||||
padding: 80rpx 0rpx; |
|
||||
// #endif |
|
||||
|
|
||||
|
|
||||
font-size: 30rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.main_section{ |
|
||||
// min-height: 100vh; |
|
||||
background: #292929 100%; |
|
||||
padding: 0 24rpx; |
|
||||
padding-top: 40rpx; |
|
||||
padding-bottom: 150rpx; |
|
||||
font-size: 24rpx; |
|
||||
color: #FFFFFF; |
|
||||
|
|
||||
.section_1 { |
|
||||
border-radius: 10rpx; |
|
||||
background-color: #525252; |
|
||||
::v-deep .fui-input__wrap{ |
|
||||
border-radius: 10rpx !important; |
|
||||
background-color: #525252 !important; |
|
||||
} |
|
||||
::v-deep .fui-input__background{ |
|
||||
background-color: #525252 !important; |
|
||||
} |
|
||||
.input_item { |
|
||||
height: 60rpx; |
|
||||
::v-deep .uni-input-wrapper{ |
|
||||
.uni-input-placeholder { |
|
||||
font-size: 28rpx !important; |
|
||||
|
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
::v-deep .uni-input-input { |
|
||||
color: #fff; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.section_2{ |
|
||||
margin-top: 34rpx; |
|
||||
.ul{ |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
//gap: 24rpx; |
|
||||
.li{ |
|
||||
margin-bottom: 24rpx; |
|
||||
background: #404045; |
|
||||
padding: 50rpx 36rpx 46rpx; |
|
||||
border-radius: 16rpx; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 32rpx; |
|
||||
.left{ |
|
||||
.pic{ |
|
||||
border-radius: 50%; |
|
||||
width: 92rpx; |
|
||||
height: 92rpx; |
|
||||
} |
|
||||
} |
|
||||
.right{ |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 28rpx; |
|
||||
.box_1{ |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 36rpx; |
|
||||
.name{ |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
.btn_box{ |
|
||||
view{ |
|
||||
border: 1px solid #FAD04D; |
|
||||
border-radius: 10rpx; |
|
||||
width: 182rpx; |
|
||||
height: 48rpx; |
|
||||
line-height: 42rpx; |
|
||||
text-align: center; |
|
||||
font-size: 26rpx; |
|
||||
color: #FAD04D; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.box_2{ |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 44rpx; |
|
||||
.user_list{ |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 14rpx; |
|
||||
image{ |
|
||||
border-radius: 50%; |
|
||||
width: 48rpx; |
|
||||
height: 48rpx; |
|
||||
} |
|
||||
} |
|
||||
.num{} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
} |
|
||||
|
|
||||
|
|
||||
</style> |
|
||||
@ -1,234 +0,0 @@ |
|||||
<!--课程-详情--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<view class="main_section"> |
|
||||
<view class="section_1"> |
|
||||
<view class="title_box">青少儿篮球课</view> |
|
||||
<view class="ul"> |
|
||||
<view class="li"> |
|
||||
<view class="title">课程名称</view> |
|
||||
<view class="content">青少年篮球课</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="title">班级</view> |
|
||||
<view class="content">班级名称</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="title">上课时间</view> |
|
||||
<view class="content">2020.03.25 15:30-17:00</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="title">上课地址</view> |
|
||||
<view class="content">xxxx体育馆302室</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="title">课程名称</view> |
|
||||
<view class="content">青少年篮球课</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="title">教练</view> |
|
||||
<view class="content">包子皮</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="title">教练号码</view> |
|
||||
<view class="content">18888888888</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="title">扣除课时</view> |
|
||||
<view class="content">2个课时</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="state_box"> |
|
||||
<view>已上</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
// import user from '@/api/user.js'; |
|
||||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|
||||
|
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
formData:{}, |
|
||||
|
|
||||
//课程下拉菜单相关 |
|
||||
show_course:false,//是否显示下拉菜单 |
|
||||
//课程下拉菜单 |
|
||||
course_name:'课程',//选中的下拉菜单名称 |
|
||||
options_course: [ |
|
||||
{ |
|
||||
text: '请选择课程', |
|
||||
value: '', |
|
||||
checked: true |
|
||||
}, { |
|
||||
text: '羽毛球课程1', |
|
||||
value: '1' |
|
||||
}, { |
|
||||
text: '篮球课程2', |
|
||||
value: '2' |
|
||||
} |
|
||||
], |
|
||||
|
|
||||
//课室下拉菜单相关 |
|
||||
show_classroom:false,//是否显示下拉菜单 |
|
||||
//课程下拉菜单 |
|
||||
classroom_name:'课室',//选中的下拉菜单名称 |
|
||||
options_classroom: [ |
|
||||
{ |
|
||||
text: '请选择课室', |
|
||||
value: '', |
|
||||
checked: true |
|
||||
}, { |
|
||||
text: '羽毛球201', |
|
||||
value: '1' |
|
||||
}, { |
|
||||
text: '篮球室101', |
|
||||
value: '2' |
|
||||
} |
|
||||
], |
|
||||
} |
|
||||
}, |
|
||||
onLoad() { |
|
||||
}, |
|
||||
methods: { |
|
||||
//选中课程下拉菜单点击事件 |
|
||||
clickCourse(e){ |
|
||||
console.log(e) |
|
||||
this.course_name = e.text |
|
||||
this.show_course = true |
|
||||
}, |
|
||||
//显示下拉菜单 |
|
||||
filterTapCourse() { |
|
||||
//显示下拉框 |
|
||||
this.$refs.ref_course.show() |
|
||||
this.show_course = true; |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
|
|
||||
//选中课室 |
|
||||
clickClassroom(e){ |
|
||||
console.log(e) |
|
||||
this.classroom_name = e.text |
|
||||
this.show_classroom = true |
|
||||
}, |
|
||||
//显示课室下拉菜单 |
|
||||
filterTapClassroom() { |
|
||||
//显示下拉框 |
|
||||
this.$refs.ref_classroom.show() |
|
||||
this.show_classroom = true; |
|
||||
}, |
|
||||
|
|
||||
//打开课时详情页 |
|
||||
openViewCourseInfo(item){ |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/coach/course/info' |
|
||||
}) |
|
||||
}, |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
|
|
||||
.main_box{ |
|
||||
background: #292929 ; |
|
||||
} |
|
||||
|
|
||||
//自定义导航栏 |
|
||||
.navbar_section{ |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
background: #292929; |
|
||||
.title{ |
|
||||
padding: 40rpx 0rpx; |
|
||||
|
|
||||
/* 小程序端样式 */ |
|
||||
// #ifdef MP-WEIXIN |
|
||||
padding: 80rpx 0rpx; |
|
||||
// #endif |
|
||||
|
|
||||
|
|
||||
font-size: 30rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.main_section{ |
|
||||
min-height: 100vh; |
|
||||
background: #292929 100%; |
|
||||
padding: 30rpx 24rpx; |
|
||||
padding-top: 40rpx; |
|
||||
padding-bottom: 150rpx; |
|
||||
font-size: 24rpx; |
|
||||
color: #FFFFFF; |
|
||||
|
|
||||
.section_1{ |
|
||||
border-radius: 22rpx; |
|
||||
padding: 20rpx 40rpx; |
|
||||
background: #333333 100%; |
|
||||
width: 100%; |
|
||||
.title_box{ |
|
||||
padding: 10rpx; |
|
||||
padding-left: 30rpx; |
|
||||
font-size: 32rpx; |
|
||||
} |
|
||||
.ul{ |
|
||||
padding: 40rpx 10rpx; |
|
||||
padding-bottom: 350rpx; |
|
||||
margin-top: 10rpx; |
|
||||
border-top: 1px solid #555555; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 40rpx; |
|
||||
|
|
||||
position: relative; |
|
||||
|
|
||||
.li{ |
|
||||
display: flex; |
|
||||
gap: 72rpx; |
|
||||
.title{ |
|
||||
width: 120rpx; |
|
||||
text-align: right; |
|
||||
} |
|
||||
.content{} |
|
||||
} |
|
||||
.state_box{ |
|
||||
position: absolute; |
|
||||
bottom: 50rpx; |
|
||||
right: 10rpx; |
|
||||
view{ |
|
||||
width: 154rpx; |
|
||||
height: 154rpx; |
|
||||
border-radius: 50%; |
|
||||
background-color: rgba(41,211,180,0.17); |
|
||||
color: rgba(41,211,180,1); |
|
||||
font-size: 26rpx; |
|
||||
text-align: center; |
|
||||
line-height: 150rpx; |
|
||||
transform: rotate(-35deg); /* 旋转 */ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
</style> |
|
||||
@ -1,793 +0,0 @@ |
|||||
<!--课程-详情列表--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<view class="main_section"> |
|
||||
<view class="section_1"> |
|
||||
<view class="title">日期:{{courseInfo.course_date}}</view> |
|
||||
<view class="title">时间:{{courseInfo.time_slot}}</view> |
|
||||
<view class="title">地点:{{courseInfo.venue.venue_name}}</view> |
|
||||
<view class="title">课程:{{courseInfo.course.course_name}}</view> |
|
||||
<view class="title">教练:{{courseInfo.coach.name}}</view> |
|
||||
<view class="title">人数:{{courseInfo.venue.capacity}}</view> |
|
||||
<view class="isbtn" @click="addStudent"> |
|
||||
添加学员 |
|
||||
</view> |
|
||||
<view v-if="courseInfo.student_courses[0] && isNowBetween(courseInfo.student_courses[0].start_date, courseInfo.student_courses[0].end_date)" class="tag" style="background-color: #FAD24E;">上课中 |
|
||||
</view> |
|
||||
<view v-if="courseInfo.student_courses[0] && !isCourseFuture(courseInfo.student_courses[0].end_date)" class="tag" style="background-color: #e2e2e2;">已结束 |
|
||||
</view> |
|
||||
<view v-if="courseInfo.student_courses[0] && isCourseFuture(courseInfo.student_courses[0].start_date)" class="tag" style="background-color: #1cd188;">未开始 |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="section_2"> |
|
||||
<view :class="['table', tableType==1 ? 'select':'']" @click="switchTag(1)">学员情况</view> |
|
||||
<view :class="['table', tableType==2 ? 'select':'']" @click="switchTag(2)">作业情况</view> |
|
||||
</view> |
|
||||
|
|
||||
<!--签到情况--> |
|
||||
<view class="section_3" v-if="tableType == 1"> |
|
||||
|
|
||||
<view class="tip_title" v-if="courseInfo.student_courses.length == 0">暂无数据</view> |
|
||||
|
|
||||
<view class="item" v-for="(v,k) in courseInfo.student_courses" :key="k"> |
|
||||
<view class="left" @click="openViewCourseInfo(v)"> |
|
||||
<image class="pic" model="aspectFit" :src="$util.img(v.avatar)"></image> |
|
||||
<view class="box"> |
|
||||
<view class="title">{{v.name}}</view> |
|
||||
<view class="title">来源:{{v.source}}</view> |
|
||||
<view class="title">一访情况:{{v['school_six_speed'].first_visit_time}}</view> |
|
||||
<view class="title">一访时间:{{v['school_six_speed'].first_visit_status}}</view> |
|
||||
|
|
||||
<view class="title">课程截止时间:{{v.end_date}}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="right" v-if="courseInfo.status == 'pending'"> |
|
||||
<view class="tag leave-tag" @click="written(v.student_id)" v-if="!isWithinTimeSlot(courseInfo.time_slot) && v.status !== 'signed'">请假</view> |
|
||||
<view class="tag signin-tag" @click="signIn(v.student_id)" v-if="isWithinTimeSlot(courseInfo.time_slot) && v.status !== 'signed'">签到</view> |
|
||||
<view class="tag signed-tag" v-if="v.status === 'signed'">已签到</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
</view> |
|
||||
|
|
||||
<!--作业情况--> |
|
||||
<view class="section_4" v-if="tableType == 2"> |
|
||||
<view class="item_box"> |
|
||||
<!-- 待批改--> |
|
||||
<fui-collapse-item @change="changeCollapse(1)" open="true" isBorder="false" contentBg="#434544"> |
|
||||
<view class="title_box"> |
|
||||
<text>待批改({{courseInfo.groupedByStatus1.length}})</text> |
|
||||
</view> |
|
||||
<template v-slot:content> |
|
||||
<view class="ul"> |
|
||||
<view v-for="(v,k) in courseInfo.groupedByStatus1" :key="k" class="li" |
|
||||
@click="openViewWorkDetails(v)"> |
|
||||
<view class="left"> |
|
||||
<image class="pic" model="aspectFit" |
|
||||
:src="$util.img(v.student.customerResources.member.headimg)"></image> |
|
||||
<view class="box"> |
|
||||
<view class="title">{{v.student.name}}</view> |
|
||||
<view class="title"> |
|
||||
<view>提交时间</view> |
|
||||
<view>{{v.created_at}}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<!-- <view class="right"> |
|
||||
<view class="btn">查看并批改</view> |
|
||||
</view> --> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
</fui-collapse-item> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 未提交--> |
|
||||
<view class="item_box"> |
|
||||
<fui-collapse-item @change="changeCollapse(2)" isBorder="false" contentBg="#434544"> |
|
||||
<view class="title_box"> |
|
||||
<text>未提交({{courseInfo.groupedByStatus2.length}})</text> |
|
||||
</view> |
|
||||
<template v-slot:content> |
|
||||
<view class="ul"> |
|
||||
<view class="li" v-for="(v,k) in courseInfo.groupedByStatus2" :key="k" |
|
||||
@click="openViewWorkDetails(v)"> |
|
||||
<view class="left"> |
|
||||
<image class="pic" model="aspectFit" |
|
||||
:src="$util.img(v.student.customerResources.member.headimg)"></image> |
|
||||
<view class="box"> |
|
||||
<view class="title">{{v.student.name}}</view> |
|
||||
<view class="title"> |
|
||||
<view>提交时间</view> |
|
||||
<!-- <view>{{v.created_at}}</view> --> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<!-- <view class="right"> |
|
||||
<view class="btn">查看并批改</view> |
|
||||
</view> --> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
</fui-collapse-item> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 已提交--> |
|
||||
<view class="item_box"> |
|
||||
<fui-collapse-item @change="changeCollapse(3)" isBorder="false" contentBg="#434544"> |
|
||||
<view class="title_box"> |
|
||||
<text>已提交({{courseInfo.groupedByStatus3.length}})</text> |
|
||||
</view> |
|
||||
<template v-slot:content> |
|
||||
<view class="ul"> |
|
||||
<view class="li" v-for="(v,k) in courseInfo.groupedByStatus3" :key="k" |
|
||||
@click="openViewWorkDetails(v)"> |
|
||||
<view class="left"> |
|
||||
<image class="pic" model="aspectFit" |
|
||||
:src="$util.img(v.student.customerResources.member.headimg)"></image> |
|
||||
<view class="box"> |
|
||||
<view class="title">{{v.student.name}}</view> |
|
||||
<view class="title"> |
|
||||
<view>提交时间</view> |
|
||||
<view>{{v.created_at}}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<!-- <view class="right"> |
|
||||
<view class="btn">查看并批改</view> |
|
||||
</view> --> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
</fui-collapse-item> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<fui-modal :show="show" title="选择学员" @click="handleModalClick" :buttons="[]" @cancel="cancel"> |
|
||||
<view class="student-list"> |
|
||||
<view class="student-item" v-for="(item, index) in StudentList" :key="index" @click="change(item)"> |
|
||||
<view class="student-info"> |
|
||||
<view class="student-name">{{item.text}}</view> |
|
||||
<view class="student-details"> |
|
||||
<text>年龄: {{item.age || '未知'}}</text> |
|
||||
<text>来源: {{item.source || '未知'}}</text> |
|
||||
<text>渠道: {{item.source_channel || '未知'}}</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="empty-list" v-if="StudentList.length === 0"> |
|
||||
<text>暂无可添加的学员</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</fui-modal> |
|
||||
<fui-picker :options="StudentList" :linkage="false" :show="false" :layer="1" @change="change" |
|
||||
@cancel="cancel"></fui-picker> |
|
||||
<fui-actionsheet :show="written_show" :tips="written_tips" :isCancel="isCancel" |
|
||||
:itemList="itemList" @cancel="written_cancel" @click="written_click"></fui-actionsheet> |
|
||||
|
|
||||
<uni-popup ref="popup" type="center"> |
|
||||
<view class="popup-content">{{ tipContent }}</view> |
|
||||
</uni-popup> |
|
||||
<AQTabber /> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import memberApi from '@/api/member.js'; |
|
||||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
course_id: '', //课程id |
|
||||
courseInfo: { |
|
||||
sign_list: [], //签到列表 |
|
||||
assignments: { |
|
||||
dpg_list: [], // 待批改作业列表 |
|
||||
wtj_list: [], // 未提交作业列表 |
|
||||
ypg_list: [] // 已批改作业列表 |
|
||||
}, |
|
||||
}, //课时详情 |
|
||||
|
|
||||
tableType: 1, //1=签到情况,2=作业情况 |
|
||||
show: false, |
|
||||
StudentList: [], |
|
||||
written_show: false, |
|
||||
written_tips: '确认请假', |
|
||||
isCancel: false, |
|
||||
itemList: ['确认', '取消'], |
|
||||
qingjia_student_id: 0 |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
this.course_id = options.id |
|
||||
}, |
|
||||
onShow() { |
|
||||
this.init() |
|
||||
}, |
|
||||
methods: { |
|
||||
//初始化 |
|
||||
async init() { |
|
||||
this.getCourseInfo() |
|
||||
}, |
|
||||
|
|
||||
isNowBetween(start_date, end_date) { |
|
||||
const now = new Date(); |
|
||||
const start = new Date(start_date); |
|
||||
const end = new Date(end_date); |
|
||||
|
|
||||
return now >= start && now <= end; |
|
||||
}, |
|
||||
|
|
||||
isCourseFuture(courseDate) { |
|
||||
const courseTime = new Date(courseDate).getTime(); |
|
||||
const nowTime = new Date().getTime(); |
|
||||
return courseTime > nowTime; |
|
||||
}, |
|
||||
|
|
||||
//教练端-课程详情 |
|
||||
async getCourseInfo() { |
|
||||
let res = await apiRoute.courseInfo({ |
|
||||
id: this.course_id |
|
||||
}) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
console.log('课程详情', res.data) |
|
||||
this.courseInfo = res.data |
|
||||
|
|
||||
|
|
||||
// 使用模拟数据 |
|
||||
// this.courseInfo = { |
|
||||
// id: this.course_id || '1', |
|
||||
// course_date: '2025-07-25', |
|
||||
// time_slot: '14:00-15:30', |
|
||||
// status: 'pending', |
|
||||
// venue: { |
|
||||
// venue_name: '总部校区 305教室', |
|
||||
// capacity: 20 |
|
||||
// }, |
|
||||
// course: { |
|
||||
// course_name: '少儿英语基础班' |
|
||||
// }, |
|
||||
// coach: { |
|
||||
// name: '王教练' |
|
||||
// }, |
|
||||
// student_courses: [ |
|
||||
// { |
|
||||
// student_id: '1001', |
|
||||
// name: '张三', |
|
||||
// avatar: '', |
|
||||
// start_date: '2025-07-25', |
|
||||
// end_date: '2025-10-25', |
|
||||
// status: 'pending' |
|
||||
// }, |
|
||||
// { |
|
||||
// student_id: '1002', |
|
||||
// name: '李四', |
|
||||
// avatar: '', |
|
||||
// start_date: '2025-07-25', |
|
||||
// end_date: '2025-10-25', |
|
||||
// status: 'pending' |
|
||||
// } |
|
||||
// ], |
|
||||
// groupedByStatus1: [], // 待批改 |
|
||||
// groupedByStatus2: [], // 未提交 |
|
||||
// groupedByStatus3: [] // 已提交 |
|
||||
// }; |
|
||||
|
|
||||
// console.log('课程详情(模拟数据)', this.courseInfo); |
|
||||
}, |
|
||||
|
|
||||
//切换标签 |
|
||||
switchTag(type) { |
|
||||
this.tableType = type |
|
||||
}, |
|
||||
|
|
||||
//打开课时详情页 |
|
||||
openViewCourseInfo(item) { |
|
||||
// this.$navigateTo({ |
|
||||
// url: '/pages/coach/course/info' |
|
||||
// }) |
|
||||
uni.navigateTo({ |
|
||||
url: `/pages/market/clue/clue_info?resource_sharing_id=25` |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
// 作业情况 |
|
||||
changeCollapse(type) {}, |
|
||||
|
|
||||
//跳转页面-作业详情 |
|
||||
openViewWorkDetails(item) { |
|
||||
let id = item.id |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/coach/student/work_details?id=${id}` |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//获取添加学员列表 |
|
||||
async addStudent() { |
|
||||
let res = await apiRoute.addStudentList({ |
|
||||
id: this.course_id |
|
||||
}) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
this.StudentList = res.data |
|
||||
if (this.StudentList.length == 0) { |
|
||||
uni.showToast({ |
|
||||
title: '暂无可填加的学员', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} else { |
|
||||
// 显示学员选择弹窗 |
|
||||
this.show = true |
|
||||
} |
|
||||
}, |
|
||||
// 处理模态框点击事件 |
|
||||
handleModalClick(e) { |
|
||||
// 如果需要响应按钮事件可在这里处理 |
|
||||
console.log('模态框点击事件', e) |
|
||||
}, |
|
||||
async change(student) { |
|
||||
this.show = false |
|
||||
// 获取学生的student_id和resource_id |
|
||||
let studentId = student.value |
|
||||
let resourceId = student.resource_id |
|
||||
|
|
||||
let res = await apiRoute.addStudent({ |
|
||||
student_id: studentId, |
|
||||
schedule_id: this.course_id, |
|
||||
time_slot: this.courseInfo.time_slot, |
|
||||
course_date: this.courseInfo.course_date, |
|
||||
resource_id: resourceId // 添加resource_id参数 |
|
||||
}) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
uni.showToast({ |
|
||||
title: '添加学员成功', |
|
||||
icon: 'success' |
|
||||
}) |
|
||||
|
|
||||
// 刷新页面数据 |
|
||||
this.init() |
|
||||
}, |
|
||||
cancel() { |
|
||||
this.show = false |
|
||||
}, |
|
||||
//请假 |
|
||||
written(student_id) { |
|
||||
this.qingjia_student_id = student_id |
|
||||
this.written_show = true |
|
||||
}, |
|
||||
written_cancel() { |
|
||||
this.written_show = false |
|
||||
}, |
|
||||
async written_click(e) { |
|
||||
if(e.text == '取消'){ |
|
||||
this.written_show = false |
|
||||
} else { |
|
||||
let res = await apiRoute.delStudentCourse({ |
|
||||
student_id: this.qingjia_student_id, |
|
||||
course_id: this.course_id, |
|
||||
}) |
|
||||
if (res.data) { |
|
||||
uni.showToast({ |
|
||||
title: '请假成功', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
this.init() |
|
||||
} else { |
|
||||
// uni.showToast({ |
|
||||
// title: '学员不存在', |
|
||||
// icon: 'none' |
|
||||
// }) |
|
||||
} |
|
||||
this.written_show = false |
|
||||
} |
|
||||
|
|
||||
}, |
|
||||
isWithinTimeSlot(time_slot) { |
|
||||
const [startStr, endStr] = time_slot.split('-'); |
|
||||
const [startHours, startMinutes] = startStr.split(':').map(Number); |
|
||||
const [endHours, endMinutes] = endStr.split(':').map(Number); |
|
||||
|
|
||||
const now = new Date(); |
|
||||
const startTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), startHours, startMinutes); |
|
||||
const endTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), endHours, endMinutes); |
|
||||
|
|
||||
return now >= startTime && now < endTime; |
|
||||
}, |
|
||||
signIn(student_id) { |
|
||||
uni.showToast({ |
|
||||
title: '签到成功', |
|
||||
icon: 'success' |
|
||||
}); |
|
||||
|
|
||||
// 在实际应用中,这里应该调用签到API |
|
||||
// 例如: |
|
||||
// apiRoute.studentSignIn({ |
|
||||
// student_id: student_id, |
|
||||
// course_id: this.course_id, |
|
||||
// }).then(res => { |
|
||||
// if (res.code == 1) { |
|
||||
// uni.showToast({ |
|
||||
// title: '签到成功', |
|
||||
// icon: 'success' |
|
||||
// }); |
|
||||
// this.init(); |
|
||||
// } else { |
|
||||
// uni.showToast({ |
|
||||
// title: res.msg, |
|
||||
// icon: 'none' |
|
||||
// }); |
|
||||
// } |
|
||||
// }); |
|
||||
|
|
||||
// 更新当前学生的状态(模拟) |
|
||||
const studentIndex = this.courseInfo.student_courses.findIndex(s => s.student_id === student_id); |
|
||||
if (studentIndex !== -1) { |
|
||||
this.courseInfo.student_courses[studentIndex].status = 'signed'; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box { |
|
||||
background: #292929; |
|
||||
} |
|
||||
|
|
||||
//自定义导航栏 |
|
||||
.navbar_section { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
background: #292929; |
|
||||
|
|
||||
.title { |
|
||||
padding: 40rpx 0rpx; |
|
||||
|
|
||||
/* 小程序端样式 */ |
|
||||
// #ifdef MP-WEIXIN |
|
||||
padding: 80rpx 0rpx; |
|
||||
// #endif |
|
||||
|
|
||||
font-size: 30rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/* 学员选择列表样式 */ |
|
||||
.student-list { |
|
||||
max-height: 600rpx; |
|
||||
overflow-y: auto; |
|
||||
} |
|
||||
|
|
||||
.student-item { |
|
||||
padding: 20rpx 30rpx; |
|
||||
border-bottom: 1px solid #eee; |
|
||||
background-color: #f8f8f8; |
|
||||
margin-bottom: 10rpx; |
|
||||
border-radius: 8rpx; |
|
||||
} |
|
||||
|
|
||||
.student-item:active { |
|
||||
background-color: #e0e0e0; |
|
||||
} |
|
||||
|
|
||||
.student-info { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
} |
|
||||
|
|
||||
.student-name { |
|
||||
font-size: 32rpx; |
|
||||
font-weight: bold; |
|
||||
color: #333; |
|
||||
margin-bottom: 10rpx; |
|
||||
} |
|
||||
|
|
||||
.student-details { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
font-size: 24rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
|
|
||||
.student-details text { |
|
||||
margin-bottom: 6rpx; |
|
||||
} |
|
||||
|
|
||||
.empty-list { |
|
||||
padding: 40rpx; |
|
||||
text-align: center; |
|
||||
color: #999; |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
|
|
||||
.main_section { |
|
||||
min-height: 100vh; |
|
||||
background: #292929 100%; |
|
||||
padding: 30rpx 24rpx; |
|
||||
padding-top: 40rpx; |
|
||||
padding-bottom: 150rpx; |
|
||||
font-size: 24rpx; |
|
||||
color: #FFFFFF; |
|
||||
|
|
||||
.section_1 { |
|
||||
position: relative; |
|
||||
padding: 18rpx 34rpx 50rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 15rpx; |
|
||||
color: #fff; |
|
||||
font-size: 24rpx; |
|
||||
background-color: #434544; |
|
||||
border-radius: 22rpx; |
|
||||
|
|
||||
.tag { |
|
||||
position: absolute; |
|
||||
top: 0; |
|
||||
right: 0; |
|
||||
|
|
||||
width: 110rpx; |
|
||||
height: 60rpx; |
|
||||
line-height: 55rpx; |
|
||||
border-radius: 0rpx 24rpx 0rpx 24rpx; |
|
||||
color: #fff; |
|
||||
font-size: 24rpx; |
|
||||
text-align: center; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.section_2 { |
|
||||
margin-top: 44rpx; |
|
||||
color: #fff; |
|
||||
font-size: 30rpx; |
|
||||
|
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
|
|
||||
.table { |
|
||||
width: 50%; |
|
||||
height: 64rpx; |
|
||||
background-color: #1684FCFF; |
|
||||
|
|
||||
line-height: 62rpx; |
|
||||
text-align: center; |
|
||||
} |
|
||||
|
|
||||
.table:nth-child(1) { |
|
||||
border-top-left-radius: 8rpx; |
|
||||
border-bottom-left-radius: 8rpx; |
|
||||
} |
|
||||
|
|
||||
.table:nth-child(2) { |
|
||||
border-top-right-radius: 8rpx; |
|
||||
border-bottom-right-radius: 8rpx; |
|
||||
} |
|
||||
|
|
||||
.select { |
|
||||
background-color: #fff; |
|
||||
color: #1684FCFF; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.section_3 { |
|
||||
margin-top: 44rpx; |
|
||||
min-height: 20vh; |
|
||||
padding: 30rpx 0; |
|
||||
border-radius: 22rpx; |
|
||||
background-color: #434544; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
|
|
||||
//提示 |
|
||||
.tip_title { |
|
||||
text-align: center; |
|
||||
font-size: 30rpx; |
|
||||
color: #FFFFFF; |
|
||||
} |
|
||||
|
|
||||
.item { |
|
||||
border-top: 1px solid #D7D7D7; |
|
||||
padding: 20rpx 33rpx 20rpx 14rpx; |
|
||||
|
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
|
|
||||
.left { |
|
||||
width: 80%; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 26rpx; |
|
||||
|
|
||||
.pic { |
|
||||
width: 92rpx; |
|
||||
height: 92rpx; |
|
||||
border-radius: 50%; |
|
||||
background-color: #797979FF; |
|
||||
} |
|
||||
|
|
||||
.box { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 10rpx; |
|
||||
|
|
||||
.title { |
|
||||
color: #fff; |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.right { |
|
||||
.tag { |
|
||||
width: 93rpx; |
|
||||
height: 93rpx; |
|
||||
border-radius: 50%; |
|
||||
line-height: 90rpx; |
|
||||
font-size: 26rpx; |
|
||||
text-align: center; |
|
||||
border: 0rpx; |
|
||||
//旋转45° |
|
||||
transform: rotate(-30deg); |
|
||||
} |
|
||||
|
|
||||
.leave-tag { |
|
||||
background-color: rgba(254, 250, 131, 0.62); |
|
||||
color: rgba(255, 255, 255, 1); |
|
||||
} |
|
||||
|
|
||||
.signin-tag { |
|
||||
background-color: #1cd188; |
|
||||
color: #FFFFFF; |
|
||||
} |
|
||||
|
|
||||
.signed-tag { |
|
||||
background-color: #a4adb3; |
|
||||
color: #FFFFFF; |
|
||||
transform: none; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.item:nth-child(1) { |
|
||||
border-top: 0px; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.section_4 { |
|
||||
margin-top: 44rpx; |
|
||||
padding: 30rpx 0; |
|
||||
border-radius: 22rpx; |
|
||||
background-color: #434544; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
|
|
||||
.item_box { |
|
||||
margin-bottom: 30rpx; |
|
||||
padding-left: 24rpx; |
|
||||
padding-right: 32rpx; |
|
||||
|
|
||||
|
|
||||
font-size: 28rpx; |
|
||||
color: #fff; |
|
||||
background-color: #434544; |
|
||||
|
|
||||
::v-deep .fui-collapse-item__title { |
|
||||
background-color: #434544 !important; |
|
||||
} |
|
||||
|
|
||||
::v-deep .fui-collapse__border-color { |
|
||||
border-top: none !important; |
|
||||
/* 取消上边框 */ |
|
||||
background: #434544 !important; |
|
||||
} |
|
||||
|
|
||||
.title_box {} |
|
||||
|
|
||||
.ul { |
|
||||
background-color: #434544; |
|
||||
|
|
||||
.li { |
|
||||
background-color: #434544; |
|
||||
border-top: 1px solid #D7D7D7; |
|
||||
padding: 20rpx 33rpx 20rpx 14rpx; |
|
||||
|
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
|
|
||||
.left { |
|
||||
width: 80%; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 26rpx; |
|
||||
|
|
||||
.pic { |
|
||||
width: 92rpx; |
|
||||
height: 92rpx; |
|
||||
border-radius: 50%; |
|
||||
background-color: #797979FF; |
|
||||
} |
|
||||
|
|
||||
.box { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 10rpx; |
|
||||
|
|
||||
.title { |
|
||||
color: #fff; |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.right { |
|
||||
.btn { |
|
||||
background-color: #a4adb3; |
|
||||
color: #fff; |
|
||||
|
|
||||
width: 160rpx; |
|
||||
height: 60rpx; |
|
||||
line-height: 60rpx; |
|
||||
border-radius: 8rpx; |
|
||||
background-color: rgba(164, 173, 179, 1); |
|
||||
color: rgba(255, 255, 255, 1); |
|
||||
font-size: 24rpx; |
|
||||
text-align: center; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.li:nth-child(1) { |
|
||||
border-top: none !important; |
|
||||
/* 取消上边框 */ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.isbtn { |
|
||||
border: 1px solid #FAD04D; |
|
||||
border-radius: 10rpx; |
|
||||
background: #434544; |
|
||||
color: #FAD04D; |
|
||||
width: 110rpx; |
|
||||
height: 60rpx; |
|
||||
line-height: 55rpx; |
|
||||
text-align: center; |
|
||||
font-size: 24rpx; |
|
||||
position: absolute; |
|
||||
bottom: 20rpx; |
|
||||
right: 15rpx; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,648 +0,0 @@ |
|||||
<!--课程-列表--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<view class="main_section"> |
|
||||
<view class="section_1"> |
|
||||
<view class="ul"> |
|
||||
<view class="li" v-for="(v,k) in dates" :key="k" @click="selectDate(v.date)"> |
|
||||
<text>{{v.weekday}}</text> |
|
||||
<text :class="[filteredData.schedule_date == v.date ? 'today':'']">{{today == v.date ? '今':v.dayOfMonth}}</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="btn" @click="show_calendar=true"> |
|
||||
查看更多 <fui-icon name="arrowdown" color="#A4ADB3" size="45"></fui-icon> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- <view class="section_2">--> |
|
||||
<!-- <view class="item_box">--> |
|
||||
<!-- <fui-dropdown-menu :size="28" selectedColor="#465CFF" :options="options_course" @click="clickCourse" @close="show_course=false" ref="ref_course">--> |
|
||||
<!-- <view class="fui-filter__item" @tap="filterTapCourse">--> |
|
||||
<!-- <text>{{course_name}}</text>--> |
|
||||
<!-- <view class="fui-filter__icon" :class="{'fui-icon__ani':show_course}">--> |
|
||||
<!-- <fui-icon name="turningdown" :size="32" color="#FFF"></fui-icon>--> |
|
||||
<!-- </view>--> |
|
||||
<!-- </view>--> |
|
||||
<!-- </fui-dropdown-menu>--> |
|
||||
<!-- </view>--> |
|
||||
<!-- <view class="item_box">--> |
|
||||
<!-- <fui-dropdown-menu :size="28" selectedColor="#465CFF" :options="options_classroom" @click="clickClassroom" @close="show_classroom=false" ref="ref_classroom">--> |
|
||||
<!-- <view class="fui-filter__item" @tap="filterTapClassroom">--> |
|
||||
<!-- <text>{{classroom_name}}</text>--> |
|
||||
<!-- <view class="fui-filter__icon" :class="{'fui-icon__ani':show_classroom}">--> |
|
||||
<!-- <fui-icon name="turningdown" :size="32" color="#FFF"></fui-icon>--> |
|
||||
<!-- </view>--> |
|
||||
<!-- </view>--> |
|
||||
<!-- </fui-dropdown-menu>--> |
|
||||
<!-- </view>--> |
|
||||
|
|
||||
<!-- </view>--> |
|
||||
|
|
||||
|
|
||||
|
|
||||
<scroll-view class="section_3" scroll-y="true" :lower-threshold="lowerThreshold" |
|
||||
@scrolltolower="loadMoreData" style="height: 100vh;"> |
|
||||
<view class="ul"> |
|
||||
<view class="li" v-for="(v,k) in tableList" :key="k" @click="openViewCourseInfoList(v)"> |
|
||||
<view class="top_box"> |
|
||||
<view class="center_box"> |
|
||||
<view>时间:{{v.course_date}}</view> |
|
||||
<view>课室:{{v.venue.venue_name}}</view> |
|
||||
<view>课程:{{v.course.course_name}}</view> |
|
||||
<view>人数:{{v.venue.capacity}}</view> |
|
||||
</view> |
|
||||
<view class="right_box"> |
|
||||
<!-- v.status|1=未开始,2=进行中,3=已结束--> |
|
||||
<!-- <view class="tag" |
|
||||
:style="{background: v.status == 'pending' ? '#1cd188' : v.status == 'ongoing' ? '#fad24e' : '#ff4d4f'}"> |
|
||||
{{ v.status === 'pending' ? '未开始' : v.status === 'ongoing' ? '上课中' : '已结束' }} |
|
||||
</view> --> |
|
||||
<!-- <view class="tag" style="background:#1cd188;">待上课</view>--> |
|
||||
</view> |
|
||||
</view> |
|
||||
<!-- <view class="bottom_box" v-if="v.status !== 'pending'"> --> |
|
||||
<view class="bottom_box"> |
|
||||
<view class="hint"> |
|
||||
已签到学生 ({{v.student.length }}/{{v.venue.capacity}}) |
|
||||
</view> |
|
||||
<view class="list_box"> |
|
||||
<view class="list"> |
|
||||
<view class="itme" v-for="(item,index) in v.student || 0" :key="index"> |
|
||||
<image :src="$util.img(item.avatar)"></image> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="btn"> |
|
||||
详情 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<!-- <view class="isbtn" v-if="v.status === 'pending'"> |
|
||||
详情 |
|
||||
</view> --> |
|
||||
</view> |
|
||||
</view> |
|
||||
</scroll-view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 日历选择--> |
|
||||
<fui-bottom-popup :show="show_calendar" @close="show_calendar=false"> |
|
||||
<view class="fui-custom__wrap"> |
|
||||
<uni-calendar :insert="true" :lunar="false" :selected="calendarSelected" :startDate="startDate" |
|
||||
:endDate="endDate" @change="changeCalendar" /> |
|
||||
</view> |
|
||||
</fui-bottom-popup> |
|
||||
|
|
||||
|
|
||||
<!-- 底部导航--> |
|
||||
<AQTabber /> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
// import user from '@/api/user.js'; |
|
||||
import memberApi from '@/api/member.js'; |
|
||||
import commonApi from '@/api/common.js'; |
|
||||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
loading: false, //加载状态 |
|
||||
lowerThreshold: 100, //距离底部多远触发 |
|
||||
isReachedBottom: false, //防止重复加载|true=不可加载|false=可加载 |
|
||||
|
|
||||
//筛选条件 |
|
||||
filteredData: { |
|
||||
page: 1, //当前页码 |
|
||||
limit: 10, //每页返回数据条数 |
|
||||
total: 10, //数据总条数 |
|
||||
schedule_date: '', //日期 |
|
||||
venue_id: '', //场地id |
|
||||
}, |
|
||||
tableList: [], //表格数据 |
|
||||
venuesInfo: {}, //场地信息 |
|
||||
|
|
||||
formData: {}, |
|
||||
|
|
||||
//课程下拉菜单相关 |
|
||||
show_course: false, //是否显示下拉菜单 |
|
||||
//课程下拉菜单 |
|
||||
course_name: '课程', //选中的下拉菜单名称 |
|
||||
options_course: [{ |
|
||||
text: '请选择课程', |
|
||||
value: '', |
|
||||
checked: true |
|
||||
}, { |
|
||||
text: '羽毛球课程1', |
|
||||
value: '1' |
|
||||
}, { |
|
||||
text: '篮球课程2', |
|
||||
value: '2' |
|
||||
}], |
|
||||
|
|
||||
//课室下拉菜单相关 |
|
||||
show_classroom: false, //是否显示下拉菜单 |
|
||||
//课程下拉菜单 |
|
||||
classroom_name: '课室', //选中的下拉菜单名称 |
|
||||
options_classroom: [{ |
|
||||
text: '请选择课室', |
|
||||
value: '', |
|
||||
checked: true |
|
||||
}, { |
|
||||
text: '羽毛球201', |
|
||||
value: '1' |
|
||||
}, { |
|
||||
text: '篮球室101', |
|
||||
value: '2' |
|
||||
}], |
|
||||
|
|
||||
//今日日期 |
|
||||
today: '', |
|
||||
dateList: [], //日期列表 |
|
||||
|
|
||||
//日历选择相关 |
|
||||
show_calendar: false, //是否展示日期 |
|
||||
startDate: '', //开始日期 |
|
||||
endDate: '', //结束日期 |
|
||||
calendarSelected: [], //日历打点 |
|
||||
dates: {} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
onLoad() {}, |
|
||||
onShow() { |
|
||||
this.init() //初始化 |
|
||||
}, |
|
||||
//下拉刷新 |
|
||||
async onPullDownRefresh() { |
|
||||
//重置为第一页 |
|
||||
this.getThisDate() |
|
||||
let schedule_date = this.filteredData.schedule_date |
|
||||
await this.loadData() |
|
||||
this.filteredData.schedule_date = schedule_date |
|
||||
await this.getList() |
|
||||
}, |
|
||||
methods: { |
|
||||
//初始化 |
|
||||
async init() { |
|
||||
|
|
||||
await this.getThisDate() |
|
||||
await this.getHeadDate() |
|
||||
await this.getList() |
|
||||
// this.getDateRange() |
|
||||
// this.setCalendarSelected() |
|
||||
}, |
|
||||
|
|
||||
//选中课程下拉菜单点击事件 |
|
||||
clickCourse(e) { |
|
||||
console.log(e) |
|
||||
this.course_name = e.text |
|
||||
this.show_course = true |
|
||||
}, |
|
||||
//显示下拉菜单 |
|
||||
filterTapCourse() { |
|
||||
//显示下拉框 |
|
||||
this.$refs.ref_course.show() |
|
||||
this.show_course = true; |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
|
|
||||
//选中课室 |
|
||||
clickClassroom(e) { |
|
||||
console.log(e) |
|
||||
this.classroom_name = e.text |
|
||||
this.show_classroom = true |
|
||||
}, |
|
||||
//显示课室下拉菜单 |
|
||||
filterTapClassroom() { |
|
||||
//显示下拉框 |
|
||||
this.$refs.ref_classroom.show() |
|
||||
this.show_classroom = true; |
|
||||
}, |
|
||||
|
|
||||
//打开课时详情页 |
|
||||
openViewCourseInfoList(item) { |
|
||||
let id = item.id |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/coach/course/info_list?id=${id}` |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
|
|
||||
getDatesAroundToday(offsetDays = 0) { |
|
||||
const date = new Date(); |
|
||||
date.setDate(date.getDate() + offsetDays); |
|
||||
const year = date.getFullYear(); |
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0'); |
|
||||
const day = String(date.getDate()).padStart(2, '0'); |
|
||||
const weekDay = ['日', '一', '二', '三', '四', '五', '六'][date.getDay()]; |
|
||||
return { |
|
||||
date: `${year}-${month}-${day}`, |
|
||||
weekday: `星期${weekDay}`, |
|
||||
dayOfMonth: day // 👈 新增字段:几号 |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
//获取课程头日期 |
|
||||
async getHeadDate() { |
|
||||
// let res = await commonApi.getDate() |
|
||||
// if (res.code != 1) { |
|
||||
// //提示 |
|
||||
// uni.showToast({ |
|
||||
// title: res.msg, |
|
||||
// icon: 'none', |
|
||||
// }) |
|
||||
// return |
|
||||
// } |
|
||||
|
|
||||
// this.dateList = [] |
|
||||
// res.data.forEach((v, k) => { |
|
||||
// let today = v.date.split("-")[2]; // "09" |
|
||||
// this.dateList.push({ |
|
||||
// date: v.date, |
|
||||
// status: v.status, //1是正常 2请假 |
|
||||
// week: v.week, |
|
||||
// today: today, |
|
||||
// }) |
|
||||
// }) |
|
||||
|
|
||||
this.dates = {}; |
|
||||
for (let i = -3; i <= 3; i++) { |
|
||||
const key = i === 0 ? '今天' : `${Math.abs(i)}天${i < 0 ? '前' : '后'}`; |
|
||||
this.dates[key] = this.getDatesAroundToday(i); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
//获取当前日期 |
|
||||
async getThisDate() { |
|
||||
let date = new Date(); |
|
||||
let year = date.getFullYear(); |
|
||||
let month = String(date.getMonth() + 1).padStart(2, '0'); // 月份前补零 |
|
||||
let day = String(date.getDate()).padStart(2, '0'); // 日期前补零 |
|
||||
let hour = date.getHours(); |
|
||||
let minute = date.getMinutes(); |
|
||||
let second = date.getSeconds(); |
|
||||
|
|
||||
let res = `${year}-${month}-${day}`; // 格式化日期 |
|
||||
this.today = res; |
|
||||
this.filteredData.schedule_date = res; |
|
||||
}, |
|
||||
|
|
||||
//选择日期 |
|
||||
async selectDate(date) { |
|
||||
this.loadData() |
|
||||
this.filteredData.schedule_date = date |
|
||||
this.getList() |
|
||||
}, |
|
||||
|
|
||||
//加载更过(下一页) |
|
||||
loadMoreData() { |
|
||||
//判断是否加载 |
|
||||
if (!this.isReachedBottom) { |
|
||||
this.isReachedBottom = true; //设置为不可请求状态 |
|
||||
this.getList(); |
|
||||
} |
|
||||
}, |
|
||||
//重置为第一页 |
|
||||
async loadData() { |
|
||||
this.isReachedBottom = false; // 重置状态,以便下次触发加载更多 |
|
||||
this.filteredData.page = 1 //当前页码 |
|
||||
this.filteredData.limit = 10 //每页返回数据条数 |
|
||||
this.filteredData.total = 10 //数据总条数 |
|
||||
this.filteredData.schedule_date = '' |
|
||||
}, |
|
||||
//获取列表 |
|
||||
async getList() { |
|
||||
this.loading = true |
|
||||
|
|
||||
let data = { |
|
||||
...this.filteredData |
|
||||
} |
|
||||
|
|
||||
//判断是否还有数据 |
|
||||
if (this.filteredData.page * this.filteredData.limit > this.filteredData.total || this.filteredData.limit > this.filteredData.total) { |
|
||||
this.loading = false |
|
||||
uni.showToast({ |
|
||||
title: '暂无更多', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
let res = await apiRoute.courseList(data) |
|
||||
this.loading = false |
|
||||
this.isReachedBottom = false; |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.tableList = res.data.data |
|
||||
//场地信息 |
|
||||
this.venuesInfo = res.data.venues_info |
|
||||
|
|
||||
this.filteredData.total = res.data.total |
|
||||
|
|
||||
this.filteredData.page++ |
|
||||
}, |
|
||||
|
|
||||
//日历选择相关 |
|
||||
// 获取日期范围 |
|
||||
getDateRange() { |
|
||||
const today = new Date(); // 获取今天的日期 |
|
||||
const startDate = new Date(today); // 复制今天的日期 |
|
||||
const endDate = new Date(today); // 复制今天的日期 |
|
||||
|
|
||||
// 计算 startDate:往前推 1 个月 |
|
||||
startDate.setMonth(today.getMonth() - 1); |
|
||||
|
|
||||
// 计算 endDate:往后推 1 个月 |
|
||||
endDate.setMonth(today.getMonth() + 2); |
|
||||
|
|
||||
// 将日期格式化为 YYYY-MM-DD |
|
||||
const formatDate = (date) => { |
|
||||
const year = date.getFullYear(); |
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0'); |
|
||||
const day = String(date.getDate()).padStart(2, '0'); |
|
||||
return `${year}-${month}-${day}`; |
|
||||
}; |
|
||||
|
|
||||
// 更新 data 中的 startDate 和 endDate |
|
||||
this.startDate = formatDate(startDate); |
|
||||
this.endDate = formatDate(endDate); |
|
||||
console.log([this.startDate, this.endDate]) |
|
||||
}, |
|
||||
//设置日期打点 |
|
||||
async setCalendarSelected() { |
|
||||
//获取当前月份 |
|
||||
let month = new Date().getMonth() + 1; |
|
||||
|
|
||||
let res = await commonApi.getMonthDate({ |
|
||||
month: month |
|
||||
}) |
|
||||
if (res.code != 1) { |
|
||||
//提示 |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none', |
|
||||
duration: 2000 |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
this.calendarSelected = [] |
|
||||
res.data.forEach((v, k) => { |
|
||||
this.calendarSelected.push({ |
|
||||
date: v.date, |
|
||||
}) |
|
||||
}) |
|
||||
|
|
||||
// this.calendarSelected = [ |
|
||||
// { |
|
||||
// date: '2025-04-07', |
|
||||
// }, |
|
||||
// { |
|
||||
// date: '2025-04-08', |
|
||||
// }, |
|
||||
// { |
|
||||
// date: '2025-04-09', |
|
||||
// } |
|
||||
// ] |
|
||||
}, |
|
||||
//日历选择 |
|
||||
changeCalendar(e) { |
|
||||
console.log('日历', e) |
|
||||
this.show_calendar = false |
|
||||
this.loadData() |
|
||||
this.filteredData.schedule_date = e.fulldate |
|
||||
this.getList() |
|
||||
}, |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box { |
|
||||
background: #292929; |
|
||||
} |
|
||||
|
|
||||
//自定义导航栏 |
|
||||
.navbar_section { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
background: #292929; |
|
||||
|
|
||||
.title { |
|
||||
padding: 40rpx 0rpx; |
|
||||
|
|
||||
/* 小程序端样式 */ |
|
||||
// #ifdef MP-WEIXIN |
|
||||
padding: 80rpx 0rpx; |
|
||||
// #endif |
|
||||
|
|
||||
font-size: 30rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.main_section { |
|
||||
min-height: 100vh; |
|
||||
background: #292929 100%; |
|
||||
padding-top: 40rpx; |
|
||||
padding-bottom: 150rpx; |
|
||||
font-size: 24rpx; |
|
||||
color: #FFFFFF; |
|
||||
|
|
||||
.section_1 { |
|
||||
background: #333333 100%; |
|
||||
width: 100%; |
|
||||
padding: 30rpx 28rpx; |
|
||||
padding-bottom: 15rpx; |
|
||||
|
|
||||
.ul { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
|
|
||||
.li { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
gap: 10rpx; |
|
||||
|
|
||||
text { |
|
||||
font-size: 24rpx; |
|
||||
color: #FFFFFF; |
|
||||
text-align: center; |
|
||||
} |
|
||||
|
|
||||
text:nth-child(2) { |
|
||||
width: 44rpx; |
|
||||
height: 44rpx; |
|
||||
} |
|
||||
|
|
||||
text:nth-child(3) { |
|
||||
width: 8rpx; |
|
||||
height: 8rpx; |
|
||||
} |
|
||||
|
|
||||
.today { |
|
||||
border-radius: 50%; |
|
||||
background: #29D3B4; |
|
||||
text-align: center; |
|
||||
line-height: 42rpx; |
|
||||
} |
|
||||
|
|
||||
.select_plan { |
|
||||
background: #F59A23; |
|
||||
border-radius: 50%; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.btn { |
|
||||
margin-top: 20rpx; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
color: #A4ADB3; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.section_2 { |
|
||||
margin-top: 30rpx; |
|
||||
padding: 0 20rpx; |
|
||||
color: #fff; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 20rpx; |
|
||||
|
|
||||
.item_box { |
|
||||
width: 45%; |
|
||||
|
|
||||
.fui-filter__item { |
|
||||
display: flex; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.section_3 { |
|
||||
margin-top: 36rpx; |
|
||||
color: #fff; |
|
||||
font-size: 24rpx; |
|
||||
|
|
||||
.ul { |
|
||||
padding: 0 26rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 30rpx; |
|
||||
|
|
||||
.li { |
|
||||
position: relative; |
|
||||
border-radius: 22rpx; |
|
||||
background: #434544 100%; |
|
||||
padding: 14rpx 0; |
|
||||
padding-bottom: 30rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
|
|
||||
.top_box { |
|
||||
padding: 20rpx 30rpx; |
|
||||
|
|
||||
.center_box { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 10rpx; |
|
||||
|
|
||||
view {} |
|
||||
} |
|
||||
|
|
||||
.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; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.bottom_box { |
|
||||
border-top: 1px dashed #F2F2F2; |
|
||||
padding: 26rpx 16rpx 0 26rpx; |
|
||||
|
|
||||
.hint { |
|
||||
color: #D7D7D7; |
|
||||
} |
|
||||
|
|
||||
.list_box { |
|
||||
margin-top: 22rpx; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
|
|
||||
.list { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 14rpx; |
|
||||
|
|
||||
.itme { |
|
||||
image { |
|
||||
width: 48rpx; |
|
||||
height: 48rpx; |
|
||||
border-radius: 50%; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.btn { |
|
||||
border: 1px solid #FAD04D; |
|
||||
border-radius: 10rpx; |
|
||||
background: #434544; |
|
||||
color: #FAD04D; |
|
||||
width: 110rpx; |
|
||||
height: 60rpx; |
|
||||
line-height: 55rpx; |
|
||||
text-align: center; |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
.isbtn { |
|
||||
border: 1px solid #FAD04D; |
|
||||
border-radius: 10rpx; |
|
||||
background: #434544; |
|
||||
color: #FAD04D; |
|
||||
width: 110rpx; |
|
||||
height: 60rpx; |
|
||||
line-height: 55rpx; |
|
||||
text-align: center; |
|
||||
font-size: 24rpx; |
|
||||
position: absolute; |
|
||||
bottom: 20rpx; |
|
||||
right: 15rpx; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,407 +0,0 @@ |
|||||
<!--发布作业--> |
|
||||
<template> |
|
||||
<view class="main_section"> |
|
||||
<fui-form class="formData" ref="form"> |
|
||||
<view class="radio_input"> |
|
||||
<fui-form-item label="发布类型" asterisk> |
|
||||
<fui-radio-group name="radio" v-model="formData.type" @change="changeType"> |
|
||||
<view class="fui-list__item"> |
|
||||
<fui-label> |
|
||||
<view class="fui-align__center"> |
|
||||
<fui-radio value="1" checked></fui-radio> |
|
||||
<text class="fui-text">班级作业</text> |
|
||||
</view> |
|
||||
</fui-label> |
|
||||
<fui-label :margin="['0','0','0','40rpx']"> |
|
||||
<view class="fui-align__center"> |
|
||||
<fui-radio value="2"></fui-radio> |
|
||||
<text class="fui-text">学员作业</text> |
|
||||
</view> |
|
||||
</fui-label> |
|
||||
</view> |
|
||||
</fui-radio-group> |
|
||||
</fui-form-item> |
|
||||
|
|
||||
</view> |
|
||||
|
|
||||
<view class="radio_input"> |
|
||||
<fui-form-item label="作业类型" asterisk> |
|
||||
<fui-radio-group name="radio" v-model="formData.content_type" @change="changeContentType"> |
|
||||
<view class="fui-list__item"> |
|
||||
<fui-label> |
|
||||
<view class="fui-align__center"> |
|
||||
<fui-radio value="1" checked></fui-radio> |
|
||||
<text class="fui-text">图片作业</text> |
|
||||
</view> |
|
||||
</fui-label> |
|
||||
<fui-label :margin="['0','0','0','40rpx']"> |
|
||||
<view class="fui-align__center"> |
|
||||
<fui-radio value="2"></fui-radio> |
|
||||
<text class="fui-text">视频作业</text> |
|
||||
</view> |
|
||||
</fui-label> |
|
||||
</view> |
|
||||
</fui-radio-group> |
|
||||
</fui-form-item> |
|
||||
|
|
||||
</view> |
|
||||
|
|
||||
<view v-if="formData.type == 1"> |
|
||||
<fui-input required label="班级" borderTop placeholder="请选择班级" v-model="formData.classes_id_name" |
|
||||
@click="show_class=true"></fui-input> |
|
||||
<fui-picker layer="1" :linkage="true" :options="options_class_arr" :show="show_class" @change="changeClass" |
|
||||
@cancel="show_class=false"></fui-picker> |
|
||||
</view> |
|
||||
|
|
||||
<view v-if="formData.type != 1"> |
|
||||
<fui-input required label="学员" borderTop placeholder="请选择学员" v-model="formData.students_ids_name" |
|
||||
@click="show_student=true"></fui-input> |
|
||||
<!--下拉多选--> |
|
||||
<fui-select |
|
||||
:show="show_student" |
|
||||
:options="options_student_arr" |
|
||||
title="请选择学员" |
|
||||
multiple |
|
||||
isReverse |
|
||||
checkboxColor="#FFC529" |
|
||||
btnBackground="#FFC529" |
|
||||
btnColor="#1A1D26" |
|
||||
closeColor="#6D758A" |
|
||||
@confirm="changeStudent" |
|
||||
@close="show_student=false"> |
|
||||
</fui-select> |
|
||||
|
|
||||
</view> |
|
||||
|
|
||||
<view> |
|
||||
<fui-input required label="课程" borderTop placeholder="请选择课程" v-model="formData.course_id_name" |
|
||||
@click="show_course=true"></fui-input> |
|
||||
<fui-picker |
|
||||
layer="1" |
|
||||
:linkage="true" |
|
||||
:options="options_course_arr" :show="show_course" @change="changeCourse" |
|
||||
@cancel="show_course=false"></fui-picker> |
|
||||
</view> |
|
||||
|
|
||||
<view> |
|
||||
<fui-textarea required flexStart label="作业" placeholder="请输入内容" v-model="formData.description"></fui-textarea> |
|
||||
</view> |
|
||||
|
|
||||
<view class="submet_btn" @click="submetForm">提交</view> |
|
||||
|
|
||||
</fui-form> |
|
||||
|
|
||||
<!--吸顶消息提示--> |
|
||||
<fui-message ref="msg" :background="`#ff2b2b`"></fui-message> |
|
||||
<!-- 底部导航--> |
|
||||
<AQTabber/> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import memberApi from '@/api/member.js'; |
|
||||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
//校验规则 |
|
||||
const rules = [ |
|
||||
// { |
|
||||
// name: "classes_id_name", |
|
||||
// rule: ["required"], |
|
||||
// msg: ["请选择班级"] |
|
||||
// }, |
|
||||
{ |
|
||||
name: "course_id_name", |
|
||||
rule: ["required"], |
|
||||
msg: ["请选择课程"] |
|
||||
}, |
|
||||
{ |
|
||||
name: "description", |
|
||||
rule: ["required"], |
|
||||
msg: ["请输入作业内容"] |
|
||||
}, |
|
||||
]; |
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
show_class:false, |
|
||||
show_course:false, |
|
||||
show_student:false, |
|
||||
|
|
||||
|
|
||||
//班级可选值列表 |
|
||||
options_class_arr:[ |
|
||||
// { value: 1, text: '班级1' }, |
|
||||
], |
|
||||
//课程可选值列表 |
|
||||
options_course_arr:[ |
|
||||
// { value: 1, text: '课程1' }, |
|
||||
], |
|
||||
//学员可选值列表 |
|
||||
options_student_arr:[ |
|
||||
// { |
|
||||
// text: '标签3', |
|
||||
// value: '3', |
|
||||
// checked: false,//是否选中 |
|
||||
// } |
|
||||
], |
|
||||
|
|
||||
|
|
||||
//表单数据 |
|
||||
formData: { |
|
||||
type: '1',//作业类型(单选)|1班级,2学员 |
|
||||
course_id: '',//课程id(下拉) |
|
||||
course_id_name: '',//课程id(中文名字) |
|
||||
|
|
||||
content_type: '1',//作业类型(单选)|1图片,2视频 |
|
||||
description: '',//文字作业内容 |
|
||||
|
|
||||
class_id: '',//班级id(下拉) |
|
||||
classes_id_name: '',//班级id(中文名字) |
|
||||
|
|
||||
student_id: '',//学员id 逗号拼接 |
|
||||
students_ids_name:'',//学员id数组(中文名字) |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
onLoad() { |
|
||||
|
|
||||
}, |
|
||||
onShow() { |
|
||||
this.init() |
|
||||
}, |
|
||||
methods: { |
|
||||
//初始化 |
|
||||
async init() { |
|
||||
// 获取班级-学员二级联动(用来获取班级列表) |
|
||||
this.getClassesList() |
|
||||
// 全部课程名称列表 |
|
||||
this.getCoursesList() |
|
||||
// 学员列表 |
|
||||
this.getStudentList() |
|
||||
}, |
|
||||
|
|
||||
//获取班级列表 |
|
||||
async getClassesList(){ |
|
||||
let res = await apiRoute.jlGetClassesList({}) |
|
||||
if(res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
this.options_class_arr = [] |
|
||||
res.data.forEach((v,k)=>{ |
|
||||
this.options_class_arr.push({ |
|
||||
text: v.class_name, |
|
||||
value: v.id, |
|
||||
}) |
|
||||
}) |
|
||||
}, |
|
||||
//获取课程列表 |
|
||||
async getCoursesList(){ |
|
||||
let res = await apiRoute.jlGetCoursesList({}) |
|
||||
if(res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.options_course_arr = [] |
|
||||
res.data.forEach((v,k)=>{ |
|
||||
this.options_course_arr.push({ |
|
||||
text: v.course_name, |
|
||||
value: v.id, |
|
||||
}) |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//获取学员列表 |
|
||||
async getStudentList() { |
|
||||
let res = await apiRoute.jlGetStudentList({}) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.options_student_arr = [] |
|
||||
res.data.forEach((v, k) => { |
|
||||
this.options_student_arr.push({ |
|
||||
text: v.name, |
|
||||
value: v.id, |
|
||||
checked: false,//是否选中 |
|
||||
}) |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
//监听选择器-班级 |
|
||||
changeClass(e) { |
|
||||
console.log('选择器-班级', e); |
|
||||
this.formData.class_id = e.value; // 更新 class_id |
|
||||
this.formData.classes_id_name = e.text; // 更新 class_name |
|
||||
this.show_class = false; // 关闭选择器 |
|
||||
}, |
|
||||
//监听选择器-课程 |
|
||||
changeCourse(e) { |
|
||||
console.log('选择器-课程', e); |
|
||||
this.formData.course_id = e.value; // 更新 course_id |
|
||||
this.formData.course_id_name = e.text; // 更新 course_name |
|
||||
this.show_course = false; // 关闭选择器 |
|
||||
}, |
|
||||
//监听选择器-学员 |
|
||||
changeStudent(e) { |
|
||||
console.log('选择器-学员', e); |
|
||||
let id_arr = [] |
|
||||
let name_arr = [] |
|
||||
e.options.forEach((v,k)=>{ |
|
||||
id_arr.push(v.value) |
|
||||
name_arr.push(v.text) |
|
||||
}) |
|
||||
//数组转字符 |
|
||||
this.formData.student_id = id_arr.join(',') |
|
||||
this.formData.students_ids_name = name_arr.join(',') |
|
||||
this.show_student = false; // 关闭选择器 |
|
||||
}, |
|
||||
|
|
||||
//监听选择器-发布类型 |
|
||||
changeType(e) { |
|
||||
console.log('选择器-作业类型', e); |
|
||||
this.formData.type = e.detail.value; // 更新 type |
|
||||
|
|
||||
//1=班级作业 |
|
||||
if(e.detail.value == 1){ |
|
||||
//清空学员选择信息 |
|
||||
this.formData.student_id = '' |
|
||||
this.formData.students_ids_name = '' |
|
||||
}else{ |
|
||||
// 2=学生作业 |
|
||||
this.formData.class_id = '' |
|
||||
this.formData.classes_id_name = '' |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
//监听选择器-作业类型 |
|
||||
changeContentType(e) { |
|
||||
console.log('选择器-作业类型', e); |
|
||||
this.formData.content_type = e.detail.value; // 更新 type |
|
||||
}, |
|
||||
|
|
||||
//表单验证 |
|
||||
async validatorForm(data) { |
|
||||
let res = await this.$refs.form.validator(data, rules) |
|
||||
return res |
|
||||
}, |
|
||||
|
|
||||
//吸顶消息意识 |
|
||||
showMsg(msg) { |
|
||||
let options = {} |
|
||||
//text值可不传 |
|
||||
options.text = msg |
|
||||
this.$refs.tips.show(options) |
|
||||
}, |
|
||||
|
|
||||
//发布作业 |
|
||||
async submetForm(){ |
|
||||
let data = {...this.formData} |
|
||||
console.log('提交',data) |
|
||||
let vf = await this.validatorForm(data)//表单验证 |
|
||||
|
|
||||
|
|
||||
if(data.type == 1){ |
|
||||
//班级作业 |
|
||||
if(!data.class_id){ |
|
||||
this.showMsg('请选择班级') |
|
||||
return |
|
||||
} |
|
||||
}else{ |
|
||||
//学生作业 |
|
||||
if(!data.student_id){ |
|
||||
this.showMsg('请选择学员') |
|
||||
return |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
if(!vf.isPassed){ |
|
||||
console.log('验证',vf) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
//发布作业 |
|
||||
let res = await apiRoute.jlPublishJob(data) |
|
||||
if (res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'success' |
|
||||
}) |
|
||||
//延迟1s |
|
||||
setTimeout(() => { |
|
||||
//关闭当前页跳转新页面 |
|
||||
uni.redirectTo({ |
|
||||
url: '/pages/coach/home/index' |
|
||||
}) |
|
||||
}, 1000) |
|
||||
}, |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
|
|
||||
.main_section{ |
|
||||
min-height: 100vh; |
|
||||
background: #292929 100%; |
|
||||
padding: 0 24rpx; |
|
||||
padding-top: 40rpx; |
|
||||
padding-bottom: 150rpx; |
|
||||
font-size: 28rpx; |
|
||||
.formData{ |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 40rpx; |
|
||||
.radio_input{ |
|
||||
.fui-form__item-wrap{ |
|
||||
border-radius: 8rpx !important; |
|
||||
} |
|
||||
.fui-list__item{ |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
} |
|
||||
} |
|
||||
.submet_btn{ |
|
||||
margin: 0 auto; |
|
||||
margin-top: 40rpx; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
background-color: #29d3b4; |
|
||||
border-radius: 8rpx; |
|
||||
|
|
||||
width: 648rpx; |
|
||||
height: 88rpx; |
|
||||
color: rgba(255,255,255,1); |
|
||||
font-size: 32rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
} |
|
||||
|
|
||||
|
|
||||
</style> |
|
||||
@ -1,836 +0,0 @@ |
|||||
<!--作业列表--> |
|
||||
<template> |
|
||||
<view class="main_section"> |
|
||||
|
|
||||
<scroll-view class="section_3" scroll-y="true" :lower-threshold="lowerThreshold" @scrolltolower="loadMoreData" |
|
||||
style="height: 80vh;"> |
|
||||
<view class="ul"> |
|
||||
<view class="li" v-for="(v,k) in tableList" :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.create_time}}</view> |
|
||||
<view>课程:{{v.course_name}} |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="right_box"> |
|
||||
<view class="tag" v-if="v.status == 1" style="background:#1cd188;">未提交</view> |
|
||||
<view class="tag" v-if="v.status == 2" style="background:#1cd188;">已提交</view> |
|
||||
<view class="tag" v-if="v.status == 3" style="background:#1cd188;">待批改</view> |
|
||||
<view class="tag" v-if="v.status == 4" style="background:#1cd188;">已批改</view> |
|
||||
|
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</scroll-view> |
|
||||
|
|
||||
<!-- 底部发布作业按钮 --> |
|
||||
<view class="publish-btn" @click="openPublishPopup"> |
|
||||
<text class="btn-text">发布作业</text> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 底部导航--> |
|
||||
<AQTabber /> |
|
||||
|
|
||||
<!-- 发布作业弹窗 --> |
|
||||
<uni-popup ref="publishPopup" type="center"> |
|
||||
<view class="popup-content"> |
|
||||
<view class="popup-title">发布作业</view> |
|
||||
<!-- |
|
||||
<view class="form-item"> |
|
||||
<text class="form-label">类型</text> |
|
||||
<input class="form-input" type="number" v-model="formData.type" placeholder="请输入类型" /> |
|
||||
</view> |
|
||||
--> |
|
||||
<view class="form-item"> |
|
||||
<text class="form-label">班级</text> |
|
||||
<!-- <input class="form-input" type="number" v-model="formData.class_id" placeholder="请输入班级ID" /> --> |
|
||||
|
|
||||
<picker mode="selector" :range="class_id_options" range-key="name" @change="handleClassChange" |
|
||||
class="form-picker"> |
|
||||
<view v-if="selectedClassName" class="picker-text">{{ selectedClassName }}</view> |
|
||||
<view v-else class="picker-placeholder">请选择班级</view> |
|
||||
</picker> |
|
||||
</view> |
|
||||
|
|
||||
|
|
||||
<view class="form-item"> |
|
||||
<text class="form-label">课程</text> |
|
||||
<!-- <input class="form-input" type="number" v-model="formData.course_id" placeholder="请输入课程" /> --> |
|
||||
|
|
||||
<picker mode="selector" :range="course_list" range-key="name" @change="handleCourseChange" |
|
||||
class="form-picker"> |
|
||||
<view v-if="selectedCourseName" class="picker-text">{{ selectedCourseName }}</view> |
|
||||
<view v-else class="picker-placeholder">请选择课程</view> |
|
||||
</picker> |
|
||||
|
|
||||
</view> |
|
||||
|
|
||||
<view class="form-item"> |
|
||||
<text class="form-label">学生</text> |
|
||||
<!-- <input class="form-input" type="number" v-model="formData.student_id" placeholder="请输入学生ID" /> --> |
|
||||
<picker mode="selector" :range="student_list" range-key="name" @change="handleStudentChange" |
|
||||
class="form-picker"> |
|
||||
<view v-if="selectedStudentName" class="picker-text">{{ selectedStudentName }}</view> |
|
||||
<view v-else class="picker-placeholder">请选择学生</view> |
|
||||
</picker> |
|
||||
</view> |
|
||||
|
|
||||
<view class="form-item"> |
|
||||
<text class="form-label">作业描述</text> |
|
||||
<textarea class="form-textarea" v-model="formData.description" placeholder="请输入作业描述" /> |
|
||||
</view> |
|
||||
|
|
||||
<!-- <view class="form-item"> |
|
||||
<text class="form-label">内容类型</text> |
|
||||
<picker class="form-picker" :value="contentTypeIndex" :range="contentTypes" |
|
||||
@change="contentTypeChange"> |
|
||||
<view class="picker-text">{{contentTypes[contentTypeIndex]}}</view> |
|
||||
</picker> |
|
||||
</view> --> |
|
||||
|
|
||||
<!-- 根据内容类型显示不同的上传控件 --> |
|
||||
<!-- 图片类型 --> |
|
||||
<!-- <view class="form-item" v-if="formData.content_type === '1'"> |
|
||||
<text class="form-label">上传图片</text> |
|
||||
<view class="upload-container"> |
|
||||
<view class="image-preview" v-if="uploadedFiles.image"> |
|
||||
<image class="preview-image" :src="uploadedFiles.image" mode="aspectFill"></image> |
|
||||
<view class="delete-btn" @click="deleteFile('image')"> |
|
||||
<text class="delete-icon">×</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="upload-btn" v-if="!uploadedFiles.image" @click="chooseFile('image')"> |
|
||||
<text class="upload-icon">+</text> |
|
||||
<text class="upload-text">上传图片</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> --> |
|
||||
|
|
||||
<!-- 视频类型 --> |
|
||||
<!-- <view class="form-item" v-if="formData.content_type === '2'"> |
|
||||
<text class="form-label">上传视频</text> |
|
||||
<view class="upload-container"> |
|
||||
<view class="video-preview" v-if="uploadedFiles.video"> |
|
||||
<video class="preview-video" :src="uploadedFiles.video" controls></video> |
|
||||
<view class="delete-btn" @click="deleteFile('video')"> |
|
||||
<text class="delete-icon">×</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="upload-btn" v-if="!uploadedFiles.video" @click="chooseFile('video')"> |
|
||||
<text class="upload-icon">+</text> |
|
||||
<text class="upload-text">上传视频</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> --> |
|
||||
|
|
||||
<!-- 文本类型 --> |
|
||||
<!-- <view class="form-item" v-if="formData.content_type === '3'"> |
|
||||
<text class="form-label">内容文本</text> |
|
||||
<textarea class="form-textarea" v-model="formData.content_text" placeholder="请输入内容文本" /> |
|
||||
</view> --> |
|
||||
|
|
||||
<view class="form-buttons"> |
|
||||
<button class="btn-cancel" @click="closePublishPopup">取消</button> |
|
||||
<button class="btn-submit" @click="submitForm">提交</button> |
|
||||
</view> |
|
||||
</view> |
|
||||
</uni-popup> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import memberApi from '@/api/member.js'; |
|
||||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
loading: false, //加载状态 |
|
||||
lowerThreshold: 100, //距离底部多远触发 |
|
||||
isReachedBottom: false, //防止重复加载|true=不可加载|false=可加载 |
|
||||
|
|
||||
//筛选条件 |
|
||||
filteredData: { |
|
||||
page: 1, //当前页码 |
|
||||
limit: 10, //每页返回数据条数 |
|
||||
total: 10, //数据总条数 |
|
||||
}, |
|
||||
tableList: [], //数据列表 |
|
||||
|
|
||||
// 发布作业表单数据 |
|
||||
formData: { |
|
||||
class_id: '', |
|
||||
course_id: '', |
|
||||
student_id: '', |
|
||||
description: '', |
|
||||
}, |
|
||||
class_id_options: [ |
|
||||
|
|
||||
], |
|
||||
selectedClassName:'', |
|
||||
course_list:[], |
|
||||
selectedCourseName:'', |
|
||||
student_list:[], |
|
||||
selectedStudentName:'', |
|
||||
// 内容类型选择器 |
|
||||
contentTypes: ['图片', '视频', '文本'], |
|
||||
contentTypeIndex: 0, |
|
||||
|
|
||||
// 上传的文件 |
|
||||
uploadedFiles: { |
|
||||
image: '', |
|
||||
video: '' |
|
||||
}, |
|
||||
|
|
||||
// 模拟数据 |
|
||||
mockData: [] |
|
||||
} |
|
||||
}, |
|
||||
onLoad() { |
|
||||
|
|
||||
}, |
|
||||
onShow() { |
|
||||
this.init() |
|
||||
// this.getData() |
|
||||
}, |
|
||||
methods: { |
|
||||
handleClassChange(e) { |
|
||||
const index = e.detail.value; |
|
||||
const selectedClass = this.class_id_options[index]; |
|
||||
this.formData.class_id = selectedClass.id; |
|
||||
this.selectedClassName = selectedClass.name; |
|
||||
}, |
|
||||
|
|
||||
handleCourseChange(e) { |
|
||||
const index = e.detail.value; |
|
||||
const selectedCourse = this.course_list[index]; |
|
||||
this.formData.course_id = selectedCourse.id; |
|
||||
this.selectedCourseName = selectedCourse.name; |
|
||||
}, |
|
||||
handleStudentChange(e) { |
|
||||
const index = e.detail.value; |
|
||||
const selectedStudent = this.student_list[index]; |
|
||||
this.formData.student_id = selectedStudent.id; |
|
||||
this.selectedStudentName = selectedStudent.name; |
|
||||
}, |
|
||||
async getClassList() { |
|
||||
let params = { |
|
||||
status: 1, //班级状态(1开启 2关闭) |
|
||||
} |
|
||||
|
|
||||
let res = await apiRoute.common_getClassAll(params) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
console.log('班级列表', res.data) |
|
||||
let arr = [] |
|
||||
res.data.forEach((v, k) => { |
|
||||
arr.push({ |
|
||||
name: `${v.campus_name}-${v.class_name}`, |
|
||||
id: v.id, |
|
||||
}) |
|
||||
}) |
|
||||
this.class_id_options = arr |
|
||||
this.getCourseList() |
|
||||
}, |
|
||||
async getCourseList() { |
|
||||
|
|
||||
let res = await apiRoute.common_getCourseAll({}) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
let arr = [] |
|
||||
res.data.forEach((v, k) => { |
|
||||
arr.push({ |
|
||||
name: `${v.course_name}`, |
|
||||
id: v.id, |
|
||||
}) |
|
||||
}) |
|
||||
this.course_list = arr |
|
||||
this.getStudentList() |
|
||||
}, |
|
||||
async getStudentList() { |
|
||||
|
|
||||
let res = await apiRoute.jlGetStudentList({}) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
let arr = [] |
|
||||
res.data.forEach((v, k) => { |
|
||||
arr.push({ |
|
||||
name: `${v.name}`, |
|
||||
id: v.id, |
|
||||
}) |
|
||||
}) |
|
||||
this.student_list = arr |
|
||||
}, |
|
||||
|
|
||||
async init() { |
|
||||
this.getList() |
|
||||
}, |
|
||||
async getData() { |
|
||||
this.getClassList() |
|
||||
}, |
|
||||
|
|
||||
//加载更多(下一页) |
|
||||
loadMoreData() { |
|
||||
//判断是否加载 |
|
||||
if (!this.isReachedBottom) { |
|
||||
this.isReachedBottom = true; //设置为不可请求状态 |
|
||||
this.getList(); |
|
||||
} |
|
||||
}, |
|
||||
//重置为第一页 |
|
||||
async resetFilteredData() { |
|
||||
this.isReachedBottom = false; // 重置状态,以便下次触发加载更多 |
|
||||
|
|
||||
this.filteredData.page = 1 //当前页码 |
|
||||
this.filteredData.limit = 10 //每页返回数据条数 |
|
||||
this.filteredData.total = 10 //数据总条数 |
|
||||
}, |
|
||||
//获取列表 |
|
||||
async getList() { |
|
||||
this.loading = true |
|
||||
|
|
||||
let data = { |
|
||||
...this.filteredData |
|
||||
} |
|
||||
|
|
||||
//判断是否还有数据 |
|
||||
if ((this.filteredData.page - 1) * this.filteredData.limit >= this.filteredData.total) { |
|
||||
this.loading = false |
|
||||
uni.showToast({ |
|
||||
title: '暂无更多', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
if (data.page == 1) { |
|
||||
this.tableList = [] |
|
||||
} |
|
||||
|
|
||||
let res = await memberApi.jsGetAssignmentsList(data) |
|
||||
this.loading = false |
|
||||
this.isReachedBottom = false; |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.tableList = this.tableList.concat(res.data.data); // 使用 concat 方法 将新数据追加到数组中 |
|
||||
|
|
||||
console.log('列表', this.tableList) |
|
||||
this.filteredData.total = res.data.total |
|
||||
this.filteredData.page++ |
|
||||
|
|
||||
this.getData() |
|
||||
}, |
|
||||
|
|
||||
//跳转页面-作业详情 |
|
||||
openViewWorkDetails(item) { |
|
||||
let id = item.id |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/coach/student/work_details?id=${id}` |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
// 打开发布作业弹窗 |
|
||||
openPublishPopup() { |
|
||||
this.$refs.publishPopup.open() |
|
||||
}, |
|
||||
|
|
||||
// 关闭发布作业弹窗 |
|
||||
closePublishPopup() { |
|
||||
this.$refs.publishPopup.close() |
|
||||
}, |
|
||||
|
|
||||
// 内容类型选择器变化 |
|
||||
contentTypeChange(e) { |
|
||||
this.contentTypeIndex = e.detail.value |
|
||||
this.formData.content_type = String(parseInt(e.detail.value) + 1) |
|
||||
}, |
|
||||
|
|
||||
// 选择文件(图片或视频) |
|
||||
chooseFile(type) { |
|
||||
if (type === 'image') { |
|
||||
// 选择图片 |
|
||||
uni.chooseImage({ |
|
||||
count: 1, |
|
||||
sizeType: ['compressed'], |
|
||||
sourceType: ['album', 'camera'], |
|
||||
success: (res) => { |
|
||||
// 模拟上传 |
|
||||
uni.showLoading({ |
|
||||
title: '上传中...' |
|
||||
}) |
|
||||
|
|
||||
setTimeout(() => { |
|
||||
uni.hideLoading() |
|
||||
this.uploadedFiles.image = res.tempFilePaths[0] |
|
||||
|
|
||||
// 模拟上传成功 |
|
||||
uni.showToast({ |
|
||||
title: '图片上传成功', |
|
||||
icon: 'success' |
|
||||
}) |
|
||||
|
|
||||
// 设置内容文本为图片路径 |
|
||||
this.formData.content_text = res.tempFilePaths[0] |
|
||||
}, 1000) |
|
||||
} |
|
||||
}) |
|
||||
} else if (type === 'video') { |
|
||||
// 选择视频 |
|
||||
uni.chooseVideo({ |
|
||||
count: 1, |
|
||||
sourceType: ['album', 'camera'], |
|
||||
maxDuration: 60, |
|
||||
camera: 'back', |
|
||||
success: (res) => { |
|
||||
// 模拟上传 |
|
||||
uni.showLoading({ |
|
||||
title: '上传中...' |
|
||||
}) |
|
||||
|
|
||||
setTimeout(() => { |
|
||||
uni.hideLoading() |
|
||||
this.uploadedFiles.video = res.tempFilePath |
|
||||
|
|
||||
// 模拟上传成功 |
|
||||
uni.showToast({ |
|
||||
title: '视频上传成功', |
|
||||
icon: 'success' |
|
||||
}) |
|
||||
|
|
||||
// 设置内容文本为视频路径 |
|
||||
this.formData.content_text = res.tempFilePath |
|
||||
}, 1500) |
|
||||
} |
|
||||
}) |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 删除已上传的文件 |
|
||||
deleteFile(type) { |
|
||||
if (type === 'image') { |
|
||||
this.uploadedFiles.image = '' |
|
||||
this.formData.content_text = '' |
|
||||
} else if (type === 'video') { |
|
||||
this.uploadedFiles.video = '' |
|
||||
this.formData.content_text = '' |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 预览文件 |
|
||||
previewFile(type) { |
|
||||
if (type === 'image' && this.uploadedFiles.image) { |
|
||||
uni.previewImage({ |
|
||||
urls: [this.uploadedFiles.image] |
|
||||
}) |
|
||||
} |
|
||||
// 视频不需要额外预览,因为已经有视频播放器 |
|
||||
}, |
|
||||
|
|
||||
// 提交表单 |
|
||||
async submitForm() { |
|
||||
// 检查必填项 |
|
||||
if (!this.formData.class_id) { |
|
||||
uni.showToast({ |
|
||||
title: '请输入班级ID', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
if (!this.formData.course_id) { |
|
||||
uni.showToast({ |
|
||||
title: '请输入课程ID', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
if (!this.formData.description) { |
|
||||
uni.showToast({ |
|
||||
title: '请输入作业描述', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
// 检查内容 |
|
||||
// if (this.formData.content_type === '1' && !this.uploadedFiles.image) { |
|
||||
// uni.showToast({ |
|
||||
// title: '请上传图片', |
|
||||
// icon: 'none' |
|
||||
// }) |
|
||||
// return |
|
||||
// } |
|
||||
|
|
||||
// if (this.formData.content_type === '2' && !this.uploadedFiles.video) { |
|
||||
// uni.showToast({ |
|
||||
// title: '请上传视频', |
|
||||
// icon: 'none' |
|
||||
// }) |
|
||||
// return |
|
||||
// } |
|
||||
|
|
||||
// if (this.formData.content_type === '3' && !this.formData.content_text) { |
|
||||
// uni.showToast({ |
|
||||
// title: '请输入内容文本', |
|
||||
// icon: 'none' |
|
||||
// }) |
|
||||
// return |
|
||||
// } |
|
||||
|
|
||||
|
|
||||
|
|
||||
let res = await apiRoute.jlPublishJob(this.formData) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
|
|
||||
uni.showToast({ |
|
||||
title: '发布成功', |
|
||||
icon: 'success' |
|
||||
}) |
|
||||
|
|
||||
// 关闭弹窗 |
|
||||
this.closePublishPopup() |
|
||||
|
|
||||
// 重置表单 |
|
||||
this.formData = { |
|
||||
class_id: '', |
|
||||
course_id: '', |
|
||||
student_id: '', |
|
||||
description: '', |
|
||||
} |
|
||||
|
|
||||
this.init() |
|
||||
// this.contentTypeIndex = 0 |
|
||||
// this.uploadedFiles = { |
|
||||
// image: '', |
|
||||
// video: '' |
|
||||
// } |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_section { |
|
||||
min-height: 100vh; |
|
||||
background: #292929 100%; |
|
||||
padding: 0 24rpx; |
|
||||
padding-top: 40rpx; |
|
||||
padding-bottom: 150rpx; |
|
||||
font-size: 28rpx; |
|
||||
|
|
||||
.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 { |
|
||||
position: relative; |
|
||||
border-radius: 22rpx; |
|
||||
background: #434544 100%; |
|
||||
padding: 14rpx 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; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 发布作业按钮样式 |
|
||||
.publish-btn { |
|
||||
position: fixed; |
|
||||
bottom: 220rpx; |
|
||||
right: 40rpx; |
|
||||
width: 120rpx; |
|
||||
height: 120rpx; |
|
||||
background: #29D3B4; |
|
||||
border-radius: 50%; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
box-shadow: 0 4rpx 20rpx rgba(41, 211, 180, 0.4); |
|
||||
z-index: 99; |
|
||||
|
|
||||
.btn-text { |
|
||||
color: #fff; |
|
||||
font-size: 26rpx; |
|
||||
text-align: center; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 弹窗内容样式 |
|
||||
.popup-content { |
|
||||
width: 650rpx; |
|
||||
background: #333; |
|
||||
border-radius: 20rpx; |
|
||||
padding: 30rpx; |
|
||||
max-height: 80vh; |
|
||||
overflow-y: auto; |
|
||||
|
|
||||
.popup-title { |
|
||||
font-size: 36rpx; |
|
||||
color: #fff; |
|
||||
text-align: center; |
|
||||
margin-bottom: 30rpx; |
|
||||
font-weight: bold; |
|
||||
} |
|
||||
|
|
||||
.form-item { |
|
||||
margin-bottom: 20rpx; |
|
||||
|
|
||||
.form-label { |
|
||||
display: block; |
|
||||
color: #fff; |
|
||||
font-size: 28rpx; |
|
||||
margin-bottom: 10rpx; |
|
||||
} |
|
||||
|
|
||||
.form-input, |
|
||||
.form-textarea, |
|
||||
.form-picker { |
|
||||
width: 100%; |
|
||||
background: #444; |
|
||||
border-radius: 10rpx; |
|
||||
padding: 16rpx; |
|
||||
color: #fff; |
|
||||
font-size: 28rpx; |
|
||||
box-sizing: border-box; |
|
||||
} |
|
||||
|
|
||||
.form-textarea { |
|
||||
height: 150rpx; |
|
||||
} |
|
||||
|
|
||||
.picker-text { |
|
||||
height: 60rpx; |
|
||||
line-height: 60rpx; |
|
||||
} |
|
||||
|
|
||||
// 上传控件样式 |
|
||||
.upload-container { |
|
||||
margin-top: 10rpx; |
|
||||
} |
|
||||
|
|
||||
.upload-btn { |
|
||||
width: 200rpx; |
|
||||
height: 200rpx; |
|
||||
background: #444; |
|
||||
border-radius: 10rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
border: 1px dashed #666; |
|
||||
|
|
||||
.upload-icon { |
|
||||
font-size: 60rpx; |
|
||||
color: #29D3B4; |
|
||||
line-height: 60rpx; |
|
||||
} |
|
||||
|
|
||||
.upload-text { |
|
||||
font-size: 24rpx; |
|
||||
color: #aaa; |
|
||||
margin-top: 10rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 图片预览 |
|
||||
.image-preview { |
|
||||
position: relative; |
|
||||
width: 200rpx; |
|
||||
height: 200rpx; |
|
||||
border-radius: 10rpx; |
|
||||
overflow: hidden; |
|
||||
|
|
||||
.preview-image { |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
} |
|
||||
|
|
||||
.delete-btn { |
|
||||
position: absolute; |
|
||||
top: 0; |
|
||||
right: 0; |
|
||||
width: 40rpx; |
|
||||
height: 40rpx; |
|
||||
background: rgba(0, 0, 0, 0.6); |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
|
|
||||
.delete-icon { |
|
||||
color: #fff; |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 视频预览 |
|
||||
.video-preview { |
|
||||
position: relative; |
|
||||
width: 100%; |
|
||||
height: 300rpx; |
|
||||
border-radius: 10rpx; |
|
||||
overflow: hidden; |
|
||||
|
|
||||
.preview-video { |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
} |
|
||||
|
|
||||
.delete-btn { |
|
||||
position: absolute; |
|
||||
top: 0; |
|
||||
right: 0; |
|
||||
width: 40rpx; |
|
||||
height: 40rpx; |
|
||||
background: rgba(0, 0, 0, 0.6); |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
|
|
||||
.delete-icon { |
|
||||
color: #fff; |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.form-buttons { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
margin-top: 40rpx; |
|
||||
|
|
||||
button { |
|
||||
width: 45%; |
|
||||
height: 80rpx; |
|
||||
line-height: 80rpx; |
|
||||
border-radius: 40rpx; |
|
||||
font-size: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.btn-cancel { |
|
||||
background: #555; |
|
||||
color: #fff; |
|
||||
} |
|
||||
|
|
||||
.btn-submit { |
|
||||
background: #29D3B4; |
|
||||
color: #fff; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,276 +0,0 @@ |
|||||
<!--到课统计-详情--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
|
|
||||
<view class="main_section"> |
|
||||
|
|
||||
<scroll-view |
|
||||
class="section_3" |
|
||||
scroll-y="true" |
|
||||
:lower-threshold="lowerThreshold" |
|
||||
@scrolltolower="loadMoreData" |
|
||||
style="height: 90vh;" |
|
||||
> |
|
||||
<view class="ul"> |
|
||||
<view class="li" |
|
||||
v-for="(v,k) in courseList" |
|
||||
:key="k" |
|
||||
@click="openViewCourseInfo(v)" |
|
||||
> |
|
||||
<view class="left_box"> |
|
||||
<view class="date_box"> |
|
||||
<text>{{v.has_sign_count}}</text> |
|
||||
<text>/</text> |
|
||||
<text>{{v.students_count}}</text> |
|
||||
</view> |
|
||||
<view class="ratio"> |
|
||||
到课率:{{v.attendance_rate}}% |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="center_box"> |
|
||||
<view>班级:{{v.classes_name}}</view> |
|
||||
<view>时间:{{v.date_time}} {{v.time_slot ? v.time_slot.replace(",", " - ") : ""}}</view> |
|
||||
<view>课室:{{v.address}} |
|
||||
</view> |
|
||||
<view>课程:{{v.courses_name}} |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="right_box"> |
|
||||
<view v-if="!(['1','2'].includes(String(v.status)))" class="tag" style="background:#20CAAF;">未开始</view> |
|
||||
|
|
||||
<view v-if="v.status == 1" class="tag" style="background:#fad24e;">上课中</view> |
|
||||
<view v-if="v.status == 2" class="tag" style="background:#e2e2e2;">已结束</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</scroll-view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import memberApi from '@/api/member.js'; |
|
||||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|
||||
|
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
loading: false,//加载状态 |
|
||||
lowerThreshold: 100,//距离底部多远触发 |
|
||||
isReachedBottom: false,//防止重复加载|true=不可加载|false=可加载 |
|
||||
|
|
||||
//筛选条件 |
|
||||
filteredData: { |
|
||||
page: 1,//当前页码 |
|
||||
limit: 10,//每页返回数据条数 |
|
||||
total: 10,//数据总条数 |
|
||||
class_id: '',//班级id |
|
||||
}, |
|
||||
courseList:[],//课程列表 |
|
||||
} |
|
||||
}, |
|
||||
onLoad() { |
|
||||
}, |
|
||||
onShow(){ |
|
||||
this.init() |
|
||||
}, |
|
||||
methods: { |
|
||||
//初始化 |
|
||||
async init(){ |
|
||||
this.getCourseList() |
|
||||
}, |
|
||||
|
|
||||
//课程列表 .courseList |
|
||||
//加载更过(下一页) |
|
||||
loadMoreData() { |
|
||||
//判断是否加载 |
|
||||
if (!this.isReachedBottom) { |
|
||||
this.isReachedBottom = true;//设置为不可请求状态 |
|
||||
this.getCourseList(); |
|
||||
} |
|
||||
}, |
|
||||
//重置为第一页 |
|
||||
async loadData() { |
|
||||
this.isReachedBottom = false; // 重置状态,以便下次触发加载更多 |
|
||||
|
|
||||
this.filteredData.page = 1//当前页码 |
|
||||
this.filteredData.limit = 10//每页返回数据条数 |
|
||||
this.filteredData.total = 10//数据总条数 |
|
||||
}, |
|
||||
//教练端-获取课程列表 |
|
||||
async getCourseList(){ |
|
||||
|
|
||||
let data = {...this.filteredData} |
|
||||
data.class_id = this.class_id |
|
||||
|
|
||||
console.log(12123,this.courseList) |
|
||||
|
|
||||
if(data.page == 1){ |
|
||||
this.courseList = [] |
|
||||
} |
|
||||
|
|
||||
//判断是否还有数据 |
|
||||
if ((this.filteredData.page - 1) * this.filteredData.limit >= this.filteredData.total) { |
|
||||
this.loading = false |
|
||||
uni.showToast({ |
|
||||
title: '暂无更多', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
let res = await memberApi.courseList(data) |
|
||||
this.loading = false |
|
||||
this.isReachedBottom = false; |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
let arr = [] |
|
||||
res.data.list.data.forEach((v,k)=>{ |
|
||||
let item = v |
|
||||
item.attendance_rate = (v.students_count && !isNaN(v.students_count) && v.students_count > 0) ? |
|
||||
parseFloat(((v.has_sign_count / v.students_count) * 100).toFixed(1)) : 0; |
|
||||
arr.push(item) |
|
||||
}) |
|
||||
|
|
||||
|
|
||||
|
|
||||
this.courseList = this.courseList.concat(res.data.list.data)// 使用 concat 方法 将新数据追加到数组中 |
|
||||
|
|
||||
this.filteredData.total = res.data.list.total |
|
||||
console.log('获取课程列表',this.courseList) |
|
||||
this.filteredData.page++ |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
|
|
||||
//打开课程详情 |
|
||||
openViewCourseInfo(item){ |
|
||||
let id= item.id |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/coach/course/info_list?id=${id}` |
|
||||
}) |
|
||||
}, |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
|
|
||||
.main_box{ |
|
||||
background: #292929 ; |
|
||||
} |
|
||||
|
|
||||
//自定义导航栏 |
|
||||
.navbar_section{ |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
background: #29d3b4; |
|
||||
.title{ |
|
||||
padding: 40rpx 0rpx; |
|
||||
|
|
||||
/* 小程序端样式 */ |
|
||||
// #ifdef MP-WEIXIN |
|
||||
padding: 80rpx 0rpx; |
|
||||
// #endif |
|
||||
|
|
||||
font-size: 30rpx; |
|
||||
color: #315d55; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.main_section{ |
|
||||
min-height: 100vh; |
|
||||
background: #292929 100%; |
|
||||
padding: 0 24rpx; |
|
||||
padding-top: 32rpx; |
|
||||
padding-bottom: 150rpx; |
|
||||
font-size: 28rpx; |
|
||||
.section_3{ |
|
||||
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: 14rpx 0; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
.left_box{ |
|
||||
margin-left: 28rpx; |
|
||||
width: 175rpx; |
|
||||
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: 22rpx; |
|
||||
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; |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
|
|
||||
</style> |
|
||||
@ -1,431 +0,0 @@ |
|||||
<!--我的-首页--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<view style="background:#29D3B4;"> |
|
||||
<!--用户信息--> |
|
||||
<view class="user_section"> |
|
||||
<view class="box"> |
|
||||
<view class="left" @click="openViewMyInfo()"> |
|
||||
<image class="pic" :src="$util.img(memberInfo.head_img)"></image> |
|
||||
<view class="name">{{memberInfo.name}}</view> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="btn"></view> |
|
||||
<!-- <view class="btn">切换身份</view>--> |
|
||||
<!-- <view class="btn" @click="openViewArrivalStatistics()">到课率统计</view> --> |
|
||||
<!-- <view class="btn">到课率统计</view> --> |
|
||||
<view class="btn"></view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!--统计信息--> |
|
||||
<view class="count_section"> |
|
||||
<view class="main"> |
|
||||
<view class="course_box"> |
|
||||
<view class="top"> |
|
||||
<view class="item"> |
|
||||
<view class="num">{{statisticsInfo.courseNum}}</view> |
|
||||
<view class="intro">总授课数/节</view> |
|
||||
</view> |
|
||||
<view class="item"> |
|
||||
<view class="num">{{statisticsInfo.classNum}}</view> |
|
||||
<view class="intro">总授班级/个</view> |
|
||||
</view> |
|
||||
<view class="item"> |
|
||||
<view class="num">{{statisticsInfo.studentNum}}</view> |
|
||||
<view class="intro">总负责学员/名 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="bg_box bg_top"></view> |
|
||||
<view class="bg_box bg_bottom"></view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
|
|
||||
|
|
||||
<view class="main_section"> |
|
||||
<view class="section_box"> |
|
||||
<view class="item" @click="openViewDueSoon()"> |
|
||||
<view>即将到期</view> |
|
||||
<view></view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item" @click="openViewSchoolingStatisticsReal()"> |
|
||||
<view>授课统计</view> |
|
||||
<view></view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- <view class="item"> --> |
|
||||
<view class="item" @click="openViewMyAttendance()"> |
|
||||
<view>我的考勤</view> |
|
||||
<view></view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- <view class="item"> --> |
|
||||
<view class="item" @click="openViewSchoolingStatistics()"> |
|
||||
<view>我的消息</view> |
|
||||
<view></view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item" @click="teachingResearchManagement()"> |
|
||||
<view>教研管理</view> |
|
||||
<view></view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item" @click="openServiceDetail()"> |
|
||||
<view>服务详情</view> |
|
||||
<view></view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item" @click="goCourseSchedule()"> |
|
||||
<view>课程安排</view> |
|
||||
<view></view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item" @click="my_contract()"> |
|
||||
<view>我的合同</view> |
|
||||
<view></view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="section_box"> |
|
||||
<!-- <view class="item" @click="openViewFeedback()"> |
|
||||
<view>意见反馈</view> |
|
||||
<view></view> |
|
||||
</view> --> |
|
||||
|
|
||||
<view class="item" @click="openViewSetUp()"> |
|
||||
<view>设置</view> |
|
||||
<view></view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 底部导航--> |
|
||||
<AQTabber /> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
// import memberApi from '@/api/member.js'; |
|
||||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
memberInfo: {}, |
|
||||
statisticsInfo: [] |
|
||||
} |
|
||||
}, |
|
||||
onLoad() { |
|
||||
|
|
||||
}, |
|
||||
onShow() { |
|
||||
|
|
||||
this.init(); |
|
||||
}, |
|
||||
methods: { |
|
||||
async init() { |
|
||||
this.getStatistics() |
|
||||
}, |
|
||||
my_contract(){ |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/common/contract/my_contract' |
|
||||
}) |
|
||||
}, |
|
||||
//教练详情(个人信息详情) |
|
||||
async getMemberInfo() { |
|
||||
let res = await apiRoute.getPersonnelInfo({}) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
this.memberInfo = res.data |
|
||||
}, |
|
||||
|
|
||||
//获取统计个数 |
|
||||
async getStatistics() { |
|
||||
let res = await apiRoute.getStatisticsInfo({}) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
this.statisticsInfo = res.data |
|
||||
|
|
||||
this.getMemberInfo() |
|
||||
}, |
|
||||
|
|
||||
//打开到课率统计 |
|
||||
openViewArrivalStatistics() { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/coach/my/arrival_statistics' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//打开即将到期 |
|
||||
openViewDueSoon() { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/coach/my/due_soon' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//我的消息 |
|
||||
openViewSchoolingStatistics() { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/common/my_message' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//打开教研管理 |
|
||||
teachingResearchManagement() { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/coach/my/teaching_management' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//打开意见反馈 |
|
||||
openViewFeedback() { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/common/feedback' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//打开个人资料 |
|
||||
openViewMyInfo() { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/coach/my/info' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//打开设置 |
|
||||
openViewSetUp() { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/coach/my/set_up' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//跳转页面-我的考勤 |
|
||||
openViewMyAttendance() { |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/common/my_attendance` |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//打开服务详情 |
|
||||
openServiceDetail() { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/coach/my/service_list' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//打开授课统计(真实的授课统计页面) |
|
||||
openViewSchoolingStatisticsReal() { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/coach/my/schooling_statistics' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
goCourseSchedule(){ |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/coach/schedule/schedule_table' |
|
||||
}) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box { |
|
||||
background: #292929; |
|
||||
min-height: 28vh; |
|
||||
} |
|
||||
|
|
||||
//自定义导航栏 |
|
||||
.navbar_section { |
|
||||
border: 1px solid #29D3B4; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
background: #29D3B4; |
|
||||
|
|
||||
.title { |
|
||||
padding: 40rpx 0rpx; |
|
||||
|
|
||||
/* 小程序端样式 */ |
|
||||
// #ifdef MP-WEIXIN |
|
||||
padding: 80rpx 0rpx; |
|
||||
// #endif |
|
||||
|
|
||||
font-size: 30rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//用户信息 |
|
||||
.user_section { |
|
||||
background-color: #29D3B4; |
|
||||
padding-top: 58rpx; |
|
||||
padding-bottom: 42rpx; |
|
||||
color: #fff; |
|
||||
font-size: 28rpx; |
|
||||
|
|
||||
.box { |
|
||||
padding-left: 19rpx; |
|
||||
padding-right: 29rpx; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
gap: 15rpx; |
|
||||
|
|
||||
.left { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 20rpx; |
|
||||
|
|
||||
.pic { |
|
||||
width: 144rpx; |
|
||||
height: 144rpx; |
|
||||
border-radius: 50%; |
|
||||
} |
|
||||
|
|
||||
.name { |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.right { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 20rpx; |
|
||||
|
|
||||
.btn { |
|
||||
min-height: 28rpx; |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//统计信息 |
|
||||
.count_section { |
|
||||
position: relative; |
|
||||
|
|
||||
.main { |
|
||||
position: relative; |
|
||||
z-index: 2; |
|
||||
padding: 0rpx 24rpx; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
|
|
||||
.course_box { |
|
||||
padding: 42rpx 28rpx; |
|
||||
width: 692rpx; |
|
||||
border-radius: 20rpx; |
|
||||
background-color: #fff; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 32rpx; |
|
||||
|
|
||||
.top { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
|
|
||||
.item { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
gap: 12rpx; |
|
||||
|
|
||||
.num { |
|
||||
color: #29D3B4; |
|
||||
font-size: 56rpx; |
|
||||
} |
|
||||
|
|
||||
.intro { |
|
||||
color: #AAAAAA; |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.bottom { |
|
||||
font-size: 24rpx; |
|
||||
color: #333333; |
|
||||
|
|
||||
text { |
|
||||
color: #29D3B4; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.bg_box { |
|
||||
z-index: 1; |
|
||||
width: 100%; |
|
||||
height: 150rpx; |
|
||||
} |
|
||||
|
|
||||
.bg_top { |
|
||||
position: absolute; |
|
||||
top: 0; |
|
||||
background-color: #29D3B4; |
|
||||
} |
|
||||
|
|
||||
.bg_bottom { |
|
||||
top: 50%; |
|
||||
position: absolute; |
|
||||
background-color: #292929; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.main_section { |
|
||||
background: #292929 100%; |
|
||||
padding: 0 24rpx; |
|
||||
padding-top: 40rpx; |
|
||||
padding-bottom: 150rpx; |
|
||||
font-size: 24rpx; |
|
||||
color: #333333; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 22rpx; |
|
||||
|
|
||||
.section_box { |
|
||||
background: #fff; |
|
||||
border-radius: 16rpx; |
|
||||
padding: 6rpx 24rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
|
|
||||
.item { |
|
||||
padding: 24rpx 78rpx; |
|
||||
border-top: 1px solid #F2F2F2; |
|
||||
font-size: 28rpx; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
} |
|
||||
|
|
||||
.item:nth-child(1) { |
|
||||
border-top: 0; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
} |
|
||||
|
|
||||
} |
|
||||
</style> |
|
||||
@ -1,497 +0,0 @@ |
|||||
<!--我的考勤-详情--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<fui-segmented-control |
|
||||
:values="optionTable" |
|
||||
type="text" |
|
||||
activeColor="#29d3b4" |
|
||||
color="#fff" |
|
||||
@click="segmented"> |
|
||||
</fui-segmented-control> |
|
||||
|
|
||||
<view class="main_section"> |
|
||||
<!--考勤--> |
|
||||
<scroll-view |
|
||||
class="section_1" |
|
||||
v-if="filteredData.type == '1'" |
|
||||
scroll-y="true" |
|
||||
:lower-threshold="lowerThreshold" |
|
||||
@scrolltolower="loadMoreData" |
|
||||
style="height: 100vh;" |
|
||||
> |
|
||||
<view class="ul"> |
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">篮球课</view> |
|
||||
<view class="content">考勤正常</view> |
|
||||
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">篮球课</view> |
|
||||
<view class="content">考勤正常</view> |
|
||||
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">篮球课</view> |
|
||||
<view class="content">考勤正常</view> |
|
||||
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="title_box">普通考勤</view> |
|
||||
<view class="subhead_box">请假</view> |
|
||||
<view class="subhead_box">2025-01-01 00:00:00 - 2505-01-01 00:00:00</view> |
|
||||
|
|
||||
<view class="ul"> |
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">普通考勤</view> |
|
||||
<view class="content">迟到</view> |
|
||||
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">普通考勤</view> |
|
||||
<view class="content">早退</view> |
|
||||
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">普通记录</view> |
|
||||
<view class="content">本周考勤情况:周一到周五均按时打卡,未请假,综合表现良好。 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
</scroll-view> |
|
||||
|
|
||||
<!--请假--> |
|
||||
<scroll-view |
|
||||
class="section_1" |
|
||||
v-if="filteredData.type == '2'" |
|
||||
scroll-y="true" |
|
||||
:lower-threshold="lowerThreshold" |
|
||||
@scrolltolower="loadMoreData" |
|
||||
style="height: 100vh;" |
|
||||
> |
|
||||
<view class="ul"> |
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">篮球课</view> |
|
||||
<view class="content">考勤正常</view> |
|
||||
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">篮球课</view> |
|
||||
<view class="content">考勤正常</view> |
|
||||
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">篮球课</view> |
|
||||
<view class="content">考勤正常</view> |
|
||||
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="title_box">普通考勤</view> |
|
||||
<view class="subhead_box">请假</view> |
|
||||
<view class="subhead_box">2025-01-01 00:00:00 - 2505-01-01 00:00:00</view> |
|
||||
|
|
||||
<view class="ul"> |
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">普通考勤</view> |
|
||||
<view class="content">迟到</view> |
|
||||
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">普通考勤</view> |
|
||||
<view class="content">早退</view> |
|
||||
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">普通记录</view> |
|
||||
<view class="content">本周考勤情况:周一到周五均按时打卡,未请假,综合表现良好。 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
</scroll-view> |
|
||||
|
|
||||
<!--异常--> |
|
||||
<scroll-view |
|
||||
class="section_1" |
|
||||
v-if="filteredData.type == '3'" |
|
||||
scroll-y="true" |
|
||||
:lower-threshold="lowerThreshold" |
|
||||
@scrolltolower="loadMoreData" |
|
||||
style="height: 100vh;" |
|
||||
> |
|
||||
<view class="ul"> |
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">篮球课</view> |
|
||||
<view class="content">考勤正常</view> |
|
||||
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">篮球课</view> |
|
||||
<view class="content">考勤正常</view> |
|
||||
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">篮球课</view> |
|
||||
<view class="content">考勤正常</view> |
|
||||
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="title_box">普通考勤</view> |
|
||||
<view class="subhead_box">请假</view> |
|
||||
<view class="subhead_box">2025-01-01 00:00:00 - 2505-01-01 00:00:00</view> |
|
||||
|
|
||||
<view class="ul"> |
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">普通考勤</view> |
|
||||
<view class="content">迟到</view> |
|
||||
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">普通考勤</view> |
|
||||
<view class="content">早退</view> |
|
||||
<view class="content">2025-01-01 00:00:00 - 2025-01-01 00:00:00</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="li"> |
|
||||
<view class="left"> |
|
||||
<image src="http://www.firstui.cn:4000/vipdoc/img/img_logo.png" model="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="content">普通记录</view> |
|
||||
<view class="content">本周考勤情况:周一到周五均按时打卡,未请假,综合表现良好。 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
</scroll-view> |
|
||||
|
|
||||
<view class="section_btn"> |
|
||||
<view class="btn">请假</view> |
|
||||
</view> |
|
||||
|
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import marketApi from '@/api/market.js'; |
|
||||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|
||||
|
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
//tab切换 |
|
||||
optionTable: [ |
|
||||
{ |
|
||||
id: 1, |
|
||||
name: '考勤' |
|
||||
}, |
|
||||
{ |
|
||||
id: 2, |
|
||||
name: '请假' |
|
||||
}, |
|
||||
{ |
|
||||
id: 3, |
|
||||
name: '异常' |
|
||||
} |
|
||||
], |
|
||||
|
|
||||
loading:false,//加载状态 |
|
||||
lowerThreshold: 100,//距离底部多远触发 |
|
||||
isReachedBottom: false,//防止重复加载|true=不可加载|false=可加载 |
|
||||
|
|
||||
//筛选条件 |
|
||||
filteredData:{ |
|
||||
page:1,//当前页码 |
|
||||
limit:10,//每页返回数据条数 |
|
||||
total:10,//数据总条数 |
|
||||
type: '1',//1=考勤,2=请假,3=异常 |
|
||||
}, |
|
||||
tableList:[],//表格数据 |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) {}, |
|
||||
onShow(){ |
|
||||
this.init()//初始化 |
|
||||
}, |
|
||||
methods: { |
|
||||
//初始化 |
|
||||
async init(){ |
|
||||
await this.getList(); |
|
||||
}, |
|
||||
|
|
||||
//切换tag列表 |
|
||||
async segmented(e) { |
|
||||
//重置为第一页 |
|
||||
await this.resetFilteredData() |
|
||||
this.filteredData.type = e.id//1=考勤,2=请假,3=异常 |
|
||||
await this.getList() |
|
||||
}, |
|
||||
|
|
||||
//加载更多(下一页) |
|
||||
loadMoreData() { |
|
||||
//判断是否加载 |
|
||||
if (!this.isReachedBottom) { |
|
||||
this.isReachedBottom = true;//设置为不可请求状态 |
|
||||
this.getList(); |
|
||||
} |
|
||||
}, |
|
||||
//重置为第一页 |
|
||||
async resetFilteredData() { |
|
||||
this.isReachedBottom = false; // 重置状态,以便下次触发加载更多 |
|
||||
|
|
||||
this.filteredData.page = 1//当前页码 |
|
||||
this.filteredData.limit = 10//每页返回数据条数 |
|
||||
this.filteredData.total = 10//数据总条数 |
|
||||
}, |
|
||||
//获取列表 |
|
||||
async getList(){ |
|
||||
this.loading = true |
|
||||
|
|
||||
let data = {...this.filteredData} |
|
||||
|
|
||||
//判断是否还有数据 |
|
||||
if ((this.filteredData.page - 1) * this.filteredData.limit >= this.filteredData.total) { |
|
||||
this.loading = false |
|
||||
uni.showToast({ |
|
||||
title: '暂无更多', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
if(data.page == 1){ |
|
||||
this.tableList = [] |
|
||||
} |
|
||||
|
|
||||
let res = await marketApi.myClient(data) |
|
||||
this.loading = false |
|
||||
this.isReachedBottom = false; |
|
||||
if (res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.tableList = this.tableList.concat(res.data.list.data); // 使用 concat 方法 将新数据追加到数组中 |
|
||||
|
|
||||
console.log('列表',this.tableList) |
|
||||
this.filteredData.total = res.data.list.total |
|
||||
this.filteredData.page++ |
|
||||
|
|
||||
this.countArr = { |
|
||||
type_0:res.data.count[0], |
|
||||
type_1:res.data.count[1], |
|
||||
type_2:res.data.count[2], |
|
||||
type_3:res.data.count[3], |
|
||||
max_count:res.data.gh.max_count, |
|
||||
lq_count:res.data.gh.lq_count, |
|
||||
} |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
|
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
|
|
||||
.main_box{ |
|
||||
background: #292929 ; |
|
||||
} |
|
||||
|
|
||||
//自定义导航栏 |
|
||||
.navbar_section{ |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
background: #29d3b4; |
|
||||
.title{ |
|
||||
padding: 40rpx 0rpx; |
|
||||
|
|
||||
/* 小程序端样式 */ |
|
||||
// #ifdef MP-WEIXIN |
|
||||
padding: 80rpx 0rpx; |
|
||||
// #endif |
|
||||
|
|
||||
font-size: 30rpx; |
|
||||
color: #315d55; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.main_section{ |
|
||||
min-height: 100vh; |
|
||||
background: #292929 100%; |
|
||||
padding: 0 24rpx; |
|
||||
padding-top: 32rpx; |
|
||||
padding-bottom: 150rpx; |
|
||||
font-size: 28rpx; |
|
||||
.section_1{ |
|
||||
color: #fff; |
|
||||
font-size: 28rpx; |
|
||||
.ul{ |
|
||||
margin-top: 23rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 24rpx; |
|
||||
.li{ |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 43rpx; |
|
||||
.left{ |
|
||||
image{ |
|
||||
width: 174rpx; |
|
||||
height: 174rpx; |
|
||||
border-radius: 24rpx; |
|
||||
background-color: #333333; |
|
||||
} |
|
||||
} |
|
||||
.right{ |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 18rpx; |
|
||||
.content{ |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
.content:nth-child(1){ |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.title_box{ |
|
||||
margin-top: 46rpx; |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
.subhead_box{ |
|
||||
margin-top: 22rpx; |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.section_btn{ |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
.btn{ |
|
||||
width: 722rpx; |
|
||||
height: 64rpx; |
|
||||
line-height: 64rpx; |
|
||||
border-radius: 8rpx; |
|
||||
background-color: rgba(32,202,175,1); |
|
||||
color: rgba(255,255,255,1); |
|
||||
font-size: 28rpx; |
|
||||
text-align: center; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
|
|
||||
</style> |
|
||||
@ -1,870 +0,0 @@ |
|||||
<!--服务详情页面--> |
|
||||
<template> |
|
||||
<view class="container"> |
|
||||
<view class="main-content"> |
|
||||
<!-- 加载状态 --> |
|
||||
<view v-if="loading" class="loading-container"> |
|
||||
<uni-load-more status="loading" content-text="加载中..."></uni-load-more> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 服务记录列表 --> |
|
||||
<view v-else class="service-cards"> |
|
||||
<view class="service-card" v-for="(service, index) in serviceList" :key="index" @click="viewServiceDetail(service)"> |
|
||||
<!-- 服务预览图 --> |
|
||||
<view class="service-preview" v-if="service.preview_image_url"> |
|
||||
<image :src="getImageUrl(service.preview_image_url)" class="preview-image" mode="aspectFill"></image> |
|
||||
</view> |
|
||||
|
|
||||
<view class="card-content"> |
|
||||
<!-- 服务名称和状态 --> |
|
||||
<view class="card-header"> |
|
||||
<view class="service-name">{{ service.service_name }}</view> |
|
||||
<view class="service-status" :class="service.status === 1 ? 'status-active' : (service.status === 0 ? 'status-pending' : 'status-inactive')"> |
|
||||
{{ service.status === 1 ? '已完成' : (service.status === 0 ? '待处理' : '未知状态') }} |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 服务信息 --> |
|
||||
<view class="service-info"> |
|
||||
<view class="info-item" v-if="service.service_type"> |
|
||||
<text class="label">服务类型:</text> |
|
||||
<text class="value">{{ service.service_type }}</text> |
|
||||
</view> |
|
||||
<view class="info-item" v-if="service.description"> |
|
||||
<text class="label">服务描述:</text> |
|
||||
<text class="value">{{ service.description }}</text> |
|
||||
</view> |
|
||||
<view class="info-item" v-if="service.service_remark || service.status !== 1"> |
|
||||
<text class="label">服务结果:</text> |
|
||||
<view class="value-content" v-if="service.service_remark"> |
|
||||
<rich-text :nodes="formatRichText(service.service_remark)"></rich-text> |
|
||||
</view> |
|
||||
<text class="value placeholder" v-else-if="service.status !== 1">点击编辑服务结果</text> |
|
||||
</view> |
|
||||
<view class="info-item" v-if="service.feedback"> |
|
||||
<text class="label">家长反馈:</text> |
|
||||
<text class="value">{{ service.feedback }}</text> |
|
||||
</view> |
|
||||
<view class="info-item" v-if="service.score"> |
|
||||
<text class="label">家长评分:</text> |
|
||||
<text class="value score">{{ service.score }}分</text> |
|
||||
</view> |
|
||||
<view class="info-item"> |
|
||||
<text class="label">创建时间:</text> |
|
||||
<text class="value">{{ formatDate(service.created_at) }}</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 操作按钮 --> |
|
||||
<view class="card-actions" v-if="service.status !== 1"> |
|
||||
<button class="edit-btn" @click.stop="editServiceRemark(service)"> |
|
||||
<text class="iconfont icon-edit"></text> |
|
||||
编辑服务结果 |
|
||||
</button> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 箭头图标 --> |
|
||||
<view class="card-arrow"> |
|
||||
<text class="iconfont icon-arrow-right"></text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 空状态 --> |
|
||||
<view class="empty-state" v-if="!loading && serviceList.length === 0"> |
|
||||
<view class="empty-icon">📝</view> |
|
||||
<view class="empty-text">暂无服务记录</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 底部加载更多 --> |
|
||||
<view v-if="hasMore && !loading && serviceList.length > 0" class="load-more"> |
|
||||
<uni-load-more :status="loadMoreStatus" @clickLoadMore="loadMore"></uni-load-more> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 编辑服务结果弹窗 --> |
|
||||
<view v-if="showEditModal" class="edit-modal" @click="closeEditModal"> |
|
||||
<view class="modal-content" @click.stop> |
|
||||
<view class="modal-header"> |
|
||||
<text class="modal-title">编辑服务结果</text> |
|
||||
<view class="modal-close" @click="closeEditModal"> |
|
||||
<text class="iconfont icon-close"></text> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="modal-body"> |
|
||||
<view class="form-item"> |
|
||||
<text class="form-label">服务结果:</text> |
|
||||
|
|
||||
<!-- 富文本工具栏 --> |
|
||||
<view class="editor-toolbar"> |
|
||||
<view class="toolbar-group"> |
|
||||
<view class="tool-btn" :class="{ active: bold }" @click="toggleBold"> |
|
||||
<text class="tool-text">B</text> |
|
||||
</view> |
|
||||
<view class="tool-btn" :class="{ active: italic }" @click="toggleItalic"> |
|
||||
<text class="tool-text">I</text> |
|
||||
</view> |
|
||||
<view class="tool-btn" @click="insertBulletList"> |
|
||||
<text class="tool-text">•</text> |
|
||||
</view> |
|
||||
<view class="tool-btn" @click="insertNumberList"> |
|
||||
<text class="tool-text">1.</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 文本输入区域 --> |
|
||||
<textarea |
|
||||
class="form-textarea" |
|
||||
v-model="editForm.service_remark" |
|
||||
placeholder="请输入服务结果内容,支持简单的格式化文本" |
|
||||
maxlength="1000" |
|
||||
:show-confirm-bar="false" |
|
||||
@focus="onTextareaFocus" |
|
||||
@blur="onTextareaBlur"> |
|
||||
</textarea> |
|
||||
|
|
||||
<!-- 字数统计 --> |
|
||||
<view class="char-count">{{ editForm.service_remark.length }}/1000</view> |
|
||||
|
|
||||
<!-- 提示信息 --> |
|
||||
<view class="editor-tips"> |
|
||||
<text class="tip-text">支持基础格式:粗体、斜体、列表等</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="modal-footer"> |
|
||||
<button class="modal-btn cancel" @click="closeEditModal">取消</button> |
|
||||
<button class="modal-btn confirm" @click="saveServiceRemark" :disabled="saving"> |
|
||||
{{ saving ? '保存中...' : '保存' }} |
|
||||
</button> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import apiRoute from '@/common/axios.js'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
loading: true, |
|
||||
serviceList: [], |
|
||||
currentPage: 1, |
|
||||
pageSize: 10, |
|
||||
hasMore: true, |
|
||||
loadMoreStatus: 'more', |
|
||||
showEditModal: false, |
|
||||
saving: false, |
|
||||
editForm: { |
|
||||
id: 0, |
|
||||
service_remark: '' |
|
||||
}, |
|
||||
// 富文本编辑状态 |
|
||||
bold: false, |
|
||||
italic: false, |
|
||||
textareaFocused: false |
|
||||
} |
|
||||
}, |
|
||||
onLoad() { |
|
||||
this.init(); |
|
||||
}, |
|
||||
onPullDownRefresh() { |
|
||||
this.refreshServiceList(); |
|
||||
}, |
|
||||
onReachBottom() { |
|
||||
if (this.hasMore && !this.loading) { |
|
||||
this.loadMore(); |
|
||||
} |
|
||||
}, |
|
||||
methods: { |
|
||||
async init() { |
|
||||
this.getServiceList(); |
|
||||
}, |
|
||||
|
|
||||
// 获取服务记录列表 |
|
||||
async getServiceList(refresh = false) { |
|
||||
if (refresh) { |
|
||||
this.currentPage = 1; |
|
||||
this.hasMore = true; |
|
||||
this.serviceList = []; |
|
||||
} |
|
||||
|
|
||||
this.loading = true; |
|
||||
this.loadMoreStatus = 'loading'; |
|
||||
|
|
||||
try { |
|
||||
const response = await apiRoute.get('/personnel/myServiceLogs', { |
|
||||
page: this.currentPage, |
|
||||
limit: this.pageSize, |
|
||||
demo: 1 // 添加演示数据标识 |
|
||||
}); |
|
||||
|
|
||||
if (response.code === 1) { |
|
||||
const newServices = response.data.data || []; |
|
||||
|
|
||||
if (refresh) { |
|
||||
this.serviceList = newServices; |
|
||||
} else { |
|
||||
this.serviceList = [...this.serviceList, ...newServices]; |
|
||||
} |
|
||||
|
|
||||
// 检查是否还有更多数据 |
|
||||
this.hasMore = newServices.length === this.pageSize; |
|
||||
this.loadMoreStatus = this.hasMore ? 'more' : 'noMore'; |
|
||||
} else { |
|
||||
uni.showToast({ |
|
||||
title: response.data.msg || '加载失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.error('获取服务记录失败:', error); |
|
||||
uni.showToast({ |
|
||||
title: '网络错误,请稍后重试', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} finally { |
|
||||
this.loading = false; |
|
||||
if (refresh) { |
|
||||
uni.stopPullDownRefresh(); |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 刷新服务列表 |
|
||||
refreshServiceList() { |
|
||||
this.getServiceList(true); |
|
||||
}, |
|
||||
|
|
||||
// 加载更多 |
|
||||
loadMore() { |
|
||||
if (this.hasMore && !this.loading) { |
|
||||
this.currentPage++; |
|
||||
this.getServiceList(); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 查看服务详情 |
|
||||
async viewServiceDetail(service) { |
|
||||
try { |
|
||||
const response = await apiRoute.get('/personnel/serviceLogDetail', { |
|
||||
id: service.id |
|
||||
}); |
|
||||
|
|
||||
if (response.code === 1) { |
|
||||
const detail = response.data; |
|
||||
this.showServiceDetailModal(detail); |
|
||||
} else { |
|
||||
uni.showToast({ |
|
||||
title: response.data.msg || '获取详情失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.error('获取服务详情失败:', error); |
|
||||
uni.showToast({ |
|
||||
title: '网络错误,请稍后重试', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 显示服务详情弹窗 |
|
||||
showServiceDetailModal(detail) { |
|
||||
let content = `服务名称:${detail.service_name || '-'}\n`; |
|
||||
content += `服务类型:${detail.service_type || '-'}\n`; |
|
||||
content += `状态:${detail.status === 1 ? '已完成' : (detail.status === 0 ? '待处理' : '未知状态')}\n`; |
|
||||
if (detail.description) { |
|
||||
content += `描述:${detail.description}\n`; |
|
||||
} |
|
||||
if (detail.service_remark) { |
|
||||
content += `服务结果:${detail.service_remark}\n`; |
|
||||
} |
|
||||
if (detail.feedback) { |
|
||||
content += `家长反馈:${detail.feedback}\n`; |
|
||||
} |
|
||||
if (detail.score) { |
|
||||
content += `家长评分:${detail.score}分`; |
|
||||
} |
|
||||
|
|
||||
uni.showModal({ |
|
||||
title: '服务详情', |
|
||||
content: content, |
|
||||
showCancel: false |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
// 获取图片URL |
|
||||
getImageUrl(url) { |
|
||||
if (!url) return ''; |
|
||||
if (url.startsWith('http')) { |
|
||||
return url; |
|
||||
} |
|
||||
return this.$baseUrl + '/' + url; |
|
||||
}, |
|
||||
|
|
||||
// 格式化日期 |
|
||||
formatDate(dateString) { |
|
||||
if (!dateString) return '-'; |
|
||||
const date = new Date(dateString); |
|
||||
const year = date.getFullYear(); |
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0'); |
|
||||
const day = String(date.getDate()).padStart(2, '0'); |
|
||||
return `${year}-${month}-${day}`; |
|
||||
}, |
|
||||
|
|
||||
// 去除HTML标签 |
|
||||
stripHtml(html) { |
|
||||
if (!html) return ''; |
|
||||
return html.replace(/<[^>]*>/g, '').trim(); |
|
||||
}, |
|
||||
|
|
||||
// 格式化富文本内容 |
|
||||
formatRichText(text) { |
|
||||
if (!text) return ''; |
|
||||
|
|
||||
// 简单的markdown转换 |
|
||||
let formatted = text |
|
||||
// 粗体 |
|
||||
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>') |
|
||||
// 斜体 |
|
||||
.replace(/\*(.*?)\*/g, '<em>$1</em>') |
|
||||
// 无序列表 |
|
||||
.replace(/^\u2022\s(.+)$/gm, '<li>$1</li>') |
|
||||
// 有序列表 |
|
||||
.replace(/^\d+\.\s(.+)$/gm, '<li>$1</li>') |
|
||||
// 换行 |
|
||||
.replace(/\n/g, '<br/>'); |
|
||||
|
|
||||
// 如果有列表项,包装在ul标签中 |
|
||||
if (formatted.includes('<li>')) { |
|
||||
formatted = formatted.replace(/(<li>.*?<\/li>)/g, '<ul>$1</ul>'); |
|
||||
} |
|
||||
|
|
||||
return formatted; |
|
||||
}, |
|
||||
|
|
||||
// 编辑服务结果 |
|
||||
editServiceRemark(service) { |
|
||||
// 检查是否可以编辑 |
|
||||
if (service.status === 1) { |
|
||||
uni.showToast({ |
|
||||
title: '服务已完成,无法修改', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
this.editForm.id = service.id; |
|
||||
this.editForm.service_remark = this.stripHtml(service.service_remark || ''); |
|
||||
this.showEditModal = true; |
|
||||
}, |
|
||||
|
|
||||
// 关闭编辑弹窗 |
|
||||
closeEditModal() { |
|
||||
this.showEditModal = false; |
|
||||
this.editForm = { |
|
||||
id: 0, |
|
||||
service_remark: '' |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
// 保存服务结果 |
|
||||
async saveServiceRemark() { |
|
||||
if (!this.editForm.service_remark.trim()) { |
|
||||
uni.showToast({ |
|
||||
title: '请输入服务结果内容', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
this.saving = true; |
|
||||
|
|
||||
try { |
|
||||
const response = await apiRoute.post('/personnel/updateServiceRemark', { |
|
||||
id: this.editForm.id, |
|
||||
service_remark: this.editForm.service_remark |
|
||||
}); |
|
||||
|
|
||||
if (response.data.code === 1) { |
|
||||
uni.showToast({ |
|
||||
title: '保存成功', |
|
||||
icon: 'success' |
|
||||
}); |
|
||||
|
|
||||
// 更新列表中的数据 |
|
||||
const index = this.serviceList.findIndex(item => item.id === this.editForm.id); |
|
||||
if (index !== -1) { |
|
||||
this.serviceList[index].service_remark = this.editForm.service_remark; |
|
||||
} |
|
||||
|
|
||||
this.closeEditModal(); |
|
||||
} else { |
|
||||
uni.showToast({ |
|
||||
title: response.data.msg || '保存失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.error('保存服务结果失败:', error); |
|
||||
uni.showToast({ |
|
||||
title: '网络错误,请稍后重试', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} finally { |
|
||||
this.saving = false; |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 富文本编辑功能 |
|
||||
onTextareaFocus() { |
|
||||
this.textareaFocused = true; |
|
||||
}, |
|
||||
|
|
||||
onTextareaBlur() { |
|
||||
this.textareaFocused = false; |
|
||||
}, |
|
||||
|
|
||||
toggleBold() { |
|
||||
this.bold = !this.bold; |
|
||||
this.insertFormatText('**', '**'); |
|
||||
}, |
|
||||
|
|
||||
toggleItalic() { |
|
||||
this.italic = !this.italic; |
|
||||
this.insertFormatText('*', '*'); |
|
||||
}, |
|
||||
|
|
||||
insertBulletList() { |
|
||||
this.insertFormatText('\n• ', ''); |
|
||||
}, |
|
||||
|
|
||||
insertNumberList() { |
|
||||
this.insertFormatText('\n1. ', ''); |
|
||||
}, |
|
||||
|
|
||||
insertFormatText(before, after) { |
|
||||
const textarea = this.editForm.service_remark; |
|
||||
const newText = textarea + before + '请输入内容' + after; |
|
||||
this.editForm.service_remark = newText; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.container { |
|
||||
background: #1a1a1a; |
|
||||
min-height: 100vh; |
|
||||
} |
|
||||
|
|
||||
.main-content { |
|
||||
padding: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.service-cards { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.service-card { |
|
||||
background: #2a2a2a; |
|
||||
border-radius: 16rpx; |
|
||||
overflow: hidden; |
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.3); |
|
||||
border: 1rpx solid #444; |
|
||||
position: relative; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
padding: 24rpx; |
|
||||
} |
|
||||
|
|
||||
.service-preview { |
|
||||
width: 120rpx; |
|
||||
height: 120rpx; |
|
||||
border-radius: 12rpx; |
|
||||
overflow: hidden; |
|
||||
margin-right: 24rpx; |
|
||||
flex-shrink: 0; |
|
||||
|
|
||||
.preview-image { |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.card-content { |
|
||||
flex: 1; |
|
||||
} |
|
||||
|
|
||||
.card-header { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
margin-bottom: 16rpx; |
|
||||
|
|
||||
.service-name { |
|
||||
font-size: 32rpx; |
|
||||
font-weight: 600; |
|
||||
color: #fff; |
|
||||
flex: 1; |
|
||||
margin-right: 16rpx; |
|
||||
} |
|
||||
|
|
||||
.service-status { |
|
||||
padding: 8rpx 16rpx; |
|
||||
border-radius: 20rpx; |
|
||||
font-size: 24rpx; |
|
||||
font-weight: 500; |
|
||||
|
|
||||
&.status-active { |
|
||||
background: rgba(41, 211, 180, 0.2); |
|
||||
color: #29d3b4; |
|
||||
border: 1rpx solid #29d3b4; |
|
||||
} |
|
||||
|
|
||||
&.status-pending { |
|
||||
background: rgba(255, 193, 7, 0.2); |
|
||||
color: #ffc107; |
|
||||
border: 1rpx solid #ffc107; |
|
||||
} |
|
||||
|
|
||||
&.status-inactive { |
|
||||
background: rgba(220, 53, 69, 0.2); |
|
||||
color: #dc3545; |
|
||||
border: 1rpx solid #dc3545; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.service-info { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 12rpx; |
|
||||
} |
|
||||
|
|
||||
.info-item { |
|
||||
display: flex; |
|
||||
align-items: flex-start; |
|
||||
|
|
||||
.label { |
|
||||
color: #999; |
|
||||
font-size: 26rpx; |
|
||||
min-width: 140rpx; |
|
||||
flex-shrink: 0; |
|
||||
} |
|
||||
|
|
||||
.value { |
|
||||
color: #ccc; |
|
||||
font-size: 26rpx; |
|
||||
flex: 1; |
|
||||
word-break: break-all; |
|
||||
|
|
||||
&.score { |
|
||||
color: #29d3b4; |
|
||||
font-weight: 600; |
|
||||
} |
|
||||
|
|
||||
&.placeholder { |
|
||||
color: #666; |
|
||||
font-style: italic; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.value-content { |
|
||||
flex: 1; |
|
||||
color: #ccc; |
|
||||
font-size: 26rpx; |
|
||||
line-height: 1.6; |
|
||||
|
|
||||
/* 富文本样式 */ |
|
||||
:deep(strong) { |
|
||||
font-weight: 600; |
|
||||
color: #fff; |
|
||||
} |
|
||||
|
|
||||
:deep(em) { |
|
||||
font-style: italic; |
|
||||
color: #29d3b4; |
|
||||
} |
|
||||
|
|
||||
:deep(ul) { |
|
||||
margin: 8rpx 0; |
|
||||
padding-left: 24rpx; |
|
||||
} |
|
||||
|
|
||||
:deep(li) { |
|
||||
margin: 4rpx 0; |
|
||||
list-style: disc; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.card-arrow { |
|
||||
margin-left: 16rpx; |
|
||||
width: 40rpx; |
|
||||
height: 40rpx; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
flex-shrink: 0; |
|
||||
|
|
||||
.iconfont { |
|
||||
font-size: 24rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.card-actions { |
|
||||
margin-top: 20rpx; |
|
||||
padding-top: 20rpx; |
|
||||
border-top: 1rpx solid #444; |
|
||||
|
|
||||
.edit-btn { |
|
||||
background: #29d3b4; |
|
||||
color: #fff; |
|
||||
border: none; |
|
||||
border-radius: 8rpx; |
|
||||
padding: 12rpx 24rpx; |
|
||||
font-size: 26rpx; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
gap: 8rpx; |
|
||||
|
|
||||
&:active { |
|
||||
background: #22b39a; |
|
||||
} |
|
||||
|
|
||||
.iconfont { |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.empty-state { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
padding: 120rpx 40rpx; |
|
||||
|
|
||||
.empty-icon { |
|
||||
font-size: 120rpx; |
|
||||
margin-bottom: 24rpx; |
|
||||
opacity: 0.3; |
|
||||
} |
|
||||
|
|
||||
.empty-text { |
|
||||
color: #666; |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.loading-container { |
|
||||
padding: 120rpx 40rpx; |
|
||||
text-align: center; |
|
||||
} |
|
||||
|
|
||||
.load-more { |
|
||||
padding: 40rpx 0; |
|
||||
} |
|
||||
|
|
||||
/* 动画效果 */ |
|
||||
.service-card { |
|
||||
animation: slideIn 0.3s ease-out; |
|
||||
} |
|
||||
|
|
||||
@keyframes slideIn { |
|
||||
from { |
|
||||
opacity: 0; |
|
||||
transform: translateY(20rpx); |
|
||||
} |
|
||||
to { |
|
||||
opacity: 1; |
|
||||
transform: translateY(0); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/* 编辑弹窗样式 */ |
|
||||
.edit-modal { |
|
||||
position: fixed; |
|
||||
top: 0; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
bottom: 0; |
|
||||
background-color: rgba(0, 0, 0, 0.5); |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
z-index: 1000; |
|
||||
|
|
||||
.modal-content { |
|
||||
background-color: #2a2a2a; |
|
||||
border-radius: 20rpx; |
|
||||
width: 90%; |
|
||||
max-height: 80%; |
|
||||
overflow: hidden; |
|
||||
border: 1rpx solid #444; |
|
||||
|
|
||||
.modal-header { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: space-between; |
|
||||
padding: 32rpx; |
|
||||
border-bottom: 1rpx solid #444; |
|
||||
|
|
||||
.modal-title { |
|
||||
font-size: 32rpx; |
|
||||
font-weight: 600; |
|
||||
color: #fff; |
|
||||
} |
|
||||
|
|
||||
.modal-close { |
|
||||
width: 48rpx; |
|
||||
height: 48rpx; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
|
|
||||
.iconfont { |
|
||||
font-size: 32rpx; |
|
||||
color: #999; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.modal-body { |
|
||||
padding: 32rpx; |
|
||||
|
|
||||
.form-item { |
|
||||
.form-label { |
|
||||
font-size: 28rpx; |
|
||||
color: #ccc; |
|
||||
margin-bottom: 16rpx; |
|
||||
display: block; |
|
||||
} |
|
||||
|
|
||||
.editor-toolbar { |
|
||||
background-color: #1a1a1a; |
|
||||
border: 1rpx solid #444; |
|
||||
border-bottom: none; |
|
||||
border-radius: 12rpx 12rpx 0 0; |
|
||||
padding: 16rpx; |
|
||||
|
|
||||
.toolbar-group { |
|
||||
display: flex; |
|
||||
gap: 16rpx; |
|
||||
|
|
||||
.tool-btn { |
|
||||
width: 48rpx; |
|
||||
height: 48rpx; |
|
||||
background-color: #444; |
|
||||
border: 1rpx solid #666; |
|
||||
border-radius: 8rpx; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
|
|
||||
&.active { |
|
||||
background-color: #29d3b4; |
|
||||
border-color: #29d3b4; |
|
||||
} |
|
||||
|
|
||||
.tool-text { |
|
||||
font-size: 24rpx; |
|
||||
color: #fff; |
|
||||
font-weight: 600; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.form-textarea { |
|
||||
width: 100%; |
|
||||
min-height: 300rpx; |
|
||||
background-color: #1a1a1a; |
|
||||
border: 1rpx solid #444; |
|
||||
border-radius: 0 0 12rpx 12rpx; |
|
||||
border-top: none; |
|
||||
padding: 20rpx; |
|
||||
font-size: 28rpx; |
|
||||
color: #fff; |
|
||||
line-height: 1.6; |
|
||||
box-sizing: border-box; |
|
||||
|
|
||||
&::placeholder { |
|
||||
color: #666; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.char-count { |
|
||||
text-align: right; |
|
||||
margin-top: 8rpx; |
|
||||
font-size: 24rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
|
|
||||
.editor-tips { |
|
||||
margin-top: 12rpx; |
|
||||
|
|
||||
.tip-text { |
|
||||
font-size: 22rpx; |
|
||||
color: #666; |
|
||||
line-height: 1.4; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.modal-footer { |
|
||||
display: flex; |
|
||||
gap: 24rpx; |
|
||||
padding: 32rpx; |
|
||||
border-top: 1rpx solid #444; |
|
||||
|
|
||||
.modal-btn { |
|
||||
flex: 1; |
|
||||
height: 72rpx; |
|
||||
border-radius: 12rpx; |
|
||||
font-size: 28rpx; |
|
||||
font-weight: 600; |
|
||||
border: none; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
|
|
||||
&.cancel { |
|
||||
background-color: #444; |
|
||||
color: #ccc; |
|
||||
|
|
||||
&:active { |
|
||||
background-color: #555; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
&.confirm { |
|
||||
background-color: #29d3b4; |
|
||||
color: #fff; |
|
||||
|
|
||||
&:active:not(:disabled) { |
|
||||
background-color: #22b39a; |
|
||||
} |
|
||||
|
|
||||
&:disabled { |
|
||||
background-color: #666; |
|
||||
color: #999; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,565 +0,0 @@ |
|||||
<!--服务列表页面--> |
|
||||
<template> |
|
||||
<view class="container dark-theme"> |
|
||||
<view class="header"> |
|
||||
<view class="search-bar"> |
|
||||
<view class="search-input"> |
|
||||
<input |
|
||||
placeholder="搜索服务..." |
|
||||
v-model="searchText" |
|
||||
@input="handleSearch" |
|
||||
/> |
|
||||
</view> |
|
||||
<view class="filter-btn" @click="showFilter"> |
|
||||
<text>筛选</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="service-list"> |
|
||||
<view class="service-item" |
|
||||
v-for="(service, index) in filteredServiceList" |
|
||||
:key="index" |
|
||||
@click="goToDetail(service)"> |
|
||||
<view class="service-header"> |
|
||||
<view class="service-title">{{ service.name }}</view> |
|
||||
<view class="service-badge" :class="[ |
|
||||
service.status === '正常' ? 'badge-success' : '', |
|
||||
service.status === '即将到期' ? 'badge-warning' : '', |
|
||||
service.status === '已过期' ? 'badge-danger' : '', |
|
||||
!['正常', '即将到期', '已过期'].includes(service.status) ? 'badge-default' : '' |
|
||||
]"> |
|
||||
{{ service.status }} |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="service-content"> |
|
||||
<view class="service-meta"> |
|
||||
<view class="meta-item"> |
|
||||
<text class="meta-label">类型:</text> |
|
||||
<text class="meta-value">{{ service.type }}</text> |
|
||||
</view> |
|
||||
<view class="meta-item"> |
|
||||
<text class="meta-label">时长:</text> |
|
||||
<text class="meta-value">{{ service.duration }}</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="service-desc">{{ service.description }}</view> |
|
||||
|
|
||||
<view class="service-footer"> |
|
||||
<view class="service-time"> |
|
||||
{{ service.startTime }} - {{ service.endTime }} |
|
||||
</view> |
|
||||
<view class="service-action"> |
|
||||
<text class="action-text">查看详情</text> |
|
||||
<text class="action-arrow">></text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="empty-state" v-if="filteredServiceList.length === 0"> |
|
||||
<image class="empty-icon" src="/static/icon-img/empty.png"></image> |
|
||||
<view class="empty-text">{{ searchText ? '未找到相关服务' : '暂无服务记录' }}</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 筛选弹窗 --> |
|
||||
<fui-bottom-popup v-model="showFilterPopup" :zIndex="9999"> |
|
||||
<view class="filter-popup"> |
|
||||
<view class="popup-header"> |
|
||||
<view class="popup-title">筛选条件</view> |
|
||||
<view class="popup-close" @click="showFilterPopup = false">✕</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="filter-content"> |
|
||||
<view class="filter-group"> |
|
||||
<view class="filter-title">服务状态</view> |
|
||||
<view class="filter-options"> |
|
||||
<view |
|
||||
class="filter-option" |
|
||||
:class="{ active: selectedStatus === '' }" |
|
||||
@click="selectedStatus = ''" |
|
||||
> |
|
||||
全部 |
|
||||
</view> |
|
||||
<view |
|
||||
class="filter-option" |
|
||||
:class="{ active: selectedStatus === '正常' }" |
|
||||
@click="selectedStatus = '正常'" |
|
||||
> |
|
||||
正常 |
|
||||
</view> |
|
||||
<view |
|
||||
class="filter-option" |
|
||||
:class="{ active: selectedStatus === '即将到期' }" |
|
||||
@click="selectedStatus = '即将到期'" |
|
||||
> |
|
||||
即将到期 |
|
||||
</view> |
|
||||
<view |
|
||||
class="filter-option" |
|
||||
:class="{ active: selectedStatus === '已过期' }" |
|
||||
@click="selectedStatus = '已过期'" |
|
||||
> |
|
||||
已过期 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="popup-actions"> |
|
||||
<view class="btn btn-reset" @click="resetFilter">重置</view> |
|
||||
<view class="btn btn-confirm" @click="applyFilter">确定</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</fui-bottom-popup> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
serviceList: [], |
|
||||
filteredServiceList: [], |
|
||||
searchText: '', |
|
||||
showFilterPopup: false, |
|
||||
selectedStatus: '' |
|
||||
} |
|
||||
}, |
|
||||
onLoad() { |
|
||||
this.init(); |
|
||||
}, |
|
||||
methods: { |
|
||||
async init() { |
|
||||
this.getServiceList(); |
|
||||
}, |
|
||||
|
|
||||
// 获取服务列表 |
|
||||
async getServiceList() { |
|
||||
try { |
|
||||
// 模拟数据,实际应该调用API |
|
||||
this.serviceList = [ |
|
||||
{ |
|
||||
id: 1, |
|
||||
name: '专业体能训练服务', |
|
||||
type: '体能训练', |
|
||||
status: '正常', |
|
||||
duration: '3个月', |
|
||||
startTime: '2024-01-01', |
|
||||
endTime: '2024-03-31', |
|
||||
description: '专业的体能训练指导,包含有氧运动、力量训练等综合项目' |
|
||||
}, |
|
||||
{ |
|
||||
id: 2, |
|
||||
name: '基础动作指导服务', |
|
||||
type: '技术指导', |
|
||||
status: '即将到期', |
|
||||
duration: '1个月', |
|
||||
startTime: '2024-06-01', |
|
||||
endTime: '2024-06-30', |
|
||||
description: '针对基础动作的专业指导和纠正' |
|
||||
}, |
|
||||
{ |
|
||||
id: 3, |
|
||||
name: '营养咨询服务', |
|
||||
type: '营养指导', |
|
||||
status: '正常', |
|
||||
duration: '6个月', |
|
||||
startTime: '2024-01-15', |
|
||||
endTime: '2024-07-15', |
|
||||
description: '专业营养师提供个性化营养方案和饮食建议' |
|
||||
}, |
|
||||
{ |
|
||||
id: 4, |
|
||||
name: '康复训练服务', |
|
||||
type: '康复指导', |
|
||||
status: '已过期', |
|
||||
duration: '2个月', |
|
||||
startTime: '2023-10-01', |
|
||||
endTime: '2023-11-30', |
|
||||
description: '运动损伤康复和预防性训练指导' |
|
||||
} |
|
||||
]; |
|
||||
|
|
||||
this.filteredServiceList = [...this.serviceList]; |
|
||||
|
|
||||
// 实际API调用示例: |
|
||||
// let res = await apiRoute.getServiceList({}); |
|
||||
// if (res.code === 1) { |
|
||||
// this.serviceList = res.data; |
|
||||
// this.filteredServiceList = [...this.serviceList]; |
|
||||
// } |
|
||||
} catch (error) { |
|
||||
console.error('获取服务列表失败:', error); |
|
||||
uni.showToast({ |
|
||||
title: '获取数据失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 搜索处理 |
|
||||
handleSearch() { |
|
||||
this.filterServices(); |
|
||||
}, |
|
||||
|
|
||||
// 筛选服务 |
|
||||
filterServices() { |
|
||||
let filtered = [...this.serviceList]; |
|
||||
|
|
||||
// 按搜索文本筛选 |
|
||||
if (this.searchText) { |
|
||||
filtered = filtered.filter(service => |
|
||||
service.name.includes(this.searchText) || |
|
||||
service.type.includes(this.searchText) || |
|
||||
service.description.includes(this.searchText) |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
// 按状态筛选 |
|
||||
if (this.selectedStatus) { |
|
||||
filtered = filtered.filter(service => service.status === this.selectedStatus); |
|
||||
} |
|
||||
|
|
||||
this.filteredServiceList = filtered; |
|
||||
}, |
|
||||
|
|
||||
// 显示筛选 |
|
||||
showFilter() { |
|
||||
this.showFilterPopup = true; |
|
||||
}, |
|
||||
|
|
||||
// 重置筛选 |
|
||||
resetFilter() { |
|
||||
this.selectedStatus = ''; |
|
||||
this.filterServices(); |
|
||||
}, |
|
||||
|
|
||||
// 应用筛选 |
|
||||
applyFilter() { |
|
||||
this.filterServices(); |
|
||||
this.showFilterPopup = false; |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
// 跳转到详情页 |
|
||||
goToDetail(service) { |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/coach/my/service_detail?id=${service.id}` |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
// 通用样式 |
|
||||
.container { |
|
||||
min-height: 100vh; |
|
||||
} |
|
||||
|
|
||||
// 暗黑主题样式 |
|
||||
.dark-theme { |
|
||||
background-color: #121212; |
|
||||
color: #ffffff; |
|
||||
|
|
||||
.header { |
|
||||
background-color: #181818; |
|
||||
padding: 20rpx; |
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3); |
|
||||
} |
|
||||
|
|
||||
.search-input { |
|
||||
background-color: #1e1e1e; |
|
||||
border-radius: 25rpx; |
|
||||
padding: 15rpx 30rpx; |
|
||||
|
|
||||
input { |
|
||||
width: 100%; |
|
||||
font-size: 28rpx; |
|
||||
color: #ffffff; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.filter-btn { |
|
||||
background-color: #00d18c; |
|
||||
color: #121212; |
|
||||
padding: 15rpx 30rpx; |
|
||||
border-radius: 25rpx; |
|
||||
font-size: 28rpx; |
|
||||
font-weight: bold; |
|
||||
} |
|
||||
|
|
||||
.service-item { |
|
||||
background-color: #1e1e1e; |
|
||||
border-radius: 16rpx; |
|
||||
padding: 30rpx; |
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.3); |
|
||||
margin-bottom: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.service-title { |
|
||||
font-size: 32rpx; |
|
||||
font-weight: bold; |
|
||||
color: #ffffff; |
|
||||
flex: 1; |
|
||||
margin-right: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.service-badge { |
|
||||
padding: 8rpx 16rpx; |
|
||||
border-radius: 20rpx; |
|
||||
font-size: 24rpx; |
|
||||
|
|
||||
&.badge-success { |
|
||||
background-color: rgba(82, 196, 26, 0.2); |
|
||||
color: #52c41a; |
|
||||
border: 1px solid #52c41a; |
|
||||
} |
|
||||
|
|
||||
&.badge-warning { |
|
||||
background-color: rgba(250, 140, 22, 0.2); |
|
||||
color: #fa8c16; |
|
||||
border: 1px solid #fa8c16; |
|
||||
} |
|
||||
|
|
||||
&.badge-danger { |
|
||||
background-color: rgba(255, 77, 79, 0.2); |
|
||||
color: #ff4d4f; |
|
||||
border: 1px solid #ff4d4f; |
|
||||
} |
|
||||
|
|
||||
&.badge-default { |
|
||||
background-color: rgba(102, 102, 102, 0.2); |
|
||||
color: #999; |
|
||||
border: 1px solid #666; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.meta-item { |
|
||||
.meta-label { |
|
||||
color: #b0b0b0; |
|
||||
font-size: 26rpx; |
|
||||
} |
|
||||
|
|
||||
.meta-value { |
|
||||
color: #ffffff; |
|
||||
font-size: 26rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.service-desc { |
|
||||
color: #b0b0b0; |
|
||||
font-size: 26rpx; |
|
||||
line-height: 1.5; |
|
||||
} |
|
||||
|
|
||||
.service-footer { |
|
||||
padding-top: 15rpx; |
|
||||
border-top: 1px solid #333333; |
|
||||
} |
|
||||
|
|
||||
.service-time { |
|
||||
color: #999999; |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
|
|
||||
.service-action { |
|
||||
color: #00d18c; |
|
||||
font-size: 26rpx; |
|
||||
} |
|
||||
|
|
||||
.empty-state { |
|
||||
.empty-icon { |
|
||||
opacity: 0.2; |
|
||||
} |
|
||||
|
|
||||
.empty-text { |
|
||||
color: #b0b0b0; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 筛选弹窗样式 |
|
||||
.filter-popup { |
|
||||
background-color: #1e1e1e; |
|
||||
border-radius: 20rpx 20rpx 0 0; |
|
||||
} |
|
||||
|
|
||||
.popup-header { |
|
||||
border-bottom: 1px solid #333333; |
|
||||
} |
|
||||
|
|
||||
.popup-title { |
|
||||
color: #ffffff; |
|
||||
} |
|
||||
|
|
||||
.popup-close { |
|
||||
color: #b0b0b0; |
|
||||
} |
|
||||
|
|
||||
.filter-title { |
|
||||
color: #ffffff; |
|
||||
} |
|
||||
|
|
||||
.filter-option { |
|
||||
background-color: #282828; |
|
||||
color: #b0b0b0; |
|
||||
|
|
||||
&.active { |
|
||||
background-color: #00d18c; |
|
||||
color: #121212; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.popup-actions { |
|
||||
border-top: 1px solid #333333; |
|
||||
} |
|
||||
|
|
||||
.btn { |
|
||||
&.btn-reset { |
|
||||
background-color: #333333; |
|
||||
color: #ffffff; |
|
||||
} |
|
||||
|
|
||||
&.btn-confirm { |
|
||||
background-color: #00d18c; |
|
||||
color: #121212; |
|
||||
font-weight: bold; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 通用布局样式(不受主题影响的部分) |
|
||||
.search-bar { |
|
||||
display: flex; |
|
||||
gap: 20rpx; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
.search-input { |
|
||||
flex: 1; |
|
||||
} |
|
||||
|
|
||||
.service-list { |
|
||||
padding: 20rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
} |
|
||||
|
|
||||
.service-header { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
margin-bottom: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.service-content { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 15rpx; |
|
||||
} |
|
||||
|
|
||||
.service-meta { |
|
||||
display: flex; |
|
||||
gap: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.meta-item { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
.service-footer { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
.service-action { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
|
|
||||
.action-arrow { |
|
||||
margin-left: 10rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.empty-state { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
padding: 100rpx 0; |
|
||||
|
|
||||
.empty-icon { |
|
||||
width: 120rpx; |
|
||||
height: 120rpx; |
|
||||
margin-bottom: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.empty-text { |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.popup-header { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
padding: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.popup-title { |
|
||||
font-size: 32rpx; |
|
||||
font-weight: bold; |
|
||||
} |
|
||||
|
|
||||
.popup-close { |
|
||||
font-size: 36rpx; |
|
||||
} |
|
||||
|
|
||||
.filter-content { |
|
||||
padding: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.filter-group { |
|
||||
margin-bottom: 40rpx; |
|
||||
} |
|
||||
|
|
||||
.filter-title { |
|
||||
font-size: 28rpx; |
|
||||
font-weight: bold; |
|
||||
margin-bottom: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.filter-options { |
|
||||
display: flex; |
|
||||
flex-wrap: wrap; |
|
||||
gap: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.filter-option { |
|
||||
padding: 15rpx 30rpx; |
|
||||
border-radius: 25rpx; |
|
||||
font-size: 26rpx; |
|
||||
} |
|
||||
|
|
||||
.popup-actions { |
|
||||
display: flex; |
|
||||
gap: 20rpx; |
|
||||
padding: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.btn { |
|
||||
flex: 1; |
|
||||
padding: 20rpx; |
|
||||
border-radius: 12rpx; |
|
||||
text-align: center; |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,168 +0,0 @@ |
|||||
<template> |
|
||||
<view style="height: 100vh;background-color: #fff;"> |
|
||||
<view class="title_style"> |
|
||||
{{arrayInfo.title}} |
|
||||
</view> |
|
||||
<view class="date_style"> |
|
||||
{{arrayInfo.update_time}} |
|
||||
</view> |
|
||||
|
|
||||
<view class="url_style" v-if="arrayInfo.type == 1 && arrayInfo.url"> |
|
||||
<video style="margin: auto;" :src="arrayInfo.url" :enable-progress-gesture="true" |
|
||||
:show-fullscreen-btn="true" :show-play-btn="true" @error="onVideoError" @play="onPlay" |
|
||||
@pause="onPause" /> |
|
||||
</view> |
|
||||
|
|
||||
<view class="url_image_style" v-if="arrayInfo.type == 3 && arrayInfo.url"> |
|
||||
<image :src="arrayInfo.url" mode="aspectFill" @click="clickPreviewImage(arrayInfo.url)" |
|
||||
style="width: 80%;margin: auto;"> |
|
||||
</image> |
|
||||
</view> |
|
||||
|
|
||||
<view class="url_file_style" v-if="arrayInfo.type == 2 && arrayInfo.url"> |
|
||||
<a style="cursor: pointer;color: blue;" @click="previewFile(arrayInfo.url)">素材文件</a> |
|
||||
</view> |
|
||||
|
|
||||
<!-- <view class="con_style" v-html="arrayInfo.content"></view> --> |
|
||||
<jyf-parser class="con_style" :html="arrayInfo.content" :tag-style="tagStyle"></jyf-parser> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
import jyfParser from '@/components/jyf-parser/jyf-parser.vue'; |
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
jyfParser |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
articleId: undefined, |
|
||||
arrayInfo: [], |
|
||||
tagStyle: { |
|
||||
// 设置富文本样式 |
|
||||
p: 'margin:0;padding:0;color:#333333;', |
|
||||
span: 'color:#333333;', |
|
||||
h1: 'color:#333333;', |
|
||||
h2: 'color:#333333;', |
|
||||
h3: 'color:#333333;', |
|
||||
h4: 'color:#333333;', |
|
||||
h5: 'color:#333333;', |
|
||||
h6: 'color:#333333;', |
|
||||
li: 'color:#333333;', |
|
||||
div: 'color:#333333;' |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
this.articleId = options.id; |
|
||||
console.log(this.articleId, 888) |
|
||||
this.init() |
|
||||
}, |
|
||||
methods: { |
|
||||
init() { |
|
||||
apiRoute.teachingResearchInfo(this.articleId).then(res => { |
|
||||
if (res.code == 1) { |
|
||||
this.arrayInfo = res.data |
|
||||
} |
|
||||
}) |
|
||||
}, |
|
||||
clickPreviewImage(url) { |
|
||||
uni.previewImage({ |
|
||||
urls: [url], // 支持多张图预览 |
|
||||
current: url, // 当前显示的图片链接 |
|
||||
success: () => { |
|
||||
console.log('预览成功'); |
|
||||
}, |
|
||||
fail: (err) => { |
|
||||
console.error('预览失败', err); |
|
||||
} |
|
||||
}); |
|
||||
}, |
|
||||
async previewFile(url) { |
|
||||
|
|
||||
console.log(url) |
|
||||
|
|
||||
try { |
|
||||
// 1. 下载文件到本地 |
|
||||
const { |
|
||||
tempFilePath |
|
||||
} = await this.downloadFile(this.$util.img('public/'+url)); |
|
||||
console.log(tempFilePath) |
|
||||
// 2. 打开文件 |
|
||||
await uni.openDocument({ |
|
||||
filePath: this.$util.img(tempFilePath), |
|
||||
showMenu: true, |
|
||||
success: () => { |
|
||||
console.log('打开文档成功'); |
|
||||
} |
|
||||
}); |
|
||||
} catch (err) { |
|
||||
uni.showToast({ |
|
||||
title: '预览失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
console.error('预览失败:', err); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
downloadFile(url) { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
uni.downloadFile({ |
|
||||
url, |
|
||||
success: (res) => { |
|
||||
if (res.statusCode === 200) { |
|
||||
resolve(res); |
|
||||
} else { |
|
||||
reject(new Error('下载失败')); |
|
||||
} |
|
||||
}, |
|
||||
fail: (err) => { |
|
||||
reject(err); |
|
||||
} |
|
||||
}); |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style> |
|
||||
.title_style { |
|
||||
width: 100%; |
|
||||
text-align: center; |
|
||||
font-size: 40rpx; |
|
||||
font-weight: bold; |
|
||||
padding-top: 10px; |
|
||||
} |
|
||||
|
|
||||
.date_style { |
|
||||
width: 100%; |
|
||||
text-align: right; |
|
||||
font-size: 20rpx; |
|
||||
color: #ccc; |
|
||||
padding-right: 16rpx; |
|
||||
margin-top: 10px; |
|
||||
} |
|
||||
|
|
||||
.con_style { |
|
||||
font-size: 30rpx; |
|
||||
padding: 18rpx; |
|
||||
margin-top: 20px; |
|
||||
} |
|
||||
|
|
||||
.url_style { |
|
||||
margin-top: 20px; |
|
||||
text-align: center; |
|
||||
} |
|
||||
|
|
||||
.url_image_style { |
|
||||
padding: 20rpx; |
|
||||
text-align: center; |
|
||||
} |
|
||||
|
|
||||
.url_file_style{ |
|
||||
padding: 20rpx; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,481 +0,0 @@ |
|||||
<template> |
|
||||
<view class="schedule-detail-container"> |
|
||||
<!-- 页面加载状态 --> |
|
||||
<view class="loading-container" v-if="loading"> |
|
||||
<fui-loading></fui-loading> |
|
||||
<text class="loading-text">加载中...</text> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 错误状态显示 --> |
|
||||
<view class="error-container" v-else-if="error"> |
|
||||
<text class="error-text">{{ errorMessage }}</text> |
|
||||
<view class="retry-btn" @click="fetchScheduleDetail"> |
|
||||
<text>重试</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="schedule-content" v-else> |
|
||||
<!-- 课程基本信息 --> |
|
||||
<view class="schedule-header"> |
|
||||
<view class="course-title"> |
|
||||
<text>{{ scheduleDetail.title || '暂无课程名称' }}</text> |
|
||||
<text class="status-tag" :class="statusClass">{{ statusText }}</text> |
|
||||
</view> |
|
||||
<view class="course-time">{{ scheduleDetail.course_date || '' }} {{ scheduleDetail.time_slot || '' }}</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 课程详细信息 --> |
|
||||
<view class="info-card"> |
|
||||
<view class="info-item"> |
|
||||
<text class="info-label">授课教师:</text> |
|
||||
<text class="info-value">{{ scheduleDetail.coach?.name || '未设置' }}</text> |
|
||||
</view> |
|
||||
<view class="info-item"> |
|
||||
<text class="info-label">教室:</text> |
|
||||
<text class="info-value">{{ scheduleDetail.venue?.venue_name || '未设置' }}</text> |
|
||||
</view> |
|
||||
<view class="info-item"> |
|
||||
<text class="info-label">当前人数:</text> |
|
||||
<text class="info-value">{{ studentCount }}/{{ scheduleDetail.venue?.capacity || 0 }}</text> |
|
||||
</view> |
|
||||
<view class="info-item"> |
|
||||
<text class="info-label">课程内容:</text> |
|
||||
<text class="info-value">{{ scheduleDetail.content || '未设置上课内容' }}</text> |
|
||||
</view> |
|
||||
<view class="info-item" v-if="scheduleDetail.remark"> |
|
||||
<text class="info-label">备注:</text> |
|
||||
<text class="info-value">{{ scheduleDetail.remark }}</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 学员列表 --> |
|
||||
<view class="student-list-section"> |
|
||||
<view class="section-title"> |
|
||||
<text>学员列表</text> |
|
||||
</view> |
|
||||
<view class="student-list" v-if="scheduleDetail.student_courses && scheduleDetail.student_courses.length > 0"> |
|
||||
<view class="student-item" v-for="(student, index) in scheduleDetail.student_courses" :key="index"> |
|
||||
<view class="student-avatar"> |
|
||||
<image :src="$util.img(student.avatar)" mode="aspectFill"></image> |
|
||||
</view> |
|
||||
<view class="student-info"> |
|
||||
<text class="student-name">{{ student.name }}</text> |
|
||||
<text class="student-status" :class="{'signed': student.status === 'signed'}"> |
|
||||
{{ student.status === 'signed' ? '已签到' : '未签到' }} |
|
||||
</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="empty-list" v-else> |
|
||||
<text>暂无学员参与此课程</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 底部按钮区域 --> |
|
||||
<view class="footer-actions"> |
|
||||
<view class="action-btn adjust-btn" @click="handleAdjustClass"> |
|
||||
<text>调课</text> |
|
||||
</view> |
|
||||
<view class="action-btn sign-btn" @click="handleSignIn"> |
|
||||
<text>点名</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 引入课程详情组件 --> |
|
||||
<schedule-detail |
|
||||
:visible="showDetailPopup" |
|
||||
:scheduleId="scheduleId" |
|
||||
@update:visible="showDetailPopup = $event" |
|
||||
@sign-in="onSignIn" |
|
||||
@adjust-class="onAdjustClass" |
|
||||
></schedule-detail> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import apiRoute from '@/api/apiRoute.js' |
|
||||
import ScheduleDetail from '@/components/schedule/ScheduleDetail.vue' |
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
ScheduleDetail |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
scheduleId: '', // 课程安排ID |
|
||||
loading: false, |
|
||||
error: false, |
|
||||
errorMessage: '加载失败,请重试', |
|
||||
scheduleDetail: {}, |
|
||||
studentCount: 0, |
|
||||
showDetailPopup: false |
|
||||
} |
|
||||
}, |
|
||||
computed: { |
|
||||
// 课程状态文本和样式 |
|
||||
statusText() { |
|
||||
if (!this.scheduleDetail.student_courses || !this.scheduleDetail.student_courses[0]) { |
|
||||
return '未开始'; |
|
||||
} |
|
||||
|
|
||||
const now = new Date(); |
|
||||
const startDate = this.scheduleDetail.student_courses[0].start_date ? |
|
||||
new Date(this.scheduleDetail.student_courses[0].start_date) : null; |
|
||||
const endDate = this.scheduleDetail.student_courses[0].end_date ? |
|
||||
new Date(this.scheduleDetail.student_courses[0].end_date) : null; |
|
||||
|
|
||||
if (startDate && endDate) { |
|
||||
if (now >= startDate && now <= endDate) { |
|
||||
return '上课中'; |
|
||||
} else if (now > endDate) { |
|
||||
return '已结束'; |
|
||||
} else if (now < startDate) { |
|
||||
return '未开始'; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return '未开始'; |
|
||||
}, |
|
||||
statusClass() { |
|
||||
switch (this.statusText) { |
|
||||
case '上课中': |
|
||||
return 'status-in-progress'; |
|
||||
case '已结束': |
|
||||
return 'status-ended'; |
|
||||
case '未开始': |
|
||||
default: |
|
||||
return 'status-not-started'; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
if (options.id) { |
|
||||
this.scheduleId = options.id; |
|
||||
this.fetchScheduleDetail(); |
|
||||
} else { |
|
||||
this.error = true; |
|
||||
this.errorMessage = '未找到课程安排ID'; |
|
||||
} |
|
||||
}, |
|
||||
methods: { |
|
||||
// 获取课程详情 |
|
||||
async fetchScheduleDetail() { |
|
||||
if (!this.scheduleId) { |
|
||||
this.error = true; |
|
||||
this.errorMessage = '课程ID不能为空'; |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
this.loading = true; |
|
||||
this.error = false; |
|
||||
|
|
||||
try { |
|
||||
// 使用新接口获取课程安排详情 |
|
||||
const res = await apiRoute.getCourseScheduleInfo({ |
|
||||
id: this.scheduleId |
|
||||
}); |
|
||||
|
|
||||
if (res.code === 1 && res.data) { |
|
||||
this.scheduleDetail = res.data; |
|
||||
// 计算学生数量 |
|
||||
this.studentCount = this.scheduleDetail.student_courses ? |
|
||||
this.scheduleDetail.student_courses.length : 0; |
|
||||
} else { |
|
||||
// 如果新接口不可用,尝试使用旧接口 |
|
||||
const fallbackRes = await apiRoute.courseInfo({ |
|
||||
id: this.scheduleId |
|
||||
}); |
|
||||
|
|
||||
if (fallbackRes.code === 1 && fallbackRes.data) { |
|
||||
this.scheduleDetail = fallbackRes.data; |
|
||||
this.studentCount = this.scheduleDetail.student_courses ? |
|
||||
this.scheduleDetail.student_courses.length : 0; |
|
||||
} else { |
|
||||
throw new Error(res.msg || fallbackRes.msg || '获取课程详情失败'); |
|
||||
} |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.error('获取课程详情失败:', error); |
|
||||
this.error = true; |
|
||||
this.errorMessage = error.message || '获取课程详情失败,请重试'; |
|
||||
} finally { |
|
||||
this.loading = false; |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 点名功能 |
|
||||
handleSignIn() { |
|
||||
// 如果课程已结束,显示提示 |
|
||||
if (this.statusText === '已结束') { |
|
||||
uni.showToast({ |
|
||||
title: '课程已结束,无法点名', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
// 如果没有学生,显示提示 |
|
||||
if (!this.scheduleDetail.student_courses || this.scheduleDetail.student_courses.length === 0) { |
|
||||
uni.showToast({ |
|
||||
title: '暂无学员,无法点名', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
// 显示点名界面或跳转至点名页面 |
|
||||
uni.navigateTo({ |
|
||||
url: `/pages/coach/schedule/sign_in?id=${this.scheduleId}` |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
// 调课功能 |
|
||||
handleAdjustClass() { |
|
||||
// 如果课程已结束,显示提示 |
|
||||
if (this.statusText === '已结束') { |
|
||||
uni.showToast({ |
|
||||
title: '课程已结束,无法调课', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
// 跳转至调课页面 |
|
||||
uni.navigateTo({ |
|
||||
url: `/pages/coach/schedule/adjust_course?id=${this.scheduleId}` |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
// 从弹窗组件中点名处理 |
|
||||
onSignIn(data) { |
|
||||
console.log('处理点名:', data); |
|
||||
uni.navigateTo({ |
|
||||
url: `/pages/coach/schedule/sign_in?id=${data.scheduleId}` |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
// 从弹窗组件中调课处理 |
|
||||
onAdjustClass(data) { |
|
||||
console.log('处理调课:', data); |
|
||||
uni.navigateTo({ |
|
||||
url: `/pages/coach/schedule/adjust_course?id=${data.scheduleId}` |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
// 显示弹窗 |
|
||||
showPopup() { |
|
||||
this.showDetailPopup = true; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.schedule-detail-container { |
|
||||
background-color: #292929; |
|
||||
min-height: 100vh; |
|
||||
padding-bottom: 140rpx; // 为底部按钮留出空间 |
|
||||
} |
|
||||
|
|
||||
.loading-container, .error-container { |
|
||||
height: 100vh; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
} |
|
||||
|
|
||||
.loading-text, .error-text { |
|
||||
margin-top: 30rpx; |
|
||||
font-size: 28rpx; |
|
||||
color: #ccc; |
|
||||
} |
|
||||
|
|
||||
.retry-btn { |
|
||||
margin-top: 30rpx; |
|
||||
padding: 12rpx 30rpx; |
|
||||
background-color: #29d3b4; |
|
||||
border-radius: 8rpx; |
|
||||
color: #fff; |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
|
|
||||
.schedule-content { |
|
||||
padding: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.schedule-header { |
|
||||
margin-bottom: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.course-title { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
font-size: 36rpx; |
|
||||
font-weight: bold; |
|
||||
color: #fff; |
|
||||
margin-bottom: 16rpx; |
|
||||
} |
|
||||
|
|
||||
.status-tag { |
|
||||
font-size: 24rpx; |
|
||||
padding: 4rpx 16rpx; |
|
||||
border-radius: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.status-in-progress { |
|
||||
background-color: #FAD24E; |
|
||||
color: #333; |
|
||||
} |
|
||||
|
|
||||
.status-ended { |
|
||||
background-color: #e2e2e2; |
|
||||
color: #333; |
|
||||
} |
|
||||
|
|
||||
.status-not-started { |
|
||||
background-color: #1cd188; |
|
||||
color: #fff; |
|
||||
} |
|
||||
|
|
||||
.course-time { |
|
||||
font-size: 28rpx; |
|
||||
color: #FAD24E; |
|
||||
margin-bottom: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.info-card { |
|
||||
background-color: #434544; |
|
||||
border-radius: 16rpx; |
|
||||
padding: 24rpx; |
|
||||
margin-bottom: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.info-item { |
|
||||
display: flex; |
|
||||
margin-bottom: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.info-label { |
|
||||
width: 160rpx; |
|
||||
font-size: 26rpx; |
|
||||
color: #ccc; |
|
||||
} |
|
||||
|
|
||||
.info-value { |
|
||||
flex: 1; |
|
||||
font-size: 26rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
|
|
||||
.student-list-section { |
|
||||
background-color: #434544; |
|
||||
border-radius: 16rpx; |
|
||||
padding: 24rpx; |
|
||||
} |
|
||||
|
|
||||
.section-title { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
padding-bottom: 16rpx; |
|
||||
border-bottom: 1px solid #555; |
|
||||
margin-bottom: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.section-title text { |
|
||||
font-size: 28rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
|
|
||||
.student-list { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.student-item { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
.student-avatar { |
|
||||
width: 80rpx; |
|
||||
height: 80rpx; |
|
||||
border-radius: 50%; |
|
||||
overflow: hidden; |
|
||||
background-color: #555; |
|
||||
margin-right: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.student-avatar image { |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
} |
|
||||
|
|
||||
.student-info { |
|
||||
flex: 1; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
.student-name { |
|
||||
font-size: 28rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
|
|
||||
.student-status { |
|
||||
font-size: 24rpx; |
|
||||
color: #ff6b6b; |
|
||||
background: rgba(255, 107, 107, 0.1); |
|
||||
padding: 4rpx 12rpx; |
|
||||
border-radius: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.student-status.signed { |
|
||||
color: #1cd188; |
|
||||
background: rgba(28, 209, 136, 0.1); |
|
||||
} |
|
||||
|
|
||||
.empty-list { |
|
||||
padding: 40rpx 0; |
|
||||
text-align: center; |
|
||||
color: #999; |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
|
|
||||
.footer-actions { |
|
||||
position: fixed; |
|
||||
bottom: 0; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
display: flex; |
|
||||
padding: 30rpx; |
|
||||
gap: 20rpx; |
|
||||
background-color: #292929; |
|
||||
border-top: 1px solid #434544; |
|
||||
} |
|
||||
|
|
||||
.action-btn { |
|
||||
flex: 1; |
|
||||
height: 80rpx; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
border-radius: 8rpx; |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
|
|
||||
.adjust-btn { |
|
||||
background-color: #555; |
|
||||
color: #fff; |
|
||||
} |
|
||||
|
|
||||
.sign-btn { |
|
||||
background-color: #29d3b4; |
|
||||
color: #fff; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,599 +0,0 @@ |
|||||
<!--学员-详情--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<!--学员信息--> |
|
||||
<view class="user_section"> |
|
||||
<view class="box"> |
|
||||
<view class="left"> |
|
||||
<image class="pic" :src="studentsInfo.customerResources.member.headimg"></image> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="item"> |
|
||||
<view class="name">{{ studentsInfo.name }}</view> |
|
||||
<view class="age"> |
|
||||
{{ studentsInfo.customerResources.age }}岁 |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="item"> |
|
||||
<view class="title">电话:{{ studentsInfo.customerResources.phone_number }}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="main_section"> |
|
||||
<view class="section_box"> |
|
||||
<view class="tag_box"> |
|
||||
<view :class="['item', tabType=='1' ? 'select':'']" @click="tabChange(1)">出勤记录</view> |
|
||||
<view :class="['item', tabType=='2' ? 'select':'']" @click="tabChange(2)">体侧报告</view> |
|
||||
</view> |
|
||||
|
|
||||
<!--作业列表--> |
|
||||
<view v-if="tabType=='1'" class="section_1"> |
|
||||
<view class="ul"> |
|
||||
<view class="li" |
|
||||
v-for="(v,k) in assignmentsList" |
|
||||
:key="k" |
|
||||
@click="opebViewWorkDetails(v)"> |
|
||||
<view class="left"> |
|
||||
<view class="title">{{ v.courses_name }}</view> |
|
||||
<view class="date">上课时间:{{ v.submit_time }}</view> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view v-if="v.status==1" class="btn" style="background-color: #e2e2e2;">作业未提交</view> |
|
||||
<view v-else-if="v.status==2" class="btn" style="background-color: #a4adb3;">待批改</view> |
|
||||
<view v-else-if="v.status==3" class="btn" style="background-color: #29d3b4;">作业已完成</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
|
|
||||
<!--评测报告--> |
|
||||
<view v-if="tabType=='2'" class="section_2"> |
|
||||
<scroll-view |
|
||||
class="ul" |
|
||||
scroll-y="true" |
|
||||
:lower-threshold="lowerThreshold" |
|
||||
@scrolltolower="loadMoreData" |
|
||||
style="height: 65vh;" |
|
||||
> |
|
||||
<view |
|
||||
class="li" |
|
||||
v-for="(v,k) in surveyList" |
|
||||
:key="k" @click="openViewPhysicalExamination(v)" |
|
||||
> |
|
||||
<view class="top"> |
|
||||
<view class="title">综合评分:{{ v.calculateChildHealthScore }}</view> |
|
||||
<!-- <view class="hint">打败了99%学员</view>--> |
|
||||
</view> |
|
||||
<view class="bottom">测试时间:{{ $util.formatToDateTime(v.created_at, 'Y-m-d') }}</view> |
|
||||
</view> |
|
||||
</scroll-view> |
|
||||
</view> |
|
||||
|
|
||||
|
|
||||
</view> |
|
||||
|
|
||||
</view> |
|
||||
|
|
||||
<!-- 底部导航--> |
|
||||
<!-- <AQTabber/>--> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import memberApi from '@/api/member.js' |
|
||||
import AQTabber from '@/components/AQ/AQTabber.vue' |
|
||||
import apiRoute from '@/api/apiRoute.js' |
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
tabType: '1',//1=班级成员,2=作业任务 |
|
||||
Atype: 1,//1=作业完成,2=作业未提交 |
|
||||
|
|
||||
students_id: '',//学生id |
|
||||
studentsInfo: {},// 学生详情 |
|
||||
assignmentsList: [],// 作业列表 |
|
||||
|
|
||||
loading: false,//加载状态 |
|
||||
lowerThreshold: 100,//距离底部多远触发 |
|
||||
isReachedBottom: false,//防止重复加载|true=不可加载|false=可加载 |
|
||||
|
|
||||
//筛选条件 |
|
||||
filteredData: { |
|
||||
page: 1,//当前页码 |
|
||||
limit: 10,//每页返回数据条数 |
|
||||
total: 10,//数据总条数 |
|
||||
user_id: '',//学员id |
|
||||
}, |
|
||||
surveyList: [],//体测报告列表 |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
this.students_id = options.students_id//学生id |
|
||||
}, |
|
||||
onShow() { |
|
||||
this.init()//初始化 |
|
||||
}, |
|
||||
methods: { |
|
||||
//初始化 |
|
||||
async init() { |
|
||||
//获取学生详情 |
|
||||
await this.getStudentsInfo() |
|
||||
await this.getSurveyList() |
|
||||
}, |
|
||||
formatAgeMonth(input) { |
|
||||
let str = String(input) |
|
||||
// 分割小数点前后部分 |
|
||||
let [yearPart, monthPart] = str.split('.') |
|
||||
// 如果没有小数部分,默认为 0 |
|
||||
if (!monthPart) { |
|
||||
monthPart = '00' |
|
||||
} |
|
||||
// 如果是 00,则显示为 0 |
|
||||
monthPart = monthPart === '00' ? '0' : monthPart |
|
||||
return `${yearPart}岁${monthPart}月` |
|
||||
}, |
|
||||
//获取学生详情 |
|
||||
async getStudentsInfo() { |
|
||||
let data = { |
|
||||
students_id: this.students_id, |
|
||||
} |
|
||||
let res = await apiRoute.jlStudentsInfo(data) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none', |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.studentsInfo = res.data//学生信息 |
|
||||
|
|
||||
this.assignmentsList = res.data.physical_test//作业列表 |
|
||||
this.filteredData.user_id = res.data.user_id |
|
||||
|
|
||||
}, |
|
||||
// 检查 expire_time 是否大于等于当前时间 5 天 |
|
||||
checkExpireTime(expireTime = '') { |
|
||||
if (!expireTime) { |
|
||||
return false |
|
||||
} |
|
||||
|
|
||||
const expireDate = new Date(expireTime) |
|
||||
const currentDate = new Date() |
|
||||
|
|
||||
// 计算天数差 |
|
||||
const timeDifference = expireDate - currentDate |
|
||||
const daysDifference = timeDifference / (1000 * 60 * 60 * 24) |
|
||||
|
|
||||
if (daysDifference >= 5) { |
|
||||
return true |
|
||||
} else { |
|
||||
return false |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
//加载更多(下一页) |
|
||||
loadMoreData() { |
|
||||
//判断是否加载 |
|
||||
if (!this.isReachedBottom) { |
|
||||
this.isReachedBottom = true//设置为不可请求状态 |
|
||||
this.getSurveyList() |
|
||||
} |
|
||||
}, |
|
||||
//重置为第一页 |
|
||||
async resetFilteredData() { |
|
||||
this.isReachedBottom = false // 重置状态,以便下次触发加载更多 |
|
||||
|
|
||||
this.filteredData.page = 1//当前页码 |
|
||||
this.filteredData.limit = 10//每页返回数据条数 |
|
||||
this.filteredData.total = 10//数据总条数 |
|
||||
}, |
|
||||
//获取学生评测报告列表 |
|
||||
async getSurveyList() { |
|
||||
this.loading = true |
|
||||
|
|
||||
let data = { ...this.filteredData } |
|
||||
|
|
||||
//判断是否还有数据 |
|
||||
if ((this.filteredData.page - 1) * this.filteredData.limit >= this.filteredData.total) { |
|
||||
this.loading = false |
|
||||
uni.showToast({ |
|
||||
title: '暂无更多', |
|
||||
icon: 'none', |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
if (data.page == 1) { |
|
||||
this.surveyList = [] |
|
||||
} |
|
||||
|
|
||||
//学员-体测列表 |
|
||||
let res = await apiRoute.physicalTest(data) |
|
||||
this.loading = false |
|
||||
this.isReachedBottom = false |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none', |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
console.log(res, 111) |
|
||||
|
|
||||
this.surveyList = this.surveyList.concat(res.data.physical_test.data) // 使用 concat 方法 将新数据追加到数组中 |
|
||||
|
|
||||
console.log('列表', this.surveyList) |
|
||||
this.filteredData.total = res.data.total |
|
||||
this.filteredData.page++ |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
//切换tab |
|
||||
tabChange(tabType) { |
|
||||
this.tabType = tabType |
|
||||
}, |
|
||||
|
|
||||
//打开课程详情 |
|
||||
openViewCourseInfo(item) { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/coach/course/info', |
|
||||
}) |
|
||||
}, |
|
||||
//打开学员详情页 |
|
||||
openViewStudentInfo(item) { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/coach/student/info', |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//打开体测报告 |
|
||||
openViewPhysicalExamination(item) { |
|
||||
let survey_id = item.id |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/coach/student/physical_examination?survey_id=${survey_id}`, |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//打开作业任务 |
|
||||
opebViewWorkDetails(item) { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/coach/student/work_details', |
|
||||
}) |
|
||||
}, |
|
||||
}, |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
|
|
||||
.main_box { |
|
||||
background: #292929; |
|
||||
min-height: 100vh; |
|
||||
} |
|
||||
|
|
||||
//自定义导航栏 |
|
||||
.navbar_section { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
background: #292929; |
|
||||
|
|
||||
.title { |
|
||||
padding: 40rpx 0rpx; |
|
||||
|
|
||||
/* 小程序端样式 */ |
|
||||
// #ifdef MP-WEIXIN |
|
||||
padding: 80rpx 0rpx; |
|
||||
// #endif |
|
||||
|
|
||||
font-size: 30rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//学员信息 |
|
||||
.user_section { |
|
||||
background-color: #29D3B4; |
|
||||
padding-top: 58rpx; |
|
||||
padding-bottom: 42rpx; |
|
||||
|
|
||||
.box { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
gap: 15rpx; |
|
||||
|
|
||||
.left { |
|
||||
position: relative; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
width: 120rpx; |
|
||||
|
|
||||
.pic { |
|
||||
width: 92rpx; |
|
||||
height: 92rpx; |
|
||||
border-radius: 50%; |
|
||||
} |
|
||||
|
|
||||
.btn_box { |
|
||||
position: absolute; |
|
||||
bottom: -18rpx; |
|
||||
|
|
||||
.btn { |
|
||||
width: 120rpx; |
|
||||
height: 38rpx; |
|
||||
line-height: 40rpx; |
|
||||
border-radius: 4rpx; |
|
||||
background-color: rgba(245, 154, 35, 1); |
|
||||
color: rgba(255, 255, 255, 1); |
|
||||
font-size: 20rpx; |
|
||||
text-align: center; |
|
||||
border: 0rpx solid rgba(121, 121, 121, 1); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
.right { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 18rpx; |
|
||||
|
|
||||
.item { |
|
||||
color: #fff; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
|
|
||||
.name { |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
|
|
||||
.age { |
|
||||
margin-left: 20rpx; |
|
||||
width: 128rpx; |
|
||||
height: 42rpx; |
|
||||
line-height: 42rpx; |
|
||||
border-radius: 34rpx; |
|
||||
background-color: rgba(255, 255, 255, 1); |
|
||||
color: rgba(51, 51, 51, 1); |
|
||||
font-size: 28rpx; |
|
||||
text-align: center; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//课程信息 |
|
||||
.course_section { |
|
||||
position: relative; |
|
||||
|
|
||||
.main { |
|
||||
position: relative; |
|
||||
z-index: 2; |
|
||||
padding: 0 24rpx; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
|
|
||||
.course_box { |
|
||||
padding: 42rpx 28rpx; |
|
||||
width: 692rpx; |
|
||||
border-radius: 20rpx; |
|
||||
background-color: #fff; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 20rpx; |
|
||||
position: relative; |
|
||||
|
|
||||
.item { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 22rpx; |
|
||||
|
|
||||
.title { |
|
||||
font-size: 28rpx; |
|
||||
color: #333333; |
|
||||
} |
|
||||
|
|
||||
.pic { |
|
||||
width: 58rpx; |
|
||||
height: 58rpx; |
|
||||
border-radius: 50%; |
|
||||
} |
|
||||
|
|
||||
.name { |
|
||||
color: #333333; |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
|
|
||||
.content { |
|
||||
color: #AAAAAA; |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.tag { |
|
||||
position: absolute; |
|
||||
right: 0; |
|
||||
top: 0; |
|
||||
width: 110rpx; |
|
||||
height: 60rpx; |
|
||||
line-height: 60rpx; |
|
||||
border-radius: 0rpx 24rpx 0rpx 24rpx; |
|
||||
background-color: rgba(236, 128, 141, 1); |
|
||||
color: rgba(255, 255, 255, 1); |
|
||||
font-size: 24rpx; |
|
||||
text-align: center; |
|
||||
} |
|
||||
|
|
||||
.btn { |
|
||||
position: absolute; |
|
||||
right: 30rpx; |
|
||||
bottom: 50rpx; |
|
||||
width: 130rpx; |
|
||||
height: 48rpx; |
|
||||
line-height: 48rpx; |
|
||||
border-radius: 10rpx; |
|
||||
background-color: rgba(41, 211, 180, 0); |
|
||||
color: rgba(50, 219, 224, 1); |
|
||||
font-size: 24rpx; |
|
||||
text-align: center; |
|
||||
font-family: -regular; |
|
||||
border: 2rpx solid rgba(50, 219, 224, 1); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.bg_box { |
|
||||
z-index: 1; |
|
||||
width: 100%; |
|
||||
height: 150rpx; |
|
||||
} |
|
||||
|
|
||||
.bg_top { |
|
||||
position: absolute; |
|
||||
top: 0; |
|
||||
background-color: #29D3B4; |
|
||||
} |
|
||||
|
|
||||
.bg_bottom { |
|
||||
top: 50%; |
|
||||
position: absolute; |
|
||||
background-color: #292929; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.main_section { |
|
||||
background: #292929 100%; |
|
||||
padding: 0 24rpx; |
|
||||
padding-top: 40rpx; |
|
||||
padding-bottom: 150rpx; |
|
||||
font-size: 24rpx; |
|
||||
color: #333333; |
|
||||
|
|
||||
.section_box { |
|
||||
background: #fff; |
|
||||
border-radius: 16rpx; |
|
||||
padding: 34rpx 24rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
gap: 38rpx; |
|
||||
|
|
||||
.tag_box { |
|
||||
width: 100%; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
gap: 112rpx; |
|
||||
|
|
||||
.item { |
|
||||
width: 112rpx; |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
|
|
||||
.select { |
|
||||
color: #29D3B4; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//出勤记录 |
|
||||
.section_1 { |
|
||||
width: 100%; |
|
||||
|
|
||||
.ul { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 12rpx; |
|
||||
|
|
||||
.li { |
|
||||
padding: 30rpx 20rpx; |
|
||||
border: 1px solid #29D3B4; |
|
||||
border-radius: 18rpx; |
|
||||
background-color: rgba(41, 211, 180, 0.16); |
|
||||
font-size: 26rpx; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
|
|
||||
.left { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 15rpx; |
|
||||
} |
|
||||
|
|
||||
.right { |
|
||||
.btn { |
|
||||
width: 110rpx; |
|
||||
height: 44rpx; |
|
||||
line-height: 44rpx; |
|
||||
border-radius: 8rpx; |
|
||||
background-color: rgba(41, 211, 180, 1); |
|
||||
color: rgba(255, 255, 255, 1); |
|
||||
font-size: 20rpx; |
|
||||
text-align: center; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//体测报告 |
|
||||
.section_2 { |
|
||||
width: 100%; |
|
||||
|
|
||||
.ul { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
|
|
||||
.li { |
|
||||
margin-bottom: 12rpx; |
|
||||
padding: 30rpx 20rpx; |
|
||||
border: 1px solid #29D3B4; |
|
||||
border-radius: 18rpx; |
|
||||
background-color: rgba(41, 211, 180, 0.16); |
|
||||
font-size: 26rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 20rpx; |
|
||||
|
|
||||
.top { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 40rpx; |
|
||||
|
|
||||
.title { |
|
||||
font-size: 34rpx; |
|
||||
} |
|
||||
|
|
||||
.hint { |
|
||||
color: #F59A23; |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.bottom { |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
|
|
||||
</style> |
|
||||
@ -1,499 +0,0 @@ |
|||||
<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() { |
|
||||
this.$navigateToPage(`/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> |
|
||||
@ -1,130 +0,0 @@ |
|||||
<!--作业详情--> |
|
||||
<template> |
|
||||
<view class="dark-theme"> |
|
||||
<!-- 作业展示--> |
|
||||
<view class="top-style" v-if="infoData.content_text"> |
|
||||
<video v-if="infoData.content_type == 2" class="pic" style="width: 100%;border-radius: 15rpx;" :src="$util.img(infoData.content_text)"></video> |
|
||||
<image v-if="infoData.content_type == 1" style="width: 100%;border-radius: 15rpx;" :src="$util.img(infoData.content_text)" mode="aspectFit"></image> |
|
||||
|
|
||||
<view v-if="infoData.content_type == 3" class="multi-line-ellipsis" v-html="infoData.content_text"></view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 简练信息+作业描述--> |
|
||||
<view class="below-style"> |
|
||||
<view class="head-img"> |
|
||||
<!--教练头像--> |
|
||||
<fui-avatar width="80" :src="$util.img(infoData.coach_pic)"></fui-avatar> |
|
||||
<view class="head-text">{{infoData.coach_name}}</view> |
|
||||
</view> |
|
||||
<view class="multi-line-ellipsis" v-html="infoData.description"></view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
<script> |
|
||||
import memberApi from '@/api/member.js'; |
|
||||
|
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
//筛选条件 |
|
||||
filteredData: { |
|
||||
id: '',//作业id |
|
||||
}, |
|
||||
|
|
||||
infoData: {}, |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
this.filteredData.id = options.id || '1' // 默认ID为1 |
|
||||
// 使用模拟数据 |
|
||||
// this.mockData() |
|
||||
}, |
|
||||
onShow(){ |
|
||||
this.init() // 初始化数据 - 已注释 |
|
||||
}, |
|
||||
methods: { |
|
||||
//初始化 |
|
||||
async init(){ |
|
||||
this.getAssignmentsInfo() // 已注释 |
|
||||
}, |
|
||||
|
|
||||
// 模拟数据 |
|
||||
mockData() { |
|
||||
this.infoData = { |
|
||||
student_file: '/static/icon-img/empty.png', |
|
||||
student_file_type: 1, // 1-图片,2-视频 |
|
||||
coach_pic: '/static/icon-img/default_avatar.png', |
|
||||
coach_name: '张教练', |
|
||||
content_text: '<p>这是一份作业的详细说明,包含了作业的要求和注意事项。</p><p>1. 请按照要求完成动作练习</p><p>2. 注意动作的标准性和连贯性</p><p>3. 完成后请上传视频或图片记录</p>' |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
//获取作业详情 - 已注释 |
|
||||
|
|
||||
async getAssignmentsInfo() { |
|
||||
let params = {...this.filteredData} |
|
||||
let res = await memberApi.assignmentsInfo(params) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.infoData = res.data |
|
||||
}, |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.dark-theme { |
|
||||
background-color: #121212; |
|
||||
color: #ffffff; |
|
||||
min-height: 100vh; |
|
||||
padding-top: 0; |
|
||||
} |
|
||||
|
|
||||
.top-style{ |
|
||||
width: 92%; |
|
||||
height: 500rpx; |
|
||||
margin: auto; |
|
||||
margin-top: 0; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
background-color: #1e1e1e; |
|
||||
border-radius: 15rpx; |
|
||||
} |
|
||||
.top-style-img{ |
|
||||
width: 120rpx; |
|
||||
height: 120rpx; |
|
||||
} |
|
||||
.below-style{ |
|
||||
width: 92%; |
|
||||
margin: auto; |
|
||||
background-color: #1e1e1e; |
|
||||
border-radius: 15rpx; |
|
||||
margin-top: 20rpx; |
|
||||
padding: 20rpx 0; |
|
||||
} |
|
||||
.head-img { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
padding: 10rpx 20rpx; |
|
||||
} |
|
||||
.head-text { |
|
||||
color: #ffffff; |
|
||||
font-size: 35rpx; |
|
||||
padding-left: 20rpx; |
|
||||
} |
|
||||
.multi-line-ellipsis { |
|
||||
color: #e0e0e0; |
|
||||
font-size: 29rpx; |
|
||||
padding: 20rpx 30rpx; |
|
||||
line-height: 1.6; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,765 +0,0 @@ |
|||||
<!--订单列表-列表--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
|
|
||||
<view class="main_section"> |
|
||||
<scroll-view |
|
||||
class="section_1" |
|
||||
scroll-y="true" |
|
||||
:lower-threshold="lowerThreshold" |
|
||||
@scrolltolower="loadMoreData" |
|
||||
style="height: 83vh;" |
|
||||
> |
|
||||
<view |
|
||||
class="item" |
|
||||
v-for="(v,k) in tableList" |
|
||||
:key="k" |
|
||||
> |
|
||||
<view class="top"> |
|
||||
<view class="title">订单状态:{{v.order_status == 'pending' ? '待支付':'已支付' }}</view> |
|
||||
<!-- <view class="btn" @click="downloadFile($util.img(v.file_data))">下载合同 <fui-icon name="arrowright" color="#A4ADB3" size="35"></fui-icon></view>--> |
|
||||
</view> |
|
||||
<view class="bottom"> |
|
||||
<view class="box"> |
|
||||
<view class="title">客户姓名:</view> |
|
||||
<view class="content">{{ v.resource_id_name || ''}}</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="box"> |
|
||||
<view class="title">付款类型:</view> |
|
||||
<view class="content"> |
|
||||
{{ v.payment_type === 'cash' ? '现金支付' : v.payment_type === 'scan_code' ? '扫码支付' : '订阅支付' }} |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="box"> |
|
||||
<view class="title">订单金额:</view> |
|
||||
<view class="content">¥{{ v.order_amount || ''}}</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="box"> |
|
||||
<view class="title">课程:</view> |
|
||||
<view class="content">{{ v.course_id_name || ''}}</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="box"> |
|
||||
<view class="title">班级:</view> |
|
||||
<view class="content">{{ v.class_id_name }}</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="box"> |
|
||||
<view class="title">人员:</view> |
|
||||
<view class="content">{{ v.staff_id_name || ''}}</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="box"> |
|
||||
<view class="title">支付时间:</view> |
|
||||
<view class="content">{{ v.payment_time || '' }}</view> |
|
||||
</view> |
|
||||
|
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
</scroll-view> |
|
||||
<!-- <view class="btn_section">--> |
|
||||
<!-- <view class="btn" style="background-color:#29d3b4;" @click="openOrderShow()">创建订单</view>--> |
|
||||
<!-- </view>--> |
|
||||
</view> |
|
||||
|
|
||||
<!--创建订单弹出层--> |
|
||||
<fui-modal class="order_modal" :buttons="[]" width="600" :show="order_show"> |
|
||||
<text class="fui-title">创建订单</text> |
|
||||
<text class="fui-descr"></text> |
|
||||
<fui-form class="form-section" ref="form" top="0" :model="formData" :show="false"> |
|
||||
<view class="input-style"> |
|
||||
<!--客户名称--> |
|
||||
<fui-form-item |
|
||||
label="客户名称" |
|
||||
labelSize='26' |
|
||||
prop="" |
|
||||
background='#fff' |
|
||||
labelColor='#000' |
|
||||
:bottomBorder='true' |
|
||||
> |
|
||||
<view class="input-title" style="margin-right:14rpx;"> |
|
||||
<fui-input |
|
||||
:disabled="true" |
|
||||
:borderBottom="false" |
|
||||
:padding="[0]" |
|
||||
placeholder="请输入客户名称" |
|
||||
v-model="formData.resource_id_name" |
|
||||
backgroundColor="#fff" |
|
||||
size="26" |
|
||||
color="#000" |
|
||||
></fui-input> |
|
||||
</view> |
|
||||
</fui-form-item> |
|
||||
|
|
||||
<!--付款类型--> |
|
||||
<fui-form-item |
|
||||
label="选择付款类型" |
|
||||
asterisk |
|
||||
asteriskPosition="right" |
|
||||
labelSize='26' |
|
||||
prop="" |
|
||||
background='#fff' |
|
||||
labelColor='#000' |
|
||||
:bottomBorder='true' |
|
||||
> |
|
||||
<view class="input-title" style="margin-right:14rpx;"> |
|
||||
<view |
|
||||
class="input-title" |
|
||||
style="margin-right:14rpx;" |
|
||||
@click="openPaymentType()"> |
|
||||
{{ (formData.payment_type) ? formData.payment_type_name : '点击选择' }} |
|
||||
</view> |
|
||||
</view> |
|
||||
<fui-picker |
|
||||
:linkage='true' |
|
||||
:options="payment_type_options" |
|
||||
:layer="1" |
|
||||
:show="payment_type_show" |
|
||||
@change="changePaymentType" |
|
||||
@cancel="cancelPaymentType"> |
|
||||
</fui-picker> |
|
||||
</fui-form-item> |
|
||||
|
|
||||
<!--课程--> |
|
||||
<fui-form-item |
|
||||
label="选择课程" |
|
||||
asterisk |
|
||||
asteriskPosition="right" |
|
||||
labelSize='26' |
|
||||
prop="" |
|
||||
background='#fff' |
|
||||
labelColor='#000' |
|
||||
:bottomBorder='true' |
|
||||
> |
|
||||
<view class="input-title" style="margin-right:14rpx;"> |
|
||||
<view |
|
||||
class="input-title" |
|
||||
style="margin-right:14rpx;" |
|
||||
@click="openCourseId()"> |
|
||||
{{ (formData.course_id) ? formData.course_id_name : '点击选择' }} |
|
||||
</view> |
|
||||
</view> |
|
||||
<fui-picker |
|
||||
:linkage='true' |
|
||||
:options="course_id_options" |
|
||||
:layer="1" |
|
||||
:show="course_id_show" |
|
||||
@change="changeCourseId" |
|
||||
@cancel="cancelCourseId"> |
|
||||
</fui-picker> |
|
||||
</fui-form-item> |
|
||||
|
|
||||
<!--班级--> |
|
||||
<fui-form-item |
|
||||
label="选择班级" |
|
||||
asterisk |
|
||||
asteriskPosition="right" |
|
||||
labelSize='26' |
|
||||
prop="" |
|
||||
background='#fff' |
|
||||
labelColor='#000' |
|
||||
:bottomBorder='true' |
|
||||
> |
|
||||
<view class="input-title" style="margin-right:14rpx;"> |
|
||||
<view |
|
||||
class="input-title" |
|
||||
style="margin-right:14rpx;" |
|
||||
@click="openClassId()"> |
|
||||
{{ (formData.class_id) ? formData.class_id_name : '点击选择' }} |
|
||||
</view> |
|
||||
</view> |
|
||||
<fui-picker |
|
||||
:linkage='true' |
|
||||
:options="class_id_options" |
|
||||
:layer="1" |
|
||||
:show="class_id_show" |
|
||||
@change="changeClassId" |
|
||||
@cancel="cancelClassId"> |
|
||||
</fui-picker> |
|
||||
</fui-form-item> |
|
||||
|
|
||||
<!--订单金额--> |
|
||||
<fui-form-item |
|
||||
label="订单金额" |
|
||||
labelSize='26' |
|
||||
prop="" |
|
||||
background='#fff' |
|
||||
labelColor='#000' |
|
||||
:bottomBorder='true' |
|
||||
> |
|
||||
<view class="input-title" style="margin-right:14rpx;"> |
|
||||
<fui-input |
|
||||
:disabled="true" |
|
||||
:borderBottom="false" |
|
||||
:padding="[0]" |
|
||||
placeholder="订单金额" |
|
||||
v-model="formData.money" |
|
||||
backgroundColor="#fff" |
|
||||
size="26" |
|
||||
color="#000" |
|
||||
></fui-input> |
|
||||
</view> |
|
||||
</fui-form-item> |
|
||||
</view> |
|
||||
<view class="button_box"> |
|
||||
<fui-button background="#fff" color="#414141" borderColor="#465CFF" btnSize="small" @click="closeOrderShow">取消</fui-button> |
|
||||
<fui-button background="#fff" color="#465CFF" borderColor="#465CFF" btnSize="small" @click="clickOrder({index:1})">确定</fui-button> |
|
||||
|
|
||||
</view> |
|
||||
</fui-form> |
|
||||
<view class="fui-icon__close" @tap="closeOrderShow"> |
|
||||
<fui-icon name="close" color="#B2B2B2" :size="48"></fui-icon> |
|
||||
</view> |
|
||||
</fui-modal> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
loading:false,//加载状态 |
|
||||
lowerThreshold: 100,//距离底部多远触发 |
|
||||
isReachedBottom: false,//防止重复加载|true=不可加载|false=可加载 |
|
||||
|
|
||||
//筛选条件 |
|
||||
filteredData:{ |
|
||||
page:1,//当前页码 |
|
||||
limit:10,//每页返回数据条数 |
|
||||
total:10,//数据总条数 |
|
||||
resource_id:'',//客户资源表id |
|
||||
}, |
|
||||
tableList:[],//聊天数据列表 |
|
||||
|
|
||||
//订单表单 |
|
||||
formData:{ |
|
||||
payment_type:'',//付款类型必填验证 |
|
||||
payment_type_name:'',//付款类型必填验证 |
|
||||
|
|
||||
course_id:'',//课程ID必填验证 |
|
||||
course_id_name:'',//课程ID必填验证 |
|
||||
|
|
||||
class_id:'',//班级ID必填验证 |
|
||||
class_id_name:'',//班级ID必填验证 |
|
||||
|
|
||||
staff_id:'',//员工ID必填验证 |
|
||||
staff_id_name:'',//员工ID必填验证 |
|
||||
|
|
||||
resource_id:'',//客户资源表ID必填验证 |
|
||||
resource_id_name:'',//客户资源表ID必填验证 |
|
||||
|
|
||||
money:'',//金额|这个不入库就展示先 |
|
||||
}, |
|
||||
|
|
||||
order_show:false,//创建订单弹出层是否显示|true=显示,false=隐藏 |
|
||||
|
|
||||
//付款类型-下拉选择器相关 |
|
||||
payment_type_options:[ |
|
||||
// { |
|
||||
// text:'张三', |
|
||||
// value:'1' |
|
||||
// }, |
|
||||
],//可选值列表 |
|
||||
payment_type_show:false,//下拉选择器是否展示 |
|
||||
|
|
||||
//课程-下拉选择器相关 |
|
||||
course_id_options:[ |
|
||||
// { |
|
||||
// text:'张三', |
|
||||
// value:'1', |
|
||||
// price:'1'//课程价格 |
|
||||
// }, |
|
||||
],//可选值列表 |
|
||||
course_id_show:false,//下拉选择器是否展示 |
|
||||
|
|
||||
//班级-下拉选择器相关 |
|
||||
class_id_options:[ |
|
||||
// { |
|
||||
// text:'张三', |
|
||||
// value:'1' |
|
||||
// }, |
|
||||
],//可选值列表 |
|
||||
class_id_show:false,//下拉选择器是否展示 |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
this.filteredData.resource_id = options.resource_id//客户资源表id |
|
||||
|
|
||||
this.formData.resource_id = options.resource_id//客户资源表id |
|
||||
this.formData.resource_id_name = options.resource_name//客户资源表id姓名 |
|
||||
|
|
||||
|
|
||||
this.formData.staff_id = options.staff_id//员工资源表id姓名 |
|
||||
this.formData.staff_id_name = options.staff_id_name//员工资源表id姓名 |
|
||||
}, |
|
||||
onShow(){ |
|
||||
this.init() |
|
||||
}, |
|
||||
//下拉刷新 |
|
||||
async onPullDownRefresh() { |
|
||||
//重置为第一页 |
|
||||
await this.resetFilteredData() |
|
||||
await this.getList() |
|
||||
}, |
|
||||
methods: { |
|
||||
//初始化 |
|
||||
async init(){ |
|
||||
//获取付款类型 |
|
||||
await this.getPaymentTypeList() |
|
||||
//获取课程列表 |
|
||||
await this.getCourseList() |
|
||||
//获取班级列表 |
|
||||
await this.getClassList() |
|
||||
|
|
||||
//获取列表 |
|
||||
await this.getList(); |
|
||||
}, |
|
||||
|
|
||||
//加载更多(下一页) |
|
||||
loadMoreData() { |
|
||||
//判断是否加载 |
|
||||
if (!this.isReachedBottom) { |
|
||||
this.isReachedBottom = true;//设置为不可请求状态 |
|
||||
this.getList(); |
|
||||
} |
|
||||
}, |
|
||||
//重置为第一页 |
|
||||
async resetFilteredData() { |
|
||||
this.isReachedBottom = false; // 重置状态,以便下次触发加载更多 |
|
||||
|
|
||||
this.filteredData.page = 1//当前页码 |
|
||||
this.filteredData.limit = 10//每页返回数据条数 |
|
||||
this.filteredData.total = 10//数据总条数 |
|
||||
}, |
|
||||
|
|
||||
//获取合同列表 |
|
||||
async getList(){ |
|
||||
this.loading = true |
|
||||
|
|
||||
let params = {...this.filteredData} |
|
||||
|
|
||||
//判断是否还有数据 |
|
||||
if ((this.filteredData.page - 1) * this.filteredData.limit >= this.filteredData.total) { |
|
||||
this.loading = false |
|
||||
uni.showToast({ |
|
||||
title: '暂无更多', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
if(params.page == 1){ |
|
||||
this.tableList = [] |
|
||||
} |
|
||||
|
|
||||
let res = await apiRoute.xy_orderTableList(params)//获取订单列表 |
|
||||
this.loading = false |
|
||||
this.isReachedBottom = false; |
|
||||
if (res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.tableList = this.tableList.concat(res.data.data); // 使用 concat 方法 将新数据追加到数组中 |
|
||||
// this.tableList.unshift(...res.data.data); // 将新数据插入到数组头部 |
|
||||
|
|
||||
console.log('列表',this.tableList) |
|
||||
this.filteredData.total = res.data.total |
|
||||
this.filteredData.page++ |
|
||||
}, |
|
||||
|
|
||||
//获取付款类型 |
|
||||
async getPaymentTypeList(){ |
|
||||
let res = await apiRoute.common_Dictionary({key:'payment_type'}) |
|
||||
if(res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
let dictionary = res.data.dictionary |
|
||||
let arr = [] |
|
||||
dictionary.forEach((v,k)=>{ |
|
||||
arr.push({ |
|
||||
text: v.name, |
|
||||
value: v.value, |
|
||||
}) |
|
||||
}) |
|
||||
this.payment_type_options = arr |
|
||||
console.log('付款类型',this.payment_type_options) |
|
||||
}, |
|
||||
//获取课程列表 |
|
||||
async getCourseList(){ |
|
||||
let params = {} |
|
||||
|
|
||||
let res = await apiRoute.common_getCourseAll(params) |
|
||||
if(res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
|
|
||||
let arr = [] |
|
||||
res.data.forEach((v,k)=>{ |
|
||||
arr.push({ |
|
||||
text: `${v.course_name}`, |
|
||||
value: v.id, |
|
||||
price: v.price, |
|
||||
}) |
|
||||
}) |
|
||||
this.course_id_options = arr |
|
||||
console.log('课程列表',this.course_id_options) |
|
||||
|
|
||||
}, |
|
||||
//获取班级列表 |
|
||||
async getClassList(){ |
|
||||
let params = { |
|
||||
status:1,//班级状态(1开启 2关闭) |
|
||||
} |
|
||||
|
|
||||
let res = await apiRoute.common_getClassAll(params) |
|
||||
if(res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
console.log('班级列表',res.data) |
|
||||
let arr = [] |
|
||||
res.data.forEach((v,k)=>{ |
|
||||
arr.push({ |
|
||||
text: `${v.campus_name}-${v.class_name}`, |
|
||||
value: v.id, |
|
||||
}) |
|
||||
}) |
|
||||
this.class_id_options = arr |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
//创建订单相关 |
|
||||
//显示创建订单弹窗 |
|
||||
openOrderShow(){ |
|
||||
//重置的数据 |
|
||||
this.formData.payment_type = ''//付款类型必填验证 |
|
||||
this.formData.payment_type_name = ''//付款类型必填验证 |
|
||||
|
|
||||
this.formData.course_id = ''//课程ID必填验证 |
|
||||
this.formData.course_id_name = ''//课程ID必填验证 |
|
||||
|
|
||||
this.formData.class_id = ''//班级ID必填验证 |
|
||||
this.formData.class_id_name = ''//班级ID必填验证 |
|
||||
|
|
||||
this.formData.money = ''//金额|这个不入库就展示先 |
|
||||
|
|
||||
this.order_show = true//展示弹层 |
|
||||
}, |
|
||||
//关闭打卡弹窗 |
|
||||
closeOrderShow(){ |
|
||||
this.order_show = false |
|
||||
}, |
|
||||
//监听-打卡签到回调 |
|
||||
async clickOrder(e){ |
|
||||
if(e.index == 0){ |
|
||||
//取消按钮 |
|
||||
this.closeOrderShow() |
|
||||
}else{ |
|
||||
console.log('提交',this.formData) |
|
||||
await this.submitFormData() |
|
||||
} |
|
||||
}, |
|
||||
//提交表单 |
|
||||
async submitFormData() { |
|
||||
let param = {...this.formData} |
|
||||
//表单验证 |
|
||||
//... |
|
||||
if(!param.class_id){ |
|
||||
uni.showToast({ |
|
||||
title: '请选择班级', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
if(!param.course_id){ |
|
||||
uni.showToast({ |
|
||||
title: '请选择课程', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
if(!param.payment_type){ |
|
||||
uni.showToast({ |
|
||||
title: '请选择付款类型', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
console.log('提交xxx',param) |
|
||||
this.closeOrderShow() |
|
||||
|
|
||||
let res = await apiRoute.xy_orderTableAdd(param) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
uni.showToast({ |
|
||||
title: '操作成功', |
|
||||
icon: 'success' |
|
||||
}) |
|
||||
|
|
||||
//延迟1s执行 |
|
||||
setTimeout(() => { |
|
||||
this.resetFilteredData()//重置表单 |
|
||||
this.getList();//刷新列表 |
|
||||
}, 1500) |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
//下拉选择器相关-付款类型 |
|
||||
//监听-付款类型 |
|
||||
changePaymentType(e){ |
|
||||
this.formData.payment_type = e.value |
|
||||
this.formData.payment_type_name = e.text |
|
||||
this.cancelPaymentType() |
|
||||
}, |
|
||||
//打开选择器-付款类型 |
|
||||
openPaymentType(){ |
|
||||
this.payment_type_show = true |
|
||||
}, |
|
||||
//关闭选择器-付款类型 |
|
||||
cancelPaymentType(){ |
|
||||
this.payment_type_show = false |
|
||||
}, |
|
||||
|
|
||||
//下拉选择器相关-课程 |
|
||||
//监听-课程 |
|
||||
changeCourseId(e){ |
|
||||
console.log('课程',e) |
|
||||
this.formData.course_id = e.value |
|
||||
this.formData.course_id_name = e.text |
|
||||
|
|
||||
this.formData.money = this.course_id_options.find(v=>v.value == e.value).price |
|
||||
|
|
||||
// console.log('课程formData',this.formData) |
|
||||
this.cancelCourseId() |
|
||||
}, |
|
||||
//打开选择器-课程 |
|
||||
openCourseId(){ |
|
||||
this.course_id_show = true |
|
||||
}, |
|
||||
//关闭选择器-课程 |
|
||||
cancelCourseId(){ |
|
||||
this.course_id_show = false |
|
||||
}, |
|
||||
|
|
||||
//下拉选择器相关-班级 |
|
||||
//监听-班级 |
|
||||
changeClassId(e){ |
|
||||
this.formData.class_id = e.value |
|
||||
this.formData.class_id_name = e.text |
|
||||
this.cancelClassId() |
|
||||
}, |
|
||||
//打开选择器-班级 |
|
||||
openClassId(){ |
|
||||
this.class_id_show = true |
|
||||
}, |
|
||||
//关闭选择器-班级 |
|
||||
cancelClassId(){ |
|
||||
this.class_id_show = false |
|
||||
}, |
|
||||
|
|
||||
//下载文件 |
|
||||
async downloadFile(fileUrl) { |
|
||||
if (!fileUrl) { |
|
||||
this.$util.showToast({ |
|
||||
title: '暂无电子发票' |
|
||||
}); |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
uni.downloadFile({ |
|
||||
url: fileUrl, |
|
||||
success: function (res) { |
|
||||
console.log('下载成功'); |
|
||||
// uni.openDocument({ |
|
||||
// filePath: res.tempFilePath, |
|
||||
// fileType: 'pdf', |
|
||||
// success: function (res) { |
|
||||
// console.log('打开文档成功'); |
|
||||
// } |
|
||||
// }); |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box { |
|
||||
background: #292929; |
|
||||
} |
|
||||
|
|
||||
//自定义导航栏 |
|
||||
.navbar_section { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
background: #29d3b4; |
|
||||
|
|
||||
.title { |
|
||||
padding: 20rpx 0; |
|
||||
font-size: 30rpx; |
|
||||
color: #315d55; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.main_section { |
|
||||
min-height: 100vh; |
|
||||
background: #292929 100%; |
|
||||
padding: 0 0rpx; |
|
||||
padding-top: 32rpx; |
|
||||
padding-bottom: 150rpx; |
|
||||
font-size: 28rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 20rpx; |
|
||||
|
|
||||
.section { |
|
||||
background-color: #434544; |
|
||||
padding: 40rpx 40rpx; |
|
||||
} |
|
||||
|
|
||||
.section_1{ |
|
||||
padding: 0 24rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
|
|
||||
.item{ |
|
||||
margin-bottom: 38rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
padding: 32rpx 24rpx; |
|
||||
border-radius: 14rpx; |
|
||||
background-color: #434544; |
|
||||
color: #fff; |
|
||||
.top{ |
|
||||
font-size: 28rpx; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
.title{ |
|
||||
font-size: 30rpx; |
|
||||
} |
|
||||
.btn{ |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
color: #29D3B4; |
|
||||
} |
|
||||
} |
|
||||
.bottom{ |
|
||||
font-size: 26rpx; |
|
||||
margin-top: 25rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 15rpx; |
|
||||
.box{ |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
.title{ |
|
||||
width: 180rpx; |
|
||||
} |
|
||||
.content{ |
|
||||
width: 100%; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.btn_section{ |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
.btn{ |
|
||||
border-radius: 10rpx; |
|
||||
padding: 15rpx 0; |
|
||||
width: 70%; |
|
||||
color: #fff; |
|
||||
font-size: 30rpx; |
|
||||
text-align: center; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
} |
|
||||
|
|
||||
.describe { |
|
||||
color: #999999; |
|
||||
padding-left: 30rpx; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
//创建订单弹出层 |
|
||||
.order_modal{ |
|
||||
.fui-title { |
|
||||
font-size: 32rpx; |
|
||||
padding-top: 24rpx; |
|
||||
} |
|
||||
|
|
||||
.fui-descr { |
|
||||
font-size: 24rpx; |
|
||||
color: #B2B2B2; |
|
||||
padding-top: 12rpx; |
|
||||
padding-bottom: 48rpx; |
|
||||
} |
|
||||
|
|
||||
.fui-icon__close { |
|
||||
position: absolute; |
|
||||
right: 24rpx; |
|
||||
top: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.form-section{ |
|
||||
|
|
||||
.input-style { |
|
||||
text-align: right !important; |
|
||||
.input-title{} |
|
||||
} |
|
||||
.button_box{ |
|
||||
margin-top: 30rpx; |
|
||||
padding: 20rpx; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: space-between; |
|
||||
gap: 20rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,542 +0,0 @@ |
|||||
<template> |
|
||||
<view class="container"> |
|
||||
<view class="header"> |
|
||||
<text class="title">字典获取优化演示</text> |
|
||||
<text class="subtitle">对比原方式和批量获取的性能差异</text> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 性能对比 --> |
|
||||
<view class="performance-section"> |
|
||||
<view class="section-title">性能对比</view> |
|
||||
|
|
||||
<!-- 原有方式 --> |
|
||||
<view class="test-item"> |
|
||||
<view class="test-header"> |
|
||||
<text class="test-name">原方式(单个获取)</text> |
|
||||
<button |
|
||||
class="test-btn old-style" |
|
||||
@click="testOldMethod" |
|
||||
:disabled="oldTesting"> |
|
||||
{{ oldTesting ? '测试中...' : '开始测试' }} |
|
||||
</button> |
|
||||
</view> |
|
||||
<view class="test-result" v-if="oldResult"> |
|
||||
<text class="result-text">耗时: {{ oldResult.time }}ms</text> |
|
||||
<text class="result-text">请求次数: {{ oldResult.requests }}次</text> |
|
||||
<text class="result-text">获取数据: {{ oldResult.count }}个字典</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 新方式 --> |
|
||||
<view class="test-item"> |
|
||||
<view class="test-header"> |
|
||||
<text class="test-name">新方式(批量获取)</text> |
|
||||
<button |
|
||||
class="test-btn new-style" |
|
||||
@click="testNewMethod" |
|
||||
:disabled="newTesting"> |
|
||||
{{ newTesting ? '测试中...' : '开始测试' }} |
|
||||
</button> |
|
||||
</view> |
|
||||
<view class="test-result" v-if="newResult"> |
|
||||
<text class="result-text">耗时: {{ newResult.time }}ms</text> |
|
||||
<text class="result-text">请求次数: {{ newResult.requests }}次</text> |
|
||||
<text class="result-text">获取数据: {{ newResult.count }}个字典</text> |
|
||||
<text class="improvement"> |
|
||||
性能提升: {{ newResult.improvement }} |
|
||||
</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 缓存演示 --> |
|
||||
<view class="cache-section"> |
|
||||
<view class="section-title">缓存机制演示</view> |
|
||||
|
|
||||
<view class="cache-controls"> |
|
||||
<button class="cache-btn" @click="testCache">测试缓存效果</button> |
|
||||
<button class="cache-btn clear" @click="clearCache">清除缓存</button> |
|
||||
</view> |
|
||||
|
|
||||
<view class="cache-result" v-if="cacheResult"> |
|
||||
<text class="cache-text">第一次获取: {{ cacheResult.firstTime }}ms</text> |
|
||||
<text class="cache-text">缓存获取: {{ cacheResult.cacheTime }}ms</text> |
|
||||
<text class="cache-text">性能提升: {{ cacheResult.improvement }}</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 字典数据展示 --> |
|
||||
<view class="data-section"> |
|
||||
<view class="section-title">字典数据展示</view> |
|
||||
|
|
||||
<view class="dict-tabs"> |
|
||||
<view |
|
||||
class="tab-item" |
|
||||
:class="{ active: activeTab === key }" |
|
||||
v-for="(data, key) in dictData" |
|
||||
:key="key" |
|
||||
@click="activeTab = key"> |
|
||||
{{ getDictDisplayName(key) }} |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<scroll-view class="dict-content" scroll-y> |
|
||||
<view class="dict-items" v-if="dictData[activeTab]"> |
|
||||
<view |
|
||||
class="dict-item" |
|
||||
v-for="(item, index) in dictData[activeTab]" |
|
||||
:key="index"> |
|
||||
<text class="item-name">{{ item.name || item.text || '-' }}</text> |
|
||||
<text class="item-value">{{ item.value || '-' }}</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="empty-state" v-else> |
|
||||
<text>暂无数据</text> |
|
||||
</view> |
|
||||
</scroll-view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 使用说明 --> |
|
||||
<view class="usage-section"> |
|
||||
<view class="section-title">使用说明</view> |
|
||||
<view class="usage-content"> |
|
||||
<text class="usage-text">1. 使用 dictUtil.getBatchDict() 批量获取字典</text> |
|
||||
<text class="usage-text">2. 支持自动缓存,30分钟有效期</text> |
|
||||
<text class="usage-text">3. 支持业务场景批量获取</text> |
|
||||
<text class="usage-text">4. 向后兼容原有 util.getDict() 方法</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import dictUtil from '@/common/dictUtil.js' |
|
||||
import util from '@/common/util.js' |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
// 测试状态 |
|
||||
oldTesting: false, |
|
||||
newTesting: false, |
|
||||
|
|
||||
// 测试结果 |
|
||||
oldResult: null, |
|
||||
newResult: null, |
|
||||
cacheResult: null, |
|
||||
|
|
||||
// 字典数据 |
|
||||
dictData: {}, |
|
||||
activeTab: '', |
|
||||
|
|
||||
// 测试用的字典keys |
|
||||
testKeys: [ |
|
||||
'SourceChannel', |
|
||||
'source', |
|
||||
'customer_purchasing_power', |
|
||||
'preliminarycustomerintention', |
|
||||
'cognitive_concept', |
|
||||
'kh_status', |
|
||||
'decision_maker', |
|
||||
'distance' |
|
||||
] |
|
||||
} |
|
||||
}, |
|
||||
onLoad() { |
|
||||
// 初始化时获取一次字典数据用于展示 |
|
||||
this.loadInitialData() |
|
||||
}, |
|
||||
methods: { |
|
||||
// 加载初始数据 |
|
||||
async loadInitialData() { |
|
||||
try { |
|
||||
const data = await dictUtil.getBatchDict(this.testKeys) |
|
||||
this.dictData = data |
|
||||
this.activeTab = Object.keys(data)[0] || '' |
|
||||
} catch (error) { |
|
||||
console.error('加载初始数据失败:', error) |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 测试原有方式(单个获取) |
|
||||
async testOldMethod() { |
|
||||
this.oldTesting = true |
|
||||
this.oldResult = null |
|
||||
|
|
||||
try { |
|
||||
const startTime = Date.now() |
|
||||
let successCount = 0 |
|
||||
|
|
||||
// 模拟原有的单个获取方式 |
|
||||
for (const key of this.testKeys) { |
|
||||
try { |
|
||||
await this.getOldDict(key) |
|
||||
successCount++ |
|
||||
} catch (error) { |
|
||||
console.warn(`获取字典 ${key} 失败:`, error) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
const endTime = Date.now() |
|
||||
const totalTime = endTime - startTime |
|
||||
|
|
||||
this.oldResult = { |
|
||||
time: totalTime, |
|
||||
requests: this.testKeys.length, |
|
||||
count: successCount |
|
||||
} |
|
||||
|
|
||||
uni.showToast({ |
|
||||
title: `原方式完成,耗时 ${totalTime}ms`, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('测试原方式失败:', error) |
|
||||
uni.showToast({ |
|
||||
title: '测试失败', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
} finally { |
|
||||
this.oldTesting = false |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 测试新方式(批量获取) |
|
||||
async testNewMethod() { |
|
||||
this.newTesting = true |
|
||||
this.newResult = null |
|
||||
|
|
||||
try { |
|
||||
const startTime = Date.now() |
|
||||
|
|
||||
// 使用新的批量获取方式 |
|
||||
const data = await dictUtil.getBatchDict(this.testKeys, false) // 不使用缓存进行公平测试 |
|
||||
|
|
||||
const endTime = Date.now() |
|
||||
const totalTime = endTime - startTime |
|
||||
const successCount = Object.keys(data).length |
|
||||
|
|
||||
this.newResult = { |
|
||||
time: totalTime, |
|
||||
requests: 1, // 批量获取只需要1次请求 |
|
||||
count: successCount |
|
||||
} |
|
||||
|
|
||||
// 计算性能提升 |
|
||||
if (this.oldResult) { |
|
||||
const improvement = Math.round(((this.oldResult.time - totalTime) / this.oldResult.time) * 100) |
|
||||
this.newResult.improvement = `${improvement}%` |
|
||||
} |
|
||||
|
|
||||
// 更新展示数据 |
|
||||
this.dictData = data |
|
||||
|
|
||||
uni.showToast({ |
|
||||
title: `新方式完成,耗时 ${totalTime}ms`, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('测试新方式失败:', error) |
|
||||
uni.showToast({ |
|
||||
title: '测试失败', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
} finally { |
|
||||
this.newTesting = false |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 模拟原有的单个字典获取 |
|
||||
async getOldDict(key) { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
// 模拟单个接口请求的延迟 |
|
||||
setTimeout(async () => { |
|
||||
try { |
|
||||
// 这里可以调用原有的获取方法,或者模拟 |
|
||||
const result = await dictUtil.getDict(key, false) |
|
||||
resolve(result) |
|
||||
} catch (error) { |
|
||||
reject(error) |
|
||||
} |
|
||||
}, Math.random() * 200 + 100) // 模拟 100-300ms 的网络延迟 |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
// 测试缓存效果 |
|
||||
async testCache() { |
|
||||
try { |
|
||||
// 清除缓存确保公平测试 |
|
||||
dictUtil.clearCache() |
|
||||
|
|
||||
// 第一次获取(无缓存) |
|
||||
const startTime1 = Date.now() |
|
||||
await dictUtil.getBatchDict(this.testKeys.slice(0, 3), true) |
|
||||
const firstTime = Date.now() - startTime1 |
|
||||
|
|
||||
// 第二次获取(有缓存) |
|
||||
const startTime2 = Date.now() |
|
||||
await dictUtil.getBatchDict(this.testKeys.slice(0, 3), true) |
|
||||
const cacheTime = Date.now() - startTime2 |
|
||||
|
|
||||
const improvement = Math.round(((firstTime - cacheTime) / firstTime) * 100) |
|
||||
|
|
||||
this.cacheResult = { |
|
||||
firstTime, |
|
||||
cacheTime, |
|
||||
improvement: `${improvement}%` |
|
||||
} |
|
||||
|
|
||||
uni.showToast({ |
|
||||
title: '缓存测试完成', |
|
||||
icon: 'success' |
|
||||
}) |
|
||||
|
|
||||
} catch (error) { |
|
||||
console.error('缓存测试失败:', error) |
|
||||
uni.showToast({ |
|
||||
title: '缓存测试失败', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 清除缓存 |
|
||||
clearCache() { |
|
||||
dictUtil.clearCache() |
|
||||
this.cacheResult = null |
|
||||
uni.showToast({ |
|
||||
title: '缓存已清除', |
|
||||
icon: 'success' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
// 获取字典显示名称 |
|
||||
getDictDisplayName(key) { |
|
||||
const nameMap = { |
|
||||
'SourceChannel': '来源渠道', |
|
||||
'source': '来源', |
|
||||
'customer_purchasing_power': '购买力', |
|
||||
'preliminarycustomerintention': '意向度', |
|
||||
'cognitive_concept': '认知理念', |
|
||||
'kh_status': '客户状态', |
|
||||
'decision_maker': '决策人', |
|
||||
'distance': '距离' |
|
||||
} |
|
||||
return nameMap[key] || key |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.container { |
|
||||
padding: 20rpx; |
|
||||
background: #f5f5f5; |
|
||||
min-height: 100vh; |
|
||||
} |
|
||||
|
|
||||
.header { |
|
||||
background: #fff; |
|
||||
padding: 30rpx; |
|
||||
border-radius: 12rpx; |
|
||||
margin-bottom: 20rpx; |
|
||||
text-align: center; |
|
||||
|
|
||||
.title { |
|
||||
font-size: 36rpx; |
|
||||
font-weight: 600; |
|
||||
color: #333; |
|
||||
display: block; |
|
||||
margin-bottom: 10rpx; |
|
||||
} |
|
||||
|
|
||||
.subtitle { |
|
||||
font-size: 26rpx; |
|
||||
color: #666; |
|
||||
display: block; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.performance-section, .cache-section, .data-section, .usage-section { |
|
||||
background: #fff; |
|
||||
border-radius: 12rpx; |
|
||||
padding: 30rpx; |
|
||||
margin-bottom: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.section-title { |
|
||||
font-size: 32rpx; |
|
||||
font-weight: 600; |
|
||||
color: #333; |
|
||||
margin-bottom: 20rpx; |
|
||||
border-left: 4rpx solid #29d3b4; |
|
||||
padding-left: 16rpx; |
|
||||
} |
|
||||
|
|
||||
.test-item { |
|
||||
margin-bottom: 30rpx; |
|
||||
padding: 20rpx; |
|
||||
background: #f8f9fa; |
|
||||
border-radius: 8rpx; |
|
||||
|
|
||||
&:last-child { |
|
||||
margin-bottom: 0; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.test-header { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
margin-bottom: 15rpx; |
|
||||
|
|
||||
.test-name { |
|
||||
font-size: 28rpx; |
|
||||
font-weight: 500; |
|
||||
color: #333; |
|
||||
} |
|
||||
|
|
||||
.test-btn { |
|
||||
padding: 12rpx 24rpx; |
|
||||
border-radius: 6rpx; |
|
||||
border: none; |
|
||||
font-size: 24rpx; |
|
||||
color: #fff; |
|
||||
|
|
||||
&.old-style { |
|
||||
background: #ff6b6b; |
|
||||
} |
|
||||
|
|
||||
&.new-style { |
|
||||
background: #29d3b4; |
|
||||
} |
|
||||
|
|
||||
&:disabled { |
|
||||
opacity: 0.6; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.test-result { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 8rpx; |
|
||||
|
|
||||
.result-text { |
|
||||
font-size: 24rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
|
|
||||
.improvement { |
|
||||
font-size: 26rpx; |
|
||||
color: #29d3b4; |
|
||||
font-weight: 600; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.cache-controls { |
|
||||
display: flex; |
|
||||
gap: 20rpx; |
|
||||
margin-bottom: 20rpx; |
|
||||
|
|
||||
.cache-btn { |
|
||||
flex: 1; |
|
||||
padding: 16rpx; |
|
||||
border-radius: 8rpx; |
|
||||
border: none; |
|
||||
font-size: 26rpx; |
|
||||
color: #fff; |
|
||||
background: #29d3b4; |
|
||||
|
|
||||
&.clear { |
|
||||
background: #ff6b6b; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.cache-result { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 8rpx; |
|
||||
|
|
||||
.cache-text { |
|
||||
font-size: 24rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.dict-tabs { |
|
||||
display: flex; |
|
||||
flex-wrap: wrap; |
|
||||
gap: 10rpx; |
|
||||
margin-bottom: 20rpx; |
|
||||
|
|
||||
.tab-item { |
|
||||
padding: 12rpx 20rpx; |
|
||||
background: #f0f0f0; |
|
||||
border-radius: 20rpx; |
|
||||
font-size: 24rpx; |
|
||||
color: #666; |
|
||||
|
|
||||
&.active { |
|
||||
background: #29d3b4; |
|
||||
color: #fff; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.dict-content { |
|
||||
height: 400rpx; |
|
||||
border: 1rpx solid #eee; |
|
||||
border-radius: 8rpx; |
|
||||
} |
|
||||
|
|
||||
.dict-items { |
|
||||
padding: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.dict-item { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
padding: 16rpx 0; |
|
||||
border-bottom: 1rpx solid #f0f0f0; |
|
||||
|
|
||||
&:last-child { |
|
||||
border-bottom: none; |
|
||||
} |
|
||||
|
|
||||
.item-name { |
|
||||
font-size: 26rpx; |
|
||||
color: #333; |
|
||||
flex: 1; |
|
||||
} |
|
||||
|
|
||||
.item-value { |
|
||||
font-size: 24rpx; |
|
||||
color: #666; |
|
||||
margin-left: 20rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.empty-state { |
|
||||
padding: 60rpx; |
|
||||
text-align: center; |
|
||||
color: #999; |
|
||||
font-size: 26rpx; |
|
||||
} |
|
||||
|
|
||||
.usage-content { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 12rpx; |
|
||||
|
|
||||
.usage-text { |
|
||||
font-size: 26rpx; |
|
||||
color: #666; |
|
||||
line-height: 1.6; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,352 +0,0 @@ |
|||||
<template> |
|
||||
<view class="mock-demo"> |
|
||||
<view class="header"> |
|
||||
<text class="title">Mock数据演示</text> |
|
||||
<view class="env-info"> |
|
||||
<text class="env-label">当前环境: {{ envInfo.env }}</text> |
|
||||
<text class="mock-status" :class="{ active: envInfo.mockEnabled }"> |
|
||||
Mock状态: {{ envInfo.mockEnabled ? '已开启' : '已关闭' }} |
|
||||
</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="content"> |
|
||||
<!-- 用户信息展示 --> |
|
||||
<view class="section"> |
|
||||
<view class="section-title">用户信息</view> |
|
||||
<view class="user-card" v-if="userInfo"> |
|
||||
<image class="avatar" :src="userInfo.avatar" mode="aspectFill"></image> |
|
||||
<view class="user-details"> |
|
||||
<text class="username">{{ userInfo.username }}</text> |
|
||||
<text class="phone">{{ userInfo.phone }}</text> |
|
||||
<text class="email">{{ userInfo.email }}</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="loading" v-else> |
|
||||
<text>加载中...</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 课程表展示 --> |
|
||||
<view class="section"> |
|
||||
<view class="section-title">今日课程</view> |
|
||||
<view class="schedule-list"> |
|
||||
<view class="schedule-item" v-for="item in scheduleList" :key="item.id"> |
|
||||
<view class="time">{{ item.start_time }} - {{ item.end_time }}</view> |
|
||||
<view class="course-info"> |
|
||||
<text class="course-name">{{ item.course_name }}</text> |
|
||||
<text class="teacher">{{ item.teacher_name }}</text> |
|
||||
<text class="classroom">{{ item.classroom }}</text> |
|
||||
</view> |
|
||||
<view class="status" :class="item.status"> |
|
||||
{{ getStatusText(item.status) }} |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 操作按钮 --> |
|
||||
<view class="actions"> |
|
||||
<button class="btn primary" @click="refreshData">刷新数据</button> |
|
||||
<button class="btn secondary" @click="toggleMock"> |
|
||||
{{ envInfo.mockEnabled ? '关闭Mock' : '开启Mock' }} |
|
||||
</button> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { Api_url, isMockEnabled, isDebug, env } from '@/common/config.js' |
|
||||
import http from '@/common/axios.js' |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
userInfo: null, |
|
||||
scheduleList: [], |
|
||||
envInfo: { |
|
||||
env: env, |
|
||||
mockEnabled: isMockEnabled, |
|
||||
debug: isDebug |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
onLoad() { |
|
||||
this.loadData() |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
async loadData() { |
|
||||
try { |
|
||||
// 加载用户信息 |
|
||||
await this.loadUserInfo() |
|
||||
// 加载课程表 |
|
||||
await this.loadSchedule() |
|
||||
} catch (error) { |
|
||||
console.error('数据加载失败:', error) |
|
||||
uni.showToast({ |
|
||||
title: '数据加载失败', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
async loadUserInfo() { |
|
||||
try { |
|
||||
const response = await http.get('/user/info') |
|
||||
this.userInfo = response.data |
|
||||
} catch (error) { |
|
||||
console.error('用户信息加载失败:', error) |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
async loadSchedule() { |
|
||||
try { |
|
||||
const response = await http.get('/student/schedule') |
|
||||
this.scheduleList = response.data || [] |
|
||||
} catch (error) { |
|
||||
console.error('课程表加载失败:', error) |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
async refreshData() { |
|
||||
uni.showLoading({ |
|
||||
title: '刷新中...' |
|
||||
}) |
|
||||
|
|
||||
try { |
|
||||
await this.loadData() |
|
||||
uni.showToast({ |
|
||||
title: '刷新成功', |
|
||||
icon: 'success' |
|
||||
}) |
|
||||
} catch (error) { |
|
||||
uni.showToast({ |
|
||||
title: '刷新失败', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
} finally { |
|
||||
uni.hideLoading() |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
toggleMock() { |
|
||||
// 这里只是演示,实际需要重新配置环境变量 |
|
||||
uni.showModal({ |
|
||||
title: '提示', |
|
||||
content: 'Mock开关需要在环境变量中配置,请修改.env文件中的VUE_APP_MOCK_ENABLED参数', |
|
||||
showCancel: false |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
getStatusText(status) { |
|
||||
const statusMap = { |
|
||||
scheduled: '已安排', |
|
||||
completed: '已完成', |
|
||||
cancelled: '已取消' |
|
||||
} |
|
||||
return statusMap[status] || status |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style scoped> |
|
||||
.mock-demo { |
|
||||
padding: 20rpx; |
|
||||
background-color: #f8f9fa; |
|
||||
min-height: 100vh; |
|
||||
} |
|
||||
|
|
||||
.header { |
|
||||
background: white; |
|
||||
padding: 30rpx; |
|
||||
border-radius: 20rpx; |
|
||||
margin-bottom: 30rpx; |
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1); |
|
||||
} |
|
||||
|
|
||||
.title { |
|
||||
font-size: 36rpx; |
|
||||
font-weight: bold; |
|
||||
color: #333; |
|
||||
display: block; |
|
||||
margin-bottom: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.env-info { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
.env-label { |
|
||||
font-size: 28rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
|
|
||||
.mock-status { |
|
||||
font-size: 28rpx; |
|
||||
color: #999; |
|
||||
padding: 10rpx 20rpx; |
|
||||
border-radius: 10rpx; |
|
||||
background: #f5f5f5; |
|
||||
} |
|
||||
|
|
||||
.mock-status.active { |
|
||||
color: #52c41a; |
|
||||
background: #f6ffed; |
|
||||
} |
|
||||
|
|
||||
.content { |
|
||||
flex: 1; |
|
||||
} |
|
||||
|
|
||||
.section { |
|
||||
background: white; |
|
||||
padding: 30rpx; |
|
||||
border-radius: 20rpx; |
|
||||
margin-bottom: 30rpx; |
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1); |
|
||||
} |
|
||||
|
|
||||
.section-title { |
|
||||
font-size: 32rpx; |
|
||||
font-weight: bold; |
|
||||
color: #333; |
|
||||
margin-bottom: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.user-card { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
.avatar { |
|
||||
width: 120rpx; |
|
||||
height: 120rpx; |
|
||||
border-radius: 60rpx; |
|
||||
margin-right: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.user-details { |
|
||||
flex: 1; |
|
||||
} |
|
||||
|
|
||||
.username { |
|
||||
font-size: 32rpx; |
|
||||
font-weight: bold; |
|
||||
color: #333; |
|
||||
display: block; |
|
||||
margin-bottom: 10rpx; |
|
||||
} |
|
||||
|
|
||||
.phone, .email { |
|
||||
font-size: 28rpx; |
|
||||
color: #666; |
|
||||
display: block; |
|
||||
margin-bottom: 5rpx; |
|
||||
} |
|
||||
|
|
||||
.schedule-list { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
} |
|
||||
|
|
||||
.schedule-item { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
padding: 20rpx 0; |
|
||||
border-bottom: 1rpx solid #f0f0f0; |
|
||||
} |
|
||||
|
|
||||
.schedule-item:last-child { |
|
||||
border-bottom: none; |
|
||||
} |
|
||||
|
|
||||
.time { |
|
||||
width: 200rpx; |
|
||||
font-size: 28rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
|
|
||||
.course-info { |
|
||||
flex: 1; |
|
||||
margin-left: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.course-name { |
|
||||
font-size: 30rpx; |
|
||||
font-weight: bold; |
|
||||
color: #333; |
|
||||
display: block; |
|
||||
margin-bottom: 10rpx; |
|
||||
} |
|
||||
|
|
||||
.teacher, .classroom { |
|
||||
font-size: 26rpx; |
|
||||
color: #666; |
|
||||
display: block; |
|
||||
margin-bottom: 5rpx; |
|
||||
} |
|
||||
|
|
||||
.status { |
|
||||
padding: 10rpx 20rpx; |
|
||||
border-radius: 10rpx; |
|
||||
font-size: 24rpx; |
|
||||
text-align: center; |
|
||||
min-width: 120rpx; |
|
||||
} |
|
||||
|
|
||||
.status.scheduled { |
|
||||
background: #e6f7ff; |
|
||||
color: #1890ff; |
|
||||
} |
|
||||
|
|
||||
.status.completed { |
|
||||
background: #f6ffed; |
|
||||
color: #52c41a; |
|
||||
} |
|
||||
|
|
||||
.status.cancelled { |
|
||||
background: #fff2e8; |
|
||||
color: #fa8c16; |
|
||||
} |
|
||||
|
|
||||
.loading { |
|
||||
text-align: center; |
|
||||
padding: 60rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
|
|
||||
.actions { |
|
||||
display: flex; |
|
||||
gap: 20rpx; |
|
||||
padding: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.btn { |
|
||||
flex: 1; |
|
||||
padding: 24rpx; |
|
||||
border-radius: 12rpx; |
|
||||
font-size: 32rpx; |
|
||||
border: none; |
|
||||
cursor: pointer; |
|
||||
} |
|
||||
|
|
||||
.btn.primary { |
|
||||
background: #1890ff; |
|
||||
color: white; |
|
||||
} |
|
||||
|
|
||||
.btn.secondary { |
|
||||
background: #f5f5f5; |
|
||||
color: #666; |
|
||||
} |
|
||||
|
|
||||
.btn:active { |
|
||||
opacity: 0.8; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,633 +0,0 @@ |
|||||
<template> |
|
||||
<div class="course-schedule"> |
|
||||
<!-- Header --> |
|
||||
<div class="header"> |
|
||||
<div class="back-btn" @click="goBack"> |
|
||||
<ChevronLeftIcon class="w-6 h-6" /> |
|
||||
</div> |
|
||||
<h1 class="title">课程安排详情</h1> |
|
||||
</div> |
|
||||
|
|
||||
<!-- Course Info --> |
|
||||
<div class="course-info"> |
|
||||
<h2 class="course-title">课程安排详情</h2> |
|
||||
<p class="course-time">日期:2025-07-24 08:30-09:30</p> |
|
||||
</div> |
|
||||
|
|
||||
<!-- Formal Students Section --> |
|
||||
<div class="section"> |
|
||||
<h3 class="section-title">正式学员</h3> |
|
||||
<div class="cards-grid"> |
|
||||
<!-- Student Card with Data --> |
|
||||
<div class="student-card filled"> |
|
||||
<div class="renewal-badge">待续费</div> |
|
||||
<div class="avatar">未</div> |
|
||||
<div class="student-info"> |
|
||||
<div class="student-name">张小明同学的名字很长需要省略</div> |
|
||||
<div class="student-age">年龄:8岁</div> |
|
||||
<div class="course-status">课程状态:正式课</div> |
|
||||
<div class="course-arrangement">课程安排:固定课</div> |
|
||||
<div class="remaining-hours">剩余课时:12节</div> |
|
||||
<div class="expiry-date">到期时间:2025-12-31</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<!-- Empty Slots --> |
|
||||
<div |
|
||||
v-for="n in 6" |
|
||||
:key="n" |
|
||||
class="student-card empty" |
|
||||
@click="openStudentModal('formal', n)" |
|
||||
> |
|
||||
<div class="add-icon"> |
|
||||
<PlusIcon class="w-8 h-8" /> |
|
||||
</div> |
|
||||
<div class="add-text"> |
|
||||
<div class="slot-title">空位</div> |
|
||||
<div class="slot-subtitle">点击添加学员</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<!-- Waiting List Section --> |
|
||||
<div class="section"> |
|
||||
<h3 class="section-title">等待位</h3> |
|
||||
<div class="cards-grid"> |
|
||||
<div |
|
||||
v-for="n in 2" |
|
||||
:key="n" |
|
||||
class="student-card waiting" |
|
||||
@click="openStudentModal('waiting', n)" |
|
||||
> |
|
||||
<div class="add-icon waiting-icon"> |
|
||||
<PlusIcon class="w-8 h-8" /> |
|
||||
</div> |
|
||||
<div class="add-text"> |
|
||||
<div class="slot-title">等待位</div> |
|
||||
<div class="slot-subtitle">点击添加学员</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<!-- Bottom Popup Modal --> |
|
||||
<div v-if="showModal" class="modal-overlay" @click="closeModal"> |
|
||||
<div class="modal-content" @click.stop> |
|
||||
<div class="modal-header"> |
|
||||
<h3>添加学员</h3> |
|
||||
</div> |
|
||||
|
|
||||
<div class="modal-body"> |
|
||||
<!-- Customer Selection --> |
|
||||
<div class="form-section"> |
|
||||
<label class="form-label">客户选择</label> |
|
||||
<div class="search-tabs"> |
|
||||
<button |
|
||||
:class="['tab-btn', { active: searchType === 'phone' }]" |
|
||||
@click="searchType = 'phone'" |
|
||||
> |
|
||||
手机号检索 |
|
||||
</button> |
|
||||
<button |
|
||||
:class="['tab-btn', { active: searchType === 'name' }]" |
|
||||
@click="searchType = 'name'" |
|
||||
> |
|
||||
姓名检索 |
|
||||
</button> |
|
||||
</div> |
|
||||
|
|
||||
<input |
|
||||
v-model="searchQuery" |
|
||||
:placeholder="searchType === 'phone' ? '请输入手机号' : '请输入姓名'" |
|
||||
class="search-input" |
|
||||
@input="searchStudents" |
|
||||
/> |
|
||||
|
|
||||
<!-- Search Results --> |
|
||||
<div v-if="searchResults.length > 0" class="search-results"> |
|
||||
<div |
|
||||
v-for="student in searchResults" |
|
||||
:key="student.id" |
|
||||
:class="['student-item', { selected: selectedStudent?.id === student.id }]" |
|
||||
@click="selectStudent(student)" |
|
||||
> |
|
||||
<div class="student-avatar">{{ student.name.charAt(0) }}</div> |
|
||||
<div class="student-details"> |
|
||||
<div class="student-name">{{ student.name }}</div> |
|
||||
<div class="student-phone">{{ student.phone }}</div> |
|
||||
</div> |
|
||||
<div v-if="selectedStudent?.id === student.id" class="check-icon"> |
|
||||
<CheckIcon class="w-5 h-5" /> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<!-- Course Arrangement --> |
|
||||
<div class="form-section"> |
|
||||
<label class="form-label">课程安排</label> |
|
||||
<div class="radio-group"> |
|
||||
<label class="radio-item"> |
|
||||
<input |
|
||||
type="radio" |
|
||||
value="temporary" |
|
||||
v-model="courseArrangement" |
|
||||
/> |
|
||||
<span class="radio-text">临时课</span> |
|
||||
</label> |
|
||||
<label class="radio-item"> |
|
||||
<input |
|
||||
type="radio" |
|
||||
value="fixed" |
|
||||
v-model="courseArrangement" |
|
||||
/> |
|
||||
<span class="radio-text">固定课</span> |
|
||||
</label> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<!-- Remarks --> |
|
||||
<div class="form-section"> |
|
||||
<label class="form-label">备注</label> |
|
||||
<textarea |
|
||||
v-model="remarks" |
|
||||
placeholder="请输入备注信息" |
|
||||
class="remarks-textarea" |
|
||||
rows="3" |
|
||||
></textarea> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<!-- Modal Footer --> |
|
||||
<div class="modal-footer"> |
|
||||
<button class="btn btn-cancel" @click="closeModal">取消</button> |
|
||||
<button class="btn btn-confirm" @click="confirmSelection">确定</button> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { ChevronLeftIcon, PlusIcon, CheckIcon } from 'lucide-vue-next' |
|
||||
|
|
||||
export default { |
|
||||
name: 'CourseSchedule', |
|
||||
components: { |
|
||||
ChevronLeftIcon, |
|
||||
PlusIcon, |
|
||||
CheckIcon |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
showModal: false, |
|
||||
searchType: 'phone', |
|
||||
searchQuery: '', |
|
||||
courseArrangement: 'temporary', |
|
||||
remarks: '', |
|
||||
selectedStudent: null, |
|
||||
currentSlot: null, |
|
||||
searchResults: [], |
|
||||
// Mock student data |
|
||||
allStudents: [ |
|
||||
{ id: 1, name: '张小明', phone: '13800138001', age: 8 }, |
|
||||
{ id: 2, name: '李小红', phone: '13800138002', age: 9 }, |
|
||||
{ id: 3, name: '王小华', phone: '13800138003', age: 7 }, |
|
||||
{ id: 4, name: '赵小强', phone: '13800138004', age: 10 } |
|
||||
] |
|
||||
} |
|
||||
}, |
|
||||
methods: { |
|
||||
goBack() { |
|
||||
this.$router.go(-1) |
|
||||
}, |
|
||||
openStudentModal(type, index) { |
|
||||
this.showModal = true |
|
||||
this.currentSlot = { type, index } |
|
||||
this.resetForm() |
|
||||
}, |
|
||||
closeModal() { |
|
||||
this.showModal = false |
|
||||
this.resetForm() |
|
||||
}, |
|
||||
resetForm() { |
|
||||
this.searchQuery = '' |
|
||||
this.searchResults = [] |
|
||||
this.selectedStudent = null |
|
||||
this.courseArrangement = 'temporary' |
|
||||
this.remarks = '' |
|
||||
}, |
|
||||
searchStudents() { |
|
||||
if (!this.searchQuery.trim()) { |
|
||||
this.searchResults = [] |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.searchResults = this.allStudents.filter(student => { |
|
||||
if (this.searchType === 'phone') { |
|
||||
return student.phone.includes(this.searchQuery) |
|
||||
} else { |
|
||||
return student.name.includes(this.searchQuery) |
|
||||
} |
|
||||
}) |
|
||||
}, |
|
||||
selectStudent(student) { |
|
||||
this.selectedStudent = student |
|
||||
}, |
|
||||
confirmSelection() { |
|
||||
if (!this.selectedStudent) { |
|
||||
alert('请选择学员') |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
// Here you would typically save the selection |
|
||||
console.log('Selected:', { |
|
||||
student: this.selectedStudent, |
|
||||
slot: this.currentSlot, |
|
||||
arrangement: this.courseArrangement, |
|
||||
remarks: this.remarks |
|
||||
}) |
|
||||
|
|
||||
this.closeModal() |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style scoped> |
|
||||
.course-schedule { |
|
||||
min-height: 100vh; |
|
||||
background: #1a1a1a; |
|
||||
color: white; |
|
||||
padding: 0; |
|
||||
} |
|
||||
|
|
||||
.header { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
padding: 16px 20px; |
|
||||
background: #2a2a2a; |
|
||||
} |
|
||||
|
|
||||
.back-btn { |
|
||||
margin-right: 16px; |
|
||||
cursor: pointer; |
|
||||
} |
|
||||
|
|
||||
.title { |
|
||||
font-size: 18px; |
|
||||
font-weight: 600; |
|
||||
margin: 0; |
|
||||
} |
|
||||
|
|
||||
.course-info { |
|
||||
padding: 24px 20px; |
|
||||
} |
|
||||
|
|
||||
.course-title { |
|
||||
font-size: 24px; |
|
||||
font-weight: 600; |
|
||||
margin: 0 0 12px 0; |
|
||||
} |
|
||||
|
|
||||
.course-time { |
|
||||
color: #4ade80; |
|
||||
font-size: 16px; |
|
||||
margin: 0; |
|
||||
} |
|
||||
|
|
||||
.section { |
|
||||
margin: 24px 20px; |
|
||||
} |
|
||||
|
|
||||
.section-title { |
|
||||
font-size: 18px; |
|
||||
font-weight: 600; |
|
||||
color: #fbbf24; |
|
||||
margin: 0 0 16px 0; |
|
||||
} |
|
||||
|
|
||||
.cards-grid { |
|
||||
display: grid; |
|
||||
grid-template-columns: 1fr 1fr; |
|
||||
gap: 12px; |
|
||||
} |
|
||||
|
|
||||
.student-card { |
|
||||
background: #2a2a2a; |
|
||||
border-radius: 12px; |
|
||||
padding: 16px; |
|
||||
min-height: 160px; |
|
||||
position: relative; |
|
||||
cursor: pointer; |
|
||||
transition: all 0.3s ease; |
|
||||
} |
|
||||
|
|
||||
.student-card.empty { |
|
||||
border: 2px dashed #fbbf24; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
text-align: center; |
|
||||
} |
|
||||
|
|
||||
.student-card.waiting { |
|
||||
border: 2px dashed #8b5cf6; |
|
||||
} |
|
||||
|
|
||||
.student-card.filled { |
|
||||
border: 1px solid #374151; |
|
||||
} |
|
||||
|
|
||||
.student-card:hover { |
|
||||
transform: translateY(-2px); |
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); |
|
||||
} |
|
||||
|
|
||||
.renewal-badge { |
|
||||
position: absolute; |
|
||||
top: 8px; |
|
||||
right: 8px; |
|
||||
background: #ef4444; |
|
||||
color: white; |
|
||||
font-size: 10px; |
|
||||
padding: 2px 6px; |
|
||||
border-radius: 8px; |
|
||||
} |
|
||||
|
|
||||
.avatar { |
|
||||
width: 32px; |
|
||||
height: 32px; |
|
||||
border-radius: 50%; |
|
||||
background: #4ade80; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
font-weight: 600; |
|
||||
margin-bottom: 8px; |
|
||||
} |
|
||||
|
|
||||
.student-info { |
|
||||
font-size: 12px; |
|
||||
line-height: 1.4; |
|
||||
} |
|
||||
|
|
||||
.student-name { |
|
||||
font-weight: 600; |
|
||||
margin-bottom: 4px; |
|
||||
overflow: hidden; |
|
||||
text-overflow: ellipsis; |
|
||||
white-space: nowrap; |
|
||||
} |
|
||||
|
|
||||
.student-age, |
|
||||
.course-status, |
|
||||
.course-arrangement, |
|
||||
.remaining-hours, |
|
||||
.expiry-date { |
|
||||
color: #9ca3af; |
|
||||
margin-bottom: 2px; |
|
||||
} |
|
||||
|
|
||||
.add-icon { |
|
||||
color: #fbbf24; |
|
||||
margin-bottom: 8px; |
|
||||
} |
|
||||
|
|
||||
.waiting-icon { |
|
||||
color: #8b5cf6; |
|
||||
} |
|
||||
|
|
||||
.add-text { |
|
||||
text-align: center; |
|
||||
} |
|
||||
|
|
||||
.slot-title { |
|
||||
font-size: 16px; |
|
||||
font-weight: 600; |
|
||||
margin-bottom: 4px; |
|
||||
} |
|
||||
|
|
||||
.slot-subtitle { |
|
||||
font-size: 12px; |
|
||||
color: #9ca3af; |
|
||||
} |
|
||||
|
|
||||
/* Modal Styles */ |
|
||||
.modal-overlay { |
|
||||
position: fixed; |
|
||||
top: 0; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
bottom: 0; |
|
||||
background: rgba(0, 0, 0, 0.5); |
|
||||
display: flex; |
|
||||
align-items: flex-end; |
|
||||
z-index: 1000; |
|
||||
} |
|
||||
|
|
||||
.modal-content { |
|
||||
background: white; |
|
||||
border-radius: 16px 16px 0 0; |
|
||||
width: 100%; |
|
||||
max-height: 80vh; |
|
||||
overflow-y: auto; |
|
||||
animation: slideUp 0.3s ease-out; |
|
||||
} |
|
||||
|
|
||||
@keyframes slideUp { |
|
||||
from { |
|
||||
transform: translateY(100%); |
|
||||
} |
|
||||
to { |
|
||||
transform: translateY(0); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.modal-header { |
|
||||
padding: 20px; |
|
||||
border-bottom: 1px solid #e5e7eb; |
|
||||
text-align: center; |
|
||||
} |
|
||||
|
|
||||
.modal-header h3 { |
|
||||
margin: 0; |
|
||||
font-size: 18px; |
|
||||
font-weight: 600; |
|
||||
color: #1f2937; |
|
||||
} |
|
||||
|
|
||||
.modal-body { |
|
||||
padding: 20px; |
|
||||
color: #1f2937; |
|
||||
} |
|
||||
|
|
||||
.form-section { |
|
||||
margin-bottom: 24px; |
|
||||
} |
|
||||
|
|
||||
.form-label { |
|
||||
display: block; |
|
||||
font-weight: 600; |
|
||||
margin-bottom: 8px; |
|
||||
color: #374151; |
|
||||
} |
|
||||
|
|
||||
.search-tabs { |
|
||||
display: flex; |
|
||||
margin-bottom: 12px; |
|
||||
background: #f3f4f6; |
|
||||
border-radius: 8px; |
|
||||
padding: 4px; |
|
||||
} |
|
||||
|
|
||||
.tab-btn { |
|
||||
flex: 1; |
|
||||
padding: 8px 16px; |
|
||||
border: none; |
|
||||
background: transparent; |
|
||||
border-radius: 6px; |
|
||||
font-size: 14px; |
|
||||
cursor: pointer; |
|
||||
transition: all 0.2s; |
|
||||
} |
|
||||
|
|
||||
.tab-btn.active { |
|
||||
background: white; |
|
||||
color: #1f2937; |
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); |
|
||||
} |
|
||||
|
|
||||
.search-input { |
|
||||
width: 100%; |
|
||||
padding: 12px; |
|
||||
border: 1px solid #d1d5db; |
|
||||
border-radius: 8px; |
|
||||
font-size: 16px; |
|
||||
} |
|
||||
|
|
||||
.search-results { |
|
||||
max-height: 200px; |
|
||||
overflow-y: auto; |
|
||||
border: 1px solid #e5e7eb; |
|
||||
border-radius: 8px; |
|
||||
margin-top: 8px; |
|
||||
} |
|
||||
|
|
||||
.student-item { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
padding: 12px; |
|
||||
border-bottom: 1px solid #f3f4f6; |
|
||||
cursor: pointer; |
|
||||
transition: background 0.2s; |
|
||||
} |
|
||||
|
|
||||
.student-item:hover { |
|
||||
background: #f9fafb; |
|
||||
} |
|
||||
|
|
||||
.student-item.selected { |
|
||||
background: #eff6ff; |
|
||||
border-color: #3b82f6; |
|
||||
} |
|
||||
|
|
||||
.student-avatar { |
|
||||
width: 40px; |
|
||||
height: 40px; |
|
||||
border-radius: 50%; |
|
||||
background: #3b82f6; |
|
||||
color: white; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
font-weight: 600; |
|
||||
margin-right: 12px; |
|
||||
} |
|
||||
|
|
||||
.student-details { |
|
||||
flex: 1; |
|
||||
} |
|
||||
|
|
||||
.student-details .student-name { |
|
||||
font-weight: 600; |
|
||||
margin-bottom: 4px; |
|
||||
} |
|
||||
|
|
||||
.student-details .student-phone { |
|
||||
color: #6b7280; |
|
||||
font-size: 14px; |
|
||||
} |
|
||||
|
|
||||
.check-icon { |
|
||||
color: #3b82f6; |
|
||||
} |
|
||||
|
|
||||
.radio-group { |
|
||||
display: flex; |
|
||||
gap: 16px; |
|
||||
} |
|
||||
|
|
||||
.radio-item { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
cursor: pointer; |
|
||||
} |
|
||||
|
|
||||
.radio-item input[type="radio"] { |
|
||||
margin-right: 8px; |
|
||||
} |
|
||||
|
|
||||
.radio-text { |
|
||||
font-size: 14px; |
|
||||
} |
|
||||
|
|
||||
.remarks-textarea { |
|
||||
width: 100%; |
|
||||
padding: 12px; |
|
||||
border: 1px solid #d1d5db; |
|
||||
border-radius: 8px; |
|
||||
font-size: 14px; |
|
||||
resize: vertical; |
|
||||
font-family: inherit; |
|
||||
} |
|
||||
|
|
||||
.modal-footer { |
|
||||
padding: 20px; |
|
||||
border-top: 1px solid #e5e7eb; |
|
||||
display: flex; |
|
||||
gap: 12px; |
|
||||
} |
|
||||
|
|
||||
.btn { |
|
||||
flex: 1; |
|
||||
padding: 12px 24px; |
|
||||
border-radius: 8px; |
|
||||
font-size: 16px; |
|
||||
font-weight: 600; |
|
||||
cursor: pointer; |
|
||||
transition: all 0.2s; |
|
||||
} |
|
||||
|
|
||||
.btn-cancel { |
|
||||
background: #f3f4f6; |
|
||||
color: #374151; |
|
||||
border: 1px solid #d1d5db; |
|
||||
} |
|
||||
|
|
||||
.btn-cancel:hover { |
|
||||
background: #e5e7eb; |
|
||||
} |
|
||||
|
|
||||
.btn-confirm { |
|
||||
background: #3b82f6; |
|
||||
color: white; |
|
||||
border: 1px solid #3b82f6; |
|
||||
} |
|
||||
|
|
||||
.btn-confirm:hover { |
|
||||
background: #2563eb; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,549 +0,0 @@ |
|||||
<!--重构后的客户详情页面 - 使用组件化方式--> |
|
||||
<template> |
|
||||
<view class="assemble"> |
|
||||
<view class="main_box"> |
|
||||
<view style="height: 20rpx;background: #29D3B4;"></view> |
|
||||
|
|
||||
<!-- 头部信息区域 --> |
|
||||
<view class="count_section"> |
|
||||
<view class="main"> |
|
||||
<view class="course_box"> |
|
||||
<view class="course_box_top"> |
|
||||
<view class="course_box_top_top"> |
|
||||
<image class="pic" :src="$util.img('/uniapp_src/static/images/index/myk.png')"></image> |
|
||||
<view class="name">{{ $util.safeGet(clientInfo, 'customerResource.name', '未知客户') }}</view> |
|
||||
</view> |
|
||||
<view class="course_box_top_below"> |
|
||||
<view class="course_box_top_below-right"> |
|
||||
<!-- 操作按钮 --> |
|
||||
<view class="action-buttons"> |
|
||||
<view class="btn-item" @click="handleMakeCall"> |
|
||||
<image class="btn-icon" :src="$util.img('/uniapp_src/static/images/index/phone.png')"></image> |
|
||||
</view> |
|
||||
<view class="btn-item" @click="handleSendMessage" v-if="$util.safeGet(clientInfo, 'customerResource.member_id')"> |
|
||||
<image class="btn-icon" :src="$util.img('/uniapp_src/static/images/index/message.png')"></image> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 标签切换组件 --> |
|
||||
<TabSwitcher |
|
||||
:tabs="tabs" |
|
||||
:active-tab-id="switch_tags_type" |
|
||||
@tab-change="handleTabChange" |
|
||||
/> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="bg_box bg_top"></view> |
|
||||
<view class="bg_box bg_bottom"></view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 基本资料 --> |
|
||||
<view class="content-section" v-if="switch_tags_type == 1"> |
|
||||
<view class="integrated-info-section"> |
|
||||
<view class="basic-message"> |
|
||||
<view>客户和学生信息</view> |
|
||||
<view class="add-student-btn" @click="openAddStudentDialog"> |
|
||||
<view class="add-icon">+</view> |
|
||||
<view class="add-text">添加学生</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 使用客户信息卡片组件 --> |
|
||||
<ClientInfoCard |
|
||||
:client-info="clientInfo" |
|
||||
@call="handleMakeCall" |
|
||||
/> |
|
||||
|
|
||||
<!-- 学生信息列表 --> |
|
||||
<view class="student-list" v-if="studentList.length > 0"> |
|
||||
<StudentInfoCard |
|
||||
v-for="student in studentList" |
|
||||
:key="student.id" |
|
||||
:student="student" |
|
||||
:actions="studentActions" |
|
||||
@toggle-actions="toggleStudentActions" |
|
||||
@action="handleStudentAction" |
|
||||
/> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 课程信息 --> |
|
||||
<view class="content-section" v-else-if="switch_tags_type == 2"> |
|
||||
<view class="course-info-section"> |
|
||||
<text>课程信息内容...</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 通话记录 --> |
|
||||
<view class="content-section" v-else-if="switch_tags_type == 3"> |
|
||||
<view class="call-records-section"> |
|
||||
<CallRecordCard |
|
||||
v-for="record in listCallUp" |
|
||||
:key="record.id" |
|
||||
:record="record" |
|
||||
/> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 体测记录 --> |
|
||||
<view class="content-section" v-else-if="switch_tags_type == 4"> |
|
||||
<view class="fitness-records-section"> |
|
||||
<FitnessRecordCard |
|
||||
v-for="record in fitnessRecords" |
|
||||
:key="record.id" |
|
||||
:record="record" |
|
||||
@file-click="handleFitnessFileClick" |
|
||||
/> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 学习计划 --> |
|
||||
<view class="content-section" v-else-if="switch_tags_type == 5"> |
|
||||
<view class="study-plan-section"> |
|
||||
<text>学习计划内容...</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import apiRoute from '@/api/apiRoute.js' |
|
||||
import marketApi from '@/api/marketApi.js' |
|
||||
// 导入组件 |
|
||||
import ClientInfoCard from '@/components/client-info-card/client-info-card.vue' |
|
||||
import StudentInfoCard from '@/components/student-info-card/student-info-card.vue' |
|
||||
import TabSwitcher from '@/components/tab-switcher/tab-switcher.vue' |
|
||||
import FitnessRecordCard from '@/components/fitness-record-card/fitness-record-card.vue' |
|
||||
import CallRecordCard from '@/components/call-record-card/call-record-card.vue' |
|
||||
|
|
||||
export default { |
|
||||
name: 'ClueInfoRefactored', |
|
||||
components: { |
|
||||
ClientInfoCard, |
|
||||
StudentInfoCard, |
|
||||
TabSwitcher, |
|
||||
FitnessRecordCard, |
|
||||
CallRecordCard |
|
||||
}, |
|
||||
|
|
||||
data() { |
|
||||
return { |
|
||||
resource_sharing_id: '', |
|
||||
switch_tags_type: 1, // 默认显示基本资料 |
|
||||
|
|
||||
// 标签配置 |
|
||||
tabs: [ |
|
||||
{ id: 1, name: '基本资料' }, |
|
||||
{ id: 2, name: '课程信息' }, |
|
||||
{ id: 3, name: '通话记录' }, |
|
||||
{ id: 4, name: '体测记录' }, |
|
||||
{ id: 5, name: '学习计划' } |
|
||||
], |
|
||||
|
|
||||
// 学生操作按钮配置 |
|
||||
studentActions: [ |
|
||||
{ key: 'edit', text: '编辑学生' }, |
|
||||
{ key: 'order', text: '查看订单' }, |
|
||||
{ key: 'course', text: '课程安排' }, |
|
||||
{ key: 'fitness', text: '体测记录' } |
|
||||
], |
|
||||
|
|
||||
// 数据 |
|
||||
clientInfo: {}, |
|
||||
userInfo: {}, |
|
||||
studentList: [], |
|
||||
listCallUp: [], |
|
||||
fitnessRecords: [], |
|
||||
followList: [], |
|
||||
courseInfo: [], |
|
||||
coachList: [], |
|
||||
educationList: [], |
|
||||
assistantList: [] |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
onLoad(option) { |
|
||||
console.log('页面加载参数:', option) |
|
||||
this.resource_sharing_id = option.resource_sharing_id || '' |
|
||||
this.init() |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
async init() { |
|
||||
console.log('开始初始化数据...') |
|
||||
try { |
|
||||
await this.getInfo() |
|
||||
await Promise.all([ |
|
||||
this.getUserInfo(), |
|
||||
this.getListCallUp(), |
|
||||
this.getStudentList(), |
|
||||
this.getFitnessRecords() |
|
||||
]) |
|
||||
console.log('数据初始化完成') |
|
||||
} catch (error) { |
|
||||
console.error('初始化失败:', error) |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 获取客户详情 |
|
||||
async getInfo() { |
|
||||
if (!this.resource_sharing_id) { |
|
||||
uni.showToast({ title: '缺少必要参数', icon: 'none' }) |
|
||||
return false |
|
||||
} |
|
||||
|
|
||||
try { |
|
||||
const res = await apiRoute.xs_resourceSharingInfo({ |
|
||||
resource_sharing_id: this.resource_sharing_id |
|
||||
}) |
|
||||
|
|
||||
if (res.code === 1) { |
|
||||
this.clientInfo = res.data |
|
||||
return true |
|
||||
} else { |
|
||||
uni.showToast({ title: res.msg, icon: 'none' }) |
|
||||
return false |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.error('获取客户详情失败:', error) |
|
||||
return false |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 获取员工信息 |
|
||||
async getUserInfo() { |
|
||||
try { |
|
||||
const res = await apiRoute.getPersonnelInfo({}) |
|
||||
if (res.code === 1) { |
|
||||
this.userInfo = res.data |
|
||||
return true |
|
||||
} |
|
||||
return false |
|
||||
} catch (error) { |
|
||||
console.error('获取员工信息失败:', error) |
|
||||
return false |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 获取通话记录 |
|
||||
async getListCallUp() { |
|
||||
if (!this.clientInfo.resource_id) return false |
|
||||
|
|
||||
try { |
|
||||
const res = await apiRoute.listCallUp({ |
|
||||
resource_id: this.clientInfo.resource_id |
|
||||
}) |
|
||||
|
|
||||
if (res.code === 1) { |
|
||||
this.listCallUp = res.data || [] |
|
||||
return true |
|
||||
} |
|
||||
return false |
|
||||
} catch (error) { |
|
||||
console.error('获取通话记录失败:', error) |
|
||||
return false |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 获取学生列表 |
|
||||
async getStudentList() { |
|
||||
try { |
|
||||
if (!this.clientInfo.resource_id) { |
|
||||
// 使用Mock数据 |
|
||||
this.studentList = this.getMockStudentList() |
|
||||
return true |
|
||||
} |
|
||||
|
|
||||
const res = await apiRoute.xs_getStudentList({ |
|
||||
parent_resource_id: this.clientInfo.resource_id |
|
||||
}) |
|
||||
|
|
||||
if (res.code === 1) { |
|
||||
this.studentList = res.data || [] |
|
||||
} else { |
|
||||
this.studentList = this.getMockStudentList() |
|
||||
} |
|
||||
return true |
|
||||
} catch (error) { |
|
||||
console.error('获取学生列表失败:', error) |
|
||||
this.studentList = this.getMockStudentList() |
|
||||
return true |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 获取体测记录 |
|
||||
async getFitnessRecords() { |
|
||||
try { |
|
||||
// 使用Mock数据 |
|
||||
this.fitnessRecords = this.getMockFitnessRecords() |
|
||||
return true |
|
||||
} catch (error) { |
|
||||
console.error('获取体测记录失败:', error) |
|
||||
return false |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// Mock数据方法 |
|
||||
getMockStudentList() { |
|
||||
return [ |
|
||||
{ |
|
||||
id: 1, |
|
||||
name: '张小明', |
|
||||
gender: 1, |
|
||||
age: 9.05, |
|
||||
birthday: '2015-05-10', |
|
||||
emergency_contact: '张妈妈', |
|
||||
contact_phone: '13800138001', |
|
||||
member_label: '新学员', |
|
||||
note: '活泼好动,喜欢运动', |
|
||||
actionsExpanded: false |
|
||||
} |
|
||||
] |
|
||||
}, |
|
||||
|
|
||||
getMockFitnessRecords() { |
|
||||
return [ |
|
||||
{ |
|
||||
id: 1, |
|
||||
test_date: '2024-01-15', |
|
||||
height: '165', |
|
||||
weight: '55', |
|
||||
pdf_files: [ |
|
||||
{ |
|
||||
id: 1, |
|
||||
name: '体测报告_2024-01-15.pdf', |
|
||||
size: 1024000, |
|
||||
url: '/static/mock/fitness_report_1.pdf' |
|
||||
} |
|
||||
] |
|
||||
} |
|
||||
] |
|
||||
}, |
|
||||
|
|
||||
// 事件处理方法 |
|
||||
handleTabChange({ tabId }) { |
|
||||
this.switch_tags_type = tabId |
|
||||
}, |
|
||||
|
|
||||
handleMakeCall() { |
|
||||
const phoneNumber = this.$util.safeGet(this.clientInfo, 'customerResource.phone_number', '') |
|
||||
this.$util.makePhoneCall(phoneNumber) |
|
||||
}, |
|
||||
|
|
||||
handleSendMessage() { |
|
||||
uni.showToast({ |
|
||||
title: '发送消息功能待实现', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
toggleStudentActions(student) { |
|
||||
const index = this.studentList.findIndex(s => s.id === student.id) |
|
||||
if (index !== -1) { |
|
||||
this.$set(this.studentList[index], 'actionsExpanded', !student.actionsExpanded) |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
handleStudentAction({ action, student }) { |
|
||||
console.log('学生操作:', action, student) |
|
||||
|
|
||||
switch (action.key) { |
|
||||
case 'edit': |
|
||||
this.editStudent(student) |
|
||||
break |
|
||||
case 'order': |
|
||||
this.viewStudentOrders(student) |
|
||||
break |
|
||||
case 'course': |
|
||||
this.viewStudentCourse(student) |
|
||||
break |
|
||||
case 'fitness': |
|
||||
this.viewStudentFitness(student) |
|
||||
break |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
handleFitnessFileClick({ file, record }) { |
|
||||
console.log('点击体测文件:', file, record) |
|
||||
// 实现文件查看逻辑 |
|
||||
}, |
|
||||
|
|
||||
openAddStudentDialog() { |
|
||||
console.log('打开添加学生对话框') |
|
||||
// 实现添加学生逻辑 |
|
||||
}, |
|
||||
|
|
||||
// 学生操作相关方法 |
|
||||
editStudent(student) { |
|
||||
this.$util.navigateToPage('/pages/student/edit', { |
|
||||
student_id: student.id |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
viewStudentOrders(student) { |
|
||||
this.$util.navigateToPage('/pages/market/clue/order_list', { |
|
||||
resource_id: this.clientInfo.resource_id, |
|
||||
student_id: student.id, |
|
||||
student_name: student.name |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
viewStudentCourse(student) { |
|
||||
this.$util.navigateToPage('/pages/market/clue/course_arrange', { |
|
||||
resource_id: this.clientInfo.resource_id, |
|
||||
student_id: student.id, |
|
||||
student_name: student.name |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
viewStudentFitness(student) { |
|
||||
this.$util.navigateToPage('/pages/fitness/records', { |
|
||||
student_id: student.id |
|
||||
}) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.assemble { |
|
||||
width: 100%; |
|
||||
height: 100vh; |
|
||||
overflow: auto; |
|
||||
background-color: #292929; |
|
||||
} |
|
||||
|
|
||||
.main_box { |
|
||||
background: #292929; |
|
||||
min-height: 20vh; |
|
||||
} |
|
||||
|
|
||||
.action-buttons { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
|
|
||||
.btn-item { |
|
||||
width: 60rpx; |
|
||||
height: 60rpx; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
margin-left: 20rpx; |
|
||||
|
|
||||
.btn-icon { |
|
||||
width: 40rpx; |
|
||||
height: 40rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.count_section { |
|
||||
width: 100%; |
|
||||
position: relative; |
|
||||
|
|
||||
.main { |
|
||||
width: 100%; |
|
||||
position: absolute; |
|
||||
z-index: 2; |
|
||||
padding: 0rpx 24rpx; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
|
|
||||
.course_box { |
|
||||
padding: 26rpx 22rpx 0 22rpx; |
|
||||
width: 95%; |
|
||||
height: 250rpx; |
|
||||
border-radius: 20rpx; |
|
||||
background-color: #fff; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.bg_top { |
|
||||
height: 180rpx; |
|
||||
background-color: #29D3B4; |
|
||||
} |
|
||||
|
|
||||
.bg_bottom { |
|
||||
height: 80rpx; |
|
||||
background-color: #292929; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.course_box_top { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
|
|
||||
.course_box_top_top { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
|
|
||||
.pic { |
|
||||
width: 60rpx; |
|
||||
height: 60rpx; |
|
||||
margin-right: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.name { |
|
||||
font-size: 32rpx; |
|
||||
font-weight: bold; |
|
||||
color: #333; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.content-section { |
|
||||
background-color: #292929; |
|
||||
min-height: 60vh; |
|
||||
padding: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.integrated-info-section { |
|
||||
.basic-message { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
padding: 30rpx 20rpx; |
|
||||
color: white; |
|
||||
font-size: 28rpx; |
|
||||
font-weight: bold; |
|
||||
|
|
||||
.add-student-btn { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
background-color: #29d3b4; |
|
||||
padding: 15rpx 25rpx; |
|
||||
border-radius: 25rpx; |
|
||||
|
|
||||
.add-icon { |
|
||||
color: white; |
|
||||
font-size: 24rpx; |
|
||||
margin-right: 10rpx; |
|
||||
} |
|
||||
|
|
||||
.add-text { |
|
||||
color: white; |
|
||||
font-size: 22rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.student-list, |
|
||||
.call-records-section, |
|
||||
.fitness-records-section { |
|
||||
padding: 20rpx 0; |
|
||||
} |
|
||||
|
|
||||
.course-info-section, |
|
||||
.study-plan-section { |
|
||||
padding: 40rpx 20rpx; |
|
||||
color: white; |
|
||||
text-align: center; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,425 +0,0 @@ |
|||||
<template> |
|
||||
<view class="assemble"> |
|
||||
<view class="title">跟进任务</view> |
|
||||
<view class="form-style"> |
|
||||
<fui-form class="input-style" ref="form" top="0" :model="formData" :show="false"> |
|
||||
<!--基础表单--> |
|
||||
<!--下拉--> |
|
||||
<fui-form-item |
|
||||
asterisk |
|
||||
label="跟进类型" |
|
||||
asteriskPosition="right" |
|
||||
labelSize='26' |
|
||||
prop="" |
|
||||
background='#434544' |
|
||||
labelColor='#fff' |
|
||||
:bottomBorder='false' |
|
||||
> |
|
||||
<view class="input-title" style="margin-right:14rpx;"> |
|
||||
<view v-if="!formData.entry_type" class="input-title" style="margin-right:14rpx;" @click="selectCon(`entry_type`)">点击选择 |
|
||||
</view> |
|
||||
<view v-else class="input-title" style="margin-right:14rpx;" @click="selectCon(`entry_type`)"> |
|
||||
{{ str_entry_type }} |
|
||||
</view> |
|
||||
</view> |
|
||||
</fui-form-item> |
|
||||
|
|
||||
<!--下拉--> |
|
||||
<fui-form-item |
|
||||
asterisk |
|
||||
label="跟进人员" |
|
||||
asteriskPosition="right" |
|
||||
labelSize='26' |
|
||||
prop="" |
|
||||
background='#434544' |
|
||||
labelColor='#fff' |
|
||||
:bottomBorder='false' |
|
||||
> |
|
||||
<view class="input-title" style="margin-right:14rpx;"> |
|
||||
<view v-if="!formData.follow_staff_id" class="input-title" style="margin-right:14rpx;" @click="selectCon(`follow_staff_id`)">点击选择 |
|
||||
</view> |
|
||||
<view v-else class="input-title" style="margin-right:14rpx;" @click="selectCon(`follow_staff_id`)"> |
|
||||
{{ str_follow_staff_id }} |
|
||||
</view> |
|
||||
</view> |
|
||||
</fui-form-item> |
|
||||
|
|
||||
<!--下拉--> |
|
||||
<fui-form-item |
|
||||
asterisk |
|
||||
label="跟进时间" |
|
||||
asteriskPosition="right" |
|
||||
labelSize='26' |
|
||||
prop="" |
|
||||
background='#434544' |
|
||||
labelColor='#fff' |
|
||||
:bottomBorder='false' |
|
||||
> |
|
||||
<view class="input-title" style="margin-right:14rpx;"> |
|
||||
<view v-if="!formData.reminder_time" class="input-title" style="margin-right:14rpx;" @click="selectCon(`reminder_time`)">点击选择 |
|
||||
</view> |
|
||||
<view v-else class="input-title" style="margin-right:14rpx;" @click="selectCon(`reminder_time`)"> |
|
||||
{{ formData.reminder_time }} |
|
||||
</view> |
|
||||
</view> |
|
||||
</fui-form-item> |
|
||||
|
|
||||
<!--手写--> |
|
||||
<fui-form-item |
|
||||
label="备注" |
|
||||
asteriskPosition="right" |
|
||||
labelSize='26' |
|
||||
prop="" |
|
||||
background='#434544' |
|
||||
labelColor='#fff' |
|
||||
:bottomBorder='false' |
|
||||
> |
|
||||
<view class="input-title" style="margin-right:14rpx;"> |
|
||||
<fui-input :borderBottom="false" :padding="[0]" placeholder="点击填写" v-model="formData.follow_content" |
|
||||
backgroundColor="#434544" size="26" color="#fff"></fui-input> |
|
||||
</view> |
|
||||
</fui-form-item> |
|
||||
</fui-form> |
|
||||
</view> |
|
||||
<view class="fui-btn__box"> |
|
||||
<fui-button background="#434544" color="#24BA9F" borderColor="#24BA9F" @click="submit">保存</fui-button> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 年月日-选择时间 --> |
|
||||
<fui-date-picker :show="show_date" type="5" @change="change_date" @cancel="cancel_date"></fui-date-picker> |
|
||||
|
|
||||
<!-- 下拉选择器 --> |
|
||||
<fui-picker :linkage='linkage' :options="options" :layer="1" :show="show" @change="changeOptions" |
|
||||
@cancel="cancel"></fui-picker> |
|
||||
|
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import marketApi from '@/api/market.js'; |
|
||||
import memberApi from '@/api/member.js'; |
|
||||
|
|
||||
const rules = [{ |
|
||||
name: "mobile", |
|
||||
rule: ["required", "isMobile"], |
|
||||
msg: ["请输入手机号", "请输入正确的手机号"] |
|
||||
}]; |
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
rules, |
|
||||
|
|
||||
is_submit: true,//是否提交(防止重复提交)|true=可提交,false=不可提交 |
|
||||
|
|
||||
//表单数据 |
|
||||
formData:{ |
|
||||
//##### 基础表单 ##### |
|
||||
entry_type:'',//跟进类型(1=市场人员录入的,2=销售人员录入) |
|
||||
follow_staff_id:'',//跟进人员 |
|
||||
reminder_time:'',//跟进时间 |
|
||||
follow_content:'',//备注 |
|
||||
}, |
|
||||
|
|
||||
//下拉选择器组件 |
|
||||
options_type: undefined,//选择器标识 |
|
||||
show: false,//是否显示下拉选择器 |
|
||||
linkage: true,//是否联动选择 |
|
||||
options: [ |
|
||||
// { |
|
||||
// 'value': 1, |
|
||||
// 'text': '类型1' |
|
||||
// } |
|
||||
],//下拉选择器可选值列表 |
|
||||
|
|
||||
//时间选择器相关 |
|
||||
show_date: false,//是否显示时间选择器|true=是,false=否 |
|
||||
|
|
||||
//跟进类型-相关 |
|
||||
//字典-跟进类型 |
|
||||
options_entry_type:[ |
|
||||
{ |
|
||||
value: 1, |
|
||||
text: '市场人员' |
|
||||
}, |
|
||||
{ |
|
||||
value: 2, |
|
||||
text: '销售人员' |
|
||||
}, |
|
||||
], |
|
||||
//文本展示-跟进类型 |
|
||||
str_entry_type:'', |
|
||||
|
|
||||
//跟进人员-相关 |
|
||||
//字典-跟进人员 |
|
||||
options_follow_staff_id_sc:[],//(市场-跟进人员) |
|
||||
options_follow_staff_id_xs:[],//(销售-跟进人员) |
|
||||
//文本展示-跟进人员 |
|
||||
str_follow_staff_id:'', |
|
||||
|
|
||||
|
|
||||
} |
|
||||
}, |
|
||||
onShow() { |
|
||||
this.init() |
|
||||
}, |
|
||||
methods: { |
|
||||
|
|
||||
//初始化 |
|
||||
async init() { |
|
||||
this.getUserInfo() |
|
||||
//获取字典-跟进人员(市场) |
|
||||
this.getDic_staff_id('5') |
|
||||
//获取字典-跟进人员(销售) |
|
||||
this.getDic_staff_id('6') |
|
||||
}, |
|
||||
|
|
||||
//获取当前登陆用户信息 |
|
||||
async getUserInfo(){ |
|
||||
let res = await marketApi.member({}) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
console.log(111,res.data) |
|
||||
this.formData.staff_id = res.data.staff_id//基础表单->跟进人员 |
|
||||
this.str_staff_id = res.data.name//基础表单->跟进人员名字 |
|
||||
}, |
|
||||
|
|
||||
//获取字典-跟进人员(全部) |
|
||||
//获取人员列表 role_id|5=市场,6=销售 |
|
||||
async getDic_staff_id(role_id){ |
|
||||
let res = await memberApi.staffList({ |
|
||||
type: 2, |
|
||||
role_id:role_id |
|
||||
}) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
let arr = [] |
|
||||
res.data.forEach((v,k)=>{ |
|
||||
arr.push({ |
|
||||
text: v.name, |
|
||||
value: v.id, |
|
||||
}) |
|
||||
}) |
|
||||
|
|
||||
if(role_id == 5){ |
|
||||
this.options_follow_staff_id_sc = arr |
|
||||
console.log('市场',arr) |
|
||||
}else if(role_id == 6){ |
|
||||
this.options_follow_staff_id_xs = arr |
|
||||
console.log('销售',arr) |
|
||||
}else{ |
|
||||
//全部 |
|
||||
this.options_staff_id = arr |
|
||||
console.log('全部',arr) |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
//表单验证 |
|
||||
async validatorForm(data) { |
|
||||
//跟进类型 |
|
||||
if(!data.entry_type){ |
|
||||
uni.showToast({ |
|
||||
title: '跟进类型必填', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return false |
|
||||
} |
|
||||
//跟进人员 |
|
||||
if(!data.follow_staff_id){ |
|
||||
uni.showToast({ |
|
||||
title: '跟进人员必填', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return false |
|
||||
} |
|
||||
//跟进时间 |
|
||||
if(!data.reminder_time){ |
|
||||
uni.showToast({ |
|
||||
title: '跟进时间必填', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return false |
|
||||
} |
|
||||
return true |
|
||||
}, |
|
||||
//提交 |
|
||||
async submit() { |
|
||||
console.log('提交',this.formData) |
|
||||
let data = {...this.formData} |
|
||||
//表单验证 |
|
||||
let validatorForm = await this.validatorForm(data) |
|
||||
console.log('验证结果',validatorForm) |
|
||||
if(!validatorForm){ |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
//防止重复提交 |
|
||||
if (!this.is_submit) { |
|
||||
return |
|
||||
} |
|
||||
this.is_submit = false |
|
||||
|
|
||||
let res = await marketApi.createTask(data)//转移跟进任务 |
|
||||
|
|
||||
this.is_submit = true |
|
||||
|
|
||||
if(res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'success' |
|
||||
}) |
|
||||
//延迟1s执行 |
|
||||
setTimeout(() => { |
|
||||
//跳转页面-线索列表 |
|
||||
//关闭当前页跳转新页面 |
|
||||
uni.redirectTo({ |
|
||||
url: `/pages/market/clue/index` |
|
||||
}) |
|
||||
}, 1000) |
|
||||
}, |
|
||||
//选择弹窗 |
|
||||
selectCon(type) { |
|
||||
this.options_type = type |
|
||||
switch (type) { |
|
||||
//跟进类型 |
|
||||
case 'entry_type': |
|
||||
this.options = this.options_entry_type |
|
||||
this.show = true |
|
||||
this.linkage = true |
|
||||
//清空跟进任务->跟进人员 |
|
||||
this.formData.follow_staff_id = '' |
|
||||
break; |
|
||||
//跟进任务->跟进人员 |
|
||||
case 'follow_staff_id': |
|
||||
if(!this.formData.entry_type){ |
|
||||
uni.showToast({ |
|
||||
title: '请先选择跟进类型', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
if(this.formData.entry_type == 1){ |
|
||||
//市场人员列表 |
|
||||
this.options = this.options_follow_staff_id_sc |
|
||||
}else{ |
|
||||
//销售人员列表 |
|
||||
this.options = this.options_follow_staff_id_xs |
|
||||
} |
|
||||
|
|
||||
this.show = true |
|
||||
this.linkage = true |
|
||||
break; |
|
||||
//跟进时间 |
|
||||
case 'reminder_time': |
|
||||
this.show_date = true |
|
||||
break; |
|
||||
} |
|
||||
}, |
|
||||
//监听-下拉选择框 |
|
||||
changeOptions(e) { |
|
||||
console.log('选择器选中',e) |
|
||||
this.show = false |
|
||||
let type = this.options_type |
|
||||
switch (type) { |
|
||||
//跟进类型 |
|
||||
case 'entry_type': |
|
||||
this.str_entry_type = e.text//选中的text值 |
|
||||
this.formData.entry_type = e.value//选中value值 |
|
||||
break; |
|
||||
//跟进人员 |
|
||||
case 'follow_staff_id': |
|
||||
this.str_follow_staff_id = e.text//选中的text值 |
|
||||
this.formData.follow_staff_id = e.value//选中value值 |
|
||||
break; |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
//关闭选择框 |
|
||||
cancel() { |
|
||||
this.show = false |
|
||||
}, |
|
||||
|
|
||||
//监听-时间选择器 |
|
||||
change_date(e) { |
|
||||
|
|
||||
this.show_date = false |
|
||||
//跟进时间 |
|
||||
let type = this.options_type |
|
||||
console.log('时间选择器',type,e) |
|
||||
let val = (e.result ?? '') |
|
||||
if(val){ |
|
||||
val = val + ':00' |
|
||||
} |
|
||||
|
|
||||
switch (type) { |
|
||||
//跟进任务->跟进时间 |
|
||||
case 'reminder_time': |
|
||||
this.formData.reminder_time = val |
|
||||
break; |
|
||||
} |
|
||||
}, |
|
||||
//关闭时间选择器 |
|
||||
cancel_date() { |
|
||||
this.show_date = false |
|
||||
}, |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.assemble { |
|
||||
width: 100%; |
|
||||
height: 100vh; |
|
||||
background: #292929; |
|
||||
} |
|
||||
|
|
||||
.title { |
|
||||
font-size: 26rpx; |
|
||||
color: #fff; |
|
||||
padding: 26rpx 0 26rpx 32rpx; |
|
||||
} |
|
||||
|
|
||||
.input-title { |
|
||||
font-size: 26rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
|
|
||||
.form-style { |
|
||||
width: 100%; |
|
||||
background: #434544; |
|
||||
} |
|
||||
|
|
||||
.form-style-vid { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: space-between; |
|
||||
padding: 12rpx 0; |
|
||||
} |
|
||||
|
|
||||
.input-style { |
|
||||
text-align: right !important; |
|
||||
} |
|
||||
|
|
||||
.fui-btn__box { |
|
||||
margin: 20rpx auto; |
|
||||
width: 92%; |
|
||||
|
|
||||
} |
|
||||
</style> |
|
||||
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -1,514 +0,0 @@ |
|||||
<template> |
|
||||
<view class="course-detail-container"> |
|
||||
<!-- 课程基本信息 --> |
|
||||
<view class="course-info-card"> |
|
||||
<view class="course-header"> |
|
||||
<text class="course-title">{{ courseInfo.course_name || '课程详情' }}</text> |
|
||||
<view :class="['course-status',getStatusClass(courseInfo.status)]"> |
|
||||
{{ getStatusText(courseInfo.status) }} |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="course-stats"> |
|
||||
<view class="stat-item"> |
|
||||
<text class="stat-label">总课时</text> |
|
||||
<text class="stat-value">{{ courseInfo.total_hours || 0 }}</text> |
|
||||
</view> |
|
||||
<view class="stat-item"> |
|
||||
<text class="stat-label">赠送课时</text> |
|
||||
<text class="stat-value">{{ courseInfo.gift_hours || 0 }}</text> |
|
||||
</view> |
|
||||
<view class="stat-item"> |
|
||||
<text class="stat-label">已用课时</text> |
|
||||
<text class="stat-value">{{ (courseInfo.use_total_hours || 0) + (courseInfo.use_gift_hours || 0) }}</text> |
|
||||
</view> |
|
||||
<view class="stat-item"> |
|
||||
<text class="stat-label">剩余课时</text> |
|
||||
<text class="stat-value remaining">{{ getRemainingHours() }}</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="course-dates"> |
|
||||
<text class="date-item">开始日期:{{ courseInfo.start_date || '--' }}</text> |
|
||||
<text class="date-item">结束日期:{{ courseInfo.end_date || '--' }}</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 课程安排列表 --> |
|
||||
<view class="section-title"> |
|
||||
<text class="title-text">课程安排</text> |
|
||||
<text class="title-count">({{ scheduleList.length }})</text> |
|
||||
</view> |
|
||||
|
|
||||
<view class="schedule-list"> |
|
||||
<view |
|
||||
v-for="(item, index) in scheduleList" |
|
||||
:key="item.id" |
|
||||
class="schedule-item" |
|
||||
@tap="showScheduleDetail(item)" |
|
||||
> |
|
||||
<view class="schedule-date"> |
|
||||
<text class="date-text">{{ formatDate(item.course_date) }}</text> |
|
||||
<text class="time-text">{{ item.time_slot }}</text> |
|
||||
</view> |
|
||||
|
|
||||
<view class="schedule-info"> |
|
||||
<view class="schedule-type"> |
|
||||
<text :class="['type-tag',getScheduleTypeClass(item.schedule_type)]"> |
|
||||
{{ getScheduleTypeText(item.schedule_type) }} |
|
||||
</text> |
|
||||
<text :class="['type-tag',getCourseTypeClass(item.course_type)]"> |
|
||||
{{ getCourseTypeText(item.course_type) }} |
|
||||
</text> |
|
||||
</view> |
|
||||
|
|
||||
<view class="schedule-status"> |
|
||||
<text :class="['status-tag',getScheduleStatusClass(item.status)]"> |
|
||||
{{ getScheduleStatusText(item.status) }} |
|
||||
</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="schedule-arrow"> |
|
||||
<text class="arrow-icon">></text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 课程使用记录 --> |
|
||||
<view class="section-title"> |
|
||||
<text class="title-text">使用记录</text> |
|
||||
<text class="title-count">({{ usageList.length }})</text> |
|
||||
</view> |
|
||||
|
|
||||
<view class="usage-list"> |
|
||||
<view |
|
||||
v-for="(item, index) in usageList" |
|
||||
:key="item.id" |
|
||||
class="usage-item" |
|
||||
> |
|
||||
<view class="usage-date"> |
|
||||
<text class="date-text">{{ formatDate(item.usage_date) }}</text> |
|
||||
<text class="time-text">{{ item.time_slot || '--' }}</text> |
|
||||
</view> |
|
||||
|
|
||||
<view class="usage-info"> |
|
||||
<text class="usage-hours">消耗课时:{{ item.hours_used || 0 }}</text> |
|
||||
<text class="usage-type">{{ item.usage_type || '正常上课' }}</text> |
|
||||
</view> |
|
||||
|
|
||||
<view class="usage-status"> |
|
||||
<text class="status-text confirmed">已确认</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 无数据提示 --> |
|
||||
<view v-if="scheduleList.length === 0 && usageList.length === 0" class="no-data"> |
|
||||
<text class="no-data-text">暂无课程安排和使用记录</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
courseId: '', |
|
||||
courseInfo: {}, |
|
||||
scheduleList: [], |
|
||||
usageList: [] |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
onLoad(options) { |
|
||||
this.courseId = options.courseId || '' |
|
||||
if (this.courseId) { |
|
||||
this.loadCourseDetail() |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
// 加载课程详情 |
|
||||
async loadCourseDetail() { |
|
||||
try { |
|
||||
uni.showLoading({ title: '加载中...' }) |
|
||||
|
|
||||
const res = await this.$http.get('/xy/course/detail', { |
|
||||
course_id: this.courseId |
|
||||
}) |
|
||||
|
|
||||
if (res.data.code === 1) { |
|
||||
this.courseInfo = res.data.data.course_info || {} |
|
||||
this.scheduleList = res.data.data.schedule_list || [] |
|
||||
this.usageList = res.data.data.usage_list || [] |
|
||||
} else { |
|
||||
uni.showToast({ |
|
||||
title: res.data.msg || '加载失败', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.error('加载课程详情失败:', error) |
|
||||
uni.showToast({ |
|
||||
title: '加载失败', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
} finally { |
|
||||
uni.hideLoading() |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 计算剩余课时 |
|
||||
getRemainingHours() { |
|
||||
const total = (this.courseInfo.total_hours || 0) + (this.courseInfo.gift_hours || 0) |
|
||||
const used = (this.courseInfo.use_total_hours || 0) + (this.courseInfo.use_gift_hours || 0) |
|
||||
return Math.max(0, total - used) |
|
||||
}, |
|
||||
|
|
||||
// 获取课程状态文本 |
|
||||
getStatusText(status) { |
|
||||
const statusMap = { |
|
||||
1: '有效', |
|
||||
2: '过期', |
|
||||
3: '等待期', |
|
||||
4: '延期' |
|
||||
} |
|
||||
return statusMap[status] || '未知' |
|
||||
}, |
|
||||
|
|
||||
// 获取课程状态样式 |
|
||||
getStatusClass(status) { |
|
||||
const classMap = { |
|
||||
1: 'status-active', |
|
||||
2: 'status-expired', |
|
||||
3: 'status-waiting', |
|
||||
4: 'status-delayed' |
|
||||
} |
|
||||
return classMap[status] || 'status-unknown' |
|
||||
}, |
|
||||
|
|
||||
// 获取课程安排类型文本 |
|
||||
getScheduleTypeText(type) { |
|
||||
const typeMap = { |
|
||||
1: '临时课', |
|
||||
2: '固定课' |
|
||||
} |
|
||||
return typeMap[type] || '未知' |
|
||||
}, |
|
||||
|
|
||||
// 获取课程安排类型样式 |
|
||||
getScheduleTypeClass(type) { |
|
||||
const classMap = { |
|
||||
1: 'type-temp', |
|
||||
2: 'type-fixed' |
|
||||
} |
|
||||
return classMap[type] || 'type-unknown' |
|
||||
}, |
|
||||
|
|
||||
// 获取课程类型文本 |
|
||||
getCourseTypeText(type) { |
|
||||
const typeMap = { |
|
||||
1: '加课', |
|
||||
2: '补课', |
|
||||
3: '等待位' |
|
||||
} |
|
||||
return typeMap[type] || '正常课' |
|
||||
}, |
|
||||
|
|
||||
// 获取课程类型样式 |
|
||||
getCourseTypeClass(type) { |
|
||||
const classMap = { |
|
||||
1: 'course-add', |
|
||||
2: 'course-makeup', |
|
||||
3: 'course-waiting' |
|
||||
} |
|
||||
return classMap[type] || 'course-normal' |
|
||||
}, |
|
||||
|
|
||||
// 获取课程安排状态文本 |
|
||||
getScheduleStatusText(status) { |
|
||||
const statusMap = { |
|
||||
0: '待上课', |
|
||||
1: '已上课', |
|
||||
2: '请假' |
|
||||
} |
|
||||
return statusMap[status] || '未知' |
|
||||
}, |
|
||||
|
|
||||
// 获取课程安排状态样式 |
|
||||
getScheduleStatusClass(status) { |
|
||||
const classMap = { |
|
||||
0: 'schedule-pending', |
|
||||
1: 'schedule-completed', |
|
||||
2: 'schedule-leave' |
|
||||
} |
|
||||
return classMap[status] || 'schedule-unknown' |
|
||||
}, |
|
||||
|
|
||||
// 格式化日期 |
|
||||
formatDate(dateStr) { |
|
||||
if (!dateStr) return '--' |
|
||||
const date = new Date(dateStr) |
|
||||
const month = (date.getMonth() + 1).toString().padStart(2, '0') |
|
||||
const day = date.getDate().toString().padStart(2, '0') |
|
||||
return `${month}-${day}` |
|
||||
}, |
|
||||
|
|
||||
// 显示课程安排详情 |
|
||||
showScheduleDetail(item) { |
|
||||
// 可以跳转到课程安排详情页面 |
|
||||
console.log('查看课程安排详情:', item) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.course-detail-container { |
|
||||
padding: 20rpx; |
|
||||
background-color: #f5f5f5; |
|
||||
min-height: 100vh; |
|
||||
} |
|
||||
|
|
||||
.course-info-card { |
|
||||
background: white; |
|
||||
border-radius: 16rpx; |
|
||||
padding: 24rpx; |
|
||||
margin-bottom: 20rpx; |
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); |
|
||||
} |
|
||||
|
|
||||
.course-header { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
margin-bottom: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.course-title { |
|
||||
font-size: 32rpx; |
|
||||
font-weight: 600; |
|
||||
color: #333; |
|
||||
} |
|
||||
|
|
||||
.course-status { |
|
||||
padding: 8rpx 16rpx; |
|
||||
border-radius: 20rpx; |
|
||||
font-size: 24rpx; |
|
||||
font-weight: 500; |
|
||||
|
|
||||
&.status-active { |
|
||||
background: #e8f5e8; |
|
||||
color: #52c41a; |
|
||||
} |
|
||||
|
|
||||
&.status-expired { |
|
||||
background: #fff2f0; |
|
||||
color: #ff4d4f; |
|
||||
} |
|
||||
|
|
||||
&.status-waiting { |
|
||||
background: #f6ffed; |
|
||||
color: #faad14; |
|
||||
} |
|
||||
|
|
||||
&.status-delayed { |
|
||||
background: #f0f5ff; |
|
||||
color: #1890ff; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.course-stats { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
margin-bottom: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.stat-item { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
flex: 1; |
|
||||
} |
|
||||
|
|
||||
.stat-label { |
|
||||
font-size: 24rpx; |
|
||||
color: #666; |
|
||||
margin-bottom: 8rpx; |
|
||||
} |
|
||||
|
|
||||
.stat-value { |
|
||||
font-size: 28rpx; |
|
||||
font-weight: 600; |
|
||||
color: #333; |
|
||||
|
|
||||
&.remaining { |
|
||||
color: #1890ff; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.course-dates { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
padding-top: 20rpx; |
|
||||
border-top: 1rpx solid #f0f0f0; |
|
||||
} |
|
||||
|
|
||||
.date-item { |
|
||||
font-size: 24rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
|
|
||||
.section-title { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
margin: 30rpx 0 16rpx; |
|
||||
} |
|
||||
|
|
||||
.title-text { |
|
||||
font-size: 28rpx; |
|
||||
font-weight: 600; |
|
||||
color: #333; |
|
||||
} |
|
||||
|
|
||||
.title-count { |
|
||||
font-size: 24rpx; |
|
||||
color: #666; |
|
||||
margin-left: 8rpx; |
|
||||
} |
|
||||
|
|
||||
.schedule-list, .usage-list { |
|
||||
background: white; |
|
||||
border-radius: 16rpx; |
|
||||
overflow: hidden; |
|
||||
margin-bottom: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.schedule-item, .usage-item { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
padding: 24rpx; |
|
||||
border-bottom: 1rpx solid #f0f0f0; |
|
||||
|
|
||||
&:last-child { |
|
||||
border-bottom: none; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.schedule-date, .usage-date { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
width: 140rpx; |
|
||||
margin-right: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.date-text { |
|
||||
font-size: 28rpx; |
|
||||
font-weight: 600; |
|
||||
color: #333; |
|
||||
margin-bottom: 4rpx; |
|
||||
} |
|
||||
|
|
||||
.time-text { |
|
||||
font-size: 24rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
|
|
||||
.schedule-info, .usage-info { |
|
||||
flex: 1; |
|
||||
} |
|
||||
|
|
||||
.schedule-type { |
|
||||
display: flex; |
|
||||
gap: 8rpx; |
|
||||
margin-bottom: 8rpx; |
|
||||
} |
|
||||
|
|
||||
.type-tag, .course-type-tag { |
|
||||
padding: 4rpx 8rpx; |
|
||||
border-radius: 8rpx; |
|
||||
font-size: 20rpx; |
|
||||
|
|
||||
&.type-temp { |
|
||||
background: #fff7e6; |
|
||||
color: #fa8c16; |
|
||||
} |
|
||||
|
|
||||
&.type-fixed { |
|
||||
background: #f6ffed; |
|
||||
color: #52c41a; |
|
||||
} |
|
||||
|
|
||||
&.course-add { |
|
||||
background: #e6f7ff; |
|
||||
color: #1890ff; |
|
||||
} |
|
||||
|
|
||||
&.course-makeup { |
|
||||
background: #f9f0ff; |
|
||||
color: #722ed1; |
|
||||
} |
|
||||
|
|
||||
&.course-waiting { |
|
||||
background: #fff2f0; |
|
||||
color: #ff4d4f; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.schedule-status, .usage-status { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
.status-text { |
|
||||
font-size: 24rpx; |
|
||||
font-weight: 500; |
|
||||
|
|
||||
&.schedule-pending { |
|
||||
color: #faad14; |
|
||||
} |
|
||||
|
|
||||
&.schedule-completed { |
|
||||
color: #52c41a; |
|
||||
} |
|
||||
|
|
||||
&.schedule-leave { |
|
||||
color: #ff4d4f; |
|
||||
} |
|
||||
|
|
||||
&.confirmed { |
|
||||
color: #52c41a; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.schedule-arrow { |
|
||||
margin-left: 16rpx; |
|
||||
} |
|
||||
|
|
||||
.arrow-icon { |
|
||||
font-size: 24rpx; |
|
||||
color: #ccc; |
|
||||
} |
|
||||
|
|
||||
.usage-hours { |
|
||||
font-size: 26rpx; |
|
||||
color: #333; |
|
||||
margin-bottom: 4rpx; |
|
||||
} |
|
||||
|
|
||||
.usage-type { |
|
||||
font-size: 24rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
|
|
||||
.no-data { |
|
||||
text-align: center; |
|
||||
padding: 100rpx 0; |
|
||||
} |
|
||||
|
|
||||
.no-data-text { |
|
||||
font-size: 24rpx; |
|
||||
color: #999; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,836 +0,0 @@ |
|||||
<!--数据-首页--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<!--自定义导航栏--> |
|
||||
<view class="navbar_section"> |
|
||||
<view class="title">数据</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 市场人员展示--> |
|
||||
<view v-if="infoData.role_type == 'market_type'"> |
|
||||
<view class="count_section"> |
|
||||
<view class="title_box">业绩统计</view> |
|
||||
<view class="box_1"> |
|
||||
<view class="left"> |
|
||||
<view class="charts-box"> |
|
||||
<qiun-data-charts |
|
||||
type="ring" |
|
||||
:opts="opts" |
|
||||
:chartData="chartData" |
|
||||
/> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="title">本周已分配</view> |
|
||||
<view class="content"> |
|
||||
<text class="strong">{{infoData.num_1}}人</text> |
|
||||
</view> |
|
||||
<view class="title">本周未分配</view> |
|
||||
<view class="content"> |
|
||||
<text class="strong">{{infoData.num_2}}人</text> |
|
||||
<!-- <text>较上月</text>--> |
|
||||
</view> |
|
||||
|
|
||||
<view class="legeng"> |
|
||||
<view class="item"> |
|
||||
<view class="piece" style="background-color: #45c59f;"></view> |
|
||||
<view class="lable">已分配</view> |
|
||||
|
|
||||
<view class="item"> |
|
||||
<view class="piece" style="background-color:#02a7f0;"></view> |
|
||||
<view class="lable">未分配</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="title_box" v-show="box_2_show">新客签到</view> |
|
||||
<view class="box_2" v-show="box_2_show"> |
|
||||
<view class="progress-container"> |
|
||||
<view :style="{ width: progress + '%' }" class="progress-bar"> |
|
||||
</view> |
|
||||
<view class="dian" :style="{ left: (progress - 2) + '%' }"></view> |
|
||||
</view> |
|
||||
<view class="progress-text"> |
|
||||
<text>0</text> |
|
||||
<text>50人</text> |
|
||||
<text>100人</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="main_section"> |
|
||||
<view class="tag_section"> |
|
||||
<view :class="['left',tagType=='1'?'select':'']" @click="changeTag('1')">统计分析</view> |
|
||||
<view :class="['right',tagType=='2'?'select':'']" @click="changeTag('2')">统计排名</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 销售分析--> |
|
||||
<view class="section_box_1" v-if="tagType=='1'"> |
|
||||
<view class="left"> |
|
||||
<qiun-data-charts |
|
||||
type="funnel" |
|
||||
:opts="opts_2" |
|
||||
:chartData="chartData_2" |
|
||||
/> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="item"> |
|
||||
<view class="title" style="color: #12E7E8;"> |
|
||||
已分配<text>({{infoData.num_1_rate}}%)</text> |
|
||||
</view> |
|
||||
<view class="title" style="color: #12E7E8;"> |
|
||||
{{infoData.num_1}}<text>人</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item"> |
|
||||
<view class="title" style="color: #4DA3FF;"> |
|
||||
未分配<text>({{infoData.num_2_rate}}%)</text> |
|
||||
</view> |
|
||||
<view class="title" style="color: #4DA3FF;"> |
|
||||
{{infoData.num_2}}<text>人</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item"> |
|
||||
<view class="title" style="color: #FFCB31;"> |
|
||||
本周拉新<text>({{infoData.num_3_rate}}%)</text> |
|
||||
</view> |
|
||||
<view class="title" style="color: #FFCB31;"> |
|
||||
{{infoData.total_1}}<text>人</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 销售排名--> |
|
||||
<view class="section_box_2" v-else> |
|
||||
<view class="itme" v-for="(v,k) in infoData.staff_list" :key="k"> |
|
||||
<view class="title">{{k+1}} {{v.name}}</view> |
|
||||
<view class="money">{{v.goal}}人</view> |
|
||||
<view class="plan"> |
|
||||
<fui-progress :percent="getPercent(v.wx_yj,v.goal)" height="15" radius="100" background="#e4e4e4" activeColor="#4bced0"></fui-progress> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 销售人员展示--> |
|
||||
<view v-else> |
|
||||
<view class="count_section"> |
|
||||
<view class="title_box">业绩统计</view> |
|
||||
<view class="box_1"> |
|
||||
<view class="left"> |
|
||||
<view class="charts-box"> |
|
||||
<qiun-data-charts |
|
||||
type="ring" |
|
||||
:opts="opts" |
|
||||
:chartData="chartData" |
|
||||
/> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="title">已成交</view> |
|
||||
<view class="content"> |
|
||||
<text class="strong">{{infoData.num_1}}人</text> |
|
||||
</view> |
|
||||
<view class="title">未成交</view> |
|
||||
<view class="content"> |
|
||||
<text class="strong">{{infoData.num_2}}人</text> |
|
||||
<!-- <text>较上月</text>--> |
|
||||
</view> |
|
||||
|
|
||||
<view class="legeng"> |
|
||||
<view class="item"> |
|
||||
<view class="piece" style="background-color: #45c59f;"></view> |
|
||||
<view class="lable">已成交</view> |
|
||||
|
|
||||
<view class="item"> |
|
||||
<view class="piece" style="background-color:#02a7f0;"></view> |
|
||||
<view class="lable">未成交</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="main_section"> |
|
||||
<view class="tag_section"> |
|
||||
<view :class="['left',tagType=='1'?'select':'']" @click="changeTag('1')">统计分析</view> |
|
||||
<view :class="['right',tagType=='2'?'select':'']" @click="changeTag('2')">统计排名</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 销售分析--> |
|
||||
<view class="section_box_1" v-if="tagType=='1'"> |
|
||||
<view class="left"> |
|
||||
<qiun-data-charts |
|
||||
type="funnel" |
|
||||
:opts="opts_2" |
|
||||
:chartData="chartData_2" |
|
||||
/> |
|
||||
</view> |
|
||||
<view class="right"> |
|
||||
<view class="item"> |
|
||||
<view class="title" style="color: #12E7E8;"> |
|
||||
已成交<text>({{infoData.num_1_rate}}%)</text> |
|
||||
</view> |
|
||||
<view class="title" style="color: #12E7E8;"> |
|
||||
{{infoData.num_1}}<text>人</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item"> |
|
||||
<view class="title" style="color: #4DA3FF;"> |
|
||||
未成交<text>({{infoData.num_2_rate}}%)</text> |
|
||||
</view> |
|
||||
<view class="title" style="color: #4DA3FF;"> |
|
||||
{{infoData.num_2}}<text>人</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item"> |
|
||||
<view class="title" style="color: #FFCB31;"> |
|
||||
本周分配<text>({{infoData.num_3_rate}}%)</text> |
|
||||
</view> |
|
||||
<view class="title" style="color: #FFCB31;"> |
|
||||
{{infoData.total_1}}<text>人</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 销售排名--> |
|
||||
<view class="section_box_2" v-else> |
|
||||
<view class="itme" v-for="(v,k) in infoData.staff_list" :key="k"> |
|
||||
<view class="title">{{k+1}} {{v.name}}</view> |
|
||||
<view class="money">{{v.goal}}人</view> |
|
||||
<view class="plan"> |
|
||||
<fui-progress :percent="getPercent(v.wx_yj,v.goal)" height="15" radius="100" background="#e4e4e4" activeColor="#4bced0"></fui-progress> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
|
|
||||
<!-- 底部导航--> |
|
||||
<AQTabber/> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
|
|
||||
|
|
||||
<script> |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
// import marketApi from '@/api/market.js'; |
|
||||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|
||||
|
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
|
|
||||
infoData:{ |
|
||||
staff_list:[],//销售排行 |
|
||||
},//详情数据 |
|
||||
|
|
||||
//统计图相关 |
|
||||
chartData: {}, |
|
||||
opts: { |
|
||||
rotate: false, // 是否旋转图表 |
|
||||
rotateLock: false, // 是否锁定旋转 |
|
||||
color: [ |
|
||||
"#e9e9e9", // 颜色1:未完成 |
|
||||
"#02a7f0", // 颜色2:续费 |
|
||||
"#45c59f", // 颜色3:新签 |
|
||||
], |
|
||||
padding: [0, 0, 0, 0], // 图表内边距 [上, 右, 下, 左] |
|
||||
dataLabel: true, // 是否显示数据标签 |
|
||||
enableScroll: false, // 是否启用滚动 |
|
||||
legend: { |
|
||||
show: false, // 是否显示图例 |
|
||||
// position: "right", // 图例位置 |
|
||||
// lineHeight: 25 // 图例行高 |
|
||||
}, |
|
||||
title: { |
|
||||
name: "本周分析", // 主标题文本 |
|
||||
fontSize: 16, // 主标题字体大小 |
|
||||
color: "#666666" // 主标题颜色 |
|
||||
}, |
|
||||
subtitle: { |
|
||||
name: "0%", // 副标题文本 |
|
||||
fontSize: 18, // 副标题字体大小 |
|
||||
color: "#7cb5ec" // 副标题颜色 |
|
||||
}, |
|
||||
extra: { |
|
||||
ring: { |
|
||||
ringWidth: 17, // 环形图宽度 |
|
||||
activeOpacity: 0.5, // 激活状态透明度 |
|
||||
activeRadius: 5, // 启用Tooltip点击时,突出部分的宽度(最大值不得超过labelWidth) |
|
||||
offsetAngle: 0, // 起始角度偏移 |
|
||||
labelWidth: 1, // 标签宽度 |
|
||||
border: true, // 是否显示边框 |
|
||||
customRadius:68,//自定义半径(一般不需要传值,饼图会自动计算半径,自定义半径可能会导致显示图表显示不全) |
|
||||
borderWidth: 2, // 分割线的宽度 |
|
||||
borderColor: "#fff" // 边框颜色 |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
//新客签到进度条统计 |
|
||||
progress: 50, // 初始进度为50% |
|
||||
box_2_show: false,//新客签到进度条统计|true=显示,false=隐藏 |
|
||||
|
|
||||
tagType:'1',//1=销售分析,2=销售排名 |
|
||||
|
|
||||
//销售分析统计图 |
|
||||
chartData_2: {}, |
|
||||
opts_2: { |
|
||||
// 颜色数组,用于图表的系列颜色 |
|
||||
// color: ["#12E7E8","#4DA3FF","#FFCB31"], |
|
||||
// 内边距,顺序为上、右、下、左 |
|
||||
padding: [0,0,0,0], |
|
||||
// 是否启用滚动,false 表示不启用 |
|
||||
enableScroll: false, |
|
||||
legend:{ |
|
||||
show:true// 是否显示图例标识 |
|
||||
}, |
|
||||
// 额外配置项 |
|
||||
extra: { |
|
||||
// 漏斗图配置 |
|
||||
funnel: { |
|
||||
// 激活状态下的透明度 |
|
||||
activeOpacity: 0.3, |
|
||||
// 激活状态下的宽度 |
|
||||
activeWidth: 10, |
|
||||
// 是否显示边框 |
|
||||
border: true, |
|
||||
// 边框宽度 |
|
||||
borderWidth: 2, |
|
||||
// 边框颜色 |
|
||||
borderColor: "#FFFFFF", |
|
||||
// 填充透明度 |
|
||||
fillOpacity: 1, |
|
||||
// 标签对齐方式,left 表示左对齐 |
|
||||
labelAlign: "right", |
|
||||
// 漏斗图类型,pyramid 表示金字塔型 |
|
||||
type: "pyramid" |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
userInfo: {},//当前登录的用户信息 |
|
||||
} |
|
||||
}, |
|
||||
onLoad() {}, |
|
||||
onShow() { |
|
||||
this.init() |
|
||||
}, |
|
||||
methods: { |
|
||||
|
|
||||
async init(){ |
|
||||
await this.getUserInfo() |
|
||||
await this.getPerformance() |
|
||||
}, |
|
||||
|
|
||||
//获取用户信息 |
|
||||
async getUserInfo(){ |
|
||||
let res = await apiRoute.getPersonnelInfo({}) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.userInfo = res.data |
|
||||
}, |
|
||||
|
|
||||
//获取统计信息 |
|
||||
async getPerformance(){ |
|
||||
let role_key_arr = this.userInfo.role_key_arr.join(',') |
|
||||
let params = { |
|
||||
personnel_id:this.userInfo.id,//员工表id |
|
||||
role_key_arr: role_key_arr, // 角色key 转换数组为字符串,若为空则赋予空字符串 |
|
||||
} |
|
||||
let res= await apiRoute.xs_statisticsMarketData(params) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
return |
|
||||
} |
|
||||
// console.log('xx',res) |
|
||||
this.infoData = res.data |
|
||||
|
|
||||
if(this.infoData.role_type == 'market_type'){ |
|
||||
//市场人员 |
|
||||
//环形统计图相关 |
|
||||
let chartData_1 = { |
|
||||
series: [ |
|
||||
{ |
|
||||
data: [ |
|
||||
{ |
|
||||
"name": "已分配", |
|
||||
"value": this.infoData.num_1_rate, |
|
||||
"labelShow": false |
|
||||
}, |
|
||||
{ |
|
||||
"name": "未分配", |
|
||||
"value": this.infoData.num_2_rate, |
|
||||
"labelShow": false |
|
||||
}, |
|
||||
{ |
|
||||
"name": "总人数", |
|
||||
"value": this.infoData.num_3_rate, |
|
||||
"labelShow": false |
|
||||
}, |
|
||||
] |
|
||||
} |
|
||||
] |
|
||||
}; |
|
||||
this.chartData = JSON.parse(JSON.stringify(chartData_1)); |
|
||||
this.opts.subtitle = { |
|
||||
name: `${this.infoData.num_4_rate}%`, // 副标题文本 |
|
||||
fontSize: 18, // 副标题字体大小 |
|
||||
color: "#7cb5ec" // 副标题颜色 |
|
||||
} |
|
||||
|
|
||||
//销售分析统计图相关 |
|
||||
let chartDataB = { |
|
||||
series: [ |
|
||||
{ |
|
||||
data: [ |
|
||||
{ |
|
||||
"name": "本周拉新", // 数据项的名称,表示当前数据的分类为“跟进中” |
|
||||
"centerText": this.infoData.total_1, // 中心显示的文本内容,这里为空字符串,表示不显示中心文本 |
|
||||
"value": this.infoData.num_3_rate, // 数据项的值,表示“跟进中”的数量为50 |
|
||||
// "labelText":'跟进中' |
|
||||
"labelShow":false, |
|
||||
"color": "#FFCB31", // 自定义颜色 |
|
||||
}, |
|
||||
{ |
|
||||
"name": "未分配", |
|
||||
"centerText": this.infoData.num_2, |
|
||||
"value": this.infoData.num_2_rate, |
|
||||
// "labelText":"试听" |
|
||||
"labelShow":false, |
|
||||
"color": "#4DA3FF", // 自定义颜色 |
|
||||
}, |
|
||||
{ |
|
||||
"name": "已分配", |
|
||||
"centerText": this.infoData.num_1, |
|
||||
"value": this.infoData.num_1_rate, |
|
||||
// "labelText":"已成交" |
|
||||
"labelShow":false, |
|
||||
"color": "#12E7E8", // 自定义颜色 |
|
||||
} |
|
||||
] |
|
||||
} |
|
||||
] |
|
||||
}; |
|
||||
this.chartData_2 = JSON.parse(JSON.stringify(chartDataB)); |
|
||||
}else{ |
|
||||
//环形统计图相关 |
|
||||
let chartData_1 = { |
|
||||
series: [ |
|
||||
{ |
|
||||
data: [ |
|
||||
{ |
|
||||
"name": "已成交", |
|
||||
"value": this.infoData.num_1_rate, |
|
||||
"labelShow": false |
|
||||
}, |
|
||||
{ |
|
||||
"name": "未成交", |
|
||||
"value": this.infoData.num_2_rate, |
|
||||
"labelShow": false |
|
||||
}, |
|
||||
{ |
|
||||
"name": "总人数", |
|
||||
"value": this.infoData.num_3_rate, |
|
||||
"labelShow": false |
|
||||
}, |
|
||||
] |
|
||||
} |
|
||||
] |
|
||||
}; |
|
||||
this.chartData = JSON.parse(JSON.stringify(chartData_1)); |
|
||||
this.opts.subtitle = { |
|
||||
name: `${this.infoData.num_4_rate}%`, // 副标题文本 |
|
||||
fontSize: 18, // 副标题字体大小 |
|
||||
color: "#7cb5ec" // 副标题颜色 |
|
||||
} |
|
||||
|
|
||||
//销售分析统计图相关 |
|
||||
let chartDataB = { |
|
||||
series: [ |
|
||||
{ |
|
||||
data: [ |
|
||||
{ |
|
||||
"name": "本周成交", // 数据项的名称,表示当前数据的分类为“跟进中” |
|
||||
"centerText": this.infoData.total_1, // 中心显示的文本内容,这里为空字符串,表示不显示中心文本 |
|
||||
"value": this.infoData.num_3_rate, // 数据项的值,表示“跟进中”的数量为50 |
|
||||
// "labelText":'跟进中' |
|
||||
"labelShow":false, |
|
||||
"color": "#FFCB31", // 自定义颜色 |
|
||||
}, |
|
||||
{ |
|
||||
"name": "未成交", |
|
||||
"centerText": this.infoData.num_2, |
|
||||
"value": this.infoData.num_2_rate, |
|
||||
// "labelText":"试听" |
|
||||
"labelShow":false, |
|
||||
"color": "#4DA3FF", // 自定义颜色 |
|
||||
}, |
|
||||
{ |
|
||||
"name": "已成交", |
|
||||
"centerText": this.infoData.num_1, |
|
||||
"value": this.infoData.num_1_rate, |
|
||||
// "labelText":"已成交" |
|
||||
"labelShow":false, |
|
||||
"color": "#12E7E8", // 自定义颜色 |
|
||||
} |
|
||||
] |
|
||||
} |
|
||||
] |
|
||||
}; |
|
||||
this.chartData_2 = JSON.parse(JSON.stringify(chartDataB)); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
}, |
|
||||
|
|
||||
//计算百分比取整数 |
|
||||
getPercent(num1,total){ |
|
||||
// 计算百分比并取整数 |
|
||||
if(!total){ |
|
||||
return 0 |
|
||||
} |
|
||||
|
|
||||
let num_percent = (num1 / total) * 100; |
|
||||
if(num_percent <= 0){ |
|
||||
num_percent = 0 |
|
||||
}else{ |
|
||||
num_percent = Math.ceil((num1 / total) * 100); |
|
||||
} |
|
||||
// console.log('qqq',[num_percent,num1,total]) |
|
||||
return num_percent |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
|
|
||||
//切换tag |
|
||||
changeTag(type){ |
|
||||
this.tagType = type |
|
||||
}, |
|
||||
|
|
||||
//打开到课率统计 |
|
||||
openViewArrivalStatistics(){ |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/market/my/arrival_statistics' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//打开即将到期 |
|
||||
openViewDueSoon(){ |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/market/my/due_soon' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//打开授课统计 |
|
||||
openViewSchoolingStatistics(){ |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/market/my/schooling_statistics' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//打开意见反馈 |
|
||||
openViewFeedback(){ |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/common/feedback' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//打开个人资料 |
|
||||
openViewMyInfo(){ |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/market/my/info' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//打开企业信息 |
|
||||
openViewFirmInfo(){ |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/market/my/firm_info' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
//打开设置 |
|
||||
openViewSetUp(){ |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/market/my/set_up' |
|
||||
}) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
|
|
||||
|
|
||||
.main_box{ |
|
||||
background: #292929; |
|
||||
min-height: 100%; |
|
||||
} |
|
||||
|
|
||||
//自定义导航栏 |
|
||||
.navbar_section{ |
|
||||
border: 1px solid #292929; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
background: #292929; |
|
||||
position: relative; |
|
||||
.title{ |
|
||||
padding: 40rpx 0rpx; |
|
||||
|
|
||||
/* 小程序端样式 */ |
|
||||
// #ifdef MP-WEIXIN |
|
||||
padding: 80rpx 0rpx; |
|
||||
// #endif |
|
||||
|
|
||||
font-size: 30rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
|
|
||||
.statistics-btn { |
|
||||
position: absolute; |
|
||||
right: 20rpx; |
|
||||
background-color: #29D3B4; |
|
||||
padding: 10rpx 20rpx; |
|
||||
border-radius: 30rpx; |
|
||||
font-size: 24rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
//统计信息 |
|
||||
.count_section{ |
|
||||
padding: 20rpx 46rpx; |
|
||||
padding-bottom: 60rpx; |
|
||||
background-color: #434544; |
|
||||
color: #fff; |
|
||||
.title_box{ |
|
||||
font-size: 26rpx; |
|
||||
} |
|
||||
.box_1{ |
|
||||
margin-top: 25rpx; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
gap: 30rpx; |
|
||||
.left{ |
|
||||
width: 280rpx; /* 设置宽度为 280rpx */ |
|
||||
height: 280rpx; /* 设置高度为 280rpx */ |
|
||||
.charts-box { |
|
||||
width: 280rpx; /* 设置宽度为 280rpx */ |
|
||||
height: 280rpx; /* 设置高度为 280rpx */ |
|
||||
} |
|
||||
} |
|
||||
.right{ |
|
||||
font-size: 24rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 20rpx; |
|
||||
.title{} |
|
||||
.content{ |
|
||||
display: flex; |
|
||||
gap: 40rpx; |
|
||||
.strong{ |
|
||||
font-size: 30rpx; |
|
||||
} |
|
||||
.text{ |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
} |
|
||||
.legeng{ |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 50rpx; |
|
||||
.item{ |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 20rpx; |
|
||||
.piece{ |
|
||||
|
|
||||
width: 20rpx; |
|
||||
height: 20rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
// 其他样式省略 |
|
||||
.box_2 { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
margin-top: 20rpx; |
|
||||
|
|
||||
.progress-container { |
|
||||
position: relative; |
|
||||
width: 80%; |
|
||||
height: 4rpx; |
|
||||
background-color: #ccc; |
|
||||
border-radius: 2rpx; |
|
||||
//overflow: hidden; |
|
||||
margin-bottom: 10rpx; |
|
||||
|
|
||||
.progress-bar { |
|
||||
height: 100%; |
|
||||
background-color: #45c59f; |
|
||||
border-radius: 2rpx; |
|
||||
} |
|
||||
.dian{ |
|
||||
position: absolute; |
|
||||
top: -9rpx; |
|
||||
left: 0rpx; |
|
||||
width: 18rpx; |
|
||||
height: 18rpx; |
|
||||
border-radius: 50%; |
|
||||
background-color: #fff; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.progress-text { |
|
||||
margin-left: 5%; |
|
||||
width: 85%; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
text { |
|
||||
font-size: 26rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.main_section{ |
|
||||
background: #292929 100%; |
|
||||
padding: 0 24rpx; |
|
||||
padding-top: 40rpx; |
|
||||
padding-bottom: 150rpx; |
|
||||
font-size: 24rpx; |
|
||||
color: #333333; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 22rpx; |
|
||||
|
|
||||
.tag_section{ |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
view{ |
|
||||
border: 1px solid #969696; |
|
||||
width: 258rpx; |
|
||||
height: 72rpx; |
|
||||
line-height: 72rpx; |
|
||||
background-color: #292929; |
|
||||
text-align: center; |
|
||||
font-size: 26rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
.left{ |
|
||||
border-radius: 22rpx 0rpx 0rpx 22rpx; |
|
||||
} |
|
||||
.right{ |
|
||||
border-radius: 0rpx 22rpx 22rpx 0rpx; |
|
||||
} |
|
||||
.select{ |
|
||||
background-color: #fff; |
|
||||
color: #29D3B4; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.section_box_1{ |
|
||||
margin-top: 38rpx; |
|
||||
padding: 66rpx 14rpx; |
|
||||
border-radius: 12rpx; |
|
||||
background-color: #434544FF; |
|
||||
color: #d9dada; |
|
||||
font-size: 26rpx; |
|
||||
text-align: center; |
|
||||
height: 600rpx; |
|
||||
|
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
.left{ |
|
||||
width: 70%; |
|
||||
} |
|
||||
.right{ |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 20rpx; |
|
||||
.item{ |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 10rpx; |
|
||||
.title{ |
|
||||
font-size: 26rpx; |
|
||||
text-align: left; |
|
||||
text{ |
|
||||
margin-left: 5rpx; |
|
||||
color: #d9dada; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.section_box_2{ |
|
||||
color: #fff; |
|
||||
margin-top: 38rpx; |
|
||||
padding: 20rpx 42rpx; |
|
||||
background-color: #434544; |
|
||||
border-radius: 12rpx; |
|
||||
font-size: 26rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 20rpx; |
|
||||
.itme{ |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 15rpx; |
|
||||
.money{ |
|
||||
display: flex; |
|
||||
justify-content: flex-end; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
} |
|
||||
|
|
||||
|
|
||||
</style> |
|
||||
@ -1,390 +0,0 @@ |
|||||
<template> |
|
||||
<view class="assemble"> |
|
||||
<view style="height: 20rpx;"></view> |
|
||||
<!-- 市场人员展示--> |
|
||||
<view class="div-style"> |
|
||||
<view style="height: 38vh;"> |
|
||||
<view style="display: flex;align-items: center;padding: 20rpx 0 0 20rpx;"> |
|
||||
<view> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/danlan.png')" class="drop-image"> |
|
||||
</image> |
|
||||
</view> |
|
||||
<view class="title">本月业绩</view> |
|
||||
</view> |
|
||||
<view class="coach-message"> |
|
||||
<view class="left1"> |
|
||||
<view style="padding: 20rpx 0;"> |
|
||||
<view style="display: flex;align-items: center;"> |
|
||||
<view style="padding: 12rpx;"> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/huang.png')" |
|
||||
class="drop-image-x"></image> |
|
||||
</view> |
|
||||
<view class="title-x">资源总数</view> |
|
||||
</view> |
|
||||
<view class="title-x1">{{infoData.month.new_total}}人</view> |
|
||||
</view> |
|
||||
|
|
||||
<view> |
|
||||
<view style="display: flex;align-items: center;"> |
|
||||
<view style="padding: 12rpx;"> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/lvs.png')" |
|
||||
class="drop-image-x"></image> |
|
||||
</view> |
|
||||
<view class="title-x">已分配</view> |
|
||||
</view> |
|
||||
<view class="title-x1">{{infoData.month.new_total}}人</view> |
|
||||
</view> |
|
||||
|
|
||||
<view> |
|
||||
<view style="display: flex;align-items: center;"> |
|
||||
<view style="padding: 12rpx;"> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/shenlan.png')" |
|
||||
class="drop-image-x"></image> |
|
||||
</view> |
|
||||
<view class="title-x">昨日新增</view> |
|
||||
</view> |
|
||||
<view class="title-x1">{{infoData.month.yesterday_new}}人</view> |
|
||||
</view> |
|
||||
|
|
||||
<view> |
|
||||
<view style="display: flex;align-items: center;"> |
|
||||
<view style="padding: 12rpx;"> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/lan.png')" |
|
||||
class="drop-image-x"></image> |
|
||||
</view> |
|
||||
<view class="title-x">今日新增</view> |
|
||||
</view> |
|
||||
<view class="title-x1">{{infoData.month.today_new}}人</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<!-- 统计图--> |
|
||||
<view class="right1"> |
|
||||
<view style="text-align: center;">{{infoData.date_range}}</view> |
|
||||
<view class="statistics_box"> |
|
||||
|
|
||||
<view class="item"> |
|
||||
<view class="box"> |
|
||||
<view class="progress-bar" |
|
||||
:style="{ height: `${infoData.month.yesterday_new_rate}%`, background: '#f59a23' }"> |
|
||||
</view> |
|
||||
<view class="ratio" |
|
||||
:style="{ color: infoData.month.yesterday_new_rate <= 0 ? '#333333' : '#000' }"> |
|
||||
{{ infoData.month.yesterday_new_rate }}% |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="title">昨日</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item"> |
|
||||
<view class="box"> |
|
||||
<view class="progress-bar" |
|
||||
:style="{ height: `${infoData.month.assigned_sales_rate}%`, background: '#039f64' }"> |
|
||||
</view> |
|
||||
<view class="ratio" |
|
||||
:style="{ color: infoData.month.assigned_sales_rate <= 0 ? '#333333' : '#000' }"> |
|
||||
{{ infoData.month.assigned_sales_rate }}% |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="title">分配</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item"> |
|
||||
<view class="box"> |
|
||||
<view class="progress-bar" |
|
||||
:style="{ height: `${infoData.month.today_new_rate}%`, background: '#4066f2' }"> |
|
||||
</view> |
|
||||
<view class="ratio" |
|
||||
:style="{ color: infoData.month.today_new_rate <= 0 ? '#333333' : '#000' }"> |
|
||||
{{ infoData.month.today_new_rate }}% |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="title">今日</view> |
|
||||
</view> |
|
||||
|
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view style="width: 90%;background: #EFF3F8;height: 4rpx;margin: auto;"></view> |
|
||||
|
|
||||
<view style="height: 38vh;"> |
|
||||
<view style="display: flex;align-items: center;padding: 20rpx 0 0 20rpx;"> |
|
||||
<view> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/danlv.png')" class="drop-image"></image> |
|
||||
</view> |
|
||||
<view class="title">个人业绩</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="coach-message"> |
|
||||
<view class="this_month"> |
|
||||
<view style="padding: 20rpx 0;display: flex;justify-content: space-between;"> |
|
||||
<view style="width: 48%;"> |
|
||||
<view style="display: flex;align-items: center;"> |
|
||||
<view style="padding: 12rpx;"> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/danlv.png')" |
|
||||
class="drop-image-x"></image> |
|
||||
</view> |
|
||||
<view class="title-x">今日新增资源</view> |
|
||||
</view> |
|
||||
<view class="title-x1">{{infoData.last_month.xzzy}}人</view> |
|
||||
</view> |
|
||||
|
|
||||
<view style="width: 48%;"> |
|
||||
<view style="display: flex;align-items: center;"> |
|
||||
<view style="padding: 12rpx;"> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/danlv.png')" |
|
||||
class="drop-image-x"></image> |
|
||||
</view> |
|
||||
<view class="title-x">今日业绩收入</view> |
|
||||
</view> |
|
||||
<view class="title-x1">{{infoData.last_month.yjsr}}元</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view style="padding: 20rpx 0;display: flex;justify-content: space-between;"> |
|
||||
<view style="width: 48%;"> |
|
||||
<view style="display: flex;align-items: center;"> |
|
||||
<view style="padding: 12rpx;"> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/danlv.png')" |
|
||||
class="drop-image-x"></image> |
|
||||
</view> |
|
||||
<view class="title-x">历史关单数量</view> |
|
||||
</view> |
|
||||
<view class="title-x1">{{infoData.last_month.gdsl}}人</view> |
|
||||
</view> |
|
||||
|
|
||||
<view style="width: 48%;"> |
|
||||
<view style="display: flex;align-items: center;"> |
|
||||
<view style="padding: 12rpx;"> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/danlv.png')" |
|
||||
class="drop-image-x"></image> |
|
||||
</view> |
|
||||
<view class="title-x">其他奖励</view> |
|
||||
</view> |
|
||||
<view class="title-x1">{{infoData.last_month.qtjl}}元</view> |
|
||||
</view> |
|
||||
|
|
||||
|
|
||||
</view> |
|
||||
<view style="padding: 20rpx 0;display: flex;justify-content: space-between;"> |
|
||||
<view style="width: 48%;"> |
|
||||
<view style="display: flex;align-items: center;"> |
|
||||
<view style="padding: 12rpx;"> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/danlv.png')" |
|
||||
class="drop-image-x"></image> |
|
||||
</view> |
|
||||
<view class="title-x">本月提成</view> |
|
||||
</view> |
|
||||
<view class="title-x1">{{infoData.last_month.bytc}}元</view> |
|
||||
</view> |
|
||||
|
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<AQTabber /> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
|
|
||||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
infoData: {}, //详情 |
|
||||
|
|
||||
userInfo: {}, //当前登录的用户信息 |
|
||||
} |
|
||||
}, |
|
||||
onShow() { |
|
||||
this.init() |
|
||||
}, |
|
||||
methods: { |
|
||||
async init() { |
|
||||
await this.getUserInfo() |
|
||||
await this.getXsIndex() |
|
||||
}, |
|
||||
|
|
||||
//获取用户信息 |
|
||||
async getUserInfo() { |
|
||||
let res = await apiRoute.getPersonnelInfo({}) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.userInfo = res.data |
|
||||
}, |
|
||||
|
|
||||
//获取销售首页详情 |
|
||||
async getXsIndex() { |
|
||||
let role_key_arr = this.userInfo.role_key_arr.join(',') |
|
||||
let params = { |
|
||||
personnel_id: this.userInfo.id, //员工表id |
|
||||
role_key_arr: role_key_arr, // 角色key 转换数组为字符串,若为空则赋予空字符串 |
|
||||
} |
|
||||
let res = await apiRoute.xs_statisticsMarketHome(params) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
this.infoData = res.data |
|
||||
console.log('统计', this.infoData) |
|
||||
}, |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
//自定义导航栏 |
|
||||
.navbar_section { |
|
||||
border: 1px solid #fff; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
background: #fff; |
|
||||
|
|
||||
.title { |
|
||||
padding: 40rpx 0rpx; |
|
||||
|
|
||||
/* 小程序端样式 */ |
|
||||
// #ifdef MP-WEIXIN |
|
||||
padding: 80rpx 0rpx; |
|
||||
// #endif |
|
||||
|
|
||||
font-size: 30rpx; |
|
||||
color: #858585; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.assemble { |
|
||||
width: 100%; |
|
||||
height: 100vh; |
|
||||
background: #292929; |
|
||||
} |
|
||||
|
|
||||
.div-style { |
|
||||
width: 92%; |
|
||||
height: 85vh; |
|
||||
background: #fff; |
|
||||
border-radius: 16rpx; |
|
||||
margin: auto; |
|
||||
} |
|
||||
|
|
||||
.coach-message { |
|
||||
width: 92%; |
|
||||
margin: 10rpx auto; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
padding-top: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.drop-image { |
|
||||
width: 50rpx; |
|
||||
height: 50rpx; |
|
||||
} |
|
||||
|
|
||||
.title { |
|
||||
font-size: 30rpx; |
|
||||
color: #7F7F7F; |
|
||||
padding-left: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.left1 { |
|
||||
width: 48%; |
|
||||
height: 95%; |
|
||||
margin: auto; |
|
||||
} |
|
||||
|
|
||||
.right1 { |
|
||||
width: 48%; |
|
||||
height: 95%; |
|
||||
margin: auto; |
|
||||
|
|
||||
.statistics_box { |
|
||||
margin: auto; |
|
||||
margin-top: 10rpx; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
|
|
||||
.item { |
|
||||
width: 90rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
|
|
||||
.box { |
|
||||
width: 100%; |
|
||||
height: 328rpx; |
|
||||
border: 1px solid #ddd; |
|
||||
border-radius: 6rpx; |
|
||||
background: #f5f5f5; |
|
||||
position: relative; |
|
||||
|
|
||||
.progress-bar { |
|
||||
width: 100%; |
|
||||
height: 0; |
|
||||
transition: height 0.3s ease; |
|
||||
position: absolute; |
|
||||
bottom: 0; |
|
||||
} |
|
||||
|
|
||||
.ratio { |
|
||||
width: 100%; |
|
||||
position: absolute; |
|
||||
bottom: -0rpx; |
|
||||
font-size: 26rpx; |
|
||||
text-align: center; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.title { |
|
||||
margin-top: 5rpx; |
|
||||
padding: 0; |
|
||||
font-size: 26rpx; |
|
||||
color: #999999; |
|
||||
; |
|
||||
text-align: center; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.this_month { |
|
||||
width: 100%; |
|
||||
height: 95%; |
|
||||
margin: auto; |
|
||||
} |
|
||||
|
|
||||
.drop-image-x { |
|
||||
width: 20rpx; |
|
||||
height: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.title-x { |
|
||||
font-size: 28rpx; |
|
||||
color: #7F7F7F; |
|
||||
padding-left: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.title-x1 { |
|
||||
font-size: 28rpx; |
|
||||
color: #333333; |
|
||||
padding-left: 60rpx; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,207 +0,0 @@ |
|||||
<!--企业信息--> |
|
||||
<template> |
|
||||
<view class="assemble"> |
|
||||
<view style="height: 30rpx;"></view> |
|
||||
|
|
||||
<scroll-view |
|
||||
class="ul" |
|
||||
scroll-y="true" |
|
||||
:lower-threshold="lowerThreshold" |
|
||||
@scrolltolower="loadMoreData_1" |
|
||||
style="height: 80vh;" |
|
||||
> |
|
||||
<view class="li" v-for="(v,k) in tableList" :key="k"> |
|
||||
<!--企业图--> |
|
||||
<view class="section_1"> |
|
||||
<image class="pic" v-if="v.campus_preview_image" :src="v.campus_preview_image" mode="aspectFit"></image> |
|
||||
</view> |
|
||||
|
|
||||
<view class="title_section">基本信息</view> |
|
||||
<view class="section_2"> |
|
||||
<view class="item"> |
|
||||
<view class="title">企业名称</view> |
|
||||
<view class="content">{{v.campus_name}}</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item"> |
|
||||
<view class="title">企业地址</view> |
|
||||
<view class="content">{{v.campus_address}}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
|
|
||||
<view class="title_section">企业地图</view> |
|
||||
<view class="section_3"> |
|
||||
<view class="map_box"> |
|
||||
<map |
|
||||
:id="`shopMap_${k}`" |
|
||||
:latitude="v.campus_coordinates_arr.lat" |
|
||||
:longitude="v.campus_coordinates_arr.lng" |
|
||||
:markers="getMarkers(k,v)" |
|
||||
:scale="15" |
|
||||
:show-location="false" |
|
||||
style="width: 90%; height: 400rpx;" |
|
||||
></map> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="title_section">企业介绍</view> |
|
||||
<view class="section_4"> |
|
||||
<view class="html" v-html="v. |
|
||||
campus_introduction"></view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</scroll-view> |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
dataInfo:{},//企业信息 |
|
||||
|
|
||||
loading:false,//加载状态 |
|
||||
lowerThreshold: 100,//距离底部多远触发 |
|
||||
isReachedBottom: false,//防止重复加载|true=不可加载|false=可加载 |
|
||||
//筛选条件 |
|
||||
filteredData:{ |
|
||||
personnel_id:'', |
|
||||
}, |
|
||||
//数据列表 |
|
||||
tableList:[], |
|
||||
|
|
||||
//地图相关 |
|
||||
//地图控件 |
|
||||
mapControls:{ |
|
||||
position:{ |
|
||||
|
|
||||
}, |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
onShow(){ |
|
||||
this.init() |
|
||||
}, |
|
||||
methods: { |
|
||||
//初始化 |
|
||||
async init(){ |
|
||||
await this.getUserInfo() |
|
||||
await this.getPersonnelCampus() |
|
||||
}, |
|
||||
|
|
||||
//获取用户信息 |
|
||||
async getUserInfo(){ |
|
||||
let res = await apiRoute.getPersonnelInfo({}) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
this.filteredData.personnel_id = res.data.id//员工id |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
//获取校区信息 |
|
||||
async getPersonnelCampus(){ |
|
||||
let params = {...this.filteredData} |
|
||||
let res = await apiRoute.common_getPersonnelCampus(params) |
|
||||
if(res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.tableList = res.data |
|
||||
console.log(123,this.tableList) |
|
||||
}, |
|
||||
|
|
||||
// 获取标记点 |
|
||||
getMarkers(id,item) { |
|
||||
return [{ |
|
||||
id: id, |
|
||||
latitude: item.campus_coordinates_arr.lat, |
|
||||
longitude: item.campus_coordinates_arr.lng, |
|
||||
name: item.campus_address, |
|
||||
iconPath: '/static/icon-img/ding_wei.png' |
|
||||
}]; |
|
||||
}, |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.assemble{ |
|
||||
width: 100%; |
|
||||
min-height: 100vh; |
|
||||
background: #333333; |
|
||||
color: #fff; |
|
||||
} |
|
||||
|
|
||||
.ul{ |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 40rpx; |
|
||||
.li{ |
|
||||
border-top: 1px solid #434544; |
|
||||
.section_1{ |
|
||||
.pic{ |
|
||||
width: 100%; |
|
||||
height: 300rpx; |
|
||||
} |
|
||||
} |
|
||||
.title_section{ |
|
||||
padding: 20rpx 40rpx; |
|
||||
color: #fff; |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
.section_2{ |
|
||||
background-color: #434544; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
.item{ |
|
||||
padding: 40rpx; |
|
||||
padding-left: 40rpx; |
|
||||
display: flex; |
|
||||
gap: 30rpx; |
|
||||
} |
|
||||
} |
|
||||
.section_3{ |
|
||||
padding: 20rpx 22rpx; |
|
||||
.html{ |
|
||||
color: #fff; |
|
||||
} |
|
||||
.map_box{ |
|
||||
color: #fff; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
} |
|
||||
} |
|
||||
.section_4{ |
|
||||
padding: 20rpx 22rpx; |
|
||||
padding-bottom: 250rpx; |
|
||||
.html{ |
|
||||
color: #fff; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.li:nth-child(1){ |
|
||||
border: 0px solid #434544; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,177 +0,0 @@ |
|||||
<!--合同详情页面--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<!-- 合同基本信息 --> |
|
||||
<view class="contract_info_card" v-if="contractInfo"> |
|
||||
<view class="contract_header"> |
|
||||
<view class="contract_title">{{ contractInfo.title }}</view> |
|
||||
<view class="contract_status" :class="contractInfo.status"> |
|
||||
{{ contractInfo.status_text }} |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="contract_details"> |
|
||||
<view class="detail_item"> |
|
||||
<view class="detail_label">合同金额</view> |
|
||||
<view class="detail_value amount">¥{{ contractInfo.amount }}</view> |
|
||||
</view> |
|
||||
<view class="detail_item"> |
|
||||
<view class="detail_label">签订日期</view> |
|
||||
<view class="detail_value">{{ contractInfo.sign_date }}</view> |
|
||||
</view> |
|
||||
<view class="detail_item"> |
|
||||
<view class="detail_label">有效期</view> |
|
||||
<view class="detail_value">{{ contractInfo.valid_date }}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 空状态 --> |
|
||||
<view class="empty_state" v-if="!loading && !contractInfo"> |
|
||||
<image src="/static/icon-img/empty.png" class="empty_icon"></image> |
|
||||
<view class="empty_text">暂无合同信息</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 加载状态 --> |
|
||||
<view class="loading_state" v-if="loading"> |
|
||||
<view class="loading_text">加载中...</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
contractInfo: null, |
|
||||
loading: false, |
|
||||
contractId: null, |
|
||||
childId: null |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
this.contractId = options.contractId |
|
||||
this.childId = options.childId |
|
||||
this.loadContractInfo() |
|
||||
}, |
|
||||
methods: { |
|
||||
async loadContractInfo() { |
|
||||
// 模拟合同详情数据 |
|
||||
this.contractInfo = { |
|
||||
title: '少儿篮球培训合同', |
|
||||
status: 'active', |
|
||||
status_text: '有效', |
|
||||
amount: '2880.00', |
|
||||
sign_date: '2024-01-01', |
|
||||
valid_date: '2024-01-01 至 2024-12-31' |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box { |
|
||||
background: #f8f9fa; |
|
||||
min-height: 100vh; |
|
||||
padding: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.contract_info_card { |
|
||||
background: #fff; |
|
||||
border-radius: 16rpx; |
|
||||
padding: 32rpx; |
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1); |
|
||||
|
|
||||
.contract_header { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
margin-bottom: 32rpx; |
|
||||
padding-bottom: 24rpx; |
|
||||
border-bottom: 1px solid #f0f0f0; |
|
||||
|
|
||||
.contract_title { |
|
||||
font-size: 36rpx; |
|
||||
font-weight: 600; |
|
||||
color: #333; |
|
||||
} |
|
||||
|
|
||||
.contract_status { |
|
||||
font-size: 24rpx; |
|
||||
padding: 8rpx 16rpx; |
|
||||
border-radius: 12rpx; |
|
||||
|
|
||||
&.active { |
|
||||
background: rgba(40, 167, 69, 0.1); |
|
||||
color: #28a745; |
|
||||
} |
|
||||
|
|
||||
&.expired { |
|
||||
background: rgba(220, 53, 69, 0.1); |
|
||||
color: #dc3545; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.contract_details { |
|
||||
.detail_item { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
padding: 20rpx 0; |
|
||||
border-bottom: 1px solid #f8f9fa; |
|
||||
|
|
||||
.detail_label { |
|
||||
font-size: 28rpx; |
|
||||
color: #666; |
|
||||
min-width: 160rpx; |
|
||||
} |
|
||||
|
|
||||
.detail_value { |
|
||||
font-size: 28rpx; |
|
||||
color: #333; |
|
||||
flex: 1; |
|
||||
text-align: right; |
|
||||
|
|
||||
&.amount { |
|
||||
color: #e67e22; |
|
||||
font-weight: 600; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.empty_state { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
padding: 120rpx 0; |
|
||||
|
|
||||
.empty_icon { |
|
||||
width: 160rpx; |
|
||||
height: 160rpx; |
|
||||
margin-bottom: 32rpx; |
|
||||
opacity: 0.3; |
|
||||
} |
|
||||
|
|
||||
.empty_text { |
|
||||
font-size: 28rpx; |
|
||||
color: #999; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.loading_state { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
padding: 60rpx 0; |
|
||||
|
|
||||
.loading_text { |
|
||||
font-size: 28rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,187 +0,0 @@ |
|||||
<!--课程详情页面--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<!-- 课程基本信息 --> |
|
||||
<view class="course_info_card" v-if="courseInfo"> |
|
||||
<view class="course_header"> |
|
||||
<view class="course_name">{{ courseInfo.course_name }}</view> |
|
||||
<view class="course_status" :class="courseInfo.status"> |
|
||||
{{ courseInfo.status === 'active' ? '进行中' : '已结束' }} |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="course_details"> |
|
||||
<view class="detail_item"> |
|
||||
<view class="detail_label">授课教师</view> |
|
||||
<view class="detail_value">{{ courseInfo.teacher_name }}</view> |
|
||||
</view> |
|
||||
<view class="detail_item"> |
|
||||
<view class="detail_label">上课校区</view> |
|
||||
<view class="detail_value">{{ courseInfo.campus_name }}</view> |
|
||||
</view> |
|
||||
<view class="detail_item"> |
|
||||
<view class="detail_label">上课时间</view> |
|
||||
<view class="detail_value">{{ courseInfo.schedule_time }}</view> |
|
||||
</view> |
|
||||
<view class="detail_item"> |
|
||||
<view class="detail_label">课程进度</view> |
|
||||
<view class="detail_value">{{ courseInfo.progress }}</view> |
|
||||
</view> |
|
||||
<view class="detail_item" v-if="courseInfo.next_class"> |
|
||||
<view class="detail_label">下节课时间</view> |
|
||||
<view class="detail_value next_class">{{ courseInfo.next_class }}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 空状态 --> |
|
||||
<view class="empty_state" v-if="!loading && !courseInfo"> |
|
||||
<image src="/static/icon-img/empty.png" class="empty_icon"></image> |
|
||||
<view class="empty_text">暂无课程信息</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 加载状态 --> |
|
||||
<view class="loading_state" v-if="loading"> |
|
||||
<view class="loading_text">加载中...</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
courseInfo: null, |
|
||||
loading: false, |
|
||||
courseId: null, |
|
||||
childId: null |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
this.courseId = options.courseId |
|
||||
this.childId = options.childId |
|
||||
this.loadCourseInfo() |
|
||||
}, |
|
||||
methods: { |
|
||||
async loadCourseInfo() { |
|
||||
// 这里可以添加具体的课程详情获取逻辑 |
|
||||
// 暂时使用模拟数据 |
|
||||
this.courseInfo = { |
|
||||
course_name: '少儿篮球训练', |
|
||||
teacher_name: '王教练', |
|
||||
campus_name: '总部校区', |
|
||||
schedule_time: '周六 09:00-10:30', |
|
||||
progress: '8/12节', |
|
||||
status: 'active', |
|
||||
next_class: '2024-01-20 09:00' |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box { |
|
||||
background: #f8f9fa; |
|
||||
min-height: 100vh; |
|
||||
padding: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.course_info_card { |
|
||||
background: #fff; |
|
||||
border-radius: 16rpx; |
|
||||
padding: 32rpx; |
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1); |
|
||||
|
|
||||
.course_header { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
margin-bottom: 32rpx; |
|
||||
padding-bottom: 24rpx; |
|
||||
border-bottom: 1px solid #f0f0f0; |
|
||||
|
|
||||
.course_name { |
|
||||
font-size: 36rpx; |
|
||||
font-weight: 600; |
|
||||
color: #333; |
|
||||
} |
|
||||
|
|
||||
.course_status { |
|
||||
font-size: 24rpx; |
|
||||
padding: 8rpx 16rpx; |
|
||||
border-radius: 12rpx; |
|
||||
|
|
||||
&.active { |
|
||||
background: rgba(41, 211, 180, 0.1); |
|
||||
color: #29d3b4; |
|
||||
} |
|
||||
|
|
||||
&.inactive { |
|
||||
background: #f0f0f0; |
|
||||
color: #999; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.course_details { |
|
||||
.detail_item { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
padding: 20rpx 0; |
|
||||
border-bottom: 1px solid #f8f9fa; |
|
||||
|
|
||||
.detail_label { |
|
||||
font-size: 28rpx; |
|
||||
color: #666; |
|
||||
min-width: 160rpx; |
|
||||
} |
|
||||
|
|
||||
.detail_value { |
|
||||
font-size: 28rpx; |
|
||||
color: #333; |
|
||||
flex: 1; |
|
||||
text-align: right; |
|
||||
|
|
||||
&.next_class { |
|
||||
color: #29d3b4; |
|
||||
font-weight: 600; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.empty_state { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
padding: 120rpx 0; |
|
||||
|
|
||||
.empty_icon { |
|
||||
width: 160rpx; |
|
||||
height: 160rpx; |
|
||||
margin-bottom: 32rpx; |
|
||||
opacity: 0.3; |
|
||||
} |
|
||||
|
|
||||
.empty_text { |
|
||||
font-size: 28rpx; |
|
||||
color: #999; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.loading_state { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
padding: 60rpx 0; |
|
||||
|
|
||||
.loading_text { |
|
||||
font-size: 28rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,181 +0,0 @@ |
|||||
<!--教学资料详情页面--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<!-- 资料基本信息 --> |
|
||||
<view class="material_info_card" v-if="materialInfo"> |
|
||||
<view class="material_header"> |
|
||||
<view class="material_title">{{ materialInfo.title }}</view> |
|
||||
<view class="material_type">{{ materialInfo.type }}</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="material_details"> |
|
||||
<view class="detail_item"> |
|
||||
<view class="detail_label">发布时间</view> |
|
||||
<view class="detail_value">{{ materialInfo.created_at }}</view> |
|
||||
</view> |
|
||||
<view class="detail_item"> |
|
||||
<view class="detail_label">资料类型</view> |
|
||||
<view class="detail_value">{{ materialInfo.type }}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="material_content"> |
|
||||
<view class="content_title">资料内容</view> |
|
||||
<view class="content_text">{{ materialInfo.content }}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 空状态 --> |
|
||||
<view class="empty_state" v-if="!loading && !materialInfo"> |
|
||||
<image src="/static/icon-img/empty.png" class="empty_icon"></image> |
|
||||
<view class="empty_text">暂无资料信息</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 加载状态 --> |
|
||||
<view class="loading_state" v-if="loading"> |
|
||||
<view class="loading_text">加载中...</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
materialInfo: null, |
|
||||
loading: false, |
|
||||
materialId: null, |
|
||||
childId: null |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
this.materialId = options.materialId |
|
||||
this.childId = options.childId |
|
||||
this.loadMaterialInfo() |
|
||||
}, |
|
||||
methods: { |
|
||||
async loadMaterialInfo() { |
|
||||
// 模拟教学资料详情数据 |
|
||||
this.materialInfo = { |
|
||||
title: '篮球基础训练视频', |
|
||||
type: '视频资料', |
|
||||
created_at: '2024-01-15 14:30:00', |
|
||||
content: '这是一套专门为少儿设计的篮球基础训练视频,包含运球、投篮、传球等基本技能的教学内容。' |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box { |
|
||||
background: #f8f9fa; |
|
||||
min-height: 100vh; |
|
||||
padding: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.material_info_card { |
|
||||
background: #fff; |
|
||||
border-radius: 16rpx; |
|
||||
padding: 32rpx; |
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1); |
|
||||
|
|
||||
.material_header { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
margin-bottom: 32rpx; |
|
||||
padding-bottom: 24rpx; |
|
||||
border-bottom: 1px solid #f0f0f0; |
|
||||
|
|
||||
.material_title { |
|
||||
font-size: 36rpx; |
|
||||
font-weight: 600; |
|
||||
color: #333; |
|
||||
} |
|
||||
|
|
||||
.material_type { |
|
||||
font-size: 24rpx; |
|
||||
padding: 8rpx 16rpx; |
|
||||
border-radius: 12rpx; |
|
||||
background: rgba(41, 211, 180, 0.1); |
|
||||
color: #29d3b4; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.material_details { |
|
||||
margin-bottom: 32rpx; |
|
||||
|
|
||||
.detail_item { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
padding: 20rpx 0; |
|
||||
border-bottom: 1px solid #f8f9fa; |
|
||||
|
|
||||
.detail_label { |
|
||||
font-size: 28rpx; |
|
||||
color: #666; |
|
||||
min-width: 160rpx; |
|
||||
} |
|
||||
|
|
||||
.detail_value { |
|
||||
font-size: 28rpx; |
|
||||
color: #333; |
|
||||
flex: 1; |
|
||||
text-align: right; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.material_content { |
|
||||
.content_title { |
|
||||
font-size: 28rpx; |
|
||||
font-weight: 600; |
|
||||
color: #333; |
|
||||
margin-bottom: 16rpx; |
|
||||
} |
|
||||
|
|
||||
.content_text { |
|
||||
font-size: 26rpx; |
|
||||
color: #666; |
|
||||
line-height: 1.6; |
|
||||
padding: 16rpx; |
|
||||
background: #f8f9fa; |
|
||||
border-radius: 8rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.empty_state { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
padding: 120rpx 0; |
|
||||
|
|
||||
.empty_icon { |
|
||||
width: 160rpx; |
|
||||
height: 160rpx; |
|
||||
margin-bottom: 32rpx; |
|
||||
opacity: 0.3; |
|
||||
} |
|
||||
|
|
||||
.empty_text { |
|
||||
font-size: 28rpx; |
|
||||
color: #999; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.loading_state { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
padding: 60rpx 0; |
|
||||
|
|
||||
.loading_text { |
|
||||
font-size: 28rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,174 +0,0 @@ |
|||||
<!--消息详情页面--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<!-- 消息基本信息 --> |
|
||||
<view class="message_info_card" v-if="messageInfo"> |
|
||||
<view class="message_header"> |
|
||||
<view class="message_title">{{ messageInfo.title }}</view> |
|
||||
<view class="message_time">{{ messageInfo.created_at }}</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="message_details"> |
|
||||
<view class="detail_item"> |
|
||||
<view class="detail_label">发送者</view> |
|
||||
<view class="detail_value">{{ messageInfo.sender }}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="message_content"> |
|
||||
<view class="content_title">消息内容</view> |
|
||||
<view class="content_text">{{ messageInfo.content }}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 空状态 --> |
|
||||
<view class="empty_state" v-if="!loading && !messageInfo"> |
|
||||
<image src="/static/icon-img/empty.png" class="empty_icon"></image> |
|
||||
<view class="empty_text">暂无消息信息</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 加载状态 --> |
|
||||
<view class="loading_state" v-if="loading"> |
|
||||
<view class="loading_text">加载中...</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
messageInfo: null, |
|
||||
loading: false, |
|
||||
messageId: null, |
|
||||
childId: null |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
this.messageId = options.messageId |
|
||||
this.childId = options.childId |
|
||||
this.loadMessageInfo() |
|
||||
}, |
|
||||
methods: { |
|
||||
async loadMessageInfo() { |
|
||||
// 模拟消息详情数据 |
|
||||
this.messageInfo = { |
|
||||
title: '课程提醒', |
|
||||
sender: '王教练', |
|
||||
created_at: '2024-01-15 09:30:00', |
|
||||
content: '提醒您的孩子明天有篮球课,请准时参加。上课时间:10:00-11:30,地点:篮球馆A。' |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box { |
|
||||
background: #f8f9fa; |
|
||||
min-height: 100vh; |
|
||||
padding: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.message_info_card { |
|
||||
background: #fff; |
|
||||
border-radius: 16rpx; |
|
||||
padding: 32rpx; |
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1); |
|
||||
|
|
||||
.message_header { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
margin-bottom: 32rpx; |
|
||||
padding-bottom: 24rpx; |
|
||||
border-bottom: 1px solid #f0f0f0; |
|
||||
|
|
||||
.message_title { |
|
||||
font-size: 36rpx; |
|
||||
font-weight: 600; |
|
||||
color: #333; |
|
||||
} |
|
||||
|
|
||||
.message_time { |
|
||||
font-size: 24rpx; |
|
||||
color: #999; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.message_details { |
|
||||
margin-bottom: 32rpx; |
|
||||
|
|
||||
.detail_item { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
padding: 20rpx 0; |
|
||||
border-bottom: 1px solid #f8f9fa; |
|
||||
|
|
||||
.detail_label { |
|
||||
font-size: 28rpx; |
|
||||
color: #666; |
|
||||
min-width: 160rpx; |
|
||||
} |
|
||||
|
|
||||
.detail_value { |
|
||||
font-size: 28rpx; |
|
||||
color: #333; |
|
||||
flex: 1; |
|
||||
text-align: right; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.message_content { |
|
||||
.content_title { |
|
||||
font-size: 28rpx; |
|
||||
font-weight: 600; |
|
||||
color: #333; |
|
||||
margin-bottom: 16rpx; |
|
||||
} |
|
||||
|
|
||||
.content_text { |
|
||||
font-size: 26rpx; |
|
||||
color: #666; |
|
||||
line-height: 1.6; |
|
||||
padding: 16rpx; |
|
||||
background: #f8f9fa; |
|
||||
border-radius: 8rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.empty_state { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
padding: 120rpx 0; |
|
||||
|
|
||||
.empty_icon { |
|
||||
width: 160rpx; |
|
||||
height: 160rpx; |
|
||||
margin-bottom: 32rpx; |
|
||||
opacity: 0.3; |
|
||||
} |
|
||||
|
|
||||
.empty_text { |
|
||||
font-size: 28rpx; |
|
||||
color: #999; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.loading_state { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
padding: 60rpx 0; |
|
||||
|
|
||||
.loading_text { |
|
||||
font-size: 28rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,182 +0,0 @@ |
|||||
<!--订单详情页面--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<!-- 订单基本信息 --> |
|
||||
<view class="order_info_card" v-if="orderInfo"> |
|
||||
<view class="order_header"> |
|
||||
<view class="order_no">订单号:{{ orderInfo.order_no }}</view> |
|
||||
<view class="order_status" :class="orderInfo.status"> |
|
||||
{{ orderInfo.status_text }} |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="order_details"> |
|
||||
<view class="detail_item"> |
|
||||
<view class="detail_label">课程名称</view> |
|
||||
<view class="detail_value">{{ orderInfo.course_name }}</view> |
|
||||
</view> |
|
||||
<view class="detail_item"> |
|
||||
<view class="detail_label">订单金额</view> |
|
||||
<view class="detail_value amount">¥{{ orderInfo.amount }}</view> |
|
||||
</view> |
|
||||
<view class="detail_item"> |
|
||||
<view class="detail_label">下单时间</view> |
|
||||
<view class="detail_value">{{ orderInfo.created_at }}</view> |
|
||||
</view> |
|
||||
<view class="detail_item" v-if="orderInfo.pay_time"> |
|
||||
<view class="detail_label">支付时间</view> |
|
||||
<view class="detail_value">{{ orderInfo.pay_time }}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 空状态 --> |
|
||||
<view class="empty_state" v-if="!loading && !orderInfo"> |
|
||||
<image src="/static/icon-img/empty.png" class="empty_icon"></image> |
|
||||
<view class="empty_text">暂无订单信息</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 加载状态 --> |
|
||||
<view class="loading_state" v-if="loading"> |
|
||||
<view class="loading_text">加载中...</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
orderInfo: null, |
|
||||
loading: false, |
|
||||
orderId: null, |
|
||||
childId: null |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
this.orderId = options.orderId |
|
||||
this.childId = options.childId |
|
||||
this.loadOrderInfo() |
|
||||
}, |
|
||||
methods: { |
|
||||
async loadOrderInfo() { |
|
||||
// 模拟订单详情数据 |
|
||||
this.orderInfo = { |
|
||||
order_no: 'ORD202401001', |
|
||||
course_name: '少儿篮球课程包', |
|
||||
amount: '2880.00', |
|
||||
status: 'paid', |
|
||||
status_text: '已支付', |
|
||||
created_at: '2024-01-01 10:00:00', |
|
||||
pay_time: '2024-01-01 10:05:00' |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box { |
|
||||
background: #f8f9fa; |
|
||||
min-height: 100vh; |
|
||||
padding: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.order_info_card { |
|
||||
background: #fff; |
|
||||
border-radius: 16rpx; |
|
||||
padding: 32rpx; |
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1); |
|
||||
|
|
||||
.order_header { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
margin-bottom: 32rpx; |
|
||||
padding-bottom: 24rpx; |
|
||||
border-bottom: 1px solid #f0f0f0; |
|
||||
|
|
||||
.order_no { |
|
||||
font-size: 32rpx; |
|
||||
font-weight: 600; |
|
||||
color: #333; |
|
||||
} |
|
||||
|
|
||||
.order_status { |
|
||||
font-size: 24rpx; |
|
||||
padding: 8rpx 16rpx; |
|
||||
border-radius: 12rpx; |
|
||||
|
|
||||
&.paid { |
|
||||
background: rgba(40, 167, 69, 0.1); |
|
||||
color: #28a745; |
|
||||
} |
|
||||
|
|
||||
&.unpaid { |
|
||||
background: rgba(220, 53, 69, 0.1); |
|
||||
color: #dc3545; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.order_details { |
|
||||
.detail_item { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
padding: 20rpx 0; |
|
||||
border-bottom: 1px solid #f8f9fa; |
|
||||
|
|
||||
.detail_label { |
|
||||
font-size: 28rpx; |
|
||||
color: #666; |
|
||||
min-width: 160rpx; |
|
||||
} |
|
||||
|
|
||||
.detail_value { |
|
||||
font-size: 28rpx; |
|
||||
color: #333; |
|
||||
flex: 1; |
|
||||
text-align: right; |
|
||||
|
|
||||
&.amount { |
|
||||
color: #e67e22; |
|
||||
font-weight: 600; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.empty_state { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
padding: 120rpx 0; |
|
||||
|
|
||||
.empty_icon { |
|
||||
width: 160rpx; |
|
||||
height: 160rpx; |
|
||||
margin-bottom: 32rpx; |
|
||||
opacity: 0.3; |
|
||||
} |
|
||||
|
|
||||
.empty_text { |
|
||||
font-size: 28rpx; |
|
||||
color: #999; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.loading_state { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
padding: 60rpx 0; |
|
||||
|
|
||||
.loading_text { |
|
||||
font-size: 28rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,159 +0,0 @@ |
|||||
<!--服务详情页面--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<!-- 服务基本信息 --> |
|
||||
<view class="service_info_card" v-if="serviceInfo"> |
|
||||
<view class="service_header"> |
|
||||
<view class="service_title">{{ serviceInfo.title }}</view> |
|
||||
<view class="service_status" :class="serviceInfo.status"> |
|
||||
{{ serviceInfo.status_text }} |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="service_details"> |
|
||||
<view class="detail_item"> |
|
||||
<view class="detail_label">服务时间</view> |
|
||||
<view class="detail_value">{{ serviceInfo.service_time }}</view> |
|
||||
</view> |
|
||||
<view class="detail_item"> |
|
||||
<view class="detail_label">服务内容</view> |
|
||||
<view class="detail_value">{{ serviceInfo.content }}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 空状态 --> |
|
||||
<view class="empty_state" v-if="!loading && !serviceInfo"> |
|
||||
<image src="/static/icon-img/empty.png" class="empty_icon"></image> |
|
||||
<view class="empty_text">暂无服务信息</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 加载状态 --> |
|
||||
<view class="loading_state" v-if="loading"> |
|
||||
<view class="loading_text">加载中...</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
serviceInfo: null, |
|
||||
loading: false, |
|
||||
serviceId: null, |
|
||||
childId: null |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
this.serviceId = options.serviceId |
|
||||
this.childId = options.childId |
|
||||
this.loadServiceInfo() |
|
||||
}, |
|
||||
methods: { |
|
||||
async loadServiceInfo() { |
|
||||
// 模拟服务详情数据 |
|
||||
this.serviceInfo = { |
|
||||
title: '课程跟踪服务', |
|
||||
status: 'completed', |
|
||||
status_text: '已完成', |
|
||||
service_time: '2024-01-15 10:00:00', |
|
||||
content: '针对学员的课程进度进行跟踪辅导,提供个性化建议。' |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box { |
|
||||
background: #f8f9fa; |
|
||||
min-height: 100vh; |
|
||||
padding: 20rpx; |
|
||||
} |
|
||||
|
|
||||
.service_info_card { |
|
||||
background: #fff; |
|
||||
border-radius: 16rpx; |
|
||||
padding: 32rpx; |
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1); |
|
||||
|
|
||||
.service_header { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
margin-bottom: 32rpx; |
|
||||
padding-bottom: 24rpx; |
|
||||
border-bottom: 1px solid #f0f0f0; |
|
||||
|
|
||||
.service_title { |
|
||||
font-size: 36rpx; |
|
||||
font-weight: 600; |
|
||||
color: #333; |
|
||||
} |
|
||||
|
|
||||
.service_status { |
|
||||
font-size: 24rpx; |
|
||||
padding: 8rpx 16rpx; |
|
||||
border-radius: 12rpx; |
|
||||
background: rgba(41, 211, 180, 0.1); |
|
||||
color: #29d3b4; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.service_details { |
|
||||
.detail_item { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
padding: 20rpx 0; |
|
||||
border-bottom: 1px solid #f8f9fa; |
|
||||
|
|
||||
.detail_label { |
|
||||
font-size: 28rpx; |
|
||||
color: #666; |
|
||||
min-width: 160rpx; |
|
||||
} |
|
||||
|
|
||||
.detail_value { |
|
||||
font-size: 28rpx; |
|
||||
color: #333; |
|
||||
flex: 1; |
|
||||
text-align: right; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.empty_state { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
padding: 120rpx 0; |
|
||||
|
|
||||
.empty_icon { |
|
||||
width: 160rpx; |
|
||||
height: 160rpx; |
|
||||
margin-bottom: 32rpx; |
|
||||
opacity: 0.3; |
|
||||
} |
|
||||
|
|
||||
.empty_text { |
|
||||
font-size: 28rpx; |
|
||||
color: #999; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.loading_state { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
padding: 60rpx 0; |
|
||||
|
|
||||
.loading_text { |
|
||||
font-size: 28rpx; |
|
||||
color: #666; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,272 +0,0 @@ |
|||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<view class="after-class-title"> |
|
||||
<view class="after-class-title-left">课后作业</view> |
|
||||
</view> |
|
||||
|
|
||||
<scroll-view |
|
||||
class="table_list" |
|
||||
scroll-y="true" |
|
||||
:lower-threshold="lowerThreshold" |
|
||||
@scrolltolower="loadMoreData" |
|
||||
style="height: 100vh;" |
|
||||
> |
|
||||
|
|
||||
<view class="con-list" v-for="(v,k) in tableList" :key="k" @click="openViewWorkDetails(v)"> |
|
||||
<view class="con-list-img" v-if="v.content_text"> |
|
||||
<video v-if="v.content_type == 2" class="pic" style="width: 100%;border-radius: 15rpx;" :src="$util.img(v.content_text)"></video> |
|
||||
<image v-else-if="v.content_type == 1" style="width: 100%;border-radius: 15rpx;" :src="$util.img(v.content_text)" mode="aspectFit"></image> |
|
||||
<view class="text" v-else>{{v.content_text}}</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="date_box"> |
|
||||
<view class="describe" style="margin-top: 20rpx;"> |
|
||||
时间:{{v.created_at}} |
|
||||
</view> |
|
||||
<!--是否已经完成作业--> |
|
||||
<view class="mark" v-if="v.status == 3"> |
|
||||
<image class="check_mark" :src="$util.img('/uniapp_src/static/images/index/check_mark.png')"></image> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
|
|
||||
<!--作业描述--> |
|
||||
<view class="con" style="margin-bottom: 20rpx; color:#fff;" v-html="v.description"></view> |
|
||||
|
|
||||
<view class="assignment"> |
|
||||
<view>{{v.type == 1 ? '班级作业' : '个人作业'}}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
</scroll-view> |
|
||||
|
|
||||
|
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
import memberApi from '@/api/member.js'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
loading:false,//加载状态 |
|
||||
lowerThreshold: 100,//距离底部多远触发 |
|
||||
isReachedBottom: false,//防止重复加载|true=不可加载|false=可加载 |
|
||||
|
|
||||
//筛选条件 |
|
||||
filteredData:{ |
|
||||
page:1,//当前页码 |
|
||||
limit:10,//每页返回数据条数 |
|
||||
total:10,//数据总条数 |
|
||||
resources_id: '',//学生资源id |
|
||||
status: '',//状态 1待批改 2未提交 3已提交 |
|
||||
}, |
|
||||
|
|
||||
tableList:[],//表格数据 |
|
||||
|
|
||||
member_info:{},//学生信息 |
|
||||
|
|
||||
} |
|
||||
}, |
|
||||
onShow(){ |
|
||||
this.init()//初始化 |
|
||||
}, |
|
||||
//下拉刷新 |
|
||||
async onPullDownRefresh() { |
|
||||
//重置为第一页 |
|
||||
await this.resetFilteredData() |
|
||||
await this.getList() |
|
||||
}, |
|
||||
methods: { |
|
||||
//初始化 |
|
||||
async init(){ |
|
||||
await this.memberInit() |
|
||||
await this.getList(); |
|
||||
}, |
|
||||
|
|
||||
//获取学员信息 |
|
||||
async memberInit() { |
|
||||
let res = await apiRoute.xy_memberInfo({}) |
|
||||
if(res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
this.member_info = res.data |
|
||||
this.filteredData.resources_id = this.member_info.id,//学生资源id |
|
||||
console.log('xxxx',this.member_info) |
|
||||
}, |
|
||||
|
|
||||
//加载更多(下一页) |
|
||||
loadMoreData() { |
|
||||
//判断是否加载 |
|
||||
if (!this.isReachedBottom) { |
|
||||
this.isReachedBottom = true;//设置为不可请求状态 |
|
||||
this.getList(); |
|
||||
} |
|
||||
}, |
|
||||
//重置为第一页 |
|
||||
async resetFilteredData() { |
|
||||
this.isReachedBottom = false; // 重置状态,以便下次触发加载更多 |
|
||||
|
|
||||
this.filteredData.page = 1//当前页码 |
|
||||
this.filteredData.limit = 10//每页返回数据条数 |
|
||||
this.filteredData.total = 10//数据总条数 |
|
||||
}, |
|
||||
|
|
||||
//获取作业列表 |
|
||||
async getList(){ |
|
||||
this.loading = true |
|
||||
|
|
||||
let data = {...this.filteredData} |
|
||||
|
|
||||
//判断是否还有数据 |
|
||||
if ((this.filteredData.page - 1) * this.filteredData.limit >= this.filteredData.total) { |
|
||||
this.loading = false |
|
||||
uni.showToast({ |
|
||||
title: '暂无更多', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
if(data.page == 1){ |
|
||||
this.tableList = [] |
|
||||
} |
|
||||
|
|
||||
let res = await apiRoute.xy_assignment(data) |
|
||||
this.loading = false |
|
||||
this.isReachedBottom = false; |
|
||||
if (res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.tableList = this.tableList.concat(res.data.data); // 使用 concat 方法 将新数据追加到数组中 |
|
||||
|
|
||||
console.log('列表',this.tableList) |
|
||||
this.filteredData.total = res.data.total |
|
||||
this.filteredData.page++ |
|
||||
}, |
|
||||
|
|
||||
//跳转页面-打开作业详情 |
|
||||
openViewWorkDetails(item) { |
|
||||
let id = item.id |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/student/index/work_details?id=${id}` |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
}, |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box{ |
|
||||
width: 100%; |
|
||||
height: 100vh; |
|
||||
background: #292929; |
|
||||
overflow: auto; |
|
||||
|
|
||||
.table_list{ |
|
||||
padding-bottom: 150rpx; |
|
||||
} |
|
||||
} |
|
||||
.after-class-title { |
|
||||
width: 92%; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
margin: auto; |
|
||||
padding-top: 30rpx; |
|
||||
} |
|
||||
.after-class-title-left { |
|
||||
color: #fff; |
|
||||
font-size: 35rpx; |
|
||||
border-bottom: 4rpx #29d3b4 solid; |
|
||||
} |
|
||||
.con-list{ |
|
||||
width: 100%; |
|
||||
padding: 30rpx; |
|
||||
margin-top: 20rpx; |
|
||||
border-bottom: 2rpx #fff solid; |
|
||||
.date_box{ |
|
||||
padding-top: 30rpx; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
.describe{ |
|
||||
width: 75%; |
|
||||
color: #fff; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.con-list-img{ |
|
||||
width: 100%; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
|
|
||||
video{ |
|
||||
width: 100%; |
|
||||
height: 280rpx; |
|
||||
} |
|
||||
image{ |
|
||||
width: 100%; |
|
||||
height: 280rpx; |
|
||||
} |
|
||||
.text{ |
|
||||
width: 100%; |
|
||||
font-size: 28rpx; |
|
||||
color:#fff; |
|
||||
white-space: pre-wrap; |
|
||||
word-wrap: break-word; |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
.pic{ |
|
||||
width: 85%; |
|
||||
height: 100%; |
|
||||
} |
|
||||
.con{ |
|
||||
width: 75%; |
|
||||
color: #fff; |
|
||||
padding-top: 30rpx; |
|
||||
} |
|
||||
.mark{ |
|
||||
width: 70rpx; |
|
||||
height: 70rpx; |
|
||||
border-radius: 100%; |
|
||||
background: #29d3b4; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
} |
|
||||
.check_mark{ |
|
||||
width: 80%; |
|
||||
height: 80%; |
|
||||
} |
|
||||
.assignment{ |
|
||||
display: flex; |
|
||||
justify-content: flex-end; |
|
||||
align-items: center; |
|
||||
view{ |
|
||||
padding: 6rpx 12rpx; |
|
||||
color: #6b9d53; |
|
||||
border: 2rpx #6b9d53 solid; |
|
||||
border-radius: 10rpx; |
|
||||
width: 150rpx; |
|
||||
text-align: center; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,114 +0,0 @@ |
|||||
<!--作业详情--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<!-- 作业展示--> |
|
||||
<view class="top-style" v-if="infoData.content_text"> |
|
||||
<video v-if="infoData.content_type == 2" class="pic" style="width: 100%;border-radius: 15rpx;" :src="$util.img(infoData.content_text)"></video> |
|
||||
<image v-else-if="infoData.content_type == 1" style="width: 100%;border-radius: 15rpx;" :src="$util.img(infoData.content_text)" mode="aspectFit"></image> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 简练信息+作业描述--> |
|
||||
<view class="below-style"> |
|
||||
<view class="head-img"> |
|
||||
<!--学生头像--> |
|
||||
<fui-avatar width="80" :src="infoData.student.customerResources.member.headimg ? infoData.student.customerResources.member.headimg : $util.img('/uniapp_src/static/images/common/yong_hu.png')"></fui-avatar> |
|
||||
<view class="head-text">{{infoData .student.name}}</view> |
|
||||
</view> |
|
||||
<view class="multi-line-ellipsis"> |
|
||||
状态:{{ infoData.status == 1 ? '待批改' : infoData.status == 2 ? '未提交' : infoData.status == 3 ? '已提交' :''}} </view> |
|
||||
<view class="multi-line-ellipsis" v-html="infoData.description"></view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
<script> |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
|
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
//筛选条件 |
|
||||
filteredData: { |
|
||||
id: '',//作业id |
|
||||
}, |
|
||||
|
|
||||
infoData:{}, |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
this.filteredData.id = options.id//作业id |
|
||||
}, |
|
||||
onShow(){ |
|
||||
this.init()//初始化数据 |
|
||||
}, |
|
||||
methods: { |
|
||||
//初始化 |
|
||||
async init(){ |
|
||||
this.getAssignmentsInfo() |
|
||||
}, |
|
||||
|
|
||||
//获取作业详情 |
|
||||
async getAssignmentsInfo() { |
|
||||
let params = {...this.filteredData} |
|
||||
let res = await apiRoute.xy_assignmentsInfo(params) |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.infoData = res.data |
|
||||
}, |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box{ |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
background: #292929; |
|
||||
padding-top: 45rpx; |
|
||||
} |
|
||||
.top-style{ |
|
||||
width: 92%; |
|
||||
height: 700rpx; |
|
||||
margin: auto; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
} |
|
||||
.top-style-img{ |
|
||||
width: 120rpx; |
|
||||
height: 120rpx; |
|
||||
} |
|
||||
.below-style{ |
|
||||
width: 92%; |
|
||||
margin: auto; |
|
||||
.head-img { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
padding: 10rpx 20rpx; |
|
||||
} |
|
||||
.head-text { |
|
||||
color: #fff; |
|
||||
font-size: 35rpx; |
|
||||
padding-left: 20rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
.multi-line-ellipsis { |
|
||||
margin-top: 20rpx; |
|
||||
color: #fff; |
|
||||
font-size: 29rpx; |
|
||||
padding: 5rpx 10rpx; |
|
||||
// display: -webkit-box; |
|
||||
// -webkit-box-orient: vertical; |
|
||||
// -webkit-line-clamp: 2; |
|
||||
// overflow: hidden; |
|
||||
// text-overflow: ellipsis; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,379 +0,0 @@ |
|||||
<!--我的-首页--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<view class="navbar_section"> |
|
||||
<view class="title">我的</view> |
|
||||
</view> |
|
||||
<view style="background:#29D3B4;"> |
|
||||
<!--用户信息--> |
|
||||
<view class="user_section"> |
|
||||
<view class="box"> |
|
||||
<view class="left" @click="personal_data"> |
|
||||
<image class="pic" :src="member_info.memberHasOne ? member_info.memberHasOne.headimg : $util.img('/uniapp_src/static/images/common/yong_hu.png')"></image> |
|
||||
<view class="name">{{member_info.name}}</view> |
|
||||
</view> |
|
||||
<view class="right" @click="setup"> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/setup.png')" style="width: 50rpx;height: 50rpx;"></image> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!--统计信息--> |
|
||||
<view class="count_section"> |
|
||||
<view class="main"> |
|
||||
<view class="course_box"> |
|
||||
<view class="top"> |
|
||||
<view class="item"> |
|
||||
<view class="num">{{member_info.classes_count}}</view> |
|
||||
<view class="intro">我的课程</view> |
|
||||
</view> |
|
||||
<view class="item"> |
|
||||
<view class="num">{{member_info.sign_count}}</view> |
|
||||
<view class="intro">已上课时</view> |
|
||||
</view> |
|
||||
<view class="item"> |
|
||||
<view class="num">{{member_info.stay_sign_count}}</view> |
|
||||
<view class="intro">待上课时 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="bottom"></view> |
|
||||
<view class="bg_box bg_top"></view> |
|
||||
<view class="bg_box bg_bottom"></view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="main_section"> |
|
||||
<view class="section_box"> |
|
||||
<view class="item" style="border-radius: 16rpx 16rpx 0 0;" @click="lesson_consumption"> |
|
||||
<view>课时消耗</view> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/right_arrow.png')" class="arrow-icon"></image> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item" @click="openViewOrder()"> |
|
||||
<view>我的订单</view> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/right_arrow.png')" class="arrow-icon"></image> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item" @click="navigateToTimetable()"> |
|
||||
<view>我的课表</view> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/right_arrow.png')" class="arrow-icon"></image> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="section_box"> |
|
||||
<view class="item" @click="openViewMyCoach()"> |
|
||||
<view>我的教练</view> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/right_arrow.png')" class="arrow-icon"></image> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item" @click="navigateToHomework()"> |
|
||||
<view>作业管理</view> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/right_arrow.png')" class="arrow-icon"></image> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item" @click="feedback"> |
|
||||
<view>意见反馈</view> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/right_arrow.png')" class="arrow-icon"></image> |
|
||||
</view> |
|
||||
|
|
||||
<view class="item" @click="openViewMyMessage({user_id:1})"> |
|
||||
<view>我的消息</view> |
|
||||
<image :src="$util.img('/uniapp_src/static/images/index/right_arrow.png')" class="arrow-icon"></image> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 底部导航--> |
|
||||
<AQTabber /> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
import member from '@/api/member.js'; |
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
member_info: [], |
|
||||
} |
|
||||
}, |
|
||||
onLoad() { |
|
||||
this.member_init(); |
|
||||
}, |
|
||||
methods: { |
|
||||
//获取学员信息 |
|
||||
async member_init() { |
|
||||
let res = await apiRoute.xy_memberInfo({}) |
|
||||
if(res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
this.member_info = res.data |
|
||||
}, |
|
||||
//打开设置 |
|
||||
setup(item) { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/student/my/set_up' |
|
||||
}) |
|
||||
}, |
|
||||
//意见反馈 |
|
||||
feedback() { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/common/feedback' |
|
||||
}) |
|
||||
}, |
|
||||
//课时消耗 |
|
||||
lesson_consumption() { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/student/my/lesson_consumption' |
|
||||
}) |
|
||||
}, |
|
||||
//我的成员 |
|
||||
my_members() { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/student/my/my_members' |
|
||||
}) |
|
||||
}, |
|
||||
//人人资料 |
|
||||
personal_data() { |
|
||||
this.$navigateTo({ |
|
||||
url: '/pages/student/my/personal_data' |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//跳转页面-订单列表 |
|
||||
openViewOrder() { |
|
||||
let resource_id = this.member_info.id//客户资源id |
|
||||
let resource_name = this.member_info.name || ''//客户资源id姓名 |
|
||||
|
|
||||
// let staff_id = this.userInfo.id//员工id |
|
||||
// let staff_id_name = this.userInfo.name || ''//员工姓名 |
|
||||
|
|
||||
let staff_id = ''//员工id |
|
||||
let staff_id_name = ''//员工姓名 |
|
||||
|
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/common/contract_list?resource_id=${resource_id}&resource_name=${resource_name}&staff_id=${staff_id}&staff_id_name=${staff_id_name}` |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//跳转页面-我的消息 |
|
||||
openViewMyMessage(item) { |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/common/my_message` |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//跳转页面-我的教练 |
|
||||
openViewMyCoach(){ |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/student/my/my_coach` |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//跳转页面-课表 |
|
||||
navigateToTimetable(){ |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/student/timetable/index` |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
//跳转页面-作业管理 |
|
||||
navigateToHomework(){ |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/student/index/job_list` |
|
||||
}) |
|
||||
}, |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box { |
|
||||
background: #292929; |
|
||||
height: 100%; |
|
||||
} |
|
||||
|
|
||||
//自定义导航栏 |
|
||||
.navbar_section { |
|
||||
border: 1px solid #29D3B4; |
|
||||
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; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//用户信息 |
|
||||
.user_section { |
|
||||
background-color: #29D3B4; |
|
||||
padding-top: 58rpx; |
|
||||
padding-bottom: 42rpx; |
|
||||
color: #fff; |
|
||||
font-size: 28rpx; |
|
||||
|
|
||||
.box { |
|
||||
padding-left: 19rpx; |
|
||||
padding-right: 29rpx; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
gap: 15rpx; |
|
||||
|
|
||||
.left { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 20rpx; |
|
||||
|
|
||||
.pic { |
|
||||
width: 144rpx; |
|
||||
height: 144rpx; |
|
||||
border-radius: 50%; |
|
||||
} |
|
||||
|
|
||||
.name { |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.right { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 20rpx; |
|
||||
|
|
||||
.btn { |
|
||||
min-height: 28rpx; |
|
||||
font-size: 28rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//统计信息 |
|
||||
.count_section { |
|
||||
position: relative; |
|
||||
|
|
||||
.main { |
|
||||
position: relative; |
|
||||
z-index: 2; |
|
||||
padding: 0rpx 24rpx; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
|
|
||||
.course_box { |
|
||||
padding: 42rpx 28rpx; |
|
||||
width: 692rpx; |
|
||||
border-radius: 20rpx; |
|
||||
background-color: #fff; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 32rpx; |
|
||||
|
|
||||
.top { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
|
|
||||
.item { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
gap: 12rpx; |
|
||||
|
|
||||
.num { |
|
||||
color: #29D3B4; |
|
||||
font-size: 56rpx; |
|
||||
} |
|
||||
|
|
||||
.intro { |
|
||||
color: #AAAAAA; |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.bg_box { |
|
||||
z-index: 1; |
|
||||
width: 100%; |
|
||||
height: 150rpx; |
|
||||
} |
|
||||
|
|
||||
.bg_top { |
|
||||
position: absolute; |
|
||||
top: 0; |
|
||||
background-color: #29D3B4; |
|
||||
} |
|
||||
|
|
||||
.bg_bottom { |
|
||||
top: 50%; |
|
||||
position: absolute; |
|
||||
background-color: #292929; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.main_section { |
|
||||
margin-top: 20rpx; |
|
||||
background: #292929 100%; |
|
||||
padding: 0 24rpx; |
|
||||
padding-top: 40rpx; |
|
||||
padding-bottom: 150rpx; |
|
||||
font-size: 24rpx; |
|
||||
color: #333333; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 22rpx; |
|
||||
|
|
||||
.section_box { |
|
||||
margin-bottom: 10rpx; |
|
||||
background: #fff; |
|
||||
border-radius: 16rpx; |
|
||||
padding: 6rpx 24rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
|
|
||||
.item { |
|
||||
padding: 35rpx 78rpx; |
|
||||
border-top: 1px solid #F2F2F2; |
|
||||
font-size: 28rpx; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
} |
|
||||
|
|
||||
.item:nth-child(1) { |
|
||||
border-top: 0; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 箭头图标样式 |
|
||||
.arrow-icon { |
|
||||
width: 24rpx; |
|
||||
height: 24rpx; |
|
||||
opacity: 0.6; |
|
||||
|
|
||||
} |
|
||||
</style> |
|
||||
@ -1,607 +0,0 @@ |
|||||
<!--课程-列表--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<!--自定义导航栏--> |
|
||||
<view class="navbar_section"> |
|
||||
<view class="title">课表</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="main_section"> |
|
||||
<view class="section_1"> |
|
||||
<view class="ul"> |
|
||||
<view class="li" v-for="(v,k) in dateList" :key="k" @click="selectDate(v.date)"> |
|
||||
<text>{{v.week}}</text> |
|
||||
|
|
||||
<text :class="[filteredData.course_date == v.date ? 'today':'']">{{today == v.date ? '今':v.today}}</text> |
|
||||
|
|
||||
<text :class="[v.is_sign == 1 ? 'select_plan':'']"></text> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="btn" @click="show_calendar=true"> |
|
||||
查看更多 <fui-icon name="arrowdown" color="#A4ADB3" size="45"></fui-icon> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="section_2"> |
|
||||
<view class="item_box"> |
|
||||
<text v-if="(venuesInfo.id || '')">{{venuesInfo.venue_name}}</text> |
|
||||
</view> |
|
||||
<view class="item_box" style="text-align: right;color: #F59A23;" @click="more"> |
|
||||
更多场馆 |
|
||||
</view> |
|
||||
|
|
||||
</view> |
|
||||
|
|
||||
<scroll-view |
|
||||
class="section_3" |
|
||||
scroll-y="true" |
|
||||
:lower-threshold="lowerThreshold" |
|
||||
@scrolltolower="loadMoreData" |
|
||||
style="height: 100vh;" |
|
||||
> |
|
||||
<view class="ul"> |
|
||||
<view v-for="(v,k) in tableList" :key="k" class="li" @click="openViewCourseInfo(v)"> |
|
||||
<view class="top_box"> |
|
||||
<view class="center_box"> |
|
||||
<view>教练:{{v.courseScheduleHasOne.coach.name}}</view> |
|
||||
<view>课程:{{v.courseScheduleHasOne.course.course_name}}</view> |
|
||||
<view>时间:{{v.course_date}}</view> |
|
||||
<view>课室:{{v.courseScheduleHasOne.campus_name}} {{v.courseScheduleHasOne.venue.venue_name}}</view> |
|
||||
</view> |
|
||||
<view class="right_box"> |
|
||||
<!-- v.status|1=未开始,2=进行中,3=已结束--> |
|
||||
<view class="tag" |
|
||||
v-if="v.status != null" |
|
||||
:style="{background: v.status == 1 ? '#1cd188' : v.status == 2 ? '#fad24e' : '#ff4d4f'}"> |
|
||||
{{ v.status == 0 ? '待上课' : v.status == 1 ? '已上课' : '请假' }} |
|
||||
</view> |
|
||||
<!-- <view class="tag" style="background:#1cd188;">待上课</view>--> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="bottom_box"> |
|
||||
<view class="hint"> |
|
||||
<!-- 已签到学生 ({{v.sign_list.length }}/{{v.max_students.split(',').length }})--> |
|
||||
</view> |
|
||||
<view class="list_box"> |
|
||||
<!-- <view class="list">--> |
|
||||
<!-- <view class="itme" v-for="(item,index) in v.sign_list || 0" :key="index">--> |
|
||||
<!-- <image :src="$util.img(item.header)"></image>--> |
|
||||
<!-- </view>--> |
|
||||
<!-- </view>--> |
|
||||
<view class="btn"> |
|
||||
详情 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</scroll-view> |
|
||||
<!-- 加载状态--> |
|
||||
<!-- <fui-loading :isFixed="true" srcCol="/static/icon-img/loading_white.png" text="正在加载..." v-if="loading"></fui-loading>--> |
|
||||
|
|
||||
</view> |
|
||||
|
|
||||
<!-- 日历选择--> |
|
||||
<fui-bottom-popup :show="show_calendar" @close="show_calendar=false"> |
|
||||
<view class="fui-custom__wrap"> |
|
||||
<uni-calendar |
|
||||
:insert="true" |
|
||||
:lunar="false" |
|
||||
:selected="calendarSelected" |
|
||||
:startDate="startDate" |
|
||||
:endDate="endDate" |
|
||||
@change="changeCalendar" |
|
||||
/> |
|
||||
</view> |
|
||||
</fui-bottom-popup> |
|
||||
|
|
||||
<!-- 底部导航--> |
|
||||
<AQTabber/> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
import memberApi from '@/api/member.js'; |
|
||||
import commonApi from '@/api/common.js'; |
|
||||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|
||||
|
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
loading: false,//加载状态 |
|
||||
lowerThreshold: 100,//距离底部多远触发 |
|
||||
isReachedBottom: false,//防止重复加载|true=不可加载|false=可加载 |
|
||||
|
|
||||
memberInfo:{},//当前登录的学生详情 |
|
||||
|
|
||||
//筛选条件 |
|
||||
filteredData: { |
|
||||
page: 1,//当前页码 |
|
||||
limit: 10,//每页返回数据条数 |
|
||||
total: 10,//数据总条数 |
|
||||
resources_id:'',//客户资源表id |
|
||||
course_date: '',//上课日期 |
|
||||
venue_id: '',//场地id |
|
||||
}, |
|
||||
tableList: [],//表格数据 |
|
||||
|
|
||||
venuesInfo: {id:''},//场地信息 |
|
||||
|
|
||||
//今日日期 |
|
||||
today: '', |
|
||||
dateList: [],//日期列表 |
|
||||
|
|
||||
//日历选择相关 |
|
||||
show_calendar:false,//是否展示日期 |
|
||||
startDate:'',//开始日期 |
|
||||
endDate:'',//结束日期 |
|
||||
calendarSelected: [ |
|
||||
// { |
|
||||
// date: '2025-04-07',//需要上课的日期 |
|
||||
// }, |
|
||||
// { |
|
||||
// date: '2025-04-09',//需要上课的日期 |
|
||||
// }, |
|
||||
],//日历打点(有课的日期) |
|
||||
|
|
||||
|
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
if (options.venue_id) { |
|
||||
this.filteredData.venue_id = options.venue_id |
|
||||
} |
|
||||
}, |
|
||||
onShow() { |
|
||||
this.init()//初始化 |
|
||||
}, |
|
||||
//下拉刷新 |
|
||||
async onPullDownRefresh() { |
|
||||
//重置为第一页 |
|
||||
let course_date = this.filteredData.course_date |
|
||||
await this.loadData() |
|
||||
this.filteredData.course_date = course_date |
|
||||
await this.getList() |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
//初始化 |
|
||||
async init() { |
|
||||
await this.getMemberInfo()//获取当前登录的学生信息 |
|
||||
await this.getThisDate()//获取当前日期 |
|
||||
await this.getList()//获取列表 |
|
||||
await this.getHeadDate()//获取课程头日期 |
|
||||
|
|
||||
this.getDateRange()//获取日期范围 |
|
||||
this.setCalendarSelected()//设置日期打点 |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
|
|
||||
//获取当前登录的学生信息 |
|
||||
async getMemberInfo() { |
|
||||
let res = await apiRoute.xy_memberInfo({}) |
|
||||
if(res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
this.memberInfo = res.data |
|
||||
this.filteredData.resources_id = res.data.id |
|
||||
}, |
|
||||
|
|
||||
//获取课程头日期 |
|
||||
async getHeadDate() { |
|
||||
// 计算开始日期:从今天往前推2天 |
|
||||
let startDate = new Date(); |
|
||||
startDate.setDate(startDate.getDate() - 2); |
|
||||
let start_date = startDate.toISOString().split('T')[0]; |
|
||||
|
|
||||
// 计算结束日期:从今天往后推4天 |
|
||||
let endDate = new Date(); |
|
||||
endDate.setDate(endDate.getDate() + 4); |
|
||||
let end_date = endDate.toISOString().split('T')[0]; |
|
||||
|
|
||||
let params = { |
|
||||
resources_id: this.memberInfo.id, // 客户资源ID |
|
||||
start_date: start_date, // 开始日期(Y-m-d) |
|
||||
end_date: end_date, // 结束日期(Y-m-d) |
|
||||
} |
|
||||
let res = await apiRoute.xy_personCourseScheduleGetCalendar(params) |
|
||||
if (res.code != 1) { |
|
||||
//提示 |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none', |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.dateList = [] |
|
||||
res.data.forEach((v, k) => { |
|
||||
this.dateList.push({ |
|
||||
date: v.date, |
|
||||
status: v.status,//1是正常 2请假 |
|
||||
week: v.week, |
|
||||
today: v.today, |
|
||||
is_sign: v.is_sign, |
|
||||
}) |
|
||||
}) |
|
||||
|
|
||||
|
|
||||
console.log('xxx', res) |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
//获取当前日期 |
|
||||
async getThisDate() { |
|
||||
let date = new Date(); |
|
||||
let year = date.getFullYear(); |
|
||||
let month = String(date.getMonth() + 1).padStart(2, '0'); // 月份前补零 |
|
||||
let day = String(date.getDate()).padStart(2, '0'); // 日期前补零 |
|
||||
let hour = date.getHours(); |
|
||||
let minute = date.getMinutes(); |
|
||||
let second = date.getSeconds(); |
|
||||
|
|
||||
let res = `${year}-${month}-${day}`; // 格式化日期 |
|
||||
this.today = res; |
|
||||
this.filteredData.course_date = res; |
|
||||
}, |
|
||||
|
|
||||
//加载更过(下一页) |
|
||||
async loadMoreData() { |
|
||||
//判断是否加载 |
|
||||
if (!this.isReachedBottom) { |
|
||||
this.isReachedBottom = true;//设置为不可请求状态 |
|
||||
await this.getList(); |
|
||||
} |
|
||||
}, |
|
||||
//重置为第一页 |
|
||||
async loadData() { |
|
||||
this.isReachedBottom = false; // 重置状态,以便下次触发加载更多 |
|
||||
|
|
||||
this.filteredData.page = 1//当前页码 |
|
||||
this.filteredData.limit = 10//每页返回数据条数 |
|
||||
this.filteredData.total = 10//数据总条数 |
|
||||
}, |
|
||||
//获取列表 |
|
||||
async getList() { |
|
||||
this.loading = true |
|
||||
|
|
||||
let data = {...this.filteredData} |
|
||||
if(this.filteredData.page == 1){ |
|
||||
this.tableList = [] |
|
||||
} |
|
||||
|
|
||||
//判断是否还有数据 |
|
||||
if ((this.filteredData.page - 1) * this.filteredData.limit >= this.filteredData.total) { |
|
||||
this.loading = false |
|
||||
uni.showToast({ |
|
||||
title: '暂无更多', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
let res = await apiRoute.xy_personCourseSchedule(data) |
|
||||
this.loading = false |
|
||||
this.isReachedBottom = false; |
|
||||
if (res.code != 1) { |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.tableList = this.tableList.concat(res.data.data); // 使用 concat 方法 将新数据追加到数组中 |
|
||||
|
|
||||
//场地信息 |
|
||||
this.venuesInfo = res.data.venues_info |
|
||||
|
|
||||
this.filteredData.total = res.data.total |
|
||||
this.filteredData.page++ |
|
||||
}, |
|
||||
|
|
||||
//选择日期 |
|
||||
async selectDate(date) { |
|
||||
this.loadData() |
|
||||
this.filteredData.course_date = date |
|
||||
this.getList() |
|
||||
}, |
|
||||
|
|
||||
//日历选择相关 |
|
||||
// 获取日期范围 |
|
||||
getDateRange() { |
|
||||
const today = new Date(); // 获取今天的日期 |
|
||||
const startDate = new Date(today); // 复制今天的日期 |
|
||||
const endDate = new Date(today); // 复制今天的日期 |
|
||||
|
|
||||
// 计算 startDate:往前推 1 个月 |
|
||||
startDate.setMonth(today.getMonth() - 1); |
|
||||
|
|
||||
// 计算 endDate:往后推 1 个月 |
|
||||
endDate.setMonth(today.getMonth() + 2); |
|
||||
|
|
||||
// 将日期格式化为 YYYY-MM-DD |
|
||||
const formatDate = (date) => { |
|
||||
const year = date.getFullYear(); |
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0'); |
|
||||
const day = String(date.getDate()).padStart(2, '0'); |
|
||||
return `${year}-${month}-${day}`; |
|
||||
}; |
|
||||
|
|
||||
// 更新 data 中的 startDate 和 endDate |
|
||||
this.startDate = formatDate(startDate); |
|
||||
this.endDate = formatDate(endDate); |
|
||||
console.log([this.startDate,this.endDate]) |
|
||||
}, |
|
||||
//设置日期打点 |
|
||||
async setCalendarSelected(){ |
|
||||
//获取当前月份 |
|
||||
const today = new Date(); // 获取当前日期 |
|
||||
const year = today.getFullYear(); // 获取年份 |
|
||||
const month = today.getMonth(); // 获取月份(0-11) |
|
||||
|
|
||||
// 计算本月第一天 |
|
||||
const firstDay = new Date(year, month, 1); |
|
||||
// 计算本月最后一天(下个月的第一天减去1天) |
|
||||
const lastDay = new Date(year, month + 1, 0); |
|
||||
|
|
||||
// 格式化日期为 YYYY-MM-DD |
|
||||
const formatDate = (date) => { |
|
||||
const y = date.getFullYear(); |
|
||||
const m = String(date.getMonth() + 1).padStart(2, '0'); // 月份补零 |
|
||||
const d = String(date.getDate()).padStart(2, '0'); // 日期补零 |
|
||||
return `${y}-${m}-${d}`; |
|
||||
}; |
|
||||
|
|
||||
let start_date = formatDate(firstDay); // 本月第一天 |
|
||||
let end_date = formatDate(lastDay); // 本月最后一天 |
|
||||
|
|
||||
let params = { |
|
||||
resources_id: this.memberInfo.id, // 客户资源ID |
|
||||
start_date: start_date, // 开始日期(Y-m-d) |
|
||||
end_date: end_date, // 结束日期(Y-m-d) |
|
||||
} |
|
||||
let res = await apiRoute.xy_personCourseScheduleGetCalendar(params) |
|
||||
|
|
||||
this.calendarSelected = [] |
|
||||
res.data.forEach((v,k)=>{ |
|
||||
if(v.is_sign == 1){ |
|
||||
this.calendarSelected.push({ |
|
||||
date: v.date, |
|
||||
}) |
|
||||
} |
|
||||
}) |
|
||||
|
|
||||
|
|
||||
// this.calendarSelected = [ |
|
||||
// { |
|
||||
// date: '2025-04-07', |
|
||||
// }, |
|
||||
// { |
|
||||
// date: '2025-04-08', |
|
||||
// }, |
|
||||
// { |
|
||||
// date: '2025-04-09', |
|
||||
// } |
|
||||
// ] |
|
||||
}, |
|
||||
//日历选择 |
|
||||
changeCalendar(e){ |
|
||||
console.log('日历',e) |
|
||||
this.show_calendar = false |
|
||||
console.log('日历',e) |
|
||||
this.show_calendar = false |
|
||||
this.loadData() |
|
||||
this.filteredData.course_date = e.fulldate |
|
||||
this.getList() |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
//打开课表详情页 |
|
||||
openViewCourseInfo(item) { |
|
||||
let person_course_schedule_id = item.id |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/student/timetable/info?person_course_schedule_id=${person_course_schedule_id}` |
|
||||
}) |
|
||||
}, |
|
||||
//体育馆列表 |
|
||||
more() { |
|
||||
let course_date = this.filteredData.course_date |
|
||||
let venue_id = this.venuesInfo.id || ''//当前场馆id |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/student/timetable/list?course_date=${course_date}&venue_id=${venue_id}` |
|
||||
}) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
|
|
||||
.main_box{ |
|
||||
background: #292929 ; |
|
||||
} |
|
||||
|
|
||||
//自定义导航栏 |
|
||||
.navbar_section{ |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
background: #292929; |
|
||||
.title{ |
|
||||
padding: 40rpx 0rpx; |
|
||||
|
|
||||
/* 小程序端样式 */ |
|
||||
// #ifdef MP-WEIXIN |
|
||||
padding: 80rpx 0rpx; |
|
||||
// #endif |
|
||||
|
|
||||
font-size: 30rpx; |
|
||||
color: #fff; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.main_section{ |
|
||||
min-height: 100vh; |
|
||||
background: #292929 100%; |
|
||||
padding-top: 40rpx; |
|
||||
padding-bottom: 150rpx; |
|
||||
font-size: 24rpx; |
|
||||
color: #FFFFFF; |
|
||||
|
|
||||
.section_1{ |
|
||||
background: #333333 100%; |
|
||||
width: 100%; |
|
||||
padding: 30rpx 28rpx; |
|
||||
.ul{ |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
.li{ |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
gap: 10rpx; |
|
||||
text{ |
|
||||
font-size: 24rpx; |
|
||||
color: #FFFFFF; |
|
||||
text-align: center; |
|
||||
} |
|
||||
text:nth-child(2){ |
|
||||
width: 44rpx; |
|
||||
height: 44rpx; |
|
||||
} |
|
||||
text:nth-child(3){ |
|
||||
width: 8rpx; |
|
||||
height: 8rpx; |
|
||||
} |
|
||||
.today{ |
|
||||
border-radius: 50%; |
|
||||
background: #29D3B4; |
|
||||
text-align: center; |
|
||||
line-height: 42rpx; |
|
||||
} |
|
||||
.select_plan{ |
|
||||
background: #F59A23; |
|
||||
border-radius: 50%; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.btn{ |
|
||||
margin-top: 20rpx; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
color: #A4ADB3; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.section_2{ |
|
||||
margin-top: 30rpx; |
|
||||
padding: 0 20rpx ; |
|
||||
color: #fff; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
.item_box { |
|
||||
width: 45%; |
|
||||
.fui-filter__item { |
|
||||
display: flex; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.section_3{ |
|
||||
margin-top: 36rpx; |
|
||||
color: #fff; |
|
||||
font-size: 24rpx; |
|
||||
.ul{ |
|
||||
padding: 0 26rpx; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 30rpx; |
|
||||
.li{ |
|
||||
position: relative; |
|
||||
border-radius: 22rpx; |
|
||||
background: #434544 100%; |
|
||||
padding: 14rpx 0; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
.top_box{ |
|
||||
padding: 20rpx 30rpx; |
|
||||
.center_box{ |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
gap: 10rpx; |
|
||||
view{} |
|
||||
} |
|
||||
.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; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.bottom_box{ |
|
||||
border-top: 1px dashed #F2F2F2; |
|
||||
padding: 26rpx 16rpx 0 26rpx; |
|
||||
.hint{ |
|
||||
color:#D7D7D7; |
|
||||
} |
|
||||
.list_box{ |
|
||||
margin-top: 22rpx; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
align-items: center; |
|
||||
.list{ |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: 14rpx; |
|
||||
.itme{ |
|
||||
image{ |
|
||||
width: 48rpx; |
|
||||
height: 48rpx; |
|
||||
border-radius: 50%; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.btn{ |
|
||||
border: 1px solid #FAD04D; |
|
||||
border-radius: 10rpx; |
|
||||
background: #434544; |
|
||||
color: #FAD04D; |
|
||||
width: 110rpx; |
|
||||
height: 60rpx; |
|
||||
line-height: 55rpx; |
|
||||
text-align: center; |
|
||||
font-size: 24rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
|
|
||||
</style> |
|
||||
@ -1,254 +0,0 @@ |
|||||
<!--课程-详情--> |
|
||||
<template> |
|
||||
<view class="main_box"> |
|
||||
<scroll-view scroll-y="true" :lower-threshold="lowerThreshold" |
|
||||
@scrolltolower="loadMoreData" style="height: 100vh;"> |
|
||||
|
|
||||
<view class="data_hint" v-if="!this.tableList.length">暂无更多数据</view> |
|
||||
|
|
||||
<view class="main_section" v-for="(v,k) in tableList" :key="k" @click="opebViewTimetable(v)"> |
|
||||
<view class="title">{{v.campus.campus_name}} </view> |
|
||||
<view class="con">{{v.campus.campus_address}} {{v.venue_name}}</view> |
|
||||
<!-- <view class="con" v-if="v.distance === null ">无法获取定位</view>--> |
|
||||
<!-- <view class="con" v-else-if="v.distance">距您{{v.distance}}km</view>--> |
|
||||
<view class="current-venue" v-if="venue_id == v.id"> |
|
||||
当前场馆 |
|
||||
</view> |
|
||||
</view> |
|
||||
</scroll-view> |
|
||||
<!-- 加载状态--> |
|
||||
<!-- <fui-loading :isFixed="true" srcCol="/static/icon-img/loading_white.png" text="正在加载..." v-if="loading"></fui-loading>--> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import apiRoute from '@/api/apiRoute.js'; |
|
||||
import memberApi from '@/api/member.js'; |
|
||||
import AQTabber from "@/components/AQ/AQTabber.vue" |
|
||||
|
|
||||
|
|
||||
export default { |
|
||||
components: { |
|
||||
AQTabber, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
loading:false,//加载状态 |
|
||||
lowerThreshold: 100,//距离底部多远触发 |
|
||||
isReachedBottom: false,//防止重复加载|true=不可加载|false=可加载 |
|
||||
|
|
||||
memberInfo:{id:''},//客户资源信息 |
|
||||
|
|
||||
//筛选条件 |
|
||||
filteredData:{ |
|
||||
// page:1,//当前页码 |
|
||||
// limit:10,//每页返回数据条数 |
|
||||
// total:10,//数据总条数 |
|
||||
course_date:'',//日期 |
|
||||
resources_id:'',//客户资源ID |
|
||||
}, |
|
||||
|
|
||||
tableList:[],//表格数据 |
|
||||
|
|
||||
longitude:'',//当前用户经度 |
|
||||
latitude:'',//当前用户纬度 |
|
||||
venue_id:'',//当前场馆id |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options) { |
|
||||
this.filteredData.course_date = options.course_date//上课日期 |
|
||||
//场馆id |
|
||||
this.venue_id = options.venue_id || ''//场地ID |
|
||||
}, |
|
||||
onShow() { |
|
||||
this.init()//初始化 |
|
||||
}, |
|
||||
methods: { |
|
||||
//初始化 |
|
||||
async init() { |
|
||||
// await this.getUserLocation(); |
|
||||
|
|
||||
await this.getMemberInfo(); |
|
||||
await this.getList(); |
|
||||
}, |
|
||||
|
|
||||
//获取当前登录的学生信息 |
|
||||
async getMemberInfo() { |
|
||||
let res = await apiRoute.xy_memberInfo({}) |
|
||||
if(res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
this.memberInfo = res.data |
|
||||
this.filteredData.resources_id = res.data.id |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
// 获取用户当前位置(支持多端) |
|
||||
async getUserLocation() { |
|
||||
try { |
|
||||
const location = await this.getLocation(); |
|
||||
this.longitude = location.longitude; |
|
||||
this.latitude = location.latitude; |
|
||||
} catch (error) { |
|
||||
console.log(error); |
|
||||
uni.showToast({ |
|
||||
title: '获取位置失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
// throw error; // 重新抛出错误,以便在 init 方法中捕获 |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 封装 uni.getLocation 为一个返回 Promise 的函数 |
|
||||
getLocation() { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
uni.getLocation({ |
|
||||
type: 'wgs84', |
|
||||
success: (res) => { |
|
||||
console.log('当前位置的经度:' + res.longitude); |
|
||||
console.log('当前位置的纬度:' + res.latitude); |
|
||||
resolve(res); |
|
||||
}, |
|
||||
fail: (err) => { |
|
||||
console.log(err); |
|
||||
reject(err); |
|
||||
} |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
//计算距离 |
|
||||
getDistance(lat1, lng1, lat2, lng2) { |
|
||||
const R = 6371; // 地球半径,单位为公里 |
|
||||
const dLat = this.deg2rad(lat2 - lat1); |
|
||||
const dLon = this.deg2rad(lng2 - lng1); |
|
||||
const a = |
|
||||
Math.sin(dLat / 2) * Math.sin(dLat / 2) + |
|
||||
Math.cos(this.deg2rad(lat1)) * Math.cos(this.deg2rad(lat2)) * |
|
||||
Math.sin(dLon / 2) * Math.sin(dLon / 2); |
|
||||
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); |
|
||||
const distance = R * c; // 距离,单位为公里 |
|
||||
|
|
||||
return distance.toFixed(2); // 保留两位小数 |
|
||||
}, |
|
||||
// 将角度转换为弧度 |
|
||||
deg2rad(deg) { |
|
||||
return deg * (Math.PI / 180); |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
//加载更多(下一页) |
|
||||
loadMoreData() { |
|
||||
return //本页面无需下一页 |
|
||||
//判断是否加载 |
|
||||
if (!this.isReachedBottom) { |
|
||||
this.isReachedBottom = true;//设置为不可请求状态 |
|
||||
this.getList(); |
|
||||
} |
|
||||
}, |
|
||||
//重置为第一页 |
|
||||
loadData() { |
|
||||
setTimeout(() => { |
|
||||
this.isReachedBottom = false; // 重置状态,以便下次触发加载更多 |
|
||||
}, 1000); |
|
||||
}, |
|
||||
|
|
||||
//获取场地列表 |
|
||||
async getList(){ |
|
||||
this.loading = true |
|
||||
|
|
||||
let data = {...this.filteredData} |
|
||||
|
|
||||
//判断是否还有数据 |
|
||||
// if(this.filteredData.page * this.filteredData.limit > this.total){ |
|
||||
// this.loading = false |
|
||||
// uni.showToast({ |
|
||||
// title: '暂无更多', |
|
||||
// icon: 'none' |
|
||||
// }) |
|
||||
// return |
|
||||
// } |
|
||||
|
|
||||
let res = await apiRoute.xy_personCourseScheduleGetVenueListAll(data) |
|
||||
this.loading = false |
|
||||
this.isReachedBottom = false; |
|
||||
if (res.code != 1){ |
|
||||
uni.showToast({ |
|
||||
title: res.msg, |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
this.tableList = res.data |
|
||||
|
|
||||
|
|
||||
this.tableList.forEach((v,k)=>{ |
|
||||
if(this.longitude && this.latitude && (v.longitude || '') && (v.latitude || '')){ |
|
||||
//计算距离 |
|
||||
v.distance = this.getDistance(this.latitude, this.longitude, v.latitude, v.longitude) |
|
||||
}else{ |
|
||||
v.distance = null |
|
||||
} |
|
||||
}) |
|
||||
|
|
||||
console.log('列表',this.tableList) |
|
||||
}, |
|
||||
|
|
||||
//跳转页面-课程列表 |
|
||||
opebViewTimetable(item) { |
|
||||
let venue_id = item.id |
|
||||
this.$navigateTo({ |
|
||||
url: `/pages/student/timetable/index?venue_id=${venue_id}` |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="less" scoped> |
|
||||
.main_box { |
|
||||
width: 100%; |
|
||||
height: 100vh; |
|
||||
overflow: auto; |
|
||||
background: #292929; |
|
||||
} |
|
||||
.data_hint{ |
|
||||
margin-top: 100rpx; |
|
||||
font-size: 30rpx; |
|
||||
text-align: center; |
|
||||
color: #fff; |
|
||||
} |
|
||||
.main_section{ |
|
||||
width: 92%; |
|
||||
border-radius: 15rpx; |
|
||||
background-color: #404045; |
|
||||
margin: 20rpx auto; |
|
||||
padding: 40rpx 0 40rpx 80rpx; |
|
||||
color: #fff; |
|
||||
position: relative; |
|
||||
} |
|
||||
.title{ |
|
||||
font-size: 32rpx; |
|
||||
} |
|
||||
.con{ |
|
||||
color: #D7D7D7; |
|
||||
font-size: 26rpx; |
|
||||
margin-top: 20rpx; |
|
||||
} |
|
||||
.current-venue{ |
|
||||
border-radius: 8rpx; |
|
||||
border: 2rpx #F59A23 solid; |
|
||||
width: 120rpx; |
|
||||
text-align: center; |
|
||||
color: #F59A23; |
|
||||
position: absolute; |
|
||||
top: 10%; |
|
||||
right: 3%; |
|
||||
} |
|
||||
</style> |
|
||||
Loading…
Reference in new issue