24 changed files with 2384 additions and 482 deletions
@ -0,0 +1,79 @@ |
|||
<?php |
|||
// +---------------------------------------------------------------------- |
|||
// | Niucloud-admin 企业快速开发的多应用管理平台 |
|||
// +---------------------------------------------------------------------- |
|||
// | 官方网址:https://www.niucloud.com |
|||
// +---------------------------------------------------------------------- |
|||
// | niucloud团队 版权所有 开源版本可自由商用 |
|||
// +---------------------------------------------------------------------- |
|||
// | Author: Niucloud Team |
|||
// +---------------------------------------------------------------------- |
|||
|
|||
namespace app\api\controller\apiController; |
|||
|
|||
use app\Request; |
|||
use app\service\api\apiService\StudentCourseService; |
|||
use core\base\BaseApiService; |
|||
|
|||
/** |
|||
* 学员课程相关接口 |
|||
* Class StudentCourse |
|||
* @package app\api\controller\apiController |
|||
*/ |
|||
class StudentCourse extends BaseApiService |
|||
{ |
|||
/** |
|||
* 获取课程详情 |
|||
* @param Request $request |
|||
* @return \think\Response |
|||
*/ |
|||
public function courseDetail(Request $request) |
|||
{ |
|||
$course_id = $request->param('course_id', ''); |
|||
$resource_id = $request->param('resource_id', ''); |
|||
|
|||
if (empty($course_id)) { |
|||
return fail('课程ID不能为空'); |
|||
} |
|||
|
|||
// 如果没有传resource_id,尝试从当前登录用户获取 |
|||
if (empty($resource_id)) { |
|||
// 这里需要根据实际情况获取当前学员的resource_id |
|||
// 可能需要从member_id获取对应的resource_id |
|||
$resource_id = $this->getResourceIdByMemberId($this->member_id); |
|||
} |
|||
|
|||
if (empty($resource_id)) { |
|||
return fail('资源ID不能为空'); |
|||
} |
|||
|
|||
$where = [ |
|||
'course_id' => $course_id, |
|||
'resource_id' => $resource_id |
|||
]; |
|||
|
|||
try { |
|||
$res = (new StudentCourseService())->getCourseDetail($where); |
|||
if (!$res['code']) { |
|||
return fail($res['msg']); |
|||
} |
|||
|
|||
return success($res['data']); |
|||
} catch (\Exception $e) { |
|||
return fail('获取课程详情失败:' . $e->getMessage()); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 根据会员ID获取资源ID |
|||
* @param int $member_id |
|||
* @return int|string |
|||
*/ |
|||
private function getResourceIdByMemberId($member_id) |
|||
{ |
|||
// 这里根据实际业务逻辑实现 |
|||
// 从customer_resources表中根据member_id获取resource_id |
|||
$customerResource = \app\model\customer_resources\CustomerResources::where('member_id', $member_id)->find(); |
|||
return $customerResource ? $customerResource->id : ''; |
|||
} |
|||
} |
|||
@ -0,0 +1,220 @@ |
|||
<?php |
|||
// +---------------------------------------------------------------------- |
|||
// | Niucloud-admin 企业快速开发的多应用管理平台 |
|||
// +---------------------------------------------------------------------- |
|||
// | 官方网址:https://www.niucloud.com |
|||
// +---------------------------------------------------------------------- |
|||
// | niucloud团队 版权所有 开源版本可自由商用 |
|||
// +---------------------------------------------------------------------- |
|||
// | Author: Niucloud Team |
|||
// +---------------------------------------------------------------------- |
|||
|
|||
namespace app\service\api\apiService; |
|||
|
|||
use app\model\customer_resources\CustomerResources; |
|||
use app\model\student_courses\StudentCourses; |
|||
use app\model\person_course_schedule\PersonCourseSchedule; |
|||
use app\model\student_course_usage\StudentCourseUsage; |
|||
use app\model\course\Course; |
|||
use app\model\campus\Campus; |
|||
use app\model\venue\Venue; |
|||
use app\model\personnel\Personnel; |
|||
use core\base\BaseApiService; |
|||
use think\facade\Log; |
|||
|
|||
/** |
|||
* 学员课程服务类 |
|||
* Class StudentCourseService |
|||
* @package app\service\api\apiService |
|||
*/ |
|||
class StudentCourseService extends BaseApiService |
|||
{ |
|||
/** |
|||
* 获取课程详情 |
|||
* @param array $where |
|||
* @return array |
|||
*/ |
|||
public function getCourseDetail(array $where) |
|||
{ |
|||
try { |
|||
Log::debug('StudentCourseService::getCourseDetail - 查询条件: ' . json_encode($where)); |
|||
|
|||
$course_id = $where['course_id'] ?? ''; |
|||
$resource_id = $where['resource_id'] ?? ''; |
|||
|
|||
if (empty($course_id) || empty($resource_id)) { |
|||
return ['code' => 0, 'msg' => '参数不完整']; |
|||
} |
|||
|
|||
// 1. 获取学员课程基本信息 |
|||
$courseInfo = $this->getCourseInfo($course_id, $resource_id); |
|||
if (!$courseInfo) { |
|||
return ['code' => 0, 'msg' => '课程信息不存在']; |
|||
} |
|||
|
|||
// 2. 获取课程安排列表 |
|||
$scheduleList = $this->getScheduleList($course_id, $resource_id); |
|||
|
|||
// 3. 获取课程使用记录 |
|||
$usageList = $this->getUsageList($course_id, $resource_id); |
|||
|
|||
$result = [ |
|||
'course_info' => $courseInfo, |
|||
'schedule_list' => $scheduleList, |
|||
'usage_list' => $usageList |
|||
]; |
|||
|
|||
Log::debug('StudentCourseService::getCourseDetail - 返回数据: ' . json_encode($result)); |
|||
|
|||
return ['code' => 1, 'data' => $result]; |
|||
|
|||
} catch (\Exception $e) { |
|||
Log::error('StudentCourseService::getCourseDetail - 异常: ' . $e->getMessage()); |
|||
return ['code' => 0, 'msg' => '获取课程详情失败: ' . $e->getMessage()]; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取课程基本信息 |
|||
* @param int $course_id |
|||
* @param int $resource_id |
|||
* @return array|null |
|||
*/ |
|||
private function getCourseInfo($course_id, $resource_id) |
|||
{ |
|||
$studentCourse = new StudentCourses(); |
|||
|
|||
$info = $studentCourse |
|||
->alias('sc') |
|||
->join(['school_course' => 'c'], 'sc.course_id = c.id', 'left') |
|||
->join(['school_campus' => 'campus'], 'sc.campus_id = campus.id', 'left') |
|||
->join(['school_personnel' => 'coach'], 'sc.main_coach_id = coach.id', 'left') |
|||
->join(['school_personnel' => 'education'], 'sc.education_id = education.id', 'left') |
|||
->where([ |
|||
'sc.course_id' => $course_id, |
|||
'sc.resource_id' => $resource_id |
|||
]) |
|||
->field([ |
|||
'sc.id', |
|||
'sc.course_id', |
|||
'sc.resource_id', |
|||
'sc.total_hours', |
|||
'sc.gift_hours', |
|||
'sc.start_date', |
|||
'sc.end_date', |
|||
'sc.use_total_hours', |
|||
'sc.use_gift_hours', |
|||
'sc.status', |
|||
'sc.single_session_count', |
|||
'c.course_name', |
|||
'campus.campus_name', |
|||
'coach.name as main_coach_name', |
|||
'education.name as education_name' |
|||
]) |
|||
->find(); |
|||
|
|||
return $info ? $info->toArray() : null; |
|||
} |
|||
|
|||
/** |
|||
* 获取课程安排列表 |
|||
* @param int $course_id |
|||
* @param int $resource_id |
|||
* @return array |
|||
*/ |
|||
private function getScheduleList($course_id, $resource_id) |
|||
{ |
|||
// 首先获取学员课程ID |
|||
$studentCourseId = $this->getStudentCourseId($course_id, $resource_id); |
|||
if (!$studentCourseId) { |
|||
return []; |
|||
} |
|||
|
|||
$personCourseSchedule = new PersonCourseSchedule(); |
|||
|
|||
$list = $personCourseSchedule |
|||
->alias('pcs') |
|||
->join(['school_course_schedule' => 'cs'], 'pcs.schedule_id = cs.id', 'left') |
|||
->join(['school_venue' => 'v'], 'cs.venue_id = v.id', 'left') |
|||
->join(['school_personnel' => 'coach'], 'cs.coach_id = coach.id', 'left') |
|||
->where([ |
|||
'pcs.student_course_id' => $studentCourseId, |
|||
'pcs.resources_id' => $resource_id |
|||
]) |
|||
->field([ |
|||
'pcs.id', |
|||
'pcs.schedule_id', |
|||
'pcs.course_date', |
|||
'pcs.time_slot', |
|||
'pcs.schedule_type', |
|||
'pcs.course_type', |
|||
'pcs.status', |
|||
'pcs.remark', |
|||
'v.venue_name', |
|||
'coach.name as coach_name' |
|||
]) |
|||
->order('pcs.course_date desc, pcs.time_slot desc') |
|||
->select(); |
|||
|
|||
return $list ? $list->toArray() : []; |
|||
} |
|||
|
|||
/** |
|||
* 获取课程使用记录 |
|||
* @param int $course_id |
|||
* @param int $resource_id |
|||
* @return array |
|||
*/ |
|||
private function getUsageList($course_id, $resource_id) |
|||
{ |
|||
// 首先获取学员课程ID |
|||
$studentCourseId = $this->getStudentCourseId($course_id, $resource_id); |
|||
if (!$studentCourseId) { |
|||
return []; |
|||
} |
|||
|
|||
$studentCourseUsage = new StudentCourseUsage(); |
|||
|
|||
$list = $studentCourseUsage |
|||
->alias('scu') |
|||
->join(['school_course_schedule' => 'cs'], 'scu.schedule_id = cs.id', 'left') |
|||
->join(['school_venue' => 'v'], 'cs.venue_id = v.id', 'left') |
|||
->where([ |
|||
'scu.student_course_id' => $studentCourseId, |
|||
'scu.resource_id' => $resource_id |
|||
]) |
|||
->field([ |
|||
'scu.id', |
|||
'scu.usage_date', |
|||
'scu.hours_used', |
|||
'scu.usage_type', |
|||
'scu.remark', |
|||
'cs.time_slot', |
|||
'v.venue_name' |
|||
]) |
|||
->order('scu.usage_date desc') |
|||
->select(); |
|||
|
|||
return $list ? $list->toArray() : []; |
|||
} |
|||
|
|||
/** |
|||
* 获取学员课程ID |
|||
* @param int $course_id |
|||
* @param int $resource_id |
|||
* @return int|null |
|||
*/ |
|||
private function getStudentCourseId($course_id, $resource_id) |
|||
{ |
|||
$studentCourse = new StudentCourses(); |
|||
|
|||
$info = $studentCourse |
|||
->where([ |
|||
'course_id' => $course_id, |
|||
'resource_id' => $resource_id |
|||
]) |
|||
->find(); |
|||
|
|||
return $info ? $info->id : null; |
|||
} |
|||
} |
|||
@ -0,0 +1,514 @@ |
|||
<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" :class="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" :class="getScheduleTypeClass(item.schedule_type)"> |
|||
{{ getScheduleTypeText(item.schedule_type) }} |
|||
</text> |
|||
<text class="course-type-tag" :class="getCourseTypeClass(item.course_type)"> |
|||
{{ getCourseTypeText(item.course_type) }} |
|||
</text> |
|||
</view> |
|||
|
|||
<view class="schedule-status"> |
|||
<text class="status-text" :class="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> |
|||
Loading…
Reference in new issue