Browse Source

修改 bug

master
王泽彦 8 months ago
parent
commit
55178e85f4
  1. 15
      niucloud/app/adminapi/controller/course_schedule/CourseSchedule.php
  2. 3
      niucloud/app/api/controller/apiController/Course.php
  3. 26
      niucloud/app/api/controller/apiController/CourseScheduleController.php
  4. 24
      niucloud/app/api/controller/student/StudentController.php
  5. 23
      niucloud/app/api/route/route.php
  6. 21
      niucloud/app/api/route/student.php
  7. 29
      niucloud/app/service/admin/course_schedule/CourseScheduleService.php
  8. 143
      niucloud/app/service/api/apiService/CourseScheduleService.php
  9. 144
      niucloud/app/service/api/apiService/CourseService.php
  10. 60
      niucloud/app/service/api/student/StudentService.php
  11. 38
      uniapp/api/apiRoute.js
  12. 113
      uniapp/pages-market/clue/class_arrangement_detail.vue
  13. 1
      uniapp/pages.json

15
niucloud/app/adminapi/controller/course_schedule/CourseSchedule.php

@ -156,19 +156,4 @@ class CourseSchedule extends BaseAdminController
]);
return success((new CourseScheduleService())->courseInfo($data['id']));
}
public function addSchedule(){
$data = $this->request->params([
["resources_id",''],
["person_type",''],
["schedule_id",''],
["course_date",''],
["time_slot",''],
["schedule_type", 1], // 1=临时, 2=固定
["course_type", 1], // 1=加课, 2=体验课, 3=补课, 4=试听课
["position", ''] // 位置信息
]);
return (new CourseScheduleService())->addSchedule($data);
}
}

3
niucloud/app/api/controller/apiController/Course.php

@ -129,7 +129,8 @@ class Course extends BaseApiService
$data = $this->request->params([
["id", ''],
["resources_id", ''],
["remark", '']
["remark", ''],
["student_id", '']
]);
return (new CourseService())->schedule_del($data);
}

26
niucloud/app/api/controller/apiController/CourseScheduleController.php

@ -205,6 +205,32 @@ class CourseScheduleController extends BaseApiController
}
}
/**
* 升级等待位学员为正式学员
*/
public function upgradeStudentSchedule()
{
$data = $this->request->post();
// 验证必要参数
if (empty($data['resources_id']) || empty($data['schedule_id'])) {
return fail('参数不完整');
}
if (empty($data['from_schedule_type']) || empty($data['to_schedule_type'])) {
return fail('升级类型参数不完整');
}
$service = new CourseScheduleService();
$result = $service->upgradeStudentSchedule($data);
if ($result['code'] == 1) {
return success($result['msg'], $result['data'] ?? []);
} else {
return fail($result['msg']);
}
}
/**
* 获取筛选选项(教练、课程、班级等)
*/

24
niucloud/app/api/controller/student/StudentController.php

@ -318,4 +318,28 @@ class StudentController extends BaseController
return fail($e->getMessage());
}
}
/**
* 获取学员课程统计
* @param int $student_id
* @return Response
*/
public function getCourseStatistics($student_id)
{
$data = $this->request->params([
['start_date', ''],
['end_date', '']
]);
$data['student_id'] = $student_id;
try {
$service = new StudentService();
$result = $service->getCourseStatistics($data);
return success($result, '获取课程统计成功');
} catch (\Exception $e) {
return fail($e->getMessage());
}
}
}

23
niucloud/app/api/route/route.php

