智慧教务系统
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.
 
 
 
 
 
 

839 lines
30 KiB

<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\api\apiService;
use app\model\chat_friends\ChatFriends;
use app\model\course_schedule\CourseSchedule;
use app\model\person_course_schedule\PersonCourseSchedule;
use app\model\personnel\Personnel;
use app\model\student_course_usage\StudentCourseUsage;
use app\model\student_courses\StudentCourses;
use app\model\student\Student;
use app\model\customer_resources\CustomerResources;
use app\model\campus_person_role\CampusPersonRole;
use app\model\venue\Venue;
use core\base\BaseApiService;
use think\facade\Db;
/**
* 测试-控制器服务层
* Class MemberService
* @package app\service\api\member
*/
class PersonCourseScheduleService extends BaseApiService
{
public function __construct()
{
parent::__construct();
}
//查询列表
public function getList(array $where)
{
$page_params = $this->getPageParam();//获取请求参数中的页码+分页数
$page = $page_params['page'];
$limit = $page_params['limit'];
$model = new PersonCourseSchedule();
//判断有没有客户资源id
if (!empty($where['resources_id'])) {
$model = $model->where('resources_id', $where['resources_id']);
}
//上课日期
if (!empty($where['course_date'])) {
$model = $model->where('school_person_course_schedule.course_date', $where['course_date']);
}
//判断有没有客户上课状态
if (array_key_exists('status', $where) && $where['status'] != '') {
// $model = $model->where('status', $where['status']);
$model = $model->where('school_person_course_schedule.status', $where['status']);
}
$venues_info = [];//场地信息
// 判断有没有场地ID
if (!empty($where['venue_id'])) {
$model = $model->hasWhere('courseScheduleHasOne', ['venue_id' => $where['venue_id']]);
$venues_info = Venue::where('id', $where['venue_id'])->find();
if ($venues_info) {
$venues_info = $venues_info->toArray();
} else {
$venues_info = [];
}
}
$data = $model->order('course_date', 'desc')
->with([
//课程安排表
'courseScheduleHasOne' => function ($query) {
$query->with([
'venue',//场地
'campus',//校区
'course',//课程
'coach',//教练
]);
},
])
->paginate([
'list_rows' => $limit,
'page' => $page,
])
->toArray();
$data['venues_info'] = $venues_info;//场地信息详情
return $data;
}
//查询详情
public function getInfo(array $where)
{
$res = [
'code' => 0,
'msg' => '暂无数据',
'data' => []
];
$model = new PersonCourseSchedule();
//判断有无人员与课程安排关系表id
if (!empty($where['person_course_schedule_id'])) {
$model = $model->where('id', $where['person_course_schedule_id']);
}
$data = $model
->with([
//课程安排表
'courseScheduleHasOne' => function ($query) {
$query->with([
'venue',//场地
'campus',//校区
'course',//课程
'coach',//教练
]);
},
])
->find();
if ($data) {
$data = $data->toArray();
if (empty($data['courseScheduleHasOne']['id'])) {
$res = [
'code' => 0,
'msg' => '暂无课程安排数据',
'data' => []
];
return $res;
}
$res = [
'code' => 1,
'msg' => '操作成功',
'data' => $data
];
return $res;
} else {
$res = [
'code' => 0,
'msg' => '暂无数据',
'data' => []
];
return $res;
}
}
//修改人员与课程安排关系表
public function editStatus($person_course_schedule_id, array $data)
{
$res = [
'code' => 0,
'msg' => '操作失败',
'data' => []
];
if (empty($data['updated_at'])) {
$data['updated_at'] = date('Y-m-d H:i:s');
}
$model = PersonCourseSchedule::where('id', $person_course_schedule_id)->find();
if (!$model) {
$res = [
'code' => 0,
'msg' => '未找到课程安排信息',
'data' => []
];
return $res;
}
//状态0待上课1已上课2请假
if (in_array($model['status'], [0, 2])) {
$edit = PersonCourseSchedule::where('id', $person_course_schedule_id)->update($data);
if ($edit) {
$res = [
'code' => 1,
'msg' => '操作成功',
'data' => []
];
}
return $res;
} elseif ($model['status'] == 1) {
$res = [
'code' => 0,
'msg' => '该课程已上课无法请假',
'data' => []
];
return $res;
}
}
//获取排课日期
public function getCalendar(array $where)
{
$data = PersonCourseSchedule::where('resources_id', $where['resources_id'])
->where('course_date', '>=', $where['start_date'])
->where('course_date', '<=', $where['end_date'])
->select()
->toArray();
$result = [];
$currentDate = strtotime($where['start_date']);
$endDate = strtotime($where['end_date']);
while ($currentDate <= $endDate) {
$dateStr = date('Y-m-d', $currentDate);
$today = date('d', $currentDate);
$weekDay = date('w', $currentDate);
$weekMap = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
$weekStr = $weekMap[$weekDay];
$result[] = [
'date' => $dateStr,
'status' => '1', // 默认状态为正常
'is_sign' => '0', // 是否有课|1=有课,0=没课
'week' => $weekStr,
'today' => $today
];
$currentDate = strtotime('+1 day', $currentDate);
}
foreach ($data as $v) {
foreach ($result as &$rv) {
if ($rv['date'] == $v['course_date']) {
//0待上课1已上课2请假
if (in_array($v['status'], [0, 1])) {
$status = '1';
} else {
$status = '2';
}
$rv['status'] = $status;//状态1是正常 2请假
$rv['is_sign'] = '1';//是否有课|1=有课,0=没课
}
}
}
return $result;
}
//获取学生排课的全部场地列表
public function getVenueListAll(array $where)
{
$schedule_id = PersonCourseSchedule::where('resources_id', $where['resources_id'])
->where('course_date', $where['course_date'])
->distinct(true)
->column('schedule_id');
if(!$schedule_id){
return [];
}
$venue_id = CourseSchedule::whereIn('id',$schedule_id)->distinct(true)->column('venue_id');
if(!$venue_id){
return [];
}
$res = Venue::whereIn('id',$venue_id)
->with([
'campus'
])
->select()->toArray();
return $res;
}
//获取学生排课的教练列表
public function memberCoachList(array $where)
{
$page_params = $this->getPageParam();//获取请求参数中的页码+分页数
$page = $page_params['page'];
$limit = $page_params['limit'];
$res = [
'code' => 0,
'msg' => '暂无课程安排',
'data' => []
];
$schedule_id = PersonCourseSchedule::where('resources_id', $where['resources_id'])->distinct(true)->column('schedule_id');
if(!$schedule_id){
return $res;
}
$coach_id = CourseSchedule::whereIn('id',$schedule_id)->distinct(true)->column('coach_id');
if(!$coach_id){
return $res;
}
$data = Personnel::whereIn('id', $coach_id)
->paginate([
'list_rows' => $limit,
'page' => $page,
])
->toArray();
$res = [
'code' => 1,
'msg' => '操作成功',
'data' => $data
];
return $res;
}
//获取学生课时消费记录列表
public function getStudentCourseUsageList(array $where)
{
$page_params = $this->getPageParam();//获取请求参数中的页码+分页数
$page = $page_params['page'];
$limit = $page_params['limit'];
$res = [
'code' => 0,
'msg' => '暂无更多',
'data' => []
];
$schedule_id = PersonCourseSchedule::where('resources_id',$where['resources_id'])
->where('status',1)
->distinct(true)
->column('schedule_id');
if(!$schedule_id){
return $res;
}
$data = StudentCourseUsage::whereIn('student_course_id',$schedule_id)
->order('usage_date', 'desc')
->with([
'studentCourseHasOne' => function ($query) {
$query->append(['course']);
}
])
->paginate([
'list_rows' => $limit,
'page' => $page,
])
->toArray();
if(!count($data['data'])){
return $res;
}
$res = [
'code' => 1,
'msg' => '操作成功',
'data' => $data
];
return $res;
}
//获取学生课程信息列表(包含教练配置)
public function getStudentCourseInfo(array $where)
{
$res = [
'code' => 1,
'msg' => '暂无课程信息',
'data' => []
];
// 构建查询条件
$query = StudentCourses::where('resource_id', $where['resource_id']);
// 如果传入了student_id参数,添加student_id条件
if (!empty($where['student_id'])) {
$query = $query->where('student_id', $where['student_id']);
}
$studentCourses = $query->with([
'course' => function($query) {
$query->field('id,course_name');
},
'student' => function($query) {
$query->field('id,name');
}
])
->select()
->toArray();
if (empty($studentCourses)) {
$res['msg'] = '该客户暂无课程信息';
return $res;
}
$courseData = [];
foreach ($studentCourses as $course) {
// 计算总课时数(正式课时 + 赠送课时)
$totalHours = ($course['total_hours'] ?? 0) + ($course['gift_hours'] ?? 0);
// 计算已使用课时数(已使用正式课时 + 已使用赠送课时)
$usedHours = ($course['use_total_hours'] ?? 0) + ($course['use_gift_hours'] ?? 0);
// 计算剩余课时数
$remainingHours = $totalHours - $usedHours;
// 计算请假次数(通过课程安排表统计该资源下的请假记录)
$leaveCount = PersonCourseSchedule::where('resources_id', $where['resource_id'])
->where('status', 2) // 2表示请假
->count();
// 获取班级关联信息
$classInfo = null;
try {
$classRel = \app\model\class_resources_rel\ClassResourcesRel::alias('crr')
->join(['school_class' => 'c'], 'crr.class_id = c.id', 'left')
->where([
'crr.resource_id' => $where['resource_id'],
'crr.status' => 1
])
->field([
'crr.class_id',
'c.class_name',
'c.head_coach',
'c.educational_id'
])
->find();
if ($classRel) {
$classInfo = $classRel->toArray();
}
} catch (\Exception $e) {
// 班级查询失败,不影响整体功能
$classInfo = null;
}
// 获取教练配置信息
$mainCoach = null;
$education = null;
$assistants = [];
if (!empty($course['main_coach_id'])) {
$mainCoach = Personnel::where('id', $course['main_coach_id'])->field('id,name')->find();
}
if (!empty($course['education_id'])) {
$education = Personnel::where('id', $course['education_id'])->field('id,name')->find();
}
if (!empty($course['assistant_ids'])) {
$assistantIds = array_filter(explode(',', $course['assistant_ids']));
if (!empty($assistantIds)) {
$assistants = Personnel::whereIn('id', $assistantIds)->field('id,name')->select()->toArray();
}
}
// 根据数据库状态字段和日期计算课程状态
$status = 'active'; // 默认进行中
$dbStatus = $course['status'] ?? 1;
switch ($dbStatus) {
case 1:
$status = 'active'; // 有效
break;
case 2:
$status = 'expired'; // 过期
break;
case 3:
$status = 'waiting'; // 等待期
break;
case 4:
$status = 'delayed'; // 延期
break;
}
// 如果课程已到期但状态还是有效,更新为过期
if ($status === 'active' && !empty($course['end_date'])) {
if (strtotime($course['end_date']) < time()) {
$status = 'expired';
}
}
// 如果课时已用完,标记为已完成
if ($remainingHours <= 0) {
$status = 'completed';
}
$courseData[] = [
'id' => $course['id'],
'course_name' => $course['course']['course_name'] ?? '未知课程',
'total_count' => $totalHours, // 总课时(正式+赠送)
'used_count' => $usedHours, // 已使用课时
'remaining_count' => $remainingHours, // 剩余课时
'formal_hours' => $course['total_hours'] ?? 0, // 正式课时
'gift_hours' => $course['gift_hours'] ?? 0, // 赠送课时
'used_formal_hours' => $course['use_total_hours'] ?? 0, // 已使用正式课时
'used_gift_hours' => $course['use_gift_hours'] ?? 0, // 已使用赠送课时
'leave_count' => $leaveCount, // 请假次数
'start_date' => $course['start_date'] ?? '', // 开始日期
'expiry_date' => $course['end_date'] ?? '', // 结束日期
'status' => $status, // 课程状态
'db_status' => $dbStatus, // 数据库原始状态
'single_session_count' => $course['single_session_count'] ?? 1, // 单次消课数量
'resource_id' => $course['resource_id'] ?? null, // 添加资源ID
'student_course_id' => $course['id'], // 添加学生课程ID
'main_coach_id' => $course['main_coach_id'] ?? null,
'main_coach_name' => $mainCoach['name'] ?? '未分配',
'education_id' => $course['education_id'] ?? null,
'education_name' => $education['name'] ?? '未分配',
'assistant_ids' => $course['assistant_ids'] ?? '',
'assistant_names' => implode(', ', array_column($assistants, 'name')) ?: '无',
// 班级相关字段
'class_id' => $classInfo['class_id'] ?? null,
'class_name' => $classInfo['class_name'] ?? null,
'has_class' => !empty($classInfo), // 是否有班级关联
'class_info' => $classInfo // 完整的班级信息
];
}
$res = [
'code' => 1,
'msg' => '获取成功',
'data' => $courseData
];
return $res;
}
//获取人员列表(教练、教务、助教)
public function getPersonnelList()
{
$res = [
'code' => 0,
'msg' => '获取人员列表失败',
'data' => []
];
try {
// 先从校区人员角色关系表查询dept_id=2的所有人员ID
$personIds = CampusPersonRole::where('dept_id', 2)
->where('deleted_at', 0) // 未删除
->distinct(true)
->column('person_id');
if (empty($personIds)) {
$res['msg'] = '暂无相关人员';
return $res;
}
// 根据获取到的人员ID查询人员详情,并关联角色信息
$personnel = Personnel::whereIn('id', $personIds)
->field('id,name,status')
->where('status', 1) // 正常状态
->append(['status_name']) // 添加状态名称字段
->select()
->toArray();
// 为每个人员获取角色信息
foreach ($personnel as &$person) {
$roles = CampusPersonRole::where('person_id', $person['id'])
->where('dept_id', 2)
->where('deleted_at', 0)
->with(['sysRole' => function($query) {
$query->field('role_id,role_name');
}])
->select()
->toArray();
// 提取角色名称
$roleNames = [];
foreach ($roles as $role) {
if (!empty($role['sys_role']['role_name'])) {
$roleNames[] = $role['sys_role']['role_name'];
}
}
$person['role_name'] = implode(',', $roleNames);
$person['roles'] = $roleNames; // 保留数组格式便于前端判断
}
$res = [
'code' => 1,
'msg' => '获取成功',
'data' => $personnel
];
} catch (\Exception $e) {
$res['msg'] = '获取人员列表异常:' . $e->getMessage();
}
return $res;
}
//获取学生课程详情(包含课时使用记录和订单信息)
public function getStudentCourseDetail(array $where)
{
$res = [
'code' => 0,
'msg' => '获取失败',
'data' => []
];
try {
$studentCourseId = $where['student_course_id'];
// 1. 获取学员课程基础信息
$studentCourse = StudentCourses::where('id', $studentCourseId)
->with([
'course' => function($query) {
$query->field('id,course_name');
},
'student' => function($query) {
$query->field('id,name');
}
])
->find();
if (!$studentCourse) {
$res['msg'] = '学员课程不存在';
return $res;
}
$studentCourse = $studentCourse->toArray();
// 2. 获取课时使用记录(一对多关联)
$usageRecords = StudentCourseUsage::where('student_course_id', $studentCourseId)
->order('usage_date', 'desc')
->select()
->toArray();
// 3. 获取关联的订单信息(一对一关联,通过course_plan_id)
$orderInfo = \app\model\order_table\OrderTable::where('course_plan_id', $studentCourseId)
->with([
'course' => function($query) {
$query->field('id,course_name');
},
'personnel' => function($query) {
$query->field('id,name');
},
'campus' => function($query) {
$query->field('id,campus_name');
}
])
->find();
// 4. 计算课时统计信息
$totalHours = ($studentCourse['total_hours'] ?? 0) + ($studentCourse['gift_hours'] ?? 0);
$usedHours = ($studentCourse['use_total_hours'] ?? 0) + ($studentCourse['use_gift_hours'] ?? 0);
$remainingHours = $totalHours - $usedHours;
// 5. 获取教练配置信息
$mainCoach = null;
$education = null;
$assistants = [];
if (!empty($studentCourse['main_coach_id'])) {
$mainCoach = Personnel::where('id', $studentCourse['main_coach_id'])->field('id,name')->find();
}
if (!empty($studentCourse['education_id'])) {
$education = Personnel::where('id', $studentCourse['education_id'])->field('id,name')->find();
}
if (!empty($studentCourse['assistant_ids'])) {
$assistantIds = array_filter(explode(',', $studentCourse['assistant_ids']));
if (!empty($assistantIds)) {
$assistants = Personnel::whereIn('id', $assistantIds)->field('id,name')->select()->toArray();
}
}
// 6. 计算课程状态
$status = 'active';
$dbStatus = $studentCourse['status'] ?? 1;
switch ($dbStatus) {
case 1:
$status = 'active';
break;
case 2:
$status = 'expired';
break;
case 3:
$status = 'waiting';
break;
case 4:
$status = 'delayed';
break;
}
if ($status === 'active' && !empty($studentCourse['end_date'])) {
if (strtotime($studentCourse['end_date']) < time()) {
$status = 'expired';
}
}
if ($remainingHours <= 0) {
$status = 'completed';
}
// 7. 组装返回数据
$data = [
// 学员课程基础信息
'student_course_info' => [
'id' => $studentCourse['id'],
'student_id' => $studentCourse['student_id'],
'student_name' => $studentCourse['student']['name'] ?? '未知学员',
'course_id' => $studentCourse['course_id'],
'course_name' => $studentCourse['course']['course_name'] ?? '未知课程',
'total_hours' => $studentCourse['total_hours'] ?? 0,
'gift_hours' => $studentCourse['gift_hours'] ?? 0,
'use_total_hours' => $studentCourse['use_total_hours'] ?? 0,
'use_gift_hours' => $studentCourse['use_gift_hours'] ?? 0,
'start_date' => $studentCourse['start_date'] ?? '',
'end_date' => $studentCourse['end_date'] ?? '',
'status' => $status,
'db_status' => $dbStatus,
'single_session_count' => $studentCourse['single_session_count'] ?? 1,
'resource_id' => $studentCourse['resource_id'] ?? null,
'main_coach_id' => $studentCourse['main_coach_id'] ?? null,
'education_id' => $studentCourse['education_id'] ?? null,
'assistant_ids' => $studentCourse['assistant_ids'] ?? '',
// 课时统计
'total_class_hours' => $totalHours,
'used_class_hours' => $usedHours,
'remaining_class_hours' => $remainingHours,
// 教练信息
'main_coach_name' => $mainCoach['name'] ?? '未分配',
'education_name' => $education['name'] ?? '未分配',
'assistant_names' => implode(', ', array_column($assistants, 'name')) ?: '无',
'coach_details' => [
'main_coach' => $mainCoach,
'education' => $education,
'assistants' => $assistants
]
],
// 课时使用记录列表
'usage_records' => array_map(function($record) {
return [
'id' => $record['id'],
'used_hours' => $record['used_hours'],
'usage_date' => $record['usage_date'],
'created_at' => $record['created_at'],
'updated_at' => $record['updated_at'],
'student_id' => $record['student_id'],
'resource_id' => $record['resource_id']
];
}, $usageRecords),
// 订单信息(如果存在)
'order_info' => $orderInfo ? [
'id' => $orderInfo['id'],
'payment_id' => $orderInfo['payment_id'] ?? '',
'order_type' => $orderInfo['order_type'] ?? '',
'order_status' => $orderInfo['order_status'] ?? '',
'payment_type' => $orderInfo['payment_type'] ?? '',
'order_amount' => $orderInfo['order_amount'] ?? 0,
'course_id' => $orderInfo['course_id'] ?? 0,
'class_id' => $orderInfo['class_id'] ?? null,
'staff_id' => $orderInfo['staff_id'] ?? 0,
'resource_id' => $orderInfo['resource_id'] ?? 0,
'campus_id' => $orderInfo['campus_id'] ?? 0,
'student_id' => $orderInfo['student_id'] ?? null,
'discount_amount' => $orderInfo['discount_amount'] ?? 0,
'remark' => $orderInfo['remark'] ?? '',
'payment_time' => $orderInfo['payment_time'] ?? '',
'created_at' => $orderInfo['created_at'] ?? '',
// 关联信息
'course_name' => $orderInfo['course']['course_name'] ?? '',
'staff_name' => $orderInfo['personnel']['name'] ?? '',
'campus_name' => $orderInfo['campus']['campus_name'] ?? ''
] : null,
// 统计信息
'statistics' => [
'total_usage_records' => count($usageRecords),
'total_used_hours_from_records' => array_sum(array_column($usageRecords, 'used_hours')),
'has_order' => !empty($orderInfo),
'usage_date_range' => $usageRecords ? [
'first_usage' => min(array_column($usageRecords, 'usage_date')),
'last_usage' => max(array_column($usageRecords, 'usage_date'))
] : null
]
];
$res = [
'code' => 1,
'msg' => '获取成功',
'data' => $data
];
} catch (\Exception $e) {
$res['msg'] = '获取异常:' . $e->getMessage();
}
return $res;
}
//更新学生课程人员配置
public function updateStudentCoursePersonnel($studentCourseId, array $data)
{
$res = [
'code' => 0,
'msg' => '更新失败',
'data' => []
];
try {
// 检查学生课程是否存在
$studentCourse = StudentCourses::where('id', $studentCourseId)->find();
if (!$studentCourse) {
$res['msg'] = '学生课程不存在';
return $res;
}
// 准备更新数据
$updateData = [];
if (isset($data['main_coach_id']) && $data['main_coach_id'] !== '') {
$updateData['main_coach_id'] = intval($data['main_coach_id']);
}
if (isset($data['education_id']) && $data['education_id'] !== '') {
$updateData['education_id'] = intval($data['education_id']);
}
if (isset($data['assistant_ids'])) {
$updateData['assistant_ids'] = strval($data['assistant_ids']);
}
$updateData['update_time'] = date('Y-m-d H:i:s');
// 执行更新
$result = StudentCourses::where('id', $studentCourseId)->update($updateData);
if ($result !== false) {
$res = [
'code' => 1,
'msg' => '更新成功',
'data' => $updateData
];
} else {
$res['msg'] = '更新数据库失败';
}
} catch (\Exception $e) {
$res['msg'] = '更新异常:' . $e->getMessage();
}
return $res;
}
}