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

366 lines
12 KiB

<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\api\apiService;
use core\base\BaseApiService;
use think\facade\Db;
/**
* 学员服务层
* Class StudentService
* @package app\service\api\apiService
*/
class StudentService extends BaseApiService
{
public function __construct()
{
parent::__construct();
}
/**
* 添加学员
* @param array $data
* @return array
*/
public function add(array $data)
{
$res = [
'code' => 0,
'msg' => '操作失败',
'data' => []
];
try {
// 准备插入数据
$insertData = [
'name' => $data['name'],
'gender' => $data['gender'],
'age' => $data['age'],
'birthday' => $data['birthday'],
'user_id' => $data['user_id'],
'campus_id' => $data['campus_id'],
'class_id' => $data['class_id'],
'note' => $data['note'],
'status' => $data['status'],
'emergency_contact' => $data['emergency_contact'],
'contact_phone' => $data['contact_phone'],
'member_label' => $data['member_label'],
'consultant_id' => $data['consultant_id'],
'coach_id' => $data['coach_id'],
'trial_class_count' => $data['trial_class_count'],
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
'deleted_at' => 0
];
// 插入数据库
$id = Db::table('school_student')->insertGetId($insertData);
if ($id) {
$res['code'] = 1;
$res['msg'] = '添加成功';
$res['data'] = ['id' => $id];
} else {
$res['msg'] = '添加失败';
}
} catch (\Exception $e) {
$res['msg'] = '添加失败:' . $e->getMessage();
}
return $res;
}
/**
* 获取学员列表(教练端专用)
* @param array $data
* @return array
*/
public function getList(array $data)
{
$res = [
'code' => 0,
'msg' => '操作失败',
'data' => []
];
try {
// 获取当前登录人员的ID
$currentUserId = $this->getUserId();
if (empty($currentUserId)) {
$res['code'] = 1;
$res['data'] = [];
$res['msg'] = '获取成功';
return $res;
}
// 构建学员基础查询条件
$where = [];
$where[] = ['s.deleted_at', '=', 0];
// 支持搜索参数
if (!empty($data['parent_resource_id'])){
$where[] = ['s.user_id', '=', $data['parent_resource_id']];
}
if (!empty($data['name'])) {
$where[] = ['s.name', 'like', '%' . $data['name'] . '%'];
}
if (!empty($data['phone'])) {
$where[] = ['s.contact_phone', 'like', '%' . $data['phone'] . '%'];
}
if (!empty($data['campus_id'])) {
$where[] = ['s.campus_id', '=', $data['campus_id']];
}
if (!empty($data['status'])) {
$where[] = ['s.status', '=', $data['status']];
}
// 查询学员基础信息
$list = Db::table('school_student s')
->leftJoin('school_campus c', 's.campus_id = c.id')
->where($where)
->field('s.*, c.campus_name as campus')
->order('s.created_at', 'desc')
->select()
->toArray();
// 为每个学员添加课程信息和到访情况
foreach ($list as &$student) {
// 获取学员最新有效的课程信息
$courseInfo = $this->getStudentLatestCourse($student['id']);
$student = array_merge($student, $courseInfo);
// 查询该学员的课程安排记录,按日期排序获取一访和二访信息
$visitRecords = Db::table('school_person_course_schedule')
->where([
['person_id', '=', $student['id']],
['person_type', '=', 'student']
])
->order('course_date', 'asc')
->select()
->toArray();
// 初始化到访信息
$student['first_visit_time'] = '';
$student['second_visit_time'] = '';
$student['first_visit_status'] = '未到访';
$student['second_visit_status'] = '未到访';
$student['academic_affairs'] = getStaffNameById($student['consultant_id']);
$student['class_teacher'] = getStaffNameById($student['coach_id']);
// 设置一访和二访信息
if (!empty($visitRecords)) {
if (isset($visitRecords[0])) {
$student['first_visit_time'] = $visitRecords[0]['course_date'];
$student['first_visit_status'] = '已到访';
}
if (isset($visitRecords[1])) {
$student['second_visit_time'] = $visitRecords[1]['course_date'];
$student['second_visit_status'] = '已到访';
}
}
// 保留原始访问记录数据供前端使用
$student['visit_records'] = $visitRecords;
}
$res['code'] = 1;
$res['data'] = $list;
} catch (\Exception $e) {
$res['msg'] = '获取失败:' . $e->getMessage();
}
return $res;
}
/**
* 获取学生ID集合(支持资源ID过滤)
* @param int $userId 当前用户ID
* @param array $data 查询条件
* @return array
*/
private function getStudentIds($userId, $data = [])
{
// 如果指定了parent_resource_id,则查询该资源下的学生
if (!empty($data['parent_resource_id'])) {
$resourceId = $data['parent_resource_id'];
// 验证当前用户是否有权限访问该资源
$resource = Db::table('school_customer_resources')
->where('id', $resourceId)
->where('consultant', $userId)
->where('deleted_at', 0)
->find();
if (empty($resource)) {
// 用户无权限访问该资源
return [];
}
// 查询该资源关联的学生ID
$studentIds = Db::table('school_student_courses')
->where('resource_id', $resourceId)
->column('student_id');
return array_values(array_unique($studentIds));
}
// 如果没有指定资源ID,则查询当前用户(教练)负责的所有学生
return $this->getCoachStudentIds($userId, $data);
}
/**
* 获取教练负责的学生ID集合
* @param int $coachId 教练ID
* @param array $data 查询条件
* @return array
*/
private function getCoachStudentIds($coachId, $data = [])
{
// 1. 从 school_student_courses 表中查询 main_coach_id 或 education_id 是当前教练的学生
$courseStudentIds = Db::table('school_student_courses')
->where(function($query) use ($coachId) {
$query->where('main_coach_id', $coachId)
->whereOr('education_id', $coachId);
})
->column('student_id');
// 2. 从 school_person_course_schedule 和 school_course_schedule 表联查,获取教练负责的学生
$scheduleStudentIds = Db::table('school_person_course_schedule pcs')
->leftJoin('school_course_schedule cs', 'pcs.schedule_id = cs.id')
->where(function($query) use ($coachId) {
$query->where('cs.education_id', $coachId)
->whereOr('cs.coach_id', $coachId);
})
->where('pcs.person_type', 'student')
->where('pcs.deleted_at', 0)
->where('cs.deleted_at', 0)
->column('pcs.student_id');
// 3. 合并并去重学生ID
$allStudentIds = array_merge($courseStudentIds, $scheduleStudentIds);
$uniqueStudentIds = array_unique($allStudentIds);
return array_values($uniqueStudentIds);
}
/**
* 获取学员最新有效的课程信息
* @param int $studentId 学员ID
* @return array
*/
private function getStudentLatestCourse($studentId)
{
$courseInfo = Db::table('school_student_courses sc')
->leftJoin('school_course c', 'sc.course_id = c.id')
->leftJoin('school_customer_resources cr', 'sc.resource_id = cr.id')
->leftJoin('school_resource_sharing rs', 'rs.resource_id = cr.id')
->where([
['sc.student_id', '=', $studentId]
])
->field('sc.total_hours, sc.gift_hours, sc.use_total_hours,
sc.use_gift_hours, sc.end_date, rs.id as resource_sharing_id, c.course_name')
->order('sc.created_at', 'desc')
->find();
if (empty($courseInfo)) {
return [
'total_hours' => 0,
'gift_hours' => 0,
'use_total_hours' => 0,
'use_gift_hours' => 0,
'end_date' => '',
'resource_sharing_id' => 0,
'course_name' => '',
'class_teacher'=>'',
'academic_affairs'=>''
];
}
return $courseInfo;
}
/**
* 获取当前登录用户ID
* @return int
*/
private function getUserId()
{
try {
// 从请求头获取token
$token = request()->header('token') ?: request()->header('Authorization');
if (empty($token)) {
return 0;
}
// 去掉Bearer前缀
$token = str_replace('Bearer ', '', $token);
// 使用项目的TokenAuth类解析token,类型为personnel(员工端)
$tokenInfo = \core\util\TokenAuth::parseToken($token, 'personnel');
if (!empty($tokenInfo)) {
// 从jti中提取用户ID(格式:用户ID_类型)
$jti = $tokenInfo['jti'] ?? '';
if (!empty($jti)) {
$parts = explode('_', $jti);
if (count($parts) >= 2) {
return (int)$parts[0];
}
}
}
return 0;
} catch (\Exception $e) {
return 0;
}
}
public function edit(array $data)
{
$res = [
'code' => 0,
'msg' => '操作失败',
'data' => []
];
$course = getValidCourseByStudentId($data['id']);
$consultant_id = $course['education_id'] ?? 0;
$coach_id = $course['main_coach_id'] ?? 0;
$data['updated_at'] = date('Y-m-d H:i:s');
if ($consultant_id || $coach_id){
$data['consultant_id'] = $consultant_id;
$data['coach_id'] = $coach_id;
}
try {
// 插入数据库
$id = Db::table('school_student')
->where('id', $data['id'])
->update($data);
if ($id) {
$res['code'] = 1;
$res['msg'] = '修改成功';
$res['data'] = ['id' => $id];
} else {
$res['msg'] = '添加失败';
}
} catch (\Exception $e) {
$res['msg'] = '添加失败:' . $e->getMessage();
}
return $res;
}
}