You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1627 lines
60 KiB
1627 lines
60 KiB
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | Niucloud-admin 企业快速开发的多应用管理平台
|
|
// +----------------------------------------------------------------------
|
|
// | 官方网址:https://www.niucloud.com
|
|
// +----------------------------------------------------------------------
|
|
// | niucloud团队 版权所有 开源版本可自由商用
|
|
// +----------------------------------------------------------------------
|
|
// | Author: Niucloud Team
|
|
// +----------------------------------------------------------------------
|
|
|
|
namespace app\service\api\apiService;
|
|
|
|
use app\model\campus_person_role\CampusPersonRole;
|
|
use app\model\course_schedule\CourseSchedule;
|
|
use app\model\person_course_schedule\PersonCourseSchedule;
|
|
use app\model\six_speed\SixSpeed;
|
|
use app\model\student_course_usage\StudentCourseUsage;
|
|
use app\model\student\Student;
|
|
use app\model\assignment\Assignment;
|
|
use app\model\course\Course;
|
|
use app\model\student_courses\StudentCourses;
|
|
use core\base\BaseApiService;
|
|
use DateTime;
|
|
use think\Model;
|
|
use think\facade\Db;
|
|
|
|
/**
|
|
* 员工服务层
|
|
* Class MemberService
|
|
* @package app\service\api\member
|
|
*/
|
|
class CourseService extends BaseApiService
|
|
{
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
$this->model = new Course();
|
|
}
|
|
|
|
//课程列表
|
|
public function list($id, $data)
|
|
{
|
|
$campus_person_role = new CampusPersonRole();
|
|
$where = [];
|
|
if ($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($where)
|
|
->with(['course' => function ($query) {
|
|
$query->select();
|
|
}, 'venue' => function ($query) {
|
|
$query->select();
|
|
}, 'campus', 'studentCourses']);
|
|
$list = $this->pageQuery($search_model);
|
|
foreach ($list['data'] as $k => $v) {
|
|
$student = Db::name('person_course_schedule')
|
|
->alias('pcs')
|
|
->where('pcs.schedule_id', $v['id']) // 建议加上表别名避免冲突
|
|
->join('school_student st', 'pcs.student_id = st.id')
|
|
->join('school_customer_resources cr', 'st.user_id = cr.id')
|
|
->join('school_member sm', 'cr.member_id = sm.member_id')
|
|
->field('st.name, sm.headimg as avatar') // 👈 正确方式取字段
|
|
->select();
|
|
$list['data'][$k]['student'] = $student;
|
|
}
|
|
return $list;
|
|
}
|
|
|
|
//获取课程详情
|
|
public function info($data)
|
|
{
|
|
$school_six_speed = new SixSpeed();
|
|
$CourseSchedule = new CourseSchedule();
|
|
$search_model = $CourseSchedule
|
|
->where('id', $data)
|
|
->with(['course' => function ($query) {
|
|
$query->select();
|
|
}, 'venue' => function ($query) {
|
|
$query->select();
|
|
}, 'coach' => function ($query) {
|
|
$query->select();
|
|
}]);
|
|
$list = $search_model->find();
|
|
$student = Db::name('person_course_schedule')
|
|
->alias('pcs')
|
|
->where('pcs.schedule_id', $list['id'])
|
|
->join('school_student st', 'pcs.student_id = st.id')
|
|
->join('school_customer_resources cr', 'st.user_id = cr.id')
|
|
->join('school_member sm', 'cr.member_id = sm.member_id')
|
|
->field('st.name, sm.headimg as avatar')
|
|
->select();
|
|
$list['student'] = $student;
|
|
$student_courses = Db::name('student_courses')
|
|
->alias('sc')
|
|
->where('sc.course_id', $list['id'])
|
|
->join('school_student_course_usage sscu', 'sc.id = sscu.student_course_id')
|
|
->field('sc.student_id,sc.end_date,sc.end_date,sc.start_date,sc.course_id')
|
|
->select()->toArray();
|
|
|
|
|
|
foreach ($student_courses as &$v) {
|
|
$student = Db::name('student')
|
|
->alias('st')
|
|
->where('st.id', $v['student_id'])
|
|
->join('school_customer_resources cr', 'st.user_id = cr.id')
|
|
->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) {
|
|
$v['school_six_speed'] = $school_six_speed->where(['staff_id' => $student['resources_id']])->find();
|
|
|
|
} else {
|
|
$v['school_six_speed'] = [];
|
|
}
|
|
$v['source'] = get_dict_value("source", $student['source']);
|
|
$v['name'] = $student['name'];
|
|
$v['avatar'] = $student['avatar'];
|
|
}
|
|
$list['student_courses'] = $student_courses;
|
|
|
|
$Assignment = new Assignment();
|
|
$search_model = $Assignment->where('course_id', $data)
|
|
->with(['student' => function ($query) {
|
|
$query->with(['customerResources' => function ($query) {
|
|
$query->with(['member' => function ($query) {
|
|
$query->select();
|
|
}]);
|
|
}]);
|
|
}]);
|
|
$search_model_res = $search_model->select()->toArray();
|
|
$groupedByStatus1 = [];
|
|
$groupedByStatus2 = [];
|
|
$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);
|
|
}
|
|
}
|
|
$list['groupedByStatus1'] = $groupedByStatus1;
|
|
$list['groupedByStatus2'] = $groupedByStatus2;
|
|
$list['groupedByStatus3'] = $groupedByStatus3;
|
|
return $list;
|
|
}
|
|
|
|
|
|
public function classList($data)
|
|
{
|
|
$CourseSchedule = new CourseSchedule();
|
|
$search_model = $CourseSchedule
|
|
->where('coach_id', $data)
|
|
->with(['course' => function ($query) {
|
|
$query->with(['studentCourses' => function ($query) {
|
|
$query->select();
|
|
}]);
|
|
}, 'venue' => function ($query) {
|
|
$query->select();
|
|
}, 'coach' => function ($query) {
|
|
$query->select();
|
|
}, 'campus']);
|
|
$list = $this->pageQuery($search_model);
|
|
foreach ($list['data'] as &$v) {
|
|
$student = Db::name('person_course_schedule')
|
|
->alias('pcs')
|
|
->where('pcs.schedule_id', $v['id'])
|
|
->join('school_student st', 'pcs.student_id = st.id')
|
|
->join('school_customer_resources cr', 'st.user_id = cr.id')
|
|
->join('school_member sm', 'cr.member_id = sm.member_id')
|
|
->field('st.name, sm.headimg as avatar')
|
|
->select();
|
|
$v['student'] = $student;
|
|
}
|
|
foreach ($list['data'] as &$v) {
|
|
$student_courses = Db::name('student_courses')
|
|
->alias('sc')
|
|
->where('sc.course_id', $v['id'])
|
|
->join('school_student_course_usage sscu', 'sc.id = sscu.student_course_id')
|
|
->field('sc.student_id,sc.end_date,sc.end_date,sc.start_date,sc.course_id')
|
|
->select()->toArray();
|
|
$v['student_courses'] = $student_courses;
|
|
}
|
|
return $list;
|
|
}
|
|
|
|
//获取添加学员列表
|
|
public function StudentList($id)
|
|
{
|
|
$StudentCourses = new StudentCourses();
|
|
$PersonCourseSchedule = new PersonCourseSchedule();
|
|
$student_arr = $PersonCourseSchedule->where('schedule_id', $id)->column('student_id');
|
|
|
|
// 获取当前时间
|
|
$now = date('Y-m-d H:i:s');
|
|
|
|
// 查询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) {
|
|
// 查找对应的学生ID
|
|
foreach ($studentCourses as $course) {
|
|
if ($course['resource_id'] == $resource['id']) {
|
|
// 源和来源渠道转换为字典值
|
|
$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'],
|
|
'text' => $resource['name'], // 学生姓名
|
|
'name' => $resource['name'],
|
|
'age' => $resource['age'],
|
|
'source' => $source,
|
|
'source_channel' => $sourceChannel,
|
|
'source_raw' => $resource['source'],
|
|
'source_channel_raw' => $resource['source_channel']
|
|
];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function addStudent($data)
|
|
{
|
|
$PersonCourseSchedule = new PersonCourseSchedule();
|
|
$res = $PersonCourseSchedule->create($data);
|
|
return $res;
|
|
}
|
|
|
|
|
|
public function delStudentCourse($data)
|
|
{
|
|
$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');
|
|
if ($PersonCourseSchedule_id) {
|
|
$StudentCourseUsage->where('student_course_id', $StudentCourses_id)->delete();
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public function getDate(array $baseDate)
|
|
{
|
|
$dates = [];
|
|
|
|
$this_date = $baseDate['date'] ?: date('Y-m-d');
|
|
|
|
$date = new DateTime($this_date);
|
|
|
|
for ($i = -2; $i <= 4; $i++) {
|
|
$tempDate = clone $date; // 避免修改原始对象
|
|
$tempDate->modify("$i days");
|
|
|
|
$status = false;
|
|
if ($baseDate['day'] == $tempDate->format('d')) {
|
|
$status = true;
|
|
} else if (empty($baseDate['day'])) {
|
|
if ($tempDate->format('Y-m-d') === date('Y-m-d')) {
|
|
$status = true;
|
|
}
|
|
}
|
|
$dates[] = [
|
|
'date' => $tempDate->format('Y-m-d'),
|
|
'day' => $tempDate->format('d'),
|
|
'week' => getChineseWeekday($tempDate),
|
|
'status' => $status
|
|
];
|
|
}
|
|
|
|
return ['dates' => $dates, 'date' => $this_date];
|
|
}
|
|
|
|
|
|
public function listAll($data)
|
|
{
|
|
$where = [];
|
|
|
|
// 基础日期查询
|
|
if ($data['schedule_date']) {
|
|
$where[] = ['course_date', '=', $data['schedule_date']];
|
|
}
|
|
|
|
// 日期范围查询
|
|
if (!empty($data['start_date'])) {
|
|
$where[] = ['course_date', '>=', $data['start_date']];
|
|
}
|
|
if (!empty($data['end_date'])) {
|
|
$where[] = ['course_date', '<=', $data['end_date']];
|
|
}
|
|
|
|
// 场地编号筛选 - 根据venue表的id或venue_name进行筛选
|
|
if (!empty($data['venue_number'])) {
|
|
// 先查询匹配的场地ID
|
|
$venue_ids = Db::name('venue')->where('id', $data['venue_number'])->column('id');
|
|
if (empty($venue_ids)) {
|
|
// 如果根据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
|
|
$coach_ids = Db::name('personnel')->where('name', 'like', '%' . $data['teacher_name'] . '%')->column('id');
|
|
if (!empty($coach_ids)) {
|
|
$where[] = ['coach_id', 'in', $coach_ids];
|
|
} else {
|
|
// 如果找不到匹配的教练,返回空结果
|
|
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']);
|
|
if ($time_condition) {
|
|
[$start_time, $end_time] = $time_condition;
|
|
// 查询time_slot字段中包含在指定时间范围内的课程
|
|
// time_slot格式为"HH:MM-HH:MM",我们需要检查时间段是否有重叠
|
|
$query = $query->where(function ($subQuery) use ($start_time, $end_time) {
|
|
$subQuery->where('time_slot', 'like', $start_time . '%')
|
|
->whereOr('time_slot', 'like', '%' . $start_time . '%')
|
|
->whereOr('time_slot', 'like', '%' . $end_time . '%')
|
|
->whereOr(function ($subQuery2) use ($start_time, $end_time) {
|
|
// 检查开始时间是否在范围内
|
|
$subQuery2->whereRaw("TIME(SUBSTRING_INDEX(time_slot, '-', 1)) >= ?", [$start_time])
|
|
->whereRaw("TIME(SUBSTRING_INDEX(time_slot, '-', 1)) < ?", [$end_time]);
|
|
})
|
|
->whereOr(function ($subQuery3) use ($start_time, $end_time) {
|
|
// 检查结束时间是否在范围内
|
|
$subQuery3->whereRaw("TIME(SUBSTRING_INDEX(time_slot, '-', -1)) > ?", [$start_time])
|
|
->whereRaw("TIME(SUBSTRING_INDEX(time_slot, '-', -1)) <= ?", [$end_time]);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
$list = $query
|
|
->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')
|
|
->alias('pcs')
|
|
->where('pcs.schedule_id', $v['id'])
|
|
->leftJoin('school_customer_resources cr', 'pcs.resources_id = cr.id')
|
|
->leftJoin('school_member sm', 'cr.member_id = sm.member_id AND cr.member_id > 0')
|
|
->field('cr.name, COALESCE(sm.headimg, "") as avatar, pcs.schedule_type, pcs.course_type, pcs.status')
|
|
->select();
|
|
$list[$k]['student'] = $student;
|
|
}
|
|
return $list;
|
|
}
|
|
|
|
/**
|
|
* 根据时间选择器的值获取时间段查询条件
|
|
* @param string $timeHour
|
|
* @return array|null 返回时间范围数组 [start_hour, end_hour] 或 null
|
|
*/
|
|
private function getTimeSlotCondition($timeHour)
|
|
{
|
|
switch ($timeHour) {
|
|
case '上午(8:00-12:00)':
|
|
return ['08:00', '12:00']; // 上午时间范围
|
|
case '下午(12:00-18:00)':
|
|
return ['12:00', '18:00']; // 下午时间范围
|
|
case '晚上(18:00-22:00)':
|
|
return ['18:00', '22:00']; // 晚上时间范围
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
public function addSchedule(array $data)
|
|
{
|
|
$CourseSchedule = new CourseSchedule();
|
|
$personCourseSchedule = new PersonCourseSchedule();
|
|
$student = Student::where('id', $data['student_id'])->find();
|
|
if (!$student) {
|
|
return fail("学员不存在");
|
|
}
|
|
|
|
$studentCourse = StudentCourses::where('student_id', $student->id)
|
|
->order('id', 'desc')
|
|
->find();
|
|
$student_status = $studentCourse && $this->handeStudentStatus($studentCourse);
|
|
if ($student_status) {
|
|
$person_type = 'student';
|
|
} else {
|
|
$person_type = 'customer_resource';
|
|
}
|
|
|
|
// 检查重复添加 - 根据person_type使用不同的检查逻辑
|
|
$checkWhere = [
|
|
'schedule_id' => $data['schedule_id'],
|
|
'student_id' => $student->id,
|
|
'resources_id' => $data['resources_id'],
|
|
'status' => 0
|
|
];
|
|
$course = $personCourseSchedule->where($checkWhere)->find();
|
|
if ($course) {
|
|
return fail("重复添加");
|
|
}
|
|
|
|
// 验证场地容量限制
|
|
$schedule = $CourseSchedule->where('id', $data['schedule_id'])->find();
|
|
if (!$schedule) {
|
|
return fail("课程安排不存在");
|
|
}
|
|
|
|
// 获取场地信息
|
|
$venue = Db::name('venue')->where('id', $schedule['venue_id'])->find();
|
|
if ($venue && $venue['capacity'] > 0) {
|
|
// 如果添加的是正式学员(非等待位),检查容量限制
|
|
if (($data['course_type'] ?? 1) != 3) { // course_type=3是等待位
|
|
// 查询当前时间段正式学员人数(排除请假、软删除和等待位)
|
|
$currentFormalCount = $personCourseSchedule
|
|
->where('schedule_id', $data['schedule_id'])
|
|
->where('course_type', '<>', 3) // 排除等待位
|
|
->where('status', '<>', 2) // 排除请假(status=2)
|
|
->where(function ($query) {
|
|
$query->where('deleted_at', 0)->whereOr('deleted_at', null);
|
|
})
|
|
->count();
|
|
|
|
if ($currentFormalCount >= $venue['capacity']) {
|
|
return fail("该时间段场地已满({$venue['capacity']}人),当前正式学员{$currentFormalCount}人,无法添加更多学员");
|
|
}
|
|
}
|
|
}
|
|
|
|
$insertData = [
|
|
'student_id' => $student->id, // 正确设置student_id
|
|
'resources_id' => $data['resources_id'], // 正确设置resources_id
|
|
'person_id' => $this->member_id,
|
|
'person_type' => $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'], // 根据上面的逻辑设置课程类型
|
|
'remark' => $data['remark'] ?? '', // 备注
|
|
'student_course_id' => $studentCourse->id ?? 0
|
|
];
|
|
|
|
$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)
|
|
]);
|
|
return success("添加成功");
|
|
|
|
}
|
|
|
|
public function schedule_list(array $data)
|
|
{
|
|
$personCourseSchedule = new PersonCourseSchedule();
|
|
$list = $personCourseSchedule
|
|
->alias('a')
|
|
->leftJoin(['school_student' => 'st'], 'a.student_id = st.id AND a.person_type = "student"')
|
|
->leftJoin(['school_customer_resources' => 'b'], 'a.resources_id = b.id')
|
|
->leftJoin(['school_course_schedule' => 'c'], 'c.id = a.schedule_id')
|
|
->where('a.schedule_id', $data['schedule_id'])
|
|
->field([
|
|
'COALESCE(st.name, b.name) as name', // 优先显示学员姓名,否则客户资源姓名
|
|
'a.status',
|
|
'a.person_type',
|
|
'c.campus_id',
|
|
'a.student_id',
|
|
'a.resources_id',
|
|
'a.schedule_type',
|
|
'a.course_type',
|
|
'a.id as person_schedule_id'
|
|
])
|
|
->select()
|
|
->toArray();
|
|
|
|
return $list;
|
|
}
|
|
|
|
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([
|
|
'id' => $record->id,
|
|
'resources_id' => $data['resources_id']
|
|
])->delete();
|
|
|
|
return success('删除成功');
|
|
} else if ($record['person_type'] == 'student') {
|
|
// 如果是学生类型,更新状态为2并更新备注
|
|
$personCourseSchedule->where([
|
|
'id' => $record->id
|
|
])->update([
|
|
'status' => 2,
|
|
'remark' => $data['remark']
|
|
]);
|
|
|
|
return success('更新成功');
|
|
} else {
|
|
return fail('未知的人员类型');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 更新学员课程人员配置
|
|
* @param array $data
|
|
* @return array
|
|
*/
|
|
public function updateStudentCoursePersonnel(array $data)
|
|
{
|
|
$res = [
|
|
'code' => 0,
|
|
'msg' => '更新失败',
|
|
'data' => []
|
|
];
|
|
|
|
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 = [
|
|
'class_id' => $classId,
|
|
'resource_id' => $studentCourse['resource_id'],
|
|
'campus_id' => 0, // 可根据实际需求设置
|
|
'source_id' => $studentCourse['student_id'],
|
|
'source_type' => 'student',
|
|
'join_time' => time(),
|
|
'status' => 1,
|
|
'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();
|
|
$res['msg'] = '更新班级关联失败';
|
|
return $res;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 提交事务
|
|
Db::commit();
|
|
|
|
$res = [
|
|
'code' => 1,
|
|
'msg' => '更新成功',
|
|
'data' => [
|
|
'student_course_id' => $studentCourseId,
|
|
'main_coach_id' => $mainCoachId,
|
|
'education_id' => $educationId,
|
|
'assistant_ids' => $assistantIds,
|
|
'class_id' => $classId
|
|
]
|
|
];
|
|
|
|
} catch (\Exception $e) {
|
|
Db::rollback();
|
|
$res['msg'] = '更新学员课程人员配置异常:' . $e->getMessage();
|
|
}
|
|
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* 获取课程列表(用于添加课程安排)
|
|
* @param array $data
|
|
* @return array
|
|
*/
|
|
public function getCourseListForSchedule(array $data)
|
|
{
|
|
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,
|
|
'msg' => '获取课程列表失败:' . $e->getMessage(),
|
|
'data' => []
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取课程安排详情
|
|
* @param int $scheduleId 课程安排ID
|
|
* @return array
|
|
*/
|
|
public function getScheduleDetail($scheduleId)
|
|
{
|
|
try {
|
|
$CourseSchedule = new CourseSchedule();
|
|
$PersonCourseSchedule = new PersonCourseSchedule();
|
|
|
|
// 获取课程安排基本信息
|
|
$schedule = $CourseSchedule
|
|
->where('id', $scheduleId)
|
|
->with(['course', 'venue', 'campus', 'coach'])
|
|
->find();
|
|
|
|
if (!$schedule) {
|
|
return [
|
|
'code' => 0,
|
|
'msg' => '课程安排不存在',
|
|
'data' => []
|
|
];
|
|
}
|
|
|
|
// 获取已安排的学员列表(包括正式学员和等待位),排除请假的学员(status!=2)
|
|
$students = $PersonCourseSchedule
|
|
->where('schedule_id', $scheduleId)
|
|
->where('status', '<>', 2) // 排除请假的学员,包含待上课(0)和已上课(1)
|
|
->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 = '';
|
|
$age = 0;
|
|
$phone = '';
|
|
$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'])
|
|
->where('status', 1) // 只获取状态为1的有效课程
|
|
->where('start_date', '<=', date('Y-m-d')) // 开始时间小于等于当前时间
|
|
->where('end_date', '>=', date('Y-m-d')) // 结束时间大于等于当前时间
|
|
->order('created_at DESC')
|
|
->find();
|
|
|
|
// 如果有付费课程,获取使用情况
|
|
if ($studentCourseInfo) {
|
|
$courseUsageInfo = Db::name('student_course_usage')
|
|
->where('student_course_id', $studentCourseInfo['id'])
|
|
->select()
|
|
->toArray();
|
|
}
|
|
} elseif ($student['person_type'] == 'customer_resource') {
|
|
// 客户资源 - 现在我们有正确的student_id,应该从学生表获取信息
|
|
if ($student['student_id'] > 0) {
|
|
// 从学生表获取学员信息
|
|
$studentInfo = Db::name('student')
|
|
->where('id', $student['student_id'])
|
|
->find();
|
|
|
|
if ($studentInfo) {
|
|
$name = $studentInfo['name'] ?: '';
|
|
$age = $studentInfo['age'] ?: 0;
|
|
$phone = $studentInfo['contact_phone'] ?: '';
|
|
$trialClassCount = $studentInfo['trial_class_count'] ?: 0;
|
|
} else {
|
|
// 如果学生信息不存在,使用客户资源信息作为后备
|
|
$name = !empty($student['resources']) ? $student['resources']['name'] : '';
|
|
$age = !empty($student['resources']) ? $student['resources']['age'] : 0;
|
|
$phone = !empty($student['resources']) ? $student['resources']['phone_number'] : '';
|
|
}
|
|
} else {
|
|
// 如果没有student_id,使用客户资源信息
|
|
$name = !empty($student['resources']) ? $student['resources']['name'] : '';
|
|
$age = !empty($student['resources']) ? $student['resources']['age'] : 0;
|
|
$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'];
|
|
if ($endDate) {
|
|
$daysUntilExpiry = (strtotime($endDate) - time()) / (24 * 3600);
|
|
if ($daysUntilExpiry <= 10) {
|
|
$needsRenewal = true;
|
|
}
|
|
}
|
|
|
|
// 条件2:剩余课时少于4节
|
|
if ($remainingHours < 4) {
|
|
$needsRenewal = true;
|
|
}
|
|
} else {
|
|
// 体验课学员(没有付费课程记录)
|
|
$isTrialStudent = true;
|
|
$totalHours = $trialClassCount;
|
|
$usedHours = 0; // 这里可以根据实际需求统计体验课使用情况
|
|
$remainingHours = $trialClassCount;
|
|
}
|
|
|
|
$studentInfo = [
|
|
'id' => $student['id'], // 人员课程安排关系ID
|
|
'student_id' => $student['student_id'] ?: 0,
|
|
'resources_id' => $student['resources_id'] ?: 0,
|
|
'name' => $name,
|
|
'age' => $age,
|
|
'phone' => $phone,
|
|
'courseStatus' => $this->getCourseTypeText($student['course_type']),
|
|
'courseType' => $student['schedule_type'] == 2 ? 'fixed' : 'temporary',
|
|
'remainingHours' => $remainingHours,
|
|
'totalHours' => $totalHours,
|
|
'usedHours' => $usedHours,
|
|
'expiryDate' => $studentCourseInfo ? ($studentCourseInfo['end_date'] ?: '') : '',
|
|
'needsRenewal' => $needsRenewal,
|
|
'isTrialStudent' => $isTrialStudent,
|
|
'trialClassCount' => $trialClassCount,
|
|
'status' => $student['status'] ?: 0,
|
|
'remark' => $student['remark'] ?: '',
|
|
'person_type' => $student['person_type'],
|
|
'schedule_type' => $student['schedule_type'] ?: 1,
|
|
'course_type' => $student['course_type'] ?: 1,
|
|
// 添加课程购买和使用信息
|
|
'student_course_info' => $studentCourseInfo,
|
|
'course_usage_info' => $courseUsageInfo,
|
|
'course_progress' => [
|
|
'total' => $totalHours,
|
|
'used' => $usedHours,
|
|
'remaining' => $remainingHours,
|
|
'percentage' => $totalHours > 0 ? round(($usedHours / $totalHours) * 100, 1) : 0
|
|
]
|
|
];
|
|
|
|
if ($student['course_type'] == 3) {
|
|
// 等待位学员
|
|
$waitingStudents[] = $studentInfo;
|
|
} else {
|
|
// 正式学员
|
|
$formalStudents[] = $studentInfo;
|
|
}
|
|
}
|
|
|
|
// 计算可用位置
|
|
$maxStudents = $schedule['max_students'] ?: 0;
|
|
$availableSlots = 0;
|
|
if ($maxStudents > 0) {
|
|
$availableSlots = max(0, $maxStudents - count($formalStudents));
|
|
} else {
|
|
// 如果没有限制,总是显示至少1个可用位置
|
|
$availableSlots = max(1, 6 - count($formalStudents));
|
|
}
|
|
|
|
$result = [
|
|
'schedule_info' => [
|
|
'id' => $schedule['id'],
|
|
'course_name' => $schedule['course']['course_name'] ?? '',
|
|
'course_date' => $schedule['course_date'],
|
|
'time_slot' => $schedule['time_slot'],
|
|
'venue_name' => $schedule['venue']['venue_name'] ?? '',
|
|
'campus_name' => $schedule['campus']['campus_name'] ?? '',
|
|
'coach_name' => $schedule['coach']['name'] ?? '',
|
|
'coach_id' => $schedule['coach_id'] ?: 0,
|
|
'available_capacity' => $schedule['available_capacity'] ?: 0,
|
|
'max_students' => $maxStudents,
|
|
'available_slots' => $availableSlots,
|
|
'status' => $schedule['status'] ?: 0
|
|
],
|
|
'formal_students' => $formalStudents,
|
|
'waiting_students' => $waitingStudents
|
|
];
|
|
|
|
return [
|
|
'code' => 1,
|
|
'msg' => '获取成功',
|
|
'data' => $result
|
|
];
|
|
|
|
} catch (\Exception $e) {
|
|
return [
|
|
'code' => 0,
|
|
'msg' => '获取课程安排详情失败:' . $e->getMessage(),
|
|
'data' => []
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 搜索可添加的学员
|
|
* @param array $data
|
|
* @return array
|
|
*/
|
|
public function searchAvailableStudents($data)
|
|
{
|
|
try {
|
|
$keyword = trim($data['keyword']);
|
|
$searchType = $data['search_type'] ?: 'auto';
|
|
$scheduleId = $data['schedule_id'] ?: 0;
|
|
|
|
if (empty($keyword)) {
|
|
return [
|
|
'code' => 1,
|
|
'msg' => '搜索成功',
|
|
'data' => []
|
|
];
|
|
}
|
|
|
|
// 获取已安排的学员ID和资源ID,用于排除
|
|
$PersonCourseSchedule = new PersonCourseSchedule();
|
|
$existingRecords = $PersonCourseSchedule
|
|
->where('schedule_id', $scheduleId)
|
|
->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
|
|
->alias('s')
|
|
->leftJoin('customer_resources cr', 's.user_id = cr.id')
|
|
->where('cr.phone_number', 'like', "%{$keyword}%")
|
|
->where('s.deleted_at', 0)
|
|
->field('s.id as student_id, s.name, s.gender, s.status, cr.age, cr.phone_number, s.user_id as resource_id, "student" as person_type')
|
|
->select()
|
|
->toArray();
|
|
} else {
|
|
// 搜索姓名
|
|
$students = $Student
|
|
->alias('s')
|
|
->leftJoin('customer_resources cr', 's.user_id = cr.id')
|
|
->where('s.name', 'like', "%{$keyword}%")
|
|
->where('s.deleted_at', 0)
|
|
->field('s.id as student_id, s.name, s.gender, s.status, cr.age, cr.phone_number, s.user_id as resource_id, "student" as person_type')
|
|
->select()
|
|
->toArray();
|
|
}
|
|
|
|
// 过滤已安排的学员
|
|
foreach ($students as $student) {
|
|
if (!in_array($student['student_id'], $existingStudentIds)) {
|
|
$results[] = [
|
|
'id' => $student['student_id'],
|
|
'student_id' => $student['student_id'],
|
|
'resources_id' => $student['resource_id'],
|
|
'name' => $student['name'],
|
|
'age' => $student['age'] ?: 0,
|
|
'phone' => $student['phone_number'] ?: '',
|
|
'gender' => $student['gender'],
|
|
'status' => $student['status'], // 添加学员状态
|
|
'person_type' => 'student',
|
|
'type_label' => '正式学员'
|
|
];
|
|
}
|
|
}
|
|
|
|
// 搜索客户资源(非正式学员)
|
|
$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)) {
|
|
$results[] = [
|
|
'id' => $customer['resources_id'],
|
|
'student_id' => 0,
|
|
'resources_id' => $customer['resources_id'],
|
|
'name' => $customer['name'],
|
|
'age' => $customer['age'] ?: 0,
|
|
'phone' => $customer['phone_number'] ?: '',
|
|
'gender' => $customer['gender'],
|
|
'person_type' => 'customer_resource',
|
|
'type_label' => '客户资源'
|
|
];
|
|
}
|
|
}
|
|
|
|
return [
|
|
'code' => 1,
|
|
'msg' => '搜索成功',
|
|
'data' => $results
|
|
];
|
|
|
|
} catch (\Exception $e) {
|
|
return [
|
|
'code' => 0,
|
|
'msg' => '搜索学员失败:' . $e->getMessage(),
|
|
'data' => []
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 添加学员到课程安排
|
|
* @param array $data
|
|
* @return array
|
|
*/
|
|
public function addStudentToSchedule($data)
|
|
{
|
|
try {
|
|
$scheduleId = $data['schedule_id'];
|
|
$studentId = $data['student_id'] ?: null;
|
|
$resourcesId = $data['resources_id'] ?: null;
|
|
$personType = $data['person_type'];
|
|
$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,
|
|
'msg' => '课程安排不存在',
|
|
'data' => []
|
|
];
|
|
}
|
|
|
|
// 检查是否已经添加过
|
|
$PersonCourseSchedule = new PersonCourseSchedule();
|
|
$existingWhere = [
|
|
['schedule_id', '=', $scheduleId],
|
|
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 [
|
|
'code' => 0,
|
|
'msg' => '该学员已经在此课程安排中',
|
|
'data' => []
|
|
];
|
|
}
|
|
|
|
// 验证学员状态 - 只有status=1的学员才能预约固定课
|
|
if ($scheduleType == 2 && $studentId) { // 固定课且是正式学员
|
|
$Student = new Student();
|
|
$student = $Student->where('id', $studentId)->find();
|
|
if (!$student) {
|
|
return [
|
|
'code' => 0,
|
|
'msg' => '学员不存在',
|
|
'data' => []
|
|
];
|
|
}
|
|
|
|
if ($student['status'] != 1) {
|
|
return [
|
|
'code' => 0,
|
|
'msg' => '只有有效状态的学员才能预约固定课,该学员只能预约临时课',
|
|
'data' => []
|
|
];
|
|
}
|
|
}
|
|
|
|
// 如果是正式学员位置,检查容量限制
|
|
if ($courseType != 3) { // 不是等待位
|
|
$maxStudents = $schedule['max_students'] ?: 0;
|
|
if ($maxStudents > 0) {
|
|
$currentCount = $PersonCourseSchedule
|
|
->where('schedule_id', $scheduleId)
|
|
->where('course_type', '<>', 3) // 不包括等待位
|
|
->where(function ($query) {
|
|
$query->where('deleted_at', 0)->whereOr('deleted_at', null);
|
|
})
|
|
->count();
|
|
|
|
if ($currentCount >= $maxStudents) {
|
|
return [
|
|
'code' => 0,
|
|
'msg' => '课程安排已满,请添加到等待位',
|
|
'data' => []
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
// 准备插入数据
|
|
$insertData = [
|
|
'resources_id' => $resourcesId,
|
|
'person_id' => null, // 这个字段根据实际业务需求设置
|
|
'student_id' => $studentId,
|
|
'person_type' => $personType,
|
|
'schedule_id' => $scheduleId,
|
|
'course_date' => $schedule['course_date'],
|
|
'schedule_type' => $scheduleType,
|
|
'course_type' => $courseType,
|
|
'time_slot' => $schedule['time_slot'],
|
|
'status' => 0, // 待上课
|
|
'remark' => $remarks,
|
|
'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' => '添加成功',
|
|
'data' => $result->toArray()
|
|
];
|
|
} else {
|
|
return [
|
|
'code' => 0,
|
|
'msg' => '添加失败',
|
|
'data' => []
|
|
];
|
|
}
|
|
|
|
} catch (\Exception $e) {
|
|
return [
|
|
'code' => 0,
|
|
'msg' => '添加学员失败:' . $e->getMessage(),
|
|
'data' => []
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 从课程安排中移除学员
|
|
* @param array $data
|
|
* @return array
|
|
*/
|
|
public function removeStudentFromSchedule($data)
|
|
{
|
|
try {
|
|
$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,
|
|
'msg' => '记录不存在',
|
|
'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' => '移除成功',
|
|
'data' => []
|
|
];
|
|
} else {
|
|
return [
|
|
'code' => 0,
|
|
'msg' => '移除失败',
|
|
'data' => []
|
|
];
|
|
}
|
|
|
|
} catch (\Exception $e) {
|
|
return [
|
|
'code' => 0,
|
|
'msg' => '移除学员失败:' . $e->getMessage(),
|
|
'data' => []
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 更新学员课程状态
|
|
* @param array $data
|
|
* @return array
|
|
*/
|
|
public function updateStudentStatus($data)
|
|
{
|
|
try {
|
|
$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,
|
|
'msg' => '记录不存在',
|
|
'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,
|
|
'msg' => '更新成功',
|
|
'data' => []
|
|
];
|
|
} else {
|
|
return [
|
|
'code' => 0,
|
|
'msg' => '更新失败',
|
|
'data' => []
|
|
];
|
|
}
|
|
|
|
} catch (\Exception $e) {
|
|
return [
|
|
'code' => 0,
|
|
'msg' => '更新学员状态失败:' . $e->getMessage(),
|
|
'data' => []
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 更新课程安排的参与人员信息
|
|
* @param int $scheduleId
|
|
*/
|
|
private function updateScheduleParticipants($scheduleId)
|
|
{
|
|
try {
|
|
$PersonCourseSchedule = new PersonCourseSchedule();
|
|
|
|
// 获取当前安排的所有人员
|
|
$participants = $PersonCourseSchedule
|
|
->where('schedule_id', $scheduleId)
|
|
->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)
|
|
->update([
|
|
'participants' => json_encode($resourceIds),
|
|
'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
|
|
* @return array
|
|
*/
|
|
public function getCoachList($campus_id = 0)
|
|
{
|
|
try {
|
|
// 查询dept_id=23的教练角色
|
|
$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.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
|
|
* @return array
|
|
*/
|
|
public function getEducationList($campus_id = 0)
|
|
{
|
|
try {
|
|
// 查询dept_id=2的教务角色
|
|
$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.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
|
|
* @return array
|
|
*/
|
|
public function updateCourseInfo($data)
|
|
{
|
|
try {
|
|
$studentCourseId = $data['student_course_id'];
|
|
$mainCoachId = $data['main_coach_id'] ?? 0;
|
|
$assistantIds = $data['assistant_ids'] ?? '';
|
|
$educationId = $data['education_id'] ?? 0;
|
|
$classId = $data['class_id'] ?? 0;
|
|
|
|
// 1. 更新学员课程表
|
|
$updateData = [];
|
|
if ($mainCoachId > 0) {
|
|
$updateData['main_coach_id'] = $mainCoachId;
|
|
}
|
|
if (!empty($assistantIds)) {
|
|
$updateData['assistant_ids'] = $assistantIds;
|
|
}
|
|
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);
|
|
if (!$result) {
|
|
return ['code' => 0, 'msg' => '更新学员课程信息失败'];
|
|
}
|
|
}
|
|
|
|
// 2. 如果需要更新班级关联
|
|
if ($classId > 0) {
|
|
// 先获取学员的resource_id
|
|
$studentCourse = StudentCourses::where('id', $studentCourseId)->find();
|
|
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;
|
|
$existingRel->update_time = date('Y-m-d H:i:s');
|
|
$existingRel->save();
|
|
} else {
|
|
// 创建新的班级关联
|
|
$classRel = new \app\model\class_resources_rel\ClassResourcesRel();
|
|
$classRel->class_id = $classId;
|
|
$classRel->resource_id = $resourceId;
|
|
$classRel->campus_id = $studentCourse->campus_id ?? 1; // 默认校区ID
|
|
$classRel->source_type = 'student';
|
|
$classRel->join_time = time();
|
|
$classRel->status = 1;
|
|
$classRel->save();
|
|
}
|
|
}
|
|
|
|
return ['code' => 1, 'data' => ['id' => $studentCourseId], 'msg' => '更新成功'];
|
|
|
|
} catch (\Exception $e) {
|
|
return ['code' => 0, 'msg' => '更新失败: ' . $e->getMessage()];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 检查学员班级关联情况
|
|
* @param int $resource_id
|
|
* @return array
|
|
*/
|
|
public function checkClassRelation($resource_id)
|
|
{
|
|
try {
|
|
$classRel = \app\model\class_resources_rel\ClassResourcesRel::alias('crr')
|
|
->join(['school_class' => 'c'], 'crr.class_id = c.id', 'left')
|
|
->where([
|
|
'crr.resource_id' => $resource_id,
|
|
'crr.status' => 1
|
|
])
|
|
->field([
|
|
'crr.id',
|
|
'crr.class_id',
|
|
'c.class_name',
|
|
'c.head_coach',
|
|
'c.educational_id'
|
|
])
|
|
->find();
|
|
|
|
$hasClass = !empty($classRel);
|
|
$classInfo = $hasClass ? $classRel->toArray() : null;
|
|
|
|
return [
|
|
'code' => 1,
|
|
'data' => [
|
|
'has_class' => $hasClass,
|
|
'class_info' => $classInfo
|
|
]
|
|
];
|
|
|
|
} catch (\Exception $e) {
|
|
return ['code' => 0, 'msg' => '检查班级关联失败: ' . $e->getMessage()];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取课程类型文本
|
|
* @param int $courseType
|
|
* @return string
|
|
*/
|
|
private function getCourseTypeText($courseType)
|
|
{
|
|
$courseTypeMap = [
|
|
1 => '临时课',
|
|
2 => '固定课',
|
|
3 => '等待位',
|
|
4 => '试听课'
|
|
];
|
|
return $courseTypeMap[$courseType] ?? '未知';
|
|
}
|
|
|
|
private function handeStudentStatus($studentCourse)
|
|
{
|
|
$now = time();
|
|
if (strtotime($studentCourse->end_date) > $now) {
|
|
$total = $studentCourse->total_hours + $studentCourse->gift_hours - $studentCourse->use_total_hours - $studentCourse->use_gift_hours;
|
|
if ($total > 0) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|