# 课程安排学员显示修复说明 ## 🔍 **问题描述** 在 `pages/market/clue/class_arrangement` 页面中,调用 `/api/course/courseAllList?schedule_date=2025-08-01` 接口时,课程安排中的学员信息显示不正确: - 应该显示一个正式学员和一个等待位学员 - 实际只显示了一个学员,另一个学员没有在列表中显示 ## 📊 **数据库分析** ### 1. **课程安排数据** ```sql SELECT id, course_date, time_slot FROM school_course_schedule WHERE course_date = '2025-08-01'; -- 结果: -- id=124, course_date='2025-08-01', time_slot='09:00-10:00' -- id=154, course_date='2025-08-01', time_slot='10:00-11:00' ``` ### 2. **学员安排数据** ```sql SELECT pcs.*, cr.name FROM school_person_course_schedule pcs LEFT JOIN school_customer_resources cr ON pcs.resources_id = cr.id WHERE pcs.schedule_id = 124; -- 结果: -- id=73, resources_id=5, schedule_type=1, course_type=1, name='测试' (正式学员) -- id=74, resources_id=31, schedule_type=2, course_type=3, name='美团01' (等待位学员) ``` ### 3. **关联数据问题** ```sql SELECT cr.id, cr.name, cr.member_id, sm.member_id, sm.headimg FROM school_customer_resources cr LEFT JOIN school_member sm ON cr.member_id = sm.member_id WHERE cr.id IN (5, 31); -- 结果: -- id=5, name='测试', member_id=2, sm.member_id=2, headimg='...' ✅ -- id=31, name='美团01', member_id=0, sm.member_id=NULL, headimg=NULL ❌ ``` **问题根源**:`美团01` 的 `member_id` 为 0,在 JOIN `school_member` 表时没有匹配到数据,导致整条记录被过滤掉。 ## 🔧 **修复方案** ### **原始代码问题** ```php // CourseService.php 第398-407行(修复前) $student = Db::name('person_course_schedule') ->alias('pcs') ->where('pcs.schedule_id', $v['id']) ->join('school_student st', 'pcs.student_id = st.id') // ❌ student_id为NULL ->join('school_customer_resources cr', 'st.user_id = cr.id') ->join('school_member sm', 'cr.member_id = sm.member_id') // ❌ INNER JOIN过滤掉member_id=0的记录 ->field('st.name, sm.headimg as avatar') ->select(); ``` ### **修复后代码** ```php // CourseService.php 第397-407行(修复后) $student = Db::name('person_course_schedule') ->alias('pcs') ->where('pcs.schedule_id', $v['id']) ->leftJoin('school_customer_resources cr', 'pcs.resources_id = cr.id') // ✅ 使用resources_id ->leftJoin('school_member sm', 'cr.member_id = sm.member_id AND cr.member_id > 0') // ✅ LEFT JOIN + 条件 ->field('cr.name, COALESCE(sm.headimg, "") as avatar, pcs.schedule_type, pcs.course_type, pcs.status') ->select(); ``` ## 🎯 **修复要点** ### 1. **字段关联修复** - **原来**:通过 `pcs.student_id = st.id` 关联(但 student_id 为 NULL) - **修复**:通过 `pcs.resources_id = cr.id` 关联(正确的关联字段) ### 2. **JOIN类型修复** - **原来**:使用 `join()` (INNER JOIN),过滤掉不匹配的记录 - **修复**:使用 `leftJoin()` (LEFT JOIN),保留所有记录 ### 3. **member_id处理** - **原来**:`cr.member_id = sm.member_id` 直接关联 - **修复**:`cr.member_id = sm.member_id AND cr.member_id > 0` 条件关联 ### 4. **字段处理** - **原来**:`sm.headimg as avatar` - **修复**:`COALESCE(sm.headimg, "") as avatar` 处理NULL值 ### 5. **增加字段** - 添加 `pcs.schedule_type`:区分正式位(1)和等待位(2) - 添加 `pcs.course_type`:区分正式课(1)、体验课(2)、等待位(3) - 添加 `pcs.status`:学员状态信息 ## 📋 **测试结果** ### **修复前** ```json { "student": [ { "name": "测试", "avatar": "https://...", "schedule_type": 1, "course_type": 1, "status": 0 } // 缺少"美团01"学员 ] } ``` ### **修复后** ```json { "student": [ { "name": "测试", "avatar": "https://...", "schedule_type": 1, "course_type": 1, "status": 0 }, { "name": "美团01", "avatar": "", "schedule_type": 2, "course_type": 3, "status": 0 } ] } ``` ## 🔍 **数据字段说明** ### **schedule_type 字段** - `1` - 正式位 - `2` - 等待位 ### **course_type 字段** - `1` - 正式课 - `2` - 体验课 - `3` - 等待位 ### **status 字段** - `0` - 正常 - `1` - 已取消 - `2` - 已完成 ## 🎯 **技术总结** ### **问题类型** 1. **数据关联错误**:使用了错误的关联字段 2. **JOIN类型错误**:INNER JOIN 过滤掉了部分数据 3. **数据完整性问题**:member_id 为 0 的记录处理不当 ### **修复原则** 1. **使用正确的关联字段**:resources_id 而不是 student_id 2. **使用LEFT JOIN**:保证所有学员记录都能显示 3. **处理NULL值**:使用 COALESCE 处理可能的空值 4. **增加业务字段**:提供更多有用的业务信息 ### **最佳实践** 1. **数据库设计**:确保关联字段的一致性 2. **查询优化**:根据实际数据结构选择合适的JOIN类型 3. **异常处理**:考虑数据不完整的情况 4. **字段完整性**:提供前端需要的所有业务字段 --- **修复完成时间**:2025-07-31 **状态**:✅ 问题已修复,学员显示正常 **影响范围**:课程安排页面的学员列表显示