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

279 lines
9.0 KiB

<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
namespace app\service\api\student;
use app\model\physical_test\PhysicalTest;
use app\model\customer_resources\CustomerResources;
use app\model\student\Student;
use core\base\BaseService;
use core\exception\CommonException;
/**
* 体测数据服务类
*/
class PhysicalTestService extends BaseService
{
/**
* 获取学员体测记录列表
* @param array $data
* @return array
*/
public function getPhysicalTestList($data)
{
$studentId = $data['student_id'];
$page = $data['page'] ?? 1;
$limit = $data['limit'] ?? 20;
$list = (new PhysicalTest())
->where('student_id', $studentId)
->field('id,student_id,height,weight,physical_test_report,created_at,updated_at')
->order('created_at desc')
->page($page, $limit)
->select()
->toArray();
// 处理数据
foreach ($list as &$item) {
$item['test_date'] = date('Y-m-d', strtotime($item['created_at']));
$item['height_text'] = $item['height'] . 'cm';
$item['weight_text'] = $item['weight'] . 'kg';
// 处理体测报告PDF文件
$item['has_report'] = !empty($item['physical_test_report']);
$item['report_files'] = [];
if ($item['physical_test_report']) {
$files = explode(',', $item['physical_test_report']);
foreach ($files as $file) {
if ($file) {
$item['report_files'][] = [
'name' => '体测报告',
'url' => get_image_url($file),
'path' => $file
];
}
}
}
}
$total = (new PhysicalTest())->where('student_id', $studentId)->count();
return [
'list' => $list,
'total' => $total,
'page' => $page,
'limit' => $limit,
'pages' => ceil($total / $limit)
];
}
/**
* 获取体测详情
* @param int $testId
* @return array
*/
public function getPhysicalTestDetail($testId)
{
$physicalTest = (new PhysicalTest())->where('id', $testId)->find();
if (!$physicalTest) {
throw new CommonException('体测记录不存在');
}
$data = $physicalTest->toArray();
// 格式化数据
$data['test_date'] = date('Y-m-d', strtotime($data['created_at']));
$data['height_text'] = $data['height'] . 'cm';
$data['weight_text'] = $data['weight'] . 'kg';
// 处理各项体测指标
$indicators = [
'seated_forward_bend' => ['name' => '坐位体前屈', 'unit' => 'cm'],
'sit_ups' => ['name' => '仰卧卷腹', 'unit' => '次'],
'push_ups' => ['name' => '九十度仰卧撑', 'unit' => '次'],
'flamingo_balance' => ['name' => '火烈鸟平衡测试', 'unit' => 's'],
'thirty_sec_jump' => ['name' => '三十秒双脚连续跳', 'unit' => '次'],
'standing_long_jump' => ['name' => '立定跳远', 'unit' => 'cm'],
'agility_run' => ['name' => '4乘10m灵敏折返跑', 'unit' => 's'],
'balance_beam' => ['name' => '走平衡木', 'unit' => 's'],
'tennis_throw' => ['name' => '网球掷远', 'unit' => 'm'],
'ten_meter_shuttle_run' => ['name' => '十米往返跑', 'unit' => 's']
];
$data['indicators'] = [];
foreach ($indicators as $key => $info) {
if ($data[$key] !== null && $data[$key] !== '') {
$data['indicators'][] = [
'name' => $info['name'],
'value' => $data[$key],
'unit' => $info['unit'],
'value_text' => $data[$key] . $info['unit']
];
}
}
// 处理体测报告文件
$data['report_files'] = [];
if ($data['physical_test_report']) {
$files = explode(',', $data['physical_test_report']);
foreach ($files as $file) {
if ($file) {
$data['report_files'][] = [
'name' => '体测报告',
'url' => get_image_url($file),
'path' => $file,
'type' => 'pdf'
];
}
}
}
return $data;
}
/**
* 获取体测趋势数据(身高体重变化)
* @param array $data
* @return array
*/
public function getPhysicalTestTrend($data)
{
$studentId = $data['student_id'];
$months = $data['months'] ?? 12;
// 获取指定月份内的体测数据
$startDate = date('Y-m-d', strtotime("-{$months} months"));
$trendData = (new PhysicalTest())
->where('student_id', $studentId)
->where('created_at', '>=', $startDate)
->field('height,weight,created_at')
->order('created_at asc')
->select()
->toArray();
$heightData = [];
$weightData = [];
$dates = [];
foreach ($trendData as $item) {
$date = date('Y-m', strtotime($item['created_at']));
$dates[] = $date;
$heightData[] = [
'date' => $date,
'value' => (float)$item['height']
];
$weightData[] = [
'date' => $date,
'value' => (float)$item['weight']
];
}
// 计算增长情况
$heightGrowth = 0;
$weightGrowth = 0;
if (count($heightData) >= 2) {
$heightGrowth = end($heightData)['value'] - $heightData[0]['value'];
$weightGrowth = end($weightData)['value'] - $weightData[0]['value'];
}
return [
'height_data' => $heightData,
'weight_data' => $weightData,
'dates' => array_unique($dates),
'growth' => [
'height' => round($heightGrowth, 1),
'weight' => round($weightGrowth, 1),
'height_text' => ($heightGrowth >= 0 ? '+' : '') . round($heightGrowth, 1) . 'cm',
'weight_text' => ($weightGrowth >= 0 ? '+' : '') . round($weightGrowth, 1) . 'kg'
],
'data_count' => count($trendData),
'months' => $months
];
}
/**
* PDF转图片分享
* @param int $testId
* @return array
*/
public function convertPdfToImage($testId)
{
$physicalTest = (new PhysicalTest())->where('id', $testId)->find();
if (!$physicalTest) {
throw new CommonException('体测记录不存在');
}
// 本地保存路径
$saveDir = public_path() . "/upload/pdf_images/";
if (!is_dir($saveDir)) {
mkdir($saveDir, 0777, true);
}
// 下载远程 PDF 到本地临时文件
$pdfPath = $saveDir . uniqid() . ".pdf";
file_put_contents($pdfPath, file_get_contents($physicalTest['physical_test_report']));
// 获取第一个PDF文件
// $files = explode('/upload', $physicalTest['physical_test_report']);
// $pdfFile = '/upload'.trim($files[0]);
if (!$pdfPath) {
throw new CommonException('PDF文件路径无效');
}
if (!file_exists($pdfPath)) {
throw new CommonException('PDF文件不存在');
}
try {
// 使用Imagick将PDF转换为图片
if (!extension_loaded('imagick')) {
throw new CommonException('系统不支持PDF转图片功能');
}
$imagick = new \Imagick();
$imagick->setResolution(150, 150);
$imagick->readImage($pdfPath . '[0]'); // 只转换第一页
$imagick->setImageFormat('jpeg');
$imagick->setImageCompressionQuality(85);
// 生成图片文件名
$imageName = 'physical_test_' . $testId . '_' . time() . '.jpg';
$imagePath = 'uploads/share/' . date('Y/m/d') . '/' . $imageName;
$fullImagePath = public_path() . $imagePath;
// 确保目录存在
$dir = dirname($fullImagePath);
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
// 保存图片
$imagick->writeImage($fullImagePath);
$imagick->clear();
$imagick->destroy();
return [
'image_url' => get_image_url($imagePath),
'image_path' => $imagePath,
'pdf_url' => get_image_url($pdfPath),
'message' => 'PDF转换为图片成功,可以分享给朋友了'
];
} catch (\Exception $e) {
throw new CommonException('PDF转图片失败:' . $e->getMessage());
}
}
}