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.
367 lines
11 KiB
367 lines
11 KiB
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | Niucloud-admin 企业快速开发的多应用管理平台
|
|
// +----------------------------------------------------------------------
|
|
|
|
namespace app\service\api\student;
|
|
|
|
use app\model\customer_resources\CustomerResources;
|
|
use app\model\student\Student;
|
|
use app\model\member\Member;
|
|
use think\facade\Db;
|
|
use core\base\BaseService;
|
|
use core\exception\CommonException;
|
|
|
|
/**
|
|
* 学员信息管理服务类
|
|
*/
|
|
class StudentService extends BaseService
|
|
{
|
|
/**
|
|
* 获取当前用户的学员列表
|
|
* @return array
|
|
*/
|
|
public function getStudentList()
|
|
{
|
|
// 获取当前登录用户ID
|
|
$customerId = $this->getUserId();
|
|
|
|
// 通过客户资源表获取user_id
|
|
$customerResource = (new CustomerResources())->where('id', $customerId)->find();
|
|
if (!$customerResource) {
|
|
throw new CommonException('用户信息不存在');
|
|
}
|
|
|
|
// 获取该用户的所有学员
|
|
$studentList = (new Student())
|
|
->where('user_id', $customerId)
|
|
->where('deleted_at', 0)
|
|
->field('id,name,gender,birthday,headimg,created_at')
|
|
->order('id desc')
|
|
->select()
|
|
->toArray();
|
|
|
|
// 计算年龄和格式化数据
|
|
foreach ($studentList as &$student) {
|
|
$student['age'] = $this->calculateAge($student['birthday']);
|
|
$student['gender_text'] = $student['gender'] == 1 ? '男' : '女';
|
|
$student['headimg'] = $student['headimg'] ? get_image_url($student['headimg']) : '';
|
|
}
|
|
|
|
return [
|
|
'list' => $studentList,
|
|
'total' => count($studentList)
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 获取学员概览信息(首页用)
|
|
* @param int $studentId
|
|
* @return array
|
|
*/
|
|
public function getStudentSummary($studentId)
|
|
{
|
|
// 验证学员权限
|
|
$this->checkStudentPermission($studentId);
|
|
|
|
$student = (new Student())
|
|
->where('id', $studentId)
|
|
->where('deleted_at', 0)
|
|
->find();
|
|
|
|
if (!$student) {
|
|
throw new CommonException('学员信息不存在');
|
|
}
|
|
|
|
// 获取用户基本信息
|
|
$member = (new CustomerResources())->where('id', $student['user_id'])->find();
|
|
|
|
return [
|
|
'student_id' => $student['id'],
|
|
'name' => $student['name'],
|
|
'age' => $this->calculateAge($student['birthday']),
|
|
'gender' => $student['gender'],
|
|
'gender_text' => $student['gender'] == 1 ? '男' : '女',
|
|
'headimg' => $student['headimg'] ? get_image_url($student['headimg']) : '',
|
|
'member_name' => $member['name'] ?? '',
|
|
'created_at' => $student['created_at'],
|
|
'create_year_month' => date('Y年m月', strtotime($student['created_at'])),
|
|
'week_day' => '星期' . ['日', '一', '二', '三', '四', '五', '六'][date('w')]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 获取学员详细信息
|
|
* @param int $studentId
|
|
* @return array
|
|
*/
|
|
public function getStudentInfo($studentId)
|
|
{
|
|
// 验证学员权限
|
|
$this->checkStudentPermission($studentId);
|
|
|
|
$student = (new Student())
|
|
->where('id', $studentId)
|
|
->where('deleted_at', 0)
|
|
->find();
|
|
|
|
if (!$student) {
|
|
throw new CommonException('学员信息不存在');
|
|
}
|
|
|
|
$studentData = $student->toArray();
|
|
|
|
// 处理图片URL
|
|
$studentData['headimg'] = $studentData['headimg'] ? get_image_url($studentData['headimg']) : '';
|
|
|
|
// 计算年龄
|
|
$studentData['age'] = $this->calculateAge($studentData['birthday']);
|
|
$studentData['gender_text'] = $studentData['gender'] == 1 ? '男' : '女';
|
|
|
|
return $studentData;
|
|
}
|
|
|
|
/**
|
|
* 获取学员详细信息(包含体测信息)
|
|
* @param int $studentId
|
|
* @return array
|
|
*/
|
|
public function getStudentInfoWithPhysicalTest($studentId)
|
|
{
|
|
// 验证学员权限
|
|
$this->checkStudentPermission($studentId);
|
|
|
|
// 获取学员基本信息
|
|
$student = Db::table('school_student')
|
|
->where('id', $studentId)
|
|
->where('deleted_at', 0)
|
|
->find();
|
|
|
|
if (!$student) {
|
|
throw new CommonException('学员信息不存在');
|
|
}
|
|
|
|
// 获取最新的体测信息
|
|
$physicalTest = Db::table('school_physical_test')
|
|
->where('student_id', $studentId)
|
|
->order('created_at desc')
|
|
->find();
|
|
|
|
// 处理学员信息
|
|
$studentInfo = [
|
|
'id' => $student['id'],
|
|
'name' => $student['name'],
|
|
'gender' => $student['gender'],
|
|
'gender_text' => $student['gender'] == 1 ? '男' : '女',
|
|
'birthday' => $student['birthday'],
|
|
'emergency_contact' => $student['emergency_contact'],
|
|
'contact_phone' => $student['contact_phone'],
|
|
'note' => $student['note'],
|
|
'headimg' => $student['headimg'] ? get_image_url($student['headimg']) : '',
|
|
];
|
|
|
|
// 处理体测信息
|
|
$physicalTestInfo = [];
|
|
if ($physicalTest) {
|
|
$physicalTestInfo = [
|
|
'height' => $physicalTest['height'] ? (string)$physicalTest['height'] : '',
|
|
'weight' => $physicalTest['weight'] ? (string)$physicalTest['weight'] : '',
|
|
'test_date' => date('Y-m-d', strtotime($physicalTest['created_at']))
|
|
];
|
|
}
|
|
|
|
return [
|
|
'student_info' => $studentInfo,
|
|
'physical_test_info' => $physicalTestInfo
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 更新学员信息
|
|
* @param array $data
|
|
* @return bool
|
|
*/
|
|
public function updateStudentInfo($data)
|
|
{
|
|
$studentId = $data['student_id'];
|
|
|
|
// 验证学员权限
|
|
$this->checkStudentPermission($studentId);
|
|
|
|
// 验证学员是否存在
|
|
$student = Db::table('school_student')
|
|
->where('id', $studentId)
|
|
->where('deleted_at', 0)
|
|
->find();
|
|
|
|
if (!$student) {
|
|
throw new CommonException('学员信息不存在');
|
|
}
|
|
|
|
// 允许更新的字段
|
|
$allowedFields = ['name', 'gender', 'birthday', 'emergency_contact', 'contact_phone', 'note', 'headimg'];
|
|
$updateData = [];
|
|
|
|
foreach ($allowedFields as $field) {
|
|
if (isset($data[$field]) && $data[$field] !== '') {
|
|
$updateData[$field] = $data[$field];
|
|
}
|
|
}
|
|
|
|
if (empty($updateData)) {
|
|
throw new CommonException('没有需要更新的数据');
|
|
}
|
|
|
|
// 如果有生日更新,需要重新计算年龄
|
|
if (isset($updateData['birthday'])) {
|
|
$updateData['age'] = $this->calculateAgeFromBirthday($updateData['birthday']);
|
|
}
|
|
|
|
$result = Db::table('school_student')
|
|
->where('id', $studentId)
|
|
->update($updateData);
|
|
|
|
if ($result === false) {
|
|
throw new CommonException('更新学员信息失败');
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 上传学员头像
|
|
* @param int $studentId
|
|
* @return array
|
|
*/
|
|
public function uploadAvatar($studentId)
|
|
{
|
|
// 验证学员权限
|
|
$this->checkStudentPermission($studentId);
|
|
|
|
// 处理文件上传
|
|
$uploadService = new \app\service\core\upload\UploadService();
|
|
$result = $uploadService->image([
|
|
'image' => request()->file('image'),
|
|
'thumb_type' => 'avatar'
|
|
]);
|
|
|
|
if (!$result) {
|
|
throw new CommonException('头像上传失败');
|
|
}
|
|
|
|
// 更新学员头像
|
|
$student = (new Student())->where('id', $studentId)->find();
|
|
$student->headimg = $result['url'];
|
|
$student->save();
|
|
|
|
return [
|
|
'url' => get_image_url($result['url']),
|
|
'path' => $result['url']
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 检查学员权限(确保只能操作自己的孩子)
|
|
* @param int $studentId
|
|
* @return bool
|
|
*/
|
|
private function checkStudentPermission($studentId)
|
|
{
|
|
$customerId = $this->getUserId();
|
|
// 获取客户资源信息
|
|
$customerResource = (new CustomerResources())->where('id', $customerId)->find();
|
|
if (!$customerResource) {
|
|
throw new CommonException('用户信息不存在');
|
|
}
|
|
|
|
// 检查学员是否属于当前用户
|
|
$student = (new Student())
|
|
->where('id', $studentId)
|
|
->where('user_id', $customerId)
|
|
->where('deleted_at', 0)
|
|
->find();
|
|
|
|
if (!$student) {
|
|
throw new CommonException('无权限访问该学员信息');
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 计算年龄
|
|
* @param string $birthday
|
|
* @return int
|
|
*/
|
|
private function calculateAge($birthday)
|
|
{
|
|
if (!$birthday) return 0;
|
|
|
|
$birthTime = strtotime($birthday);
|
|
if (!$birthTime) return 0;
|
|
|
|
$age = date('Y') - date('Y', $birthTime);
|
|
|
|
// 如果还没过生日,年龄减1
|
|
if (date('md') < date('md', $birthTime)) {
|
|
$age--;
|
|
}
|
|
|
|
return max(0, $age);
|
|
}
|
|
|
|
/**
|
|
* 根据生日精确计算年龄(支持小数表示)
|
|
* @param string $birthday
|
|
* @return float
|
|
*/
|
|
private function calculateAgeFromBirthday($birthday)
|
|
{
|
|
if (!$birthday) return 0;
|
|
|
|
$birthTime = strtotime($birthday);
|
|
if (!$birthTime) return 0;
|
|
|
|
$today = new \DateTime();
|
|
$birthDate = new \DateTime($birthday);
|
|
|
|
$interval = $today->diff($birthDate);
|
|
|
|
$years = $interval->y;
|
|
$months = $interval->m;
|
|
|
|
// 将月份转换为小数,如3岁11个月 = 3.11
|
|
return $years + ($months / 100);
|
|
}
|
|
|
|
/**
|
|
* 获取当前登录用户ID
|
|
* @return int
|
|
*/
|
|
private function getUserId()
|
|
{
|
|
// 从request中获取memberId(由ApiCheckToken中间件设置)
|
|
$memberId = request()->memberId();
|
|
if ($memberId) {
|
|
return $memberId;
|
|
}
|
|
|
|
// 如果没有中间件设置,尝试解析token
|
|
$token = request()->header('token');
|
|
if ($token) {
|
|
try {
|
|
$loginService = new \app\service\api\login\LoginService();
|
|
$tokenInfo = $loginService->parseToken($token);
|
|
if (!empty($tokenInfo) && isset($tokenInfo['member_id'])) {
|
|
return $tokenInfo['member_id'];
|
|
}
|
|
} catch (\Exception $e) {
|
|
// token解析失败,抛出异常
|
|
throw new CommonException('用户未登录或token无效');
|
|
}
|
|
}
|
|
|
|
// 如果都没有,抛出异常
|
|
throw new CommonException('用户未登录');
|
|
}
|
|
}
|