3.8 *主页信息
第 28 节 / 共 46 节
课程:ThinkPHP
获取主页的右下角的错题信息:

首先修改前段的bug,在src/views/Home.vue文件,第149行代码:

改成:
let t=response.data.data;进入主页后,前端会自动发起一个get请求,发送参数username和courseId到main,然后后台将发回的json结构如下:
{ "code": "200", "info": "", "data": { "cqcList": [ { "chapterQuizStudyId": "41832", "score": 0, "datetime": "2025-03-01 21:52:53", "stat": "3", "teacherId": "system", "comment": "错误", "chapterQuizStudy": { "chapterQuiz": { "chapter": Object{...}, "code": "", "codeLang": "PHP", "title": "PHP是Web开发语言,可以动态生成网页内容", "subjectType": { "name": "判断", "id": "5" }, "content": "", "valid": "1", "score": 2, "instruments": "", "answer": "true", "chapterId": "187", "hint": "", "typeId": "5", "id": "30", "keyword": "php", "queue": 1 }, "studentId": "abc", "stat": "0", "answer": "false", "quizId": "30", "startTime": "2025-03-01 14:35:31", "endTime": "2025-03-01 14:36:07", "id": "41832", "user": { "role": "9", "isValid": "1", "nickname": "PHP", "createDate": "2020-09-16 16:44:32", "username": "abc" } }, "id": "28430", "user": { "role": "1", "isValid": "1", "nickname": "系统", "createDate": "2018-04-03", "username": "system" } }, //这些Object是其他错题,省略 Object{...}, Object{...}, Object{...}, Object{...} ], "courseName": "PHP程序设计", "code": "010200", "chapterName": "1.2 PHP编程环境", "courseId": "1", "percent": "0.6666666666666666" }}data部分的cqcList,实际上查询的表格是chapterQuizCorrect,这个表表示批改表,与之紧密关联的表示chapterQuizStudy,表示学生做题表,ChapterQuiz则是练习题表,最后,ChapterQuiz关联了Chapter表这四个表数据库设置了外键关联。以下表都要创建模型:
| 模型类 | 说明 |
|---|---|
| Chapter | 保存章节的表,章节的标题,内容 |
| ChapterQuiz | 保存练习题的表,里面有一个Chapter的外键,记录题目是哪个章节的 |
| ChapterQuizStudy | 学员完成一道练习题的记录,里面有一个chapterQuiz的外键,记录答题对应的练习 |
| ChapterQuizCorrect | 系统批改一道学员答题的记录,里面有一个chapterQuizStudy的外键,记录本次批改对应的答题 |
| SubjectType | 记录练习题类型,ChapterQuiz只记录一个数字id,id对于的文字在这个表里面 |
外键关联的表格,在ThinkPHP8中通过模型来映射关联关系,例如下面的ChapterQuiz模型,除了chapter_id字段外,还通过belongsTo定义了与Chapter模型的关联:
<?php
namespace app\model;
use think\Model;
class ChapterQuiz extends Model
{
// 关联表名(默认自动匹配,此处显式指定)
protected $table = 'chapter_quiz';
// 关联Chapter
public function chapter()
{
return $this->belongsTo(Chapter::class, 'chapter_id', 'id');
}
// 关联SubjectType
public function subjectType()
{
return $this->belongsTo(SubjectType::class, 'type_id', 'id');
}
// 关联答题记录(一对多)
public function chapterQuizStudies()
{
return $this->hasMany(ChapterQuizStudy::class, 'quiz_id', 'id');
}
}对比下面的chapter_quiz表格的结构,可以看到每个数据库的字段都有一个属性对应,但是这里要注意:第10行代码,chapterId已经映射了chapter_id,通过模型关联方法chapter()可以自动关联查询Chapter表数据。这就是ThinkPHP模型关联的便利之处,查询ChapterQuiz时,可以同时获取关联的Chapter信息。

现在再回头去看看上面的json:

对此,我们不需要做什么,直接查询就能得到关联的表的信息,下面这个查询是本章节最核心的查询,根据用户名和课程id查询练习批改信息的函数,它应该在哪个模型里面?
// 使用模型关联查询(在ChapterQuizCorrect模型中定义)$list = ChapterQuizCorrect::whereHas('chapterQuizStudy.student', function ($q) use ($username) { $q->where('username', $username);})->where('comment', '<>', '') ->whereHas('chapterQuizStudy.chapterQuiz.chapter.course', function ($q) use ($courseId) { $q->where('id', $courseId); }) ->order('datetime', 'desc') ->select();《ThinkPHP》课程目录
介绍PHP框架ThinkPHP6
- 第1章 配置环境
- 1.1 第一个ThinkPHP8项目
- 1.2 Composer项目结构介绍
- 1.3 启动项目
- 1.4 ThinkPHP8项目的部署
- 1.5 idea教育版免费一年获取办法
- 第2章 基本特性
- 2.1 响应HTTP请求
- 2.2 响应html
- 2.3 登录-前端
- 2.4 登录-后台
- 2.5 数据库基本操作
- 2.6 模型支持
- 2.7 登录状态和session
- 2.8 注册
- 2.9 主页文章列表
- 2.10 单篇文章内容
- 2.11 完善文章页面
- 2.12 文件上传
- 第3章 实训
- 3.1 项目准备
- 3.2 登录
- 3.3 数据库登录和json规范返回
- 3.4 注册
- 3.5 查询课程
- 3.6 个人信息
- 3.7 修改昵称
- 3.8 *主页信息
- 3.9 统计
- 3.10 学习-侧边导航
- 3.11 *学习-右边内容
- 3.12 管理-课程
- 3.13 管理-班级
- 3.14 管理-班级-学生换班
- 3.15 管理-班级-查找学生
- 第4章 git代码管理
- 4.1 建立代码库
- 4.2 代码管理提交、推送和拉取
- 4.3 从云克隆代码
- 第5章 项目重构成spirngboot
- 5.1 项目技术介绍
- 5.2 创建一个ThinkPHP8项目
- 5.4 移入网页和PHP代码
- 5.5 模型和服务
- 5.7 测试
- 第6章 nginx