@ -323,12 +323,13 @@ Route::group(function () {
Route::get('courseSchedule/venueAvailableTime', 'apiController.CourseSchedule/getVenueAvailableTime');
//员工端-检查教练时间冲突
Route::get('courseSchedule/checkCoachConflict', 'apiController.CourseSchedule/checkCoachConflict');
//员工端-获取课程安排统计
Route::get('courseSchedule/statistics', 'apiController.CourseSchedule/getScheduleStatistics');
//员工端-学员加入课程安排
Route::post('courseSchedule/joinSchedule', 'apiController.CourseSchedule/joinSchedule');
//员工端-学员退出课程安排
Route::post('courseSchedule/leaveSchedule', 'apiController.CourseSchedule/leaveSchedule');
//员工端-升级等待位学员为正式学员
Route::post('course/upgradeStudentSchedule', 'apiController.CourseSchedule/upgradeStudentSchedule');
//员工端-获取筛选选项
Route::get('courseSchedule/filterOptions', 'apiController.CourseSchedule/getFilterOptions');
//员工端-获取场地时间选项
@ -559,6 +560,13 @@ Route::group(function () {
// 清除字典缓存
Route::post('dict/clear_cache', 'common.Dict/clearDictCache');
// 学员签到
Route::post('checkin', 'student.AttendanceController/checkin');
// 学员请假
Route::post('leave', 'student.AttendanceController/leave');
// 学员取消
Route::post('cancel', 'student.AttendanceController/cancel');
})->middleware(ApiChannel::class)
->middleware(ApiPersonnelCheckToken::class, true)
->middleware(ApiLog::class);
@ -576,17 +584,6 @@ Route::group(function () {
})->middleware(ApiChannel::class)
->middleware(ApiLog::class);
// 学员出勤管理(测试)
Route::group('student/attendance', function () {
// 学员签到
Route::post('checkin', 'student.AttendanceController/checkin');
// 学员请假
Route::post('leave', 'student.AttendanceController/leave');
// 学员取消
Route::post('cancel', 'student.AttendanceController/cancel');
})->middleware(ApiChannel::class)
->middleware(ApiLog::class);
//学员端路由
include_once __DIR__ . '/student.php';

21
niucloud/app/api/route/student.php

@ -58,11 +58,16 @@ Route::group('course-booking', function () {
// 课程安排查看
Route::group('course-schedule', function () {
// 获取课程安排列表
Route::get('list/:student_id', 'app\api\controller\student\StudentController@getCourseScheduleList');
Route::get('list/:student_id', 'app\\api\\controller\\student\\StudentController@getCourseScheduleList');
// 获取课程详情
Route::get('detail/:schedule_id', 'app\api\controller\student\StudentController@getCourseScheduleDetail');
Route::get('detail/:schedule_id', 'app\\api\\controller\\student\\StudentController@getCourseScheduleDetail');
// 申请课程请假
Route::post('leave', 'app\api\controller\student\StudentController@requestCourseLeave');
Route::post('leave', 'app\\api\\controller\\student\\StudentController@requestCourseLeave');
// 获取学员课程统计
Route::get('statistics/:student_id', 'app\\api\\controller\\student\\StudentController@getCourseStatistics');
//员工端-获取课程安排统计
Route::get('courseSchedule/statistics', 'apiController.CourseSchedule/getScheduleStatistics');
})->middleware(['ApiCheckToken']);
// 订单管理
@ -173,16 +178,6 @@ Route::group('message', function () {
Route::get('search/:student_id', 'app\api\controller\student\MessageController@searchMessages');
})->middleware(['ApiCheckToken']);
// 学员出勤管理
Route::group('attendance', function () {
// 学员签到
Route::post('checkin', 'student.AttendanceController/checkin');
// 学员请假
Route::post('leave', 'student.AttendanceController/leave');
// 学员取消
Route::post('cancel', 'student.AttendanceController/cancel');
});
// 学员登录相关(无需token验证)
Route::group('auth', function () {
Route::post('login/wechat', 'login.WechatLogin/login');

29
niucloud/app/service/admin/course_schedule/CourseScheduleService.php

@ -323,33 +323,4 @@ class CourseScheduleService extends BaseAdminService
->where('id', $data)->findOrEmpty();
return $info->toArray();
}
public function addSchedule(array $data){
$CourseSchedule = new CourseSchedule();
$personCourseSchedule = new PersonCourseSchedule();
dd($data);
if($personCourseSchedule->where([
'resources_id' => $data['resources_id'],
'student_id' => $data['student_id'],
'schedule_id' => $data['schedule_id']
])->find()){
return fail("重复添加");
}
$personCourseSchedule->insert([
'resources_id' => $data['resources_id'],
'student_id' => $data['student_id'],
'person_id' => 1,
'person_type' => $data['person_type'],
'schedule_id' => $data['schedule_id'],
'course_date' => $data['course_date'],
'time_slot' => $data['time_slot'],
'schedule_type' => $data['schedule_type'] ?? 1, // 1=正式位, 2=等待位
'course_type' => $data['course_type'] ?? 1, // 1=正式课, 2=体验课, 3=补课, 4=试听课
]);
$CourseSchedule->where(['id' => $data['schedule_id']])->dec("available_capacity")->update();
return success("添加成功");
}
}

143
niucloud/app/service/api/apiService/CourseScheduleService.php

@ -273,6 +273,7 @@ class CourseScheduleService extends BaseApiService
->leftJoin($this->prefix . 'customer_resources cr', 'pcs.resources_id = cr.id')
->leftJoin($this->prefix . 'member m', 'cr.member_id = m.member_id')
->where('pcs.schedule_id', $scheduleId)
->where('pcs.status', 0) // 只统计未请假的学员(status=0)
->where('pcs.deleted_at', 0)
->field([
'pcs.*',
@ -538,12 +539,13 @@ class CourseScheduleService extends BaseApiService
$schedule['class_info'] = null;
}
// 获取历史变更记录
$schedule['change_history'] = Db::name('course_schedule_changes')
->where('schedule_id', $scheduleId)
->order('created_at DESC')
->select()
->toArray();
// 获取历史变更记录(注释掉,表不存在)
// $schedule['change_history'] = Db::name('course_schedule_changes')
// ->where('schedule_id', $scheduleId)
// ->order('created_at DESC')
// ->select()
// ->toArray();
$schedule['change_history'] = [];
return $schedule;
@ -1655,4 +1657,133 @@ class CourseScheduleService extends BaseApiService
];
}
}
/**
* 升级等待位学员为正式学员
* @param array $data 升级数据
* @return array 升级结果
*/
public function upgradeStudentSchedule(array $data)
{
try {
// 验证必填字段
if (empty($data['resources_id']) || empty($data['schedule_id'])) {
return [
'code' => 0,
'msg' => '课程安排ID和资源ID不能为空'
];
}
if (empty($data['from_schedule_type']) || empty($data['to_schedule_type'])) {
return [
'code' => 0,
'msg' => '升级类型参数不完整'
];
}
// 验证升级方向(只能从等待位升级到正式位)
if ($data['from_schedule_type'] != 2 || $data['to_schedule_type'] != 1) {
return [
'code' => 0,
'msg' => '只能从等待位升级到正式位'
];
}
// 开启事务
Db::startTrans();
$scheduleId = $data['schedule_id'];
$resourcesId = $data['resources_id'];
// 查询课程安排信息
$schedule = Db::name('course_schedule')
->where('id', $scheduleId)
->where('deleted_at', 0)
->find();
if (empty($schedule)) {
Db::rollback();
return [
'code' => 0,
'msg' => '课程安排不存在'
];
}
// 查询等待位学员记录
$enrollment = Db::name('person_course_schedule')
->where('schedule_id', $scheduleId)
->where('resources_id', $resourcesId)
->where('schedule_type', 2) // 等待位
->where('deleted_at', 0)
->find();
if (empty($enrollment)) {
Db::rollback();
return [
'code' => 0,
'msg' => '找不到等待位学员记录'
];
}
// 检查正式位是否已满
$formalCount = Db::name('person_course_schedule')
->where('schedule_id', $scheduleId)
->where('schedule_type', 1) // 正式位
->where('deleted_at', 0)
->count();
$maxStudents = intval($schedule['max_students']);
if ($maxStudents > 0 && $formalCount >= $maxStudents) {
Db::rollback();
return [
'code' => 0,
'msg' => '正式位已满,无法升级'
];
}
// 更新学员记录
$updateData = [
'schedule_type' => 1, // 升级为正式位
'position' => $formalCount + 1, // 新的正式位位置
'updated_at' => date('Y-m-d H:i:s'),
'remark' => ($data['remark'] ?? '') . ' [从等待位升级]'
];
// 如果课程类型是等待位专用类型(3),改为正式课(1)
if ($enrollment['course_type'] == 3) {
$updateData['course_type'] = $data['course_type'] ?? 1;
}
$result = Db::name('person_course_schedule')
->where('id', $enrollment['id'])
->update($updateData);
if ($result === false) {
Db::rollback();
return [
'code' => 0,
'msg' => '升级失败'
];
}
// 提交事务
Db::commit();
return [
'code' => 1,
'msg' => '升级成功',
'data' => [
'enrollment_id' => $enrollment['id'],
'new_position' => $formalCount + 1
]
];
} catch (\Exception $e) {
Db::rollback();
return [
'code' => 0,
'msg' => '学员升级失败:' . $e->getMessage()
];
}
}
}

144
niucloud/app/service/api/apiService/CourseService.php

@ -39,25 +39,25 @@ class CourseService extends BaseApiService
}
//课程列表
public function list($id,$data)
public function list($id, $data)
{
$campus_person_role = new CampusPersonRole();
$where = [];
if ($data['schedule_date']) {
$where[] = ['course_date','=', $data['schedule_date']];
$where[] = ['course_date', '=', $data['schedule_date']];
}
$campus_id = $campus_person_role->where(['person_id' => $id])->column('campus_id');
$CourseSchedule = new CourseSchedule();
$search_model = $CourseSchedule
->where('campus_id','in',$campus_id)
->where('campus_id', 'in', $campus_id)
->where($where)
->with(['course' => function($query) {
->with(['course' => function ($query) {
$query->select();
},'venue' => function($query) {
}, 'venue' => function ($query) {
$query->select();
},'campus','studentCourses']);
}, 'campus', 'studentCourses']);
$list = $this->pageQuery($search_model);
foreach ($list['data'] as $k => $v) {
$student = Db::name('person_course_schedule')
@ -72,6 +72,7 @@ class CourseService extends BaseApiService
}
return $list;
}
//获取课程详情
public function info($data)
{
@ -79,11 +80,11 @@ class CourseService extends BaseApiService
$CourseSchedule = new CourseSchedule();
$search_model = $CourseSchedule
->where('id', $data)
->with(['course' => function($query) {
->with(['course' => function ($query) {
$query->select();
},'venue' => function($query) {
}, 'venue' => function ($query) {
$query->select();
},'coach' => function($query) {
}, 'coach' => function ($query) {
$query->select();
}]);
$list = $search_model->find();
@ -104,8 +105,7 @@ class CourseService extends BaseApiService
->select()->toArray();
foreach ($student_courses as &$v){
foreach ($student_courses as &$v) {
$student = Db::name('student')
->alias('st')
->where('st.id', $v['student_id'])
@ -113,13 +113,13 @@ class CourseService extends BaseApiService
->join('school_member sm', 'cr.member_id = sm.member_id')
->field('st.name, sm.headimg as avatar,cr.id as resources_id,cr.source')
->find();
if($student){
if ($student) {
$v['school_six_speed'] = $school_six_speed->where(['staff_id' => $student['resources_id']])->find();
}else{
} else {
$v['school_six_speed'] = [];
}
$v['source'] = get_dict_value("source",$student['source']);
$v['source'] = get_dict_value("source", $student['source']);
$v['name'] = $student['name'];
$v['avatar'] = $student['avatar'];
}
@ -127,9 +127,9 @@ class CourseService extends BaseApiService
$Assignment = new Assignment();
$search_model = $Assignment->where('course_id', $data)
->with(['student' => function($query) {
$query->with(['customerResources' => function($query) {
$query->with(['member' => function($query) {
->with(['student' => function ($query) {
$query->with(['customerResources' => function ($query) {
$query->with(['member' => function ($query) {
$query->select();
}]);
}]);
@ -140,12 +140,12 @@ class CourseService extends BaseApiService
$groupedByStatus3 = [];
foreach ($search_model_res as $item) {
if ($item['status'] == 1){
array_push($groupedByStatus1,$item);
} else if ($item['status'] == 2){
array_push($groupedByStatus2,$item);
} else if ($item['status'] == 3){
array_push($groupedByStatus3,$item);
if ($item['status'] == 1) {
array_push($groupedByStatus1, $item);
} else if ($item['status'] == 2) {
array_push($groupedByStatus2, $item);
} else if ($item['status'] == 3) {
array_push($groupedByStatus3, $item);
}
}
$list['groupedByStatus1'] = $groupedByStatus1;
@ -160,17 +160,17 @@ class CourseService extends BaseApiService
$CourseSchedule = new CourseSchedule();
$search_model = $CourseSchedule
->where('coach_id', $data)
->with(['course' => function($query) {
$query->with(['studentCourses' => function($query) {
->with(['course' => function ($query) {
$query->with(['studentCourses' => function ($query) {
$query->select();
}]);
},'venue' => function($query) {
}, 'venue' => function ($query) {
$query->select();
},'coach' => function($query) {
}, 'coach' => function ($query) {
$query->select();
},'campus']);
}, 'campus']);
$list = $this->pageQuery($search_model);
foreach ($list['data'] as &$v){
foreach ($list['data'] as &$v) {
$student = Db::name('person_course_schedule')
->alias('pcs')
->where('pcs.schedule_id', $v['id'])
@ -198,7 +198,7 @@ class CourseService extends BaseApiService
{
$StudentCourses = new StudentCourses();
$PersonCourseSchedule = new PersonCourseSchedule();
$student_arr = $PersonCourseSchedule->where('schedule_id',$id)->column('student_id');
$student_arr = $PersonCourseSchedule->where('schedule_id', $id)->column('student_id');
// 获取当前时间
$now = date('Y-m-d H:i:s');
@ -274,10 +274,10 @@ class CourseService extends BaseApiService
{
$StudentCourseUsage = new StudentCourseUsage();
$StudentCourses = new StudentCourses();
$StudentCourses_id = $StudentCourses->where('student_id',$data['student_id'])->where('course_id',$data['course_id'])->value('id');
$PersonCourseSchedule_id = $StudentCourseUsage->where('student_course_id',$StudentCourses_id)->value('id');
$StudentCourses_id = $StudentCourses->where('student_id', $data['student_id'])->where('course_id', $data['course_id'])->value('id');
$PersonCourseSchedule_id = $StudentCourseUsage->where('student_course_id', $StudentCourses_id)->value('id');
if ($PersonCourseSchedule_id) {
$StudentCourseUsage->where('student_course_id',$StudentCourses_id)->delete();
$StudentCourseUsage->where('student_course_id', $StudentCourses_id)->delete();
return true;
} else {
return false;
@ -297,10 +297,10 @@ class CourseService extends BaseApiService
$tempDate->modify("$i days");
$status = false;
if($baseDate['day'] == $tempDate->format('d')){
if ($baseDate['day'] == $tempDate->format('d')) {
$status = true;
}else if(empty($baseDate['day'])){
if($tempDate->format('Y-m-d') === date('Y-m-d')){
} else if (empty($baseDate['day'])) {
if ($tempDate->format('Y-m-d') === date('Y-m-d')) {
$status = true;
}
}
@ -312,7 +312,7 @@ class CourseService extends BaseApiService
];
}
return ['dates' => $dates,'date' => $this_date];
return ['dates' => $dates, 'date' => $this_date];
}
@ -322,15 +322,15 @@ class CourseService extends BaseApiService
// 基础日期查询
if ($data['schedule_date']) {
$where[] = ['course_date','=', $data['schedule_date']];
$where[] = ['course_date', '=', $data['schedule_date']];
}
// 日期范围查询
if (!empty($data['start_date'])) {
$where[] = ['course_date','>=', $data['start_date']];
$where[] = ['course_date', '>=', $data['start_date']];
}
if (!empty($data['end_date'])) {
$where[] = ['course_date','<=', $data['end_date']];
$where[] = ['course_date', '<=', $data['end_date']];
}
// 场地编号筛选 - 根据venue表的id或venue_name进行筛选
@ -391,7 +391,7 @@ class CourseService extends BaseApiService
}
$list = $query
->with(['course','venue','campus','coach'])
->with(['course', 'venue', 'campus', 'coach'])
->select()->toArray();
foreach ($list as $k => $v) {
@ -428,7 +428,8 @@ class CourseService extends BaseApiService
}
public function addSchedule(array $data){
public function addSchedule(array $data)
{
$CourseSchedule = new CourseSchedule();
$personCourseSchedule = new PersonCourseSchedule();
$student = Student::where('id', $data['student_id'])->find();
@ -439,28 +440,42 @@ class CourseService extends BaseApiService
$studentCourse = StudentCourses::where('student_id', $student->id)
->order('id', 'desc')
->find();
if ($studentCourse){
if ($studentCourse) {
$person_type = 'student';
}else{
} else {
$person_type = 'customer_resource';
}
// 检查重复添加 - 根据person_type使用不同的检查逻辑
$checkWhere = [
'schedule_id' => $data['schedule_id'],
'student_id'=>$student->id,
'resources_id'=>$data['resources_id'],
'student_id' => $student->id,
'resources_id' => $data['resources_id'],
'status' => 0
];
$course = $personCourseSchedule->where($checkWhere)->find();
if($course){
if ($course) {
if ($course->schedule_type == 2 && $course->course_type == 1) {
$course->schedule_type == 1;
$course->save();
}else{
} else {
return fail("重复添加");
}
}
// 判断课程类型:
// - 如果person_type是customer_resource则course_type设为3(等待位)
// - 如果person_type是customer_resource且schedule_type是1(正式位),则course_type设为2(体验课学员)
// - 如果person_type是student,则course_type设为1(正式学员)
$courseType = 1; // 默认正式学员
if ($person_type == 'customer_resource') {
if (($data['schedule_type'] ?? 1) == 2) {
$courseType = 3; // 等待位
} else {
$courseType = 2; // 体验课学员
}
}
$insertData = [
'student_id' => $student->id, // 正确设置student_id
'resources_id' => $data['resources_id'], // 正确设置resources_id
@ -470,21 +485,22 @@ class CourseService extends BaseApiService
'course_date' => $data['course_date'],
'time_slot' => $data['time_slot'],
'schedule_type' => $data['schedule_type'] ?? 1, // 1=正式位, 2=等待位
'course_type' => empty($course) ? 2 : 1, // 1=正式学员, 2=体验课学员
'course_type' => $courseType, // 根据上面的逻辑设置课程类型
'remark' => $data['remark'] ?? '' // 备注
];
$personCourseSchedule->insert($insertData);
$student_ids = $personCourseSchedule->where(['schedule_id' => $data['schedule_id']])->column('student_id');
$CourseSchedule->where(['id' => $data['schedule_id']])->update([
'student_ids'=>$student_ids,
'available_capacity'=>count($student_ids)
'student_ids' => $student_ids,
'available_capacity' => count($student_ids)
]);
return success("添加成功");
}
public function schedule_list(array $data){
public function schedule_list(array $data)
{
$personCourseSchedule = new PersonCourseSchedule();
$list = $personCourseSchedule
->alias('a')
@ -517,7 +533,7 @@ class CourseService extends BaseApiService
$record = $personCourseSchedule->where([
'schedule_id' => $data['id'],
'resources_id' => $data['resources_id'],
'student_id' => $data['student_id']
])->find();
if (!$record) {
@ -528,20 +544,15 @@ class CourseService extends BaseApiService
if ($record['person_type'] == 'customer_resource') {
// 如果是客户资源类型,直接删除记录
$personCourseSchedule->where([
'schedule_id' => $data['id'],
'id' => $record->id,
'resources_id' => $data['resources_id']
])->delete();
// 更新课程安排表的可用容量
$CourseSchedule = new CourseSchedule();
$CourseSchedule->where(['id' => $record['schedule_id']])->inc("available_capacity")->update();
return success('删除成功');
} else if ($record['person_type'] == 'student') {
// 如果是学生类型,更新状态为2并更新备注
$personCourseSchedule->where([
'id' => $data['id'],
'resources_id' => $data['resources_id']
'id' => $record->id
])->update([
'status' => 2,
'remark' => $data['remark']
@ -739,10 +750,11 @@ class CourseService extends BaseApiService
];
}
// 获取已安排的学员列表(包括正式学员和等待位)
// 获取已安排的学员列表(包括正式学员和等待位),只显示未请假的学员(status=0)
$students = $PersonCourseSchedule
->where('schedule_id', $scheduleId)
->where(function($query) {
->where('status', 0) // 只获取未请假的学员
->where(function ($query) {
$query->where('deleted_at', 0)->whereOr('deleted_at', null);
})
->with(['student', 'resources'])
@ -957,7 +969,7 @@ class CourseService extends BaseApiService
$PersonCourseSchedule = new PersonCourseSchedule();
$existingRecords = $PersonCourseSchedule
->where('schedule_id', $scheduleId)
->where(function($query) {
->where(function ($query) {
$query->where('deleted_at', 0)->whereOr('deleted_at', null);
})
->field('student_id, resources_id')
@ -1096,7 +1108,7 @@ class CourseService extends BaseApiService
$PersonCourseSchedule = new PersonCourseSchedule();
$existingWhere = [
['schedule_id', '=', $scheduleId],
function($query) {
function ($query) {
$query->where('deleted_at', 0)->whereOr('deleted_at', null);
}
];
@ -1144,7 +1156,7 @@ class CourseService extends BaseApiService
$currentCount = $PersonCourseSchedule
->where('schedule_id', $scheduleId)
->where('course_type', '<>', 3) // 不包括等待位
->where(function($query) {
->where(function ($query) {
$query->where('deleted_at', 0)->whereOr('deleted_at', null);
})
->count();
@ -1339,7 +1351,7 @@ class CourseService extends BaseApiService
// 获取当前安排的所有人员
$participants = $PersonCourseSchedule
->where('schedule_id', $scheduleId)
->where(function($query) {
->where(function ($query) {
$query->where('deleted_at', 0)->whereOr('deleted_at', null);
})
->field('resources_id, student_id')

60
niucloud/app/service/api/student/StudentService.php

@ -728,4 +728,64 @@ class StudentService extends BaseService
{
return (new StudentLabel())->order('sort desc,create_time desc')->select()->toArray();
}
/**
* 获取学员课程统计
* @param array $params
* @return array
*/
public function getCourseStatistics($params)
{
$studentId = $params['student_id'];
$startDate = $params['start_date'];
$endDate = $params['end_date'];
// 构建查询条件
$where = [
['pcs.student_id', '=', $studentId],
['pcs.deleted_at', '=', 0],
['cs.deleted_at', '=', 0]
];
// 日期筛选
if (!empty($startDate) && !empty($endDate)) {
$where[] = ['cs.course_date', 'between', [$startDate, $endDate]];
}
// 查询课程安排数据
$scheduleList = Db::table('school_person_course_schedule pcs')
->leftJoin('school_course_schedule cs', 'pcs.schedule_id = cs.id')
->where($where)
->field('pcs.status')
->select()
->toArray();
// 统计各状态数量
$totalCourses = count($scheduleList);
$completedCourses = 0;
$scheduledCourses = 0;
$cancelledCourses = 0;
foreach ($scheduleList as $schedule) {
switch ($schedule['status']) {
case 1: // 已完成
$completedCourses++;
break;
case 0: // 待上课
$scheduledCourses++;
break;
case 2: // 请假
case 3: // 取消
$cancelledCourses++;
break;
}
}
return [
'total_courses' => $totalCourses,
'completed_courses' => $completedCourses,
'scheduled_courses' => $scheduledCourses,
'cancelled_courses' => $cancelledCourses
];
}
}

38
uniapp/api/apiRoute.js

@ -777,6 +777,11 @@ export default {
return await http.post('/course/schedule_del', data);
},
// 升级等待位学员为正式学员
async upgradeStudentSchedule(data = {}) {
return await http.post('/course/upgradeStudentSchedule', data);
},
//课程相关API
//获取学生课程信息列表(包含教练配置)
async getStudentCourseInfo(data = {}) {
@ -1077,11 +1082,11 @@ export default {
};
}
},
// 获取课程安排详情
// 获取课程安排详情(用于课程调整页面)
async getCourseScheduleInfo(data = {}) {
try {
// 使用真实的API接口获取课程安排详情
const result = await http.get('/course/scheduleDetail', data);
// 使用真实的API接口获取课程安排详情 - 调整页面专用接口
const result = await http.get('/courseSchedule/info', data);
console.log('获取课程安排详情:', result);
return result;
} catch (error) {
@ -1214,7 +1219,32 @@ export default {
},
// 获取课程安排统计
async getCourseScheduleStatistics(data = {}) {
return await http.get('/courseSchedule/statistics', data);
try {
// 如果有student_id参数,使用学员个人统计接口
if (data.student_id) {
const response = await http.get('/course-schedule/statistics/' + data.student_id, {
start_date: data.start_date,
end_date: data.end_date
});
return response;
} else {
// 否则使用全局统计接口
return await http.get('/course-schedule/courseSchedule/statistics', data);
}
} catch (error) {
console.error('获取课程统计失败:', error);
// 返回默认统计数据
return {
code: 1,
data: {
total_courses: 0,
completed_courses: 0,
scheduled_courses: 0,
cancelled_courses: 0
},
msg: '获取统计数据成功'
};
}
},
// 学员加入课程安排
async joinCourseSchedule(data = {}) {

113
uniapp/pages-market/clue/class_arrangement_detail.vue

@ -70,8 +70,10 @@
<view class="student-name">{{ stu.name }}</view>
<view class="student-age">年龄{{ stu.age || '未知' }}</view>
<view class="course-status">课程状态{{ stu.courseStatus }}</view>
<view class="course-progress">上课情况{{ stu.course_progress.used }}/{{ stu.course_progress.total }} ({{ stu.course_progress.percentage }}%)</view>
<view class="expiry-date">到期时间{{ stu.expiryDate || '未设置' }}</view>
<view class="course-status">上课情况
{{ stu.course_progress.used }}/{{ stu.course_progress.total }} ({{ stu.course_progress.percentage }}%)
</view>
<view class="expiry-date" v-if="stu.expiryDate">到期时间{{ stu.expiryDate || '未设置' }}</view>
</view>
</view>
@ -565,15 +567,27 @@
viewStudent(stu) {
console.log(stu, this.schedule_info);
//
let itemList = [];
if (stu.person_type === 'customer_resource') {
itemList.push('取消课程');
//
if (stu.schedule_type === 2 && this.formalEmptySeats.length > 0) {
itemList.push('升级为正式学员');
}
} else {
itemList.push('申请请假');
}
//
uni.showActionSheet({
title: `学员: ${stu.name}`,
itemList: stu.person_type === 'customer_resource' ? ['取消课程'] : ['申请请假'],
itemList: itemList,
success: (res) => {
if (res.tapIndex === 0) {
//
if (stu.person_type === 'customer_resource') {
//
const selectedOption = itemList[res.tapIndex];
if (selectedOption === '取消课程') {
//
uni.showModal({
title: '取消课程',
content: `是否取消学员 ${stu.name} 的课程?`,
@ -619,15 +633,98 @@
}
}
});
} else if (stu.person_type === 'student') {
} else if (selectedOption === '升级为正式学员') {
//
this.confirmUpgradeStudent(stu);
} else if (selectedOption === '申请请假') {
//
this.$refs.leaveReasonModal.open();
this.currentStudent = stu; //
}
}
});
},
//
confirmUpgradeStudent(stu) {
//
if (this.formalEmptySeats.length === 0) {
uni.showToast({
title: '正式位已满,无法升级',
icon: 'none'
});
return;
}
uni.showModal({
title: '升级确认',
content: `是否将等待位学员 ${stu.name} 升级为正式学员?升级后将占用一个正式位。`,
success: async (res) => {
if (res.confirm) {
await this.upgradeStudent(stu);
}
}
});
},
//
async upgradeStudent(stu) {
try {
uni.showLoading({
title: '升级中...'
});
//
const upgradeData = {
resources_id: stu.resources_id,
schedule_id: this.course_id,
student_id: stu.student_id,
from_schedule_type: 2, //
to_schedule_type: 1, //
position: this.formalStudents.length + 1, //
course_type: stu.course_type === 3 ? 1 : stu.course_type //
};
//
const result = await apiRoute.upgradeStudentSchedule(upgradeData);
uni.hideLoading();
if (result.code === 1) {
uni.showToast({
title: '升级成功',
icon: 'success'
});
//
await this.getScheduleDetail();
} else {
uni.showToast({
title: result.msg || '升级失败',
icon: 'none'
});
}
} catch (error) {
uni.hideLoading();
console.error('升级学员失败:', error);
//
let errorMsg = '升级失败';
if (error && error.data && error.data.msg) {
errorMsg = error.data.msg;
} else if (error && error.message) {
errorMsg = error.message;
} else if (typeof error === 'string') {
errorMsg = error;
}
uni.showToast({
title: errorMsg,
icon: 'none'
});
}
},
getStatusText(status) {
const statusMap = {
0: '待上课',

1
uniapp/pages.json

@ -46,7 +46,6 @@
"path": "pages/common/dashboard/webview",
"style": {
"navigationBarTitleText": "数据统计",
"navigationStyle": "custom",
"navigationBarBackgroundColor": "#181A20",
"navigationBarTextStyle": "white"
}

Loading…
Cancel
Save