3.10 学习-侧边导航

第 30 节 / 共 46 节 课程:ThinkPHP
顶部菜单中的学习
首先发起一个post请求chapters,发送的参数为courseId以及一个标记参数all。
在统计的时候,已经有一个chapters请求,当时是查找所有章节,然后用作下拉菜单,并不需要做子章节,而这个all就是标记,如果这个值不为空,那么按这一节的要求做子章节(有subChapters)
返回的json将填满左侧的章节导航,json结构如下:
{
    "code": "200",
    "info": "31",
    "data": [
        {
            "score": 0,
            "code": "010000",
            "parentCode": "000000",
            "serial": "第1章",
            "name": "ThinkPHP介绍",
            "subChapters": [
                {
                    "score": 0,
                    "code": "010100",
                    "parentCode": "010000",
                    "serial": "1.1  ",
                    "name": "配置环境",
                    "id": "771"
                },
                {
                    "score": 0,
                    "code": "010200",
                    "parentCode": "010000",
                    "serial": "1.2  ",
                    "name": "第一个ThinkPHP项目",
                    "id": "772"
                },
                {
                    "score": 0,
                    "code": "010300",
                    "parentCode": "010000",
                    "serial": "1.3  ",
                    "name": "启动项目",
                    "id": "783"
                },
                {
                    "score": 0,
                    "code": "010400",
                    "parentCode": "010000",
                    "serial": "1.4  ",
                    "name": "项目部署",
                    "id": "792"
                }
            ],
            "id": "765"
        },
        {
            "score": 175,
            "code": "020000",
            "parentCode": "000000",
            "serial": "第2章",
            "name": "基本特性",
            "subChapters": [略...],
        }
        //其余部分略
    ]
}
这里的难点在于子章节,除了从数据库里找到章节数据外,还要从code值再去查一次数据库,看有没有子章节,有的话把数据绑定到subChapters下,下面是实现的PHP代码:
use think\facade\Db;
$chapterList=Db::table('chapter')
-> where('course_id',$courseId)
-> where('code','like','__0000')
-> select();
$data=[];
foreach($chapterList as $cha){
    $obj=[
    'score'=> $cha['score'],
    'code'=> $cha['code'],
    'parentCode'=> $cha['parent_code'],
    'name'=> $cha['name'],
    'id'=> $cha['id'],
    ];
    //获取子章节(只处理一层,如懂递归可改为递归实现)
    $subChapters=Db::table('chapter')
    -> where('course_id',$courseId)
    -> where('parent_code',$cha['code'])
    -> select();
     if(count($subChapters) > 0){
        $obj['subChapters']=[];
        foreach($subChapters as $c){
            $obj['subChapters'][]=[
            'score'=> $c['score'],
            'code'=> $c['code'],
            'name'=> $c['name'],
            'id'=> $c['id'],
            ];
        }
    }
    $data[]=$obj;
}
return $this-> success($data,(string)$courseId);
至于serial这个属性,也就是显示"第1章"、"1.2"等值,它是根据code值计算出来的:
function getChapterSerial($code)
{
     if(empty($code))
        return '';
    $m1=intval(substr($code,0,2));
    $m2=intval(substr($code,2,2));
    $m3=intval(substr($code,4,2));
    //主章节:返回"第1章"形式
     if($m2==0 && $m3==0){
        $chinese=['','一','二','三','四','五','六','七','八','九','十',
        '十一','十二','十三','十四','十五','十六','十七','十八','十九','二十'];
        return '第'.($chinese[$m1]?? $m1).'章';
    }
    //子章节:返回"1.2"形式
     if($m3==0){
        return "$m1.$m2 ";
    }
    return "$m1.$m2.$m3 ";
}
尝试完成学习页面的左边栏