diff --git a/niucloud/app/adminapi/controller/course_schedule/CourseSchedule.php b/niucloud/app/adminapi/controller/course_schedule/CourseSchedule.php
index aa34dfc0..2bbd5e67 100644
--- a/niucloud/app/adminapi/controller/course_schedule/CourseSchedule.php
+++ b/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);
- }
}
diff --git a/niucloud/app/api/controller/apiController/Course.php b/niucloud/app/api/controller/apiController/Course.php
index eaa0a2d3..1ef4e696 100644
--- a/niucloud/app/api/controller/apiController/Course.php
+++ b/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);
}
diff --git a/niucloud/app/api/controller/apiController/CourseScheduleController.php b/niucloud/app/api/controller/apiController/CourseScheduleController.php
index e468031c..b0faef1d 100644
--- a/niucloud/app/api/controller/apiController/CourseScheduleController.php
+++ b/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']);
+ }
+ }
+
/**
* 获取筛选选项(教练、课程、班级等)
*/
diff --git a/niucloud/app/api/controller/student/StudentController.php b/niucloud/app/api/controller/student/StudentController.php
index bb6be18d..3f690036 100644
--- a/niucloud/app/api/controller/student/StudentController.php
+++ b/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());
+ }
+ }
}
\ No newline at end of file
diff --git a/niucloud/app/api/route/route.php b/niucloud/app/api/route/route.php
index 272ca56f..3a44b585 100644
--- a/niucloud/app/api/route/route.php
+++ b/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';
diff --git a/niucloud/app/api/route/student.php b/niucloud/app/api/route/student.php
index fe4c6622..0ecc8d79 100644
--- a/niucloud/app/api/route/student.php
+++ b/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');
diff --git a/niucloud/app/service/admin/course_schedule/CourseScheduleService.php b/niucloud/app/service/admin/course_schedule/CourseScheduleService.php
index 848652c5..79a3f739 100644
--- a/niucloud/app/service/admin/course_schedule/CourseScheduleService.php
+++ b/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("添加成功");
-
- }
}
diff --git a/niucloud/app/service/api/apiService/CourseScheduleService.php b/niucloud/app/service/api/apiService/CourseScheduleService.php
index 6818bc65..84e0f8a5 100644
--- a/niucloud/app/service/api/apiService/CourseScheduleService.php
+++ b/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()
+ ];
+ }
+ }
}
\ No newline at end of file
diff --git a/niucloud/app/service/api/apiService/CourseService.php b/niucloud/app/service/api/apiService/CourseService.php
index 0792edba..6e8dd95d 100644
--- a/niucloud/app/service/api/apiService/CourseService.php
+++ b/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');
@@ -206,33 +206,33 @@ class CourseService extends BaseApiService
// 查询end_date大于当前时间的课程记录
$query = $StudentCourses->where('course_id', $id)
->where('end_date', '>', $now);
-
+
if (!empty($student_arr)) {
$query->whereNotIn('student_id', $student_arr);
}
-
+
$studentCourses = $query->field('student_id as value, resource_id')->select()->toArray();
-
+
// 如果没有符合条件的记录,直接返回空数组
if (empty($studentCourses)) {
return [];
}
-
+
// 收集所有的resource_id
$resourceIds = array_column($studentCourses, 'resource_id');
$resourceIds = array_filter($resourceIds); // 过滤掉空值
-
+
if (empty($resourceIds)) {
return [];
}
-
+
// 查询客户资源表获取详细信息
$resources = Db::name('customer_resources')
->whereIn('id', $resourceIds)
->field('id, name, source_channel, source, age')
->select()
->toArray();
-
+
// 将资源信息与学生ID关联
$result = [];
foreach ($resources as $resource) {
@@ -242,7 +242,7 @@ class CourseService extends BaseApiService
// 源和来源渠道转换为字典值
$source = get_dict_value("source", $resource['source']);
$sourceChannel = get_dict_value("source_channel", $resource['source_channel']);
-
+
$result[] = [
'value' => $course['value'], // 学生ID
'resource_id' => $resource['id'],
@@ -258,7 +258,7 @@ class CourseService extends BaseApiService
}
}
}
-
+
return $result;
}
@@ -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,27 +312,27 @@ class CourseService extends BaseApiService
];
}
- return ['dates' => $dates,'date' => $this_date];
+ return ['dates' => $dates, 'date' => $this_date];
}
public function listAll($data)
{
$where = [];
-
+
// 基础日期查询
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进行筛选
if (!empty($data['venue_number'])) {
// 先查询匹配的场地ID
@@ -341,15 +341,15 @@ class CourseService extends BaseApiService
// 如果根据ID查不到,可能是根据场地名称查询
$venue_ids = Db::name('venue')->where('venue_name', 'like', '%' . $data['venue_number'] . '%')->column('id');
}
-
+
if (empty($venue_ids)) {
// 如果没有找到匹配的场地,返回空结果
return [];
}
-
+
$where[] = ['venue_id', 'in', $venue_ids];
}
-
+
// 教练姓名筛选 - 需要关联personnel表
if (!empty($data['teacher_name'])) {
// 先查询匹配的教练ID
@@ -361,10 +361,10 @@ class CourseService extends BaseApiService
return [];
}
}
-
+
$CourseSchedule = new CourseSchedule();
$query = $CourseSchedule->where($where);
-
+
// 时间段筛选 - 根据time_slot字段和传入的时间范围
if (!empty($data['time_hour']) && $data['time_hour'] !== '全部时间') {
$time_condition = $this->getTimeSlotCondition($data['time_hour']);
@@ -389,11 +389,11 @@ class CourseService extends BaseApiService
});
}
}
-
+
$list = $query
- ->with(['course','venue','campus','coach'])
+ ->with(['course', 'venue', 'campus', 'coach'])
->select()->toArray();
-
+
foreach ($list as $k => $v) {
// 修复:通过resources_id查询学员信息,使用LEFT JOIN处理member_id为0的情况
$student = Db::name('person_course_schedule')
@@ -407,7 +407,7 @@ class CourseService extends BaseApiService
}
return $list;
}
-
+
/**
* 根据时间选择器的值获取时间段查询条件
* @param string $timeHour
@@ -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')
@@ -512,41 +528,36 @@ class CourseService extends BaseApiService
public function schedule_del(array $data)
{
$personCourseSchedule = new PersonCourseSchedule();
-
+
// 查询记录
$record = $personCourseSchedule->where([
'schedule_id' => $data['id'],
'resources_id' => $data['resources_id'],
-
+ 'student_id' => $data['student_id']
])->find();
-
+
if (!$record) {
return fail('未找到相关记录');
}
-
+
// 根据person_type执行不同操作
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']
]);
-
+
return success('更新成功');
} else {
return fail('未知的人员类型');
@@ -569,60 +580,60 @@ class CourseService extends BaseApiService
try {
// 开启事务
Db::startTrans();
-
+
$studentCourseId = $data['student_course_id'];
$mainCoachId = $data['main_coach_id'] ?? null;
$educationId = $data['education_id'] ?? null;
$assistantIds = $data['assistant_ids'] ?? '';
$classId = $data['class_id'] ?? null;
-
+
// 获取学员课程信息(需要 student_id 和 resource_id 来处理班级关联)
$studentCourse = Db::name('student_courses')
->where('id', $studentCourseId)
->field('student_id, resource_id')
->find();
-
+
if (!$studentCourse) {
Db::rollback();
$res['msg'] = '学员课程记录不存在';
return $res;
}
-
+
// 更新学员课程表
$updateData = [
'updated_at' => date('Y-m-d H:i:s')
];
-
+
if ($mainCoachId !== null) {
$updateData['main_coach_id'] = $mainCoachId;
}
-
+
if ($educationId !== null) {
$updateData['education_id'] = $educationId;
}
-
+
if ($assistantIds !== '') {
$updateData['assistant_ids'] = $assistantIds;
}
-
+
// 更新学员课程表
$updateResult = Db::name('student_courses')
->where('id', $studentCourseId)
->update($updateData);
-
+
if (!$updateResult) {
Db::rollback();
$res['msg'] = '更新学员课程配置失败';
return $res;
}
-
+
// 处理班级关联逻辑
if ($classId !== null && $studentCourse['resource_id']) {
// 先删除现有的班级关联
Db::name('class_resources_rel')
->where('resource_id', $studentCourse['resource_id'])
->delete();
-
+
// 如果选择了新的班级,创建新的关联记录
if ($classId > 0) {
$classRelData = [
@@ -636,7 +647,7 @@ class CourseService extends BaseApiService
'create_time' => date('Y-m-d H:i:s'),
'update_time' => date('Y-m-d H:i:s')
];
-
+
$classRelResult = Db::name('class_resources_rel')->insert($classRelData);
if (!$classRelResult) {
Db::rollback();
@@ -645,10 +656,10 @@ class CourseService extends BaseApiService
}
}
}
-
+
// 提交事务
Db::commit();
-
+
$res = [
'code' => 1,
'msg' => '更新成功',
@@ -660,12 +671,12 @@ class CourseService extends BaseApiService
'class_id' => $classId
]
];
-
+
} catch (\Exception $e) {
Db::rollback();
$res['msg'] = '更新学员课程人员配置异常:' . $e->getMessage();
}
-
+
return $res;
}
@@ -678,33 +689,33 @@ class CourseService extends BaseApiService
{
try {
$where = [];
-
+
// 课程名称关键词搜索
if (!empty($data['keyword'])) {
$where[] = ['course_name', 'like', '%' . $data['keyword'] . '%'];
}
-
+
// 课程类型筛选
if (!empty($data['course_type'])) {
$where[] = ['course_type', '=', $data['course_type']];
}
-
+
// 只获取有效课程(未逻辑删除)
// 注意:Course模型使用软删除,保留deleted_at条件
-
+
$courseList = $this->model
->where($where)
->field('id, course_name, course_type, duration, session_count, single_session_count, price')
->order('created_at DESC')
->select()
->toArray();
-
+
return [
'code' => 1,
'msg' => '获取成功',
'data' => $courseList
];
-
+
} catch (\Exception $e) {
return [
'code' => 0,
@@ -724,13 +735,13 @@ class CourseService extends BaseApiService
try {
$CourseSchedule = new CourseSchedule();
$PersonCourseSchedule = new PersonCourseSchedule();
-
+
// 获取课程安排基本信息
$schedule = $CourseSchedule
->where('id', $scheduleId)
->with(['course', 'venue', 'campus'])
->find();
-
+
if (!$schedule) {
return [
'code' => 0,
@@ -738,22 +749,23 @@ class CourseService extends BaseApiService
'data' => []
];
}
-
- // 获取已安排的学员列表(包括正式学员和等待位)
+
+ // 获取已安排的学员列表(包括正式学员和等待位),只显示未请假的学员(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'])
->order('course_type ASC, created_at ASC')
->select()
->toArray();
-
+
// 分组学员数据
$formalStudents = []; // 正式学员
$waitingStudents = []; // 等待位学员
-
+
foreach ($students as $student) {
// 获取学员信息
$name = '';
@@ -762,20 +774,20 @@ class CourseService extends BaseApiService
$trialClassCount = 0;
$studentCourseInfo = null;
$courseUsageInfo = null;
-
+
if ($student['person_type'] == 'student' && !empty($student['student'])) {
// 正式学员
$name = $student['student']['name'] ?: '';
$age = $student['student']['age'] ?: 0;
$phone = $student['student']['contact_phone'] ?: '';
$trialClassCount = $student['student']['trial_class_count'] ?: 0;
-
+
// 获取学员最新的付费课程信息
$studentCourseInfo = Db::name('student_courses')
->where('student_id', $student['student_id'])
->order('created_at DESC')
->find();
-
+
// 如果有付费课程,获取使用情况
if ($studentCourseInfo) {
$courseUsageInfo = Db::name('student_course_usage')
@@ -790,7 +802,7 @@ class CourseService extends BaseApiService
$studentInfo = Db::name('student')
->where('id', $student['student_id'])
->find();
-
+
if ($studentInfo) {
$name = $studentInfo['name'] ?: '';
$age = $studentInfo['age'] ?: 0;
@@ -809,25 +821,25 @@ class CourseService extends BaseApiService
$phone = !empty($student['resources']) ? $student['resources']['phone_number'] : '';
}
}
-
+
// 计算剩余课时和续费状态
$remainingHours = 0;
$totalHours = 0;
$usedHours = 0;
$needsRenewal = false;
$isTrialStudent = false; // 是否为体验课学员
-
+
if ($studentCourseInfo) {
// 付费学员
$totalRegularHours = intval($studentCourseInfo['total_hours'] ?: 0);
$totalGiftHours = intval($studentCourseInfo['gift_hours'] ?: 0);
$usedRegularHours = intval($studentCourseInfo['use_total_hours'] ?: 0);
$usedGiftHours = intval($studentCourseInfo['use_gift_hours'] ?: 0);
-
+
$totalHours = $totalRegularHours + $totalGiftHours;
$usedHours = $usedRegularHours + $usedGiftHours;
$remainingHours = $totalHours - $usedHours;
-
+
// 判断是否需要续费
// 条件1:end_date距离今天不足10天
$endDate = $studentCourseInfo['end_date'];
@@ -837,7 +849,7 @@ class CourseService extends BaseApiService
$needsRenewal = true;
}
}
-
+
// 条件2:剩余课时少于4节
if ($remainingHours < 4) {
$needsRenewal = true;
@@ -849,7 +861,7 @@ class CourseService extends BaseApiService
$usedHours = 0; // 这里可以根据实际需求统计体验课使用情况
$remainingHours = $trialClassCount;
}
-
+
$studentInfo = [
'id' => $student['id'], // 人员课程安排关系ID
'student_id' => $student['student_id'] ?: 0,
@@ -881,7 +893,7 @@ class CourseService extends BaseApiService
'percentage' => $totalHours > 0 ? round(($usedHours / $totalHours) * 100, 1) : 0
]
];
-
+
if ($student['course_type'] == 3) {
// 等待位学员
$waitingStudents[] = $studentInfo;
@@ -890,7 +902,7 @@ class CourseService extends BaseApiService
$formalStudents[] = $studentInfo;
}
}
-
+
// 计算可用位置
$maxStudents = $schedule['max_students'] ?: 0;
$availableSlots = 0;
@@ -900,7 +912,7 @@ class CourseService extends BaseApiService
// 如果没有限制,总是显示至少1个可用位置
$availableSlots = max(1, 6 - count($formalStudents));
}
-
+
$result = [
'schedule_info' => [
'id' => $schedule['id'],
@@ -917,13 +929,13 @@ class CourseService extends BaseApiService
'formal_students' => $formalStudents,
'waiting_students' => $waitingStudents
];
-
+
return [
'code' => 1,
'msg' => '获取成功',
'data' => $result
];
-
+
} catch (\Exception $e) {
return [
'code' => 0,
@@ -944,7 +956,7 @@ class CourseService extends BaseApiService
$keyword = trim($data['keyword']);
$searchType = $data['search_type'] ?: 'auto';
$scheduleId = $data['schedule_id'] ?: 0;
-
+
if (empty($keyword)) {
return [
'code' => 1,
@@ -952,28 +964,28 @@ class CourseService extends BaseApiService
'data' => []
];
}
-
+
// 获取已安排的学员ID和资源ID,用于排除
$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')
->select()
->toArray();
-
+
$existingStudentIds = array_filter(array_column($existingRecords, 'student_id'));
$existingResourceIds = array_filter(array_column($existingRecords, 'resources_id'));
-
+
$results = [];
-
+
// 搜索正式学员
$Student = new Student();
$studentWhere = [];
$studentWhere[] = ['deleted_at', '=', 0];
-
+
if ($searchType == 'phone' || ($searchType == 'auto' && preg_match('/^1[3-9]\d{9}$/', $keyword))) {
// 搜索手机号 - 通过关联客户资源表
$students = $Student
@@ -995,7 +1007,7 @@ class CourseService extends BaseApiService
->select()
->toArray();
}
-
+
// 过滤已安排的学员
foreach ($students as $student) {
if (!in_array($student['student_id'], $existingStudentIds)) {
@@ -1013,23 +1025,23 @@ class CourseService extends BaseApiService
];
}
}
-
+
// 搜索客户资源(非正式学员)
$customerWhere = [];
$customerWhere[] = ['deleted_at', '=', 0];
-
+
if ($searchType == 'phone' || ($searchType == 'auto' && preg_match('/^1[3-9]\d{9}$/', $keyword))) {
$customerWhere[] = ['phone_number', 'like', "%{$keyword}%"];
} else {
$customerWhere[] = ['name', 'like', "%{$keyword}%"];
}
-
+
$customers = Db::name('customer_resources')
->where($customerWhere)
->field('id as resources_id, name, age, phone_number, gender')
->select()
->toArray();
-
+
// 过滤已安排的客户资源
foreach ($customers as $customer) {
if (!in_array($customer['resources_id'], $existingResourceIds)) {
@@ -1046,13 +1058,13 @@ class CourseService extends BaseApiService
];
}
}
-
+
return [
'code' => 1,
'msg' => '搜索成功',
'data' => $results
];
-
+
} catch (\Exception $e) {
return [
'code' => 0,
@@ -1077,13 +1089,13 @@ class CourseService extends BaseApiService
$scheduleType = $data['schedule_type'] ?: 1;
$courseType = $data['course_type'] ?: 1;
$remarks = $data['remarks'] ?: '';
-
+
// 获取课程安排信息
$CourseSchedule = new CourseSchedule();
$schedule = $CourseSchedule
->where('id', $scheduleId)
->find();
-
+
if (!$schedule) {
return [
'code' => 0,
@@ -1091,22 +1103,22 @@ class CourseService extends BaseApiService
'data' => []
];
}
-
+
// 检查是否已经添加过
$PersonCourseSchedule = new PersonCourseSchedule();
$existingWhere = [
['schedule_id', '=', $scheduleId],
- function($query) {
+ function ($query) {
$query->where('deleted_at', 0)->whereOr('deleted_at', null);
}
];
-
+
if ($studentId) {
$existingWhere[] = ['student_id', '=', $studentId];
} else {
$existingWhere[] = ['resources_id', '=', $resourcesId];
}
-
+
$existing = $PersonCourseSchedule->where($existingWhere)->find();
if ($existing) {
return [
@@ -1115,7 +1127,7 @@ class CourseService extends BaseApiService
'data' => []
];
}
-
+
// 验证学员状态 - 只有status=1的学员才能预约固定课
if ($scheduleType == 2 && $studentId) { // 固定课且是正式学员
$Student = new Student();
@@ -1127,7 +1139,7 @@ class CourseService extends BaseApiService
'data' => []
];
}
-
+
if ($student['status'] != 1) {
return [
'code' => 0,
@@ -1136,7 +1148,7 @@ class CourseService extends BaseApiService
];
}
}
-
+
// 如果是正式学员位置,检查容量限制
if ($courseType != 3) { // 不是等待位
$maxStudents = $schedule['max_students'] ?: 0;
@@ -1144,11 +1156,11 @@ 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();
-
+
if ($currentCount >= $maxStudents) {
return [
'code' => 0,
@@ -1158,7 +1170,7 @@ class CourseService extends BaseApiService
}
}
}
-
+
// 准备插入数据
$insertData = [
'resources_id' => $resourcesId,
@@ -1175,13 +1187,13 @@ class CourseService extends BaseApiService
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s')
];
-
+
$result = $PersonCourseSchedule->create($insertData);
-
+
if ($result) {
// 更新课程安排表的参与人员信息
$this->updateScheduleParticipants($scheduleId);
-
+
return [
'code' => 1,
'msg' => '添加成功',
@@ -1194,7 +1206,7 @@ class CourseService extends BaseApiService
'data' => []
];
}
-
+
} catch (\Exception $e) {
return [
'code' => 0,
@@ -1215,12 +1227,12 @@ class CourseService extends BaseApiService
$personScheduleId = $data['person_schedule_id'];
$reason = $data['reason'] ?: '';
$remark = $data['remark'] ?: '';
-
+
$PersonCourseSchedule = new PersonCourseSchedule();
$record = $PersonCourseSchedule
->where('id', $personScheduleId)
->find();
-
+
if (!$record) {
return [
'code' => 0,
@@ -1228,22 +1240,22 @@ class CourseService extends BaseApiService
'data' => []
];
}
-
+
// 软删除记录
$updateData = [
'deleted_at' => time(),
'remark' => $remark ? ($record['remark'] . '; 移除原因:' . $remark) : $record['remark'],
'updated_at' => date('Y-m-d H:i:s')
];
-
+
$result = $PersonCourseSchedule
->where('id', $personScheduleId)
->update($updateData);
-
+
if ($result) {
// 更新课程安排表的参与人员信息
$this->updateScheduleParticipants($record['schedule_id']);
-
+
return [
'code' => 1,
'msg' => '移除成功',
@@ -1256,7 +1268,7 @@ class CourseService extends BaseApiService
'data' => []
];
}
-
+
} catch (\Exception $e) {
return [
'code' => 0,
@@ -1277,12 +1289,12 @@ class CourseService extends BaseApiService
$personScheduleId = $data['person_schedule_id'];
$status = $data['status'];
$remark = $data['remark'] ?: '';
-
+
$PersonCourseSchedule = new PersonCourseSchedule();
$record = $PersonCourseSchedule
->where('id', $personScheduleId)
->find();
-
+
if (!$record) {
return [
'code' => 0,
@@ -1290,20 +1302,20 @@ class CourseService extends BaseApiService
'data' => []
];
}
-
+
$updateData = [
'status' => $status,
'updated_at' => date('Y-m-d H:i:s')
];
-
+
if ($remark) {
$updateData['remark'] = $remark;
}
-
+
$result = $PersonCourseSchedule
->where('id', $personScheduleId)
->update($updateData);
-
+
if ($result) {
return [
'code' => 1,
@@ -1317,7 +1329,7 @@ class CourseService extends BaseApiService
'data' => []
];
}
-
+
} catch (\Exception $e) {
return [
'code' => 0,
@@ -1335,20 +1347,20 @@ class CourseService extends BaseApiService
{
try {
$PersonCourseSchedule = new PersonCourseSchedule();
-
+
// 获取当前安排的所有人员
$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')
->select()
->toArray();
-
+
$resourceIds = array_filter(array_column($participants, 'resources_id'));
$studentIds = array_filter(array_column($participants, 'student_id'));
-
+
$CourseSchedule = new CourseSchedule();
$CourseSchedule
->where('id', $scheduleId)
@@ -1357,13 +1369,13 @@ class CourseService extends BaseApiService
'student_ids' => json_encode($studentIds),
'updated_at' => date('Y-m-d H:i:s')
]);
-
+
} catch (\Exception $e) {
// 记录日志但不影响主流程
error_log('更新课程安排参与人员信息失败:' . $e->getMessage());
}
}
-
+
/**
* 获取教练列表
* @param int $campus_id
@@ -1376,39 +1388,39 @@ class CourseService extends BaseApiService
$roleIds = \app\model\sys_role\SysRole::where('dept_id', 23)
->where('status', 1)
->column('role_id');
-
+
if (empty($roleIds)) {
return ['code' => 0, 'msg' => '没有找到教练角色'];
}
-
+
// 查询校区人员角色关系表
$query = \app\model\campus_person_role\CampusPersonRole::alias('cpr')
->join(['school_personnel' => 'p'], 'cpr.person_id = p.id', 'inner')
->whereIn('cpr.role_id', $roleIds)
->where('cpr.deleted_at', 0)
->where('p.status', 1); // 只查询状态正常的人员
-
+
// 如果指定了校区,添加校区筛选
if ($campus_id > 0) {
$query->where('cpr.campus_id', $campus_id);
}
-
+
$list = $query->field([
'p.id',
- 'p.name',
+ 'p.name',
'p.phone',
'p.status',
'cpr.campus_id',
'cpr.role_id'
])->select();
-
+
return ['code' => 1, 'data' => $list ? $list->toArray() : []];
-
+
} catch (\Exception $e) {
return ['code' => 0, 'msg' => '获取教练列表失败: ' . $e->getMessage()];
}
}
-
+
/**
* 获取教务人员列表
* @param int $campus_id
@@ -1421,39 +1433,39 @@ class CourseService extends BaseApiService
$roleIds = \app\model\sys_role\SysRole::where('dept_id', 2)
->where('status', 1)
->column('role_id');
-
+
if (empty($roleIds)) {
return ['code' => 0, 'msg' => '没有找到教务角色'];
}
-
+
// 查询校区人员角色关系表
$query = \app\model\campus_person_role\CampusPersonRole::alias('cpr')
->join(['school_personnel' => 'p'], 'cpr.person_id = p.id', 'inner')
->whereIn('cpr.role_id', $roleIds)
->where('cpr.deleted_at', 0)
->where('p.status', 1); // 只查询状态正常的人员
-
+
// 如果指定了校区,添加校区筛选
if ($campus_id > 0) {
$query->where('cpr.campus_id', $campus_id);
}
-
+
$list = $query->field([
'p.id',
- 'p.name',
+ 'p.name',
'p.phone',
'p.status',
'cpr.campus_id',
'cpr.role_id'
])->select();
-
+
return ['code' => 1, 'data' => $list ? $list->toArray() : []];
-
+
} catch (\Exception $e) {
return ['code' => 0, 'msg' => '获取教务人员列表失败: ' . $e->getMessage()];
}
}
-
+
/**
* 更新学员课程信息
* @param array $data
@@ -1467,7 +1479,7 @@ class CourseService extends BaseApiService
$assistantIds = $data['assistant_ids'] ?? '';
$educationId = $data['education_id'] ?? 0;
$classId = $data['class_id'] ?? 0;
-
+
// 1. 更新学员课程表
$updateData = [];
if ($mainCoachId > 0) {
@@ -1479,7 +1491,7 @@ class CourseService extends BaseApiService
if ($educationId > 0) {
$updateData['education_id'] = $educationId;
}
-
+
if (!empty($updateData)) {
$updateData['updated_at'] = date('Y-m-d H:i:s');
$result = StudentCourses::where('id', $studentCourseId)->update($updateData);
@@ -1487,7 +1499,7 @@ class CourseService extends BaseApiService
return ['code' => 0, 'msg' => '更新学员课程信息失败'];
}
}
-
+
// 2. 如果需要更新班级关联
if ($classId > 0) {
// 先获取学员的resource_id
@@ -1495,15 +1507,15 @@ class CourseService extends BaseApiService
if (!$studentCourse) {
return ['code' => 0, 'msg' => '学员课程不存在'];
}
-
+
$resourceId = $studentCourse->resource_id;
-
+
// 检查是否已存在班级关联
$existingRel = \app\model\class_resources_rel\ClassResourcesRel::where([
'resource_id' => $resourceId,
'status' => 1
])->find();
-
+
if ($existingRel) {
// 更新现有关联
$existingRel->class_id = $classId;
@@ -1521,14 +1533,14 @@ class CourseService extends BaseApiService
$classRel->save();
}
}
-
+
return ['code' => 1, 'data' => ['id' => $studentCourseId], 'msg' => '更新成功'];
-
+
} catch (\Exception $e) {
return ['code' => 0, 'msg' => '更新失败: ' . $e->getMessage()];
}
}
-
+
/**
* 检查学员班级关联情况
* @param int $resource_id
@@ -1551,18 +1563,18 @@ class CourseService extends BaseApiService
'c.educational_id'
])
->find();
-
+
$hasClass = !empty($classRel);
$classInfo = $hasClass ? $classRel->toArray() : null;
-
+
return [
- 'code' => 1,
+ 'code' => 1,
'data' => [
'has_class' => $hasClass,
'class_info' => $classInfo
]
];
-
+
} catch (\Exception $e) {
return ['code' => 0, 'msg' => '检查班级关联失败: ' . $e->getMessage()];
}
@@ -1577,7 +1589,7 @@ class CourseService extends BaseApiService
{
$courseTypeMap = [
1 => '临时课',
- 2 => '固定课',
+ 2 => '固定课',
3 => '等待位',
4 => '试听课'
];
diff --git a/niucloud/app/service/api/student/StudentService.php b/niucloud/app/service/api/student/StudentService.php
index e1e4f316..4b5e8396 100644
--- a/niucloud/app/service/api/student/StudentService.php
+++ b/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
+ ];
+ }
}
\ No newline at end of file
diff --git a/uniapp/api/apiRoute.js b/uniapp/api/apiRoute.js
index 4b695489..74571582 100644
--- a/uniapp/api/apiRoute.js
+++ b/uniapp/api/apiRoute.js
@@ -776,6 +776,11 @@ export default {
async schedule_del(data = {}) {
return await http.post('/course/schedule_del', data);
},
+
+ // 升级等待位学员为正式学员
+ async upgradeStudentSchedule(data = {}) {
+ return await http.post('/course/upgradeStudentSchedule', data);
+ },
//课程相关API
//获取学生课程信息列表(包含教练配置)
@@ -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 = {}) {
diff --git a/uniapp/pages-market/clue/class_arrangement_detail.vue b/uniapp/pages-market/clue/class_arrangement_detail.vue
index 34290d52..3d957360 100644
--- a/uniapp/pages-market/clue/class_arrangement_detail.vue
+++ b/uniapp/pages-market/clue/class_arrangement_detail.vue
@@ -70,8 +70,10 @@
{{ stu.name }}
年龄:{{ stu.age || '未知' }}岁
课程状态:{{ stu.courseStatus }}
- 上课情况:{{ stu.course_progress.used }}/{{ stu.course_progress.total }}节 ({{ stu.course_progress.percentage }}%)
- 到期时间:{{ stu.expiryDate || '未设置' }}
+ 上课情况:
+ {{ stu.course_progress.used }}/{{ stu.course_progress.total }}节 ({{ stu.course_progress.percentage }}%)
+
+ 到期时间:{{ stu.expiryDate || '未设置' }}
@@ -565,69 +567,164 @@
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') {
- // 如果是客户资源,弹出确认取消课程的弹窗
- uni.showModal({
- title: '取消课程',
- content: `是否取消学员 ${stu.name} 的课程?`,
- success: async (res) => {
- if (res.confirm) {
- // 用户点击确定,调用schedule_del接口
- try {
- uni.showLoading({
- title: '处理中...'
+ const selectedOption = itemList[res.tapIndex];
+
+ if (selectedOption === '取消课程') {
+ // 弹出确认取消课程的弹窗
+ uni.showModal({
+ title: '取消课程',
+ content: `是否取消学员 ${stu.name} 的课程?`,
+ success: async (res) => {
+ if (res.confirm) {
+ // 用户点击确定,调用schedule_del接口
+ try {
+ uni.showLoading({
+ title: '处理中...'
+ });
+
+ const params = {
+ resources_id: stu.resources_id,
+ id: this.schedule_info.id
+ };
+
+ const result = await apiRoute.schedule_del(params);
+
+ uni.hideLoading();
+
+ if (result.code === 1) {
+ uni.showToast({
+ title: '取消课程成功',
+ icon: 'success'
});
- const params = {
- resources_id: stu.resources_id,
- id: this.schedule_info.id
- };
-
- const result = await apiRoute.schedule_del(params);
-
- 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();
+ // 刷新数据
+ await this.getScheduleDetail();
+ } else {
uni.showToast({
- title: '操作失败,请重试',
+ title: result.msg || '取消课程失败',
icon: 'none'
});
- console.error('取消课程失败:', error);
}
+ } catch (error) {
+ uni.hideLoading();
+ uni.showToast({
+ title: '操作失败,请重试',
+ icon: 'none'
+ });
+ console.error('取消课程失败:', error);
}
}
- });
- } else if (stu.person_type === 'student') {
- // 如果是学生,弹出请假原因输入框
- this.$refs.leaveReasonModal.open();
- this.currentStudent = stu; // 保存当前操作的学生信息
- }
+ }
+ });
+ } 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: '待上课',
diff --git a/uniapp/pages.json b/uniapp/pages.json
index 206c0218..ffecded0 100644
--- a/uniapp/pages.json
+++ b/uniapp/pages.json
@@ -46,7 +46,6 @@
"path": "pages/common/dashboard/webview",
"style": {
"navigationBarTitleText": "数据统计",
- "navigationStyle": "custom",
"navigationBarBackgroundColor": "#181A20",
"navigationBarTextStyle": "white"
}