From c59bea87c94db817f9cdfc348b1fbb7916553006 Mon Sep 17 00:00:00 2001 From: zeyan <258785420@qq.com> Date: Thu, 31 Jul 2025 21:52:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(student):=20=E4=BC=98=E5=8C=96=E4=BD=93?= =?UTF-8?q?=E6=B5=8B=E8=AE=B0=E5=BD=95=E5=8A=9F=E8=83=BD=E5=B9=B6=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=AD=A9=E5=AD=90=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -体测记录数据处理和PDF文件格式转换 - 添加获取图片文件对外网络路径的函数 -优化反馈页面的提交逻辑 - 改进体测记录卡片的文件预览功能 - 更新体测记录弹窗的文件上传逻辑 - 在学生首页添加"添加孩子"按钮和相关导航 --- .../controller/apiController/PhysicalTest.php | 11 +- .../controller/parent/ParentController.php | 71 -- .../controller/student/StudentController.php | 36 + niucloud/app/api/route/student.php | 13 +- niucloud/app/common.php | 10 + .../api/apiService/PhysicalTestService.php | 53 +- .../api/student/PhysicalTestService.php | 55 +- .../service/api/student/StudentService.php | 52 +- uniapp/api/member.js | 82 ++ .../fitness-record-card.vue | 69 +- .../fitness-record-popup.vue | 9 +- uniapp/pages.json | 9 + uniapp/pages/common/feedback.vue | 4 - uniapp/pages/common/my_message.vue | 4 - uniapp/pages/market/clue/clue_info.vue | 75 +- uniapp/pages/student/home/index.vue | 69 ++ uniapp/pages/student/physical-test/index.vue | 857 ++++++++++-------- uniapp/pages/student/profile/index.vue | 48 +- 18 files changed, 889 insertions(+), 638 deletions(-) diff --git a/niucloud/app/api/controller/apiController/PhysicalTest.php b/niucloud/app/api/controller/apiController/PhysicalTest.php index a34a93fe..008dacb8 100644 --- a/niucloud/app/api/controller/apiController/PhysicalTest.php +++ b/niucloud/app/api/controller/apiController/PhysicalTest.php @@ -27,13 +27,10 @@ class PhysicalTest extends BaseApiService //列表 public function index(Request $request) { - $resource_id = $request->param('resource_id', '');//学生资源表id - if (empty($resource_id)) { - return fail('缺少参数'); - } + $student_id = $request->param('student_id', '');//学生资源表id $where = [ - 'resource_id' => $resource_id, + 'student_id' => $student_id, ]; $res = (new PhysicalTestService())->getList($where); @@ -68,8 +65,8 @@ class PhysicalTest extends BaseApiService { $data = $request->param(); - // 验证必填字段 - $required_fields = ['resource_id', 'student_id', 'age', 'height', 'weight']; + // 验证必填字段 - 根据新的数据库表结构调整 + $required_fields = ['resource_id', 'student_id', 'height', 'weight']; foreach ($required_fields as $field) { if (empty($data[$field])) { return fail("缺少参数:{$field}"); diff --git a/niucloud/app/api/controller/parent/ParentController.php b/niucloud/app/api/controller/parent/ParentController.php index 6feaad7f..64fb398c 100644 --- a/niucloud/app/api/controller/parent/ParentController.php +++ b/niucloud/app/api/controller/parent/ParentController.php @@ -20,78 +20,7 @@ use think\Response; */ class ParentController extends BaseController { - /** - * 获取家长下的孩子列表 - * @return Response - */ - public function getChildrenList() - { - try { - $service = new ParentService(); - $result = $service->getChildrenList(); - - return success($result, '获取孩子列表成功'); - - } catch (\Exception $e) { - return fail($e->getMessage()); - } - } - - /** - * 获取指定孩子的详细信息 - * @return Response - */ - public function getChildInfo() - { - $data = $this->request->params([ - ['child_id', ''] - ]); - $this->validate($data, [ - 'child_id' => 'require' - ]); - - try { - $service = new ParentService(); - $result = $service->getChildInfo($data['child_id']); - - return success($result, '获取孩子信息成功'); - - } catch (\Exception $e) { - return fail($e->getMessage()); - } - } - - /** - * 新增孩子信息 - * @return Response - */ - public function addChild() - { - $data = $this->request->params([ - ['name', ''], - ['gender', 1], - ['birthday', ''], - ['age', 0], - ['remark', ''] - ]); - - $this->validate($data, [ - 'name' => 'require', - 'gender' => 'require|in:1,2', - 'birthday' => 'require|date' - ]); - - try { - $service = new ParentService(); - $result = $service->addChild($data); - - return success($result, '添加孩子成功'); - - } catch (\Exception $e) { - return fail($e->getMessage()); - } - } /** * 更新孩子信息 diff --git a/niucloud/app/api/controller/student/StudentController.php b/niucloud/app/api/controller/student/StudentController.php index e122c683..686a5f97 100644 --- a/niucloud/app/api/controller/student/StudentController.php +++ b/niucloud/app/api/controller/student/StudentController.php @@ -9,6 +9,7 @@ namespace app\api\controller\student; +use app\service\api\parent\ParentService; use app\service\api\student\StudentService; use core\base\BaseController; use think\Response; @@ -189,4 +190,39 @@ class StudentController extends BaseController return fail($e->getMessage()); } } + + /** + * 新增孩子信息 + * @return Response + */ + public function addChild() + { + $data = $this->request->params([ + ['name', ''], + ['gender', '1'], + ['birthday', ''], + ['headimg', ''], + ['emergency_contact', ''], + ['contact_phone', ''], + ['note', ''] + ]); + + $this->validate($data, [ + 'name' => 'require|length:2,20', + 'gender' => 'require|in:1,2', + 'birthday' => 'require|date', + 'contact_phone' => 'mobile', + 'emergency_contact' => 'max:20' + ]); + + try { + $service = new StudentService(); + $result = $service->addChild($data); + + return success($result, '添加孩子成功'); + + } catch (\Exception $e) { + return fail($e->getMessage()); + } + } } \ No newline at end of file diff --git a/niucloud/app/api/route/student.php b/niucloud/app/api/route/student.php index 92556f59..6099ec86 100644 --- a/niucloud/app/api/route/student.php +++ b/niucloud/app/api/route/student.php @@ -20,10 +20,7 @@ Route::group('student', function () { // 上传头像 Route::post('avatar', 'app\api\controller\student\StudentController@uploadAvatar'); - //家长端接口 - Route::get('parent/children', 'parent.ParentController/getChildrenList'); - Route::get('parent/child/info', 'parent.ParentController/getChildInfo'); - Route::post('parent/child/add', 'parent.ParentController/addChild'); + Route::post('add-child', 'app\api\controller\student\StudentController@addChild'); Route::post('parent/child/update', 'parent.ParentController/updateChildInfo'); Route::get('parent/child/courses', 'parent.ParentController/getChildCourses'); Route::get('parent/child/orders', 'parent.ParentController/getChildOrders'); @@ -35,13 +32,13 @@ Route::group('student', function () { // 体测数据管理 Route::group('physical-test', function () { // 获取体测记录列表 - Route::get('list', 'student.PhysicalTestController@getPhysicalTestList'); + Route::get('list', 'app\api\controller\student\PhysicalTestController@getPhysicalTestList'); // 获取体测详情 - Route::get('detail/:test_id', 'student.PhysicalTestController@getPhysicalTestDetail'); + Route::get('detail/:test_id', 'app\api\controller\student\PhysicalTestController@getPhysicalTestDetail'); // 获取体测趋势数据 - Route::get('trend', 'student.PhysicalTestController@getPhysicalTestTrend'); + Route::get('trend', 'app\api\controller\student\PhysicalTestController@getPhysicalTestTrend'); // PDF转图片分享 - Route::post('share/:test_id', 'student.PhysicalTestController@sharePhysicalTestPdf'); + Route::post('share/:test_id', 'app\api\controller\student\PhysicalTestController@sharePhysicalTestPdf'); })->middleware(['ApiCheckToken']); // 课程预约管理 diff --git a/niucloud/app/common.php b/niucloud/app/common.php index a3f1300a..72934547 100644 --- a/niucloud/app/common.php +++ b/niucloud/app/common.php @@ -280,6 +280,16 @@ function get_file_url(string $path) } } +/** + * 获取图片文件的对外网络路径(get_file_url的别名) + * @param string $path + * @return string + */ +function get_image_url(string $path) +{ + return get_file_url($path); +} + /** * 新增队列工作 * @param $job diff --git a/niucloud/app/service/api/apiService/PhysicalTestService.php b/niucloud/app/service/api/apiService/PhysicalTestService.php index 1613f5ad..5b7e1d99 100644 --- a/niucloud/app/service/api/apiService/PhysicalTestService.php +++ b/niucloud/app/service/api/apiService/PhysicalTestService.php @@ -37,9 +37,10 @@ class PhysicalTestService extends BaseApiService $limit = $page_params['limit']; $model = new PhysicalTest(); + //判断用没有员工id - if (!empty($where['resource_id'])) { - $model = $model->where('resource_id', $where['resource_id']); + if (!empty($where['student_id'])) { + $model = $model->where('student_id', $where['student_id']); } $data = $model @@ -56,15 +57,6 @@ class PhysicalTestService extends BaseApiService 'page' => $page, ])->toArray(); - - foreach ($data['data'] as &$v) { - $age = $v['age'];//年龄 - $gender = $v['customerResourcesHasOne']['gender'] == 'female' ? 2:1 ;//性别( 1:男,2:女) - $height = $v['height'];//身高 - $weight = $v['weight'];//体重 - $v['calculateChildHealthScore'] = calculateChildHealthScore($age, $gender, $height, $weight);//综合评分 - } - return $data; } @@ -90,13 +82,6 @@ class PhysicalTestService extends BaseApiService if ($data) { $data = $data->toArray(); - - $age = $data['age'];//年龄 - $gender = $data['customerResourcesHasOne']['gender'] == 'female' ? 2 : 1;//性别( 1:男,2:女) - $height = $data['height'];//身高 - $weight = $data['weight'];//体重 - $data['calculateChildHealthScore'] = calculateChildHealthScore($age, $gender, $height, $weight);//综合评分 - $res = [ 'code' => 1, 'msg' => '操作成功', @@ -123,11 +108,10 @@ class PhysicalTestService extends BaseApiService try { $model = new PhysicalTest(); - // 设置基础数据 + // 设置基础数据 - 根据新的数据库表结构调整 $physicalTestData = [ 'resource_id' => $data['resource_id'], 'student_id' => $data['student_id'], - 'age' => $data['age'], 'height' => $data['height'], 'weight' => $data['weight'], 'coach_id' => $data['coach_id'] ?? null, @@ -135,18 +119,18 @@ class PhysicalTestService extends BaseApiService 'updated_at' => date('Y-m-d H:i:s') ]; - // 设置体测项目数据 - $test_items = [ - 'seated_forward_bend', 'sit_ups', 'push_ups', 'flamingo_balance', - 'thirty_sec_jump', 'standing_long_jump', 'agility_run', 'balance_beam', - 'tennis_throw', 'ten_meter_shuttle_run' - ]; + // 数据库表结构已简化,移除体测项目字段的处理 + // $test_items = [ + // 'seated_forward_bend', 'sit_ups', 'push_ups', 'flamingo_balance', + // 'thirty_sec_jump', 'standing_long_jump', 'agility_run', 'balance_beam', + // 'tennis_throw', 'ten_meter_shuttle_run' + // ]; - foreach ($test_items as $item) { - if (isset($data[$item])) { - $physicalTestData[$item] = $data[$item]; - } - } + // foreach ($test_items as $item) { + // if (isset($data[$item])) { + // $physicalTestData[$item] = $data[$item]; + // } + // } // 处理体测报告附件 if (!empty($data['physical_test_report'])) { @@ -203,12 +187,9 @@ class PhysicalTestService extends BaseApiService 'updated_at' => date('Y-m-d H:i:s') ]; - // 允许更新的字段 + // 允许更新的字段 - 根据新的数据库表结构调整 $allowed_fields = [ - 'age', 'height', 'weight', 'coach_id', - 'seated_forward_bend', 'sit_ups', 'push_ups', 'flamingo_balance', - 'thirty_sec_jump', 'standing_long_jump', 'agility_run', 'balance_beam', - 'tennis_throw', 'ten_meter_shuttle_run' + 'height', 'weight', 'coach_id' ]; foreach ($allowed_fields as $field) { diff --git a/niucloud/app/service/api/student/PhysicalTestService.php b/niucloud/app/service/api/student/PhysicalTestService.php index a6ccddcb..da7b5f16 100644 --- a/niucloud/app/service/api/student/PhysicalTestService.php +++ b/niucloud/app/service/api/student/PhysicalTestService.php @@ -24,16 +24,13 @@ class PhysicalTestService extends BaseService public function getPhysicalTestList($data) { $studentId = $data['student_id']; - - // 验证学员权限 - $this->checkStudentPermission($studentId); $page = $data['page'] ?? 1; $limit = $data['limit'] ?? 20; $list = (new PhysicalTest()) ->where('student_id', $studentId) - ->field('id,student_id,age,height,weight,physical_test_report,created_at,updated_at') + ->field('id,student_id,height,weight,physical_test_report,created_at,updated_at') ->order('created_at desc') ->page($page, $limit) ->select() @@ -87,9 +84,6 @@ class PhysicalTestService extends BaseService throw new CommonException('体测记录不存在'); } - // 验证学员权限 - $this->checkStudentPermission($physicalTest['student_id']); - $data = $physicalTest->toArray(); // 格式化数据 @@ -151,9 +145,6 @@ class PhysicalTestService extends BaseService { $studentId = $data['student_id']; $months = $data['months'] ?? 12; - - // 验证学员权限 - $this->checkStudentPermission($studentId); // 获取指定月份内的体测数据 $startDate = date('Y-m-d', strtotime("-{$months} months")); @@ -220,13 +211,6 @@ class PhysicalTestService extends BaseService throw new CommonException('体测记录不存在'); } - // 验证学员权限 - $this->checkStudentPermission($physicalTest['student_id']); - - if (!$physicalTest['physical_test_report']) { - throw new CommonException('该体测记录没有PDF报告'); - } - // 获取第一个PDF文件 $files = explode(',', $physicalTest['physical_test_report']); $pdfFile = trim($files[0]); @@ -282,41 +266,4 @@ class PhysicalTestService extends BaseService } } - /** - * 检查学员权限 - * @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('member_id', $customerResource['member_id']) - ->where('delete_time', 0) - ->find(); - - if (!$student) { - throw new CommonException('无权限访问该学员信息'); - } - - return true; - } - - /** - * 获取当前登录用户ID - * @return int - */ - private function getUserId() - { - return request()->userId ?? 0; - } } \ No newline at end of file diff --git a/niucloud/app/service/api/student/StudentService.php b/niucloud/app/service/api/student/StudentService.php index de11c4b0..a8a45e8e 100644 --- a/niucloud/app/service/api/student/StudentService.php +++ b/niucloud/app/service/api/student/StudentService.php @@ -239,11 +239,8 @@ class StudentService extends BaseService $this->checkStudentPermission($studentId); // 处理文件上传 - $uploadService = new \app\service\core\upload\UploadService(); - $result = $uploadService->image([ - 'image' => request()->file('image'), - 'thumb_type' => 'avatar' - ]); + $uploadService = new \app\service\api\upload\UploadService(); + $result = $uploadService->avatar(request()->file('image')); if (!$result) { throw new CommonException('头像上传失败'); @@ -334,6 +331,51 @@ class StudentService extends BaseService return $years + ($months / 100); } + /** + * 添加孩子信息 + * @param array $data + * @return array + */ + public function addChild($data) + { + $customerId = $this->getUserId(); + + // 创建学员数据 + $studentData = [ + 'user_id' => $customerId, + 'name' => $data['name'], + 'gender' => (int)$data['gender'], + 'birthday' => $data['birthday'], + 'headimg' => $data['headimg'] ?? '', + 'emergency_contact' => $data['emergency_contact'] ?? '', + 'contact_phone' => $data['contact_phone'] ?? '', + 'note' => $data['note'] ?? '', + 'age' => $this->calculateAgeFromBirthday($data['birthday']), + 'created_at' => date('Y-m-d H:i:s'), + 'updated_at' => date('Y-m-d H:i:s'), + 'deleted_at' => 0 + ]; + + try { + // 插入学员数据 + $studentId = Db::table('school_student')->insertGetId($studentData); + + if (!$studentId) { + throw new CommonException('添加孩子失败'); + } + + return [ + 'student_id' => $studentId, + 'name' => $data['name'], + 'gender_text' => $data['gender'] == 1 ? '男' : '女', + 'age' => $this->calculateAge($data['birthday']) + ]; + + } catch (\Exception $e) { + throw new CommonException('添加孩子失败:' . $e->getMessage()); + } + } + /** * 获取当前登录用户ID * @return int diff --git a/uniapp/api/member.js b/uniapp/api/member.js index 075214fa..62579456 100644 --- a/uniapp/api/member.js +++ b/uniapp/api/member.js @@ -1,4 +1,5 @@ import http from '../common/axios.js' +import { Api_url } from '../common/config.js' export default { //↓↓↓↓↓↓↓↓↓↓↓↓-----学员信息管理接口-----↓↓↓↓↓↓↓↓↓↓↓↓ @@ -37,4 +38,85 @@ export default { } }; }, + + //↓↓↓↓↓↓↓↓↓↓↓↓-----体测数据管理接口-----↓↓↓↓↓↓↓↓↓↓↓↓ + // 获取学员体测数据列表(从school_physical_test表) + async getPhysicalTestList(data = {}) { + return await http.get('/physical-test/list', data); + }, + + // PDF转图片接口 + async convertPdfToImage(data = {}) { + return await http.post('/physical-test/pdf-to-image', data); + }, + + // 生成体测分享图片 + async generateShareImage(data = {}) { + return await http.post('/share-image', data); + }, + + //↓↓↓↓↓↓↓↓↓↓↓↓-----添加孩子相关接口-----↓↓↓↓↓↓↓↓↓↓↓↓ + // 添加孩子 + async addChild(data = {}) { + return await http.post('/student/add-child', data); + }, + + // 上传头像 + async uploadAvatar(filePath, studentId) { + return new Promise((resolve, reject) => { + uni.uploadFile({ + url: Api_url + '/student/avatar', + filePath: filePath, + name: 'image', + formData: { + 'student_id': studentId + }, + header: { + 'token': uni.getStorageSync('token') || '' + }, + success: (uploadFileRes) => { + console.log('上传文件响应:', uploadFileRes) + try { + const result = JSON.parse(uploadFileRes.data) + resolve(result) + } catch (e) { + console.error('响应数据解析失败:', e) + reject(new Error('响应数据解析失败')) + } + }, + fail: (error) => { + console.error('文件上传失败:', error) + reject(error) + } + }) + }) + }, + + // 添加孩子时上传头像(不需要student_id) + async uploadAvatarForAdd(filePath) { + return new Promise((resolve, reject) => { + uni.uploadFile({ + url: Api_url + '/file/avatar', + filePath: filePath, + name: 'file', + header: { + 'token': uni.getStorageSync('token') || '' + }, + success: (uploadFileRes) => { + console.log('上传文件响应:', uploadFileRes) + try { + const result = JSON.parse(uploadFileRes.data) + resolve(result) + } catch (e) { + console.error('响应数据解析失败:', e) + reject(new Error('响应数据解析失败')) + } + }, + fail: (error) => { + console.error('文件上传失败:', error) + reject(error) + } + }) + }) + }, } \ No newline at end of file diff --git a/uniapp/components/fitness-record-card/fitness-record-card.vue b/uniapp/components/fitness-record-card/fitness-record-card.vue index df07bd99..a18518bb 100644 --- a/uniapp/components/fitness-record-card/fitness-record-card.vue +++ b/uniapp/components/fitness-record-card/fitness-record-card.vue @@ -63,48 +63,37 @@ export default { async handleFileClick(file) { try { - // 发起PDF预览请求 - const response = await this.$api.get('/fitness/record/pdf/preview', { - file_id: file.id, - record_id: this.record.id - }) - - if (response.code === 1 && response.data) { - // 在微信小程序中预览PDF - uni.downloadFile({ - url: response.data.file_url, - success: (res) => { - if (res.statusCode === 200) { - uni.openDocument({ - filePath: res.tempFilePath, - fileType: 'pdf', - success: () => { - console.log('PDF预览成功') - }, - fail: (err) => { - console.error('PDF预览失败:', err) - uni.showToast({ - title: 'PDF预览失败', - icon: 'none' - }) - } - }) - } - }, - fail: (err) => { - console.error('PDF下载失败:', err) - uni.showToast({ - title: 'PDF下载失败', - icon: 'none' + let url = this.$util.getResourceUrl(file) + console.log('file url:', url) + // 在微信小程序中预览PDF + uni.downloadFile({ + url: url, + success: (res) => { + if (res.statusCode === 200) { + uni.openDocument({ + filePath: res.tempFilePath, + fileType: 'pdf', + success: () => { + console.log('PDF预览成功') + }, + fail: (err) => { + console.error('PDF预览失败:', err) + uni.showToast({ + title: 'PDF预览失败', + icon: 'none' + }) + } }) } - }) - } else { - uni.showToast({ - title: response.msg || 'PDF预览失败', - icon: 'none' - }) - } + }, + fail: (err) => { + console.error('PDF下载失败:', err) + uni.showToast({ + title: 'PDF下载失败', + icon: 'none' + }) + } + }) } catch (error) { console.error('PDF预览异常:', error) uni.showToast({ diff --git a/uniapp/components/fitness-record-popup/fitness-record-popup.vue b/uniapp/components/fitness-record-popup/fitness-record-popup.vue index 3346d38e..092409c6 100644 --- a/uniapp/components/fitness-record-popup/fitness-record-popup.vue +++ b/uniapp/components/fitness-record-popup/fitness-record-popup.vue @@ -175,13 +175,14 @@ export default { const params = { resource_id: this.resourceId, student_id: this.resourceId, // 添加student_id字段 - age: 18, // 临时设置默认年龄,实际应该从学生信息获取 test_date: this.recordData.test_date, height: this.recordData.height, weight: this.recordData.weight, - pdf_files: this.recordData.pdf_files, - // 处理PDF文件路径 - physical_test_report: this.recordData.pdf_files.map(file => file.server_path || file.url).filter(path => path) + // 将PDF文件转换为服务器需要的格式 + physical_test_report: this.recordData.pdf_files + .map(file => file.server_path || file.url) + .filter(path => path) + .join(',') // 用逗号连接多个文件路径 } if (this.isEditing) { diff --git a/uniapp/pages.json b/uniapp/pages.json index 94513de1..b4caec6b 100644 --- a/uniapp/pages.json +++ b/uniapp/pages.json @@ -180,6 +180,15 @@ "navigationBarTextStyle": "white" } }, + { + "path": "pages/student/child/add", + "style": { + "navigationBarTitleText": "添加孩子", + "navigationStyle": "custom", + "navigationBarBackgroundColor": "#29d3b4", + "navigationBarTextStyle": "white" + } + }, { "path": "pages/common/privacy_agreement", "style": { diff --git a/uniapp/pages/common/feedback.vue b/uniapp/pages/common/feedback.vue index c66557d5..706463ab 100644 --- a/uniapp/pages/common/feedback.vue +++ b/uniapp/pages/common/feedback.vue @@ -123,10 +123,6 @@ title:'提交成功', icon:'none' }) - //延迟1s执行 - setTimeout(() => { - this.$util.openHomeView(); - }, 1000); } }, diff --git a/uniapp/pages/common/my_message.vue b/uniapp/pages/common/my_message.vue index 58c0f01c..6bb9b21c 100644 --- a/uniapp/pages/common/my_message.vue +++ b/uniapp/pages/common/my_message.vue @@ -238,10 +238,6 @@ export default { title: '提交成功', icon: 'none' }) - //延迟1s执行 - setTimeout(() => { - this.$util.openHomeView(); - }, 1000); } }, diff --git a/uniapp/pages/market/clue/clue_info.vue b/uniapp/pages/market/clue/clue_info.vue index 38b37ee6..ffaad38c 100644 --- a/uniapp/pages/market/clue/clue_info.vue +++ b/uniapp/pages/market/clue/clue_info.vue @@ -761,7 +761,8 @@ export default { }) if (res.code === 1 && res.data) { - this.fitnessRecords = res.data.data || [] + // 处理体测记录数据,转换PDF文件格式 + this.fitnessRecords = this.processFitnessRecords(res.data.data || []) } else { console.warn('获取体测记录失败:', res.msg) this.fitnessRecords = [] @@ -772,13 +773,83 @@ export default { } }, + // 处理体测记录数据,转换PDF文件格式 + processFitnessRecords(records) { + if (!records || !Array.isArray(records)) return [] + + return records.map(record => { + const processedRecord = { + ...record, + test_date: record.created_at ? record.created_at.split(' ')[0] : '', // 从created_at提取日期 + pdf_files: [] + } + + // 处理PDF文件 + if (record.physical_test_report) { + // 如果physical_test_report是字符串路径 + if (typeof record.physical_test_report === 'string') { + const pdfPaths = record.physical_test_report.split(',').filter(path => path.trim()) + processedRecord.pdf_files = pdfPaths.map((path, index) => ({ + id: `${record.id}_${index}`, + name: this.extractFileName(path) || `体测报告_${index + 1}.pdf`, + size: 0, // 无法从路径获取大小 + url: this.getFullPdfUrl(path), + server_path: path.trim(), + upload_time: record.created_at || '' + })) + } + // 如果physical_test_report已经是数组格式 + else if (Array.isArray(record.physical_test_report)) { + processedRecord.pdf_files = record.physical_test_report + } + } + + return processedRecord + }) + }, + + // 从文件路径提取文件名 + extractFileName(filePath) { + if (!filePath) return '' + const parts = filePath.split('/') + return parts[parts.length - 1] || '' + }, + + // 获取完整的PDF文件URL + getFullPdfUrl(relativePath) { + if (!relativePath) return '' + + // 如果已经是完整URL,直接返回 + if (relativePath.startsWith('http://') || relativePath.startsWith('https://')) { + return relativePath + } + + // 构建完整的URL + const { img_domian } = require('@/common/config.js') + + // 处理相对路径 + let cleanPath = relativePath + if (cleanPath.startsWith('./')) { + cleanPath = cleanPath.substring(2) + } + if (cleanPath.startsWith('/')) { + cleanPath = cleanPath.substring(1) + } + + return `${img_domian}${cleanPath}` + }, openAddFitnessRecord() { this.$refs.fitnessRecordPopup.openAdd() }, openEditFitnessRecord(record) { - this.$refs.fitnessRecordPopup.openEdit(record) + // 确保记录包含正确格式的PDF文件信息 + const processedRecord = { + ...record, + pdf_files: record.pdf_files || [] // 使用已处理的pdf_files数据 + } + this.$refs.fitnessRecordPopup.openEdit(processedRecord) }, async handleFitnessRecordConfirm(result) { diff --git a/uniapp/pages/student/home/index.vue b/uniapp/pages/student/home/index.vue index 5374fe11..6071cded 100644 --- a/uniapp/pages/student/home/index.vue +++ b/uniapp/pages/student/home/index.vue @@ -162,6 +162,14 @@ + + + + + @@ -419,6 +427,14 @@ }) }, + navigateToAddChild() { + console.log('跳转到添加孩子页面') + this.closeStudentPopup() + uni.navigateTo({ + url: '/pages/student/child/add' + }) + }, + checkStudentSelected() { if (!this.selectedStudent) { uni.showToast({ @@ -682,6 +698,7 @@ justify-content: center; align-items: center; z-index: 1000; + animation: fadeIn 0.3s ease-out; .popup_content { background: #fff; @@ -689,6 +706,8 @@ width: 80%; max-height: 60vh; overflow: hidden; + animation: slideUp 0.3s ease-out; + box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.1); .popup_header { display: flex; @@ -768,6 +787,56 @@ } } } + + .popup_footer { + padding: 32rpx; + border-top: 1px solid #f0f0f0; + + .add_child_button { + width: 100%; + background: linear-gradient(135deg, #29D3B4 0%, #1BA297 100%); + color: #fff; + border: none; + border-radius: 16rpx; + padding: 24rpx 0; + font-size: 28rpx; + font-weight: 600; + display: flex; + align-items: center; + justify-content: center; + gap: 12rpx; + + .add_icon { + width: 24rpx; + height: 24rpx; + } + + &:active { + opacity: 0.8; + } + } + } + } +} + +// 动画定义 +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes slideUp { + from { + transform: translateY(100rpx); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; } } \ No newline at end of file diff --git a/uniapp/pages/student/physical-test/index.vue b/uniapp/pages/student/physical-test/index.vue index f77b4555..b827279d 100644 --- a/uniapp/pages/student/physical-test/index.vue +++ b/uniapp/pages/student/physical-test/index.vue @@ -3,13 +3,15 @@ - - - - 体测数据 - - @@ -20,8 +22,6 @@ {{ studentInfo.gender_text }} {{ studentInfo.age }}岁 - 身高: {{ studentInfo.height }}cm - 体重: {{ studentInfo.weight }}kg @@ -31,27 +31,13 @@ {{ physicalTestList.length }} 测试次数 - - {{ latestScore || 0 }} - 最新得分 + + {{ latestTest.height }}cm + 最新身高 - - {{ improvementRate }}% - 提升率 - - - - - - - - {{ tab.text }} - + + {{ latestTest.weight }}kg + 最新体重 @@ -61,7 +47,7 @@ 加载中... - + 📊 暂无体测数据 完成体测后数据会在这里显示 @@ -69,34 +55,50 @@ - {{ formatDate(test.test_date) }} - - {{ test.total_score }}分 - + {{ formatDate(test.created_at) }} + 体测记录 - - - {{ item.project_name }} - - {{ item.test_value }}{{ item.unit }} - {{ item.score }}分 + + + + 身高 + {{ test.height || '-' }}cm + + + 体重 + {{ test.weight || '-' }}kg + + + + + + 体测报告 + + + + + + + 体测报告{{ index + 1 }} + 点击预览 + + + + + - - - - 备注:{{ test.remark }} @@ -104,20 +106,47 @@ - + + + + + + + + 体测报告预览 + × + + + + 加载中... + + + + + + 预览失败 + + + + + + +