ThinkPHP5实现答题管理系统(四)

简介: 我们之前三篇文章实现了模板+题目+选项的增删,现在我们要完成答题管理系统的答题模块啦。一.UI及功能设计既然是用户答题,就要有一张表专门用来存放用户答题的答案。

我们之前三篇文章实现了模板+题目+选项的增删,现在我们要完成答题管理系统的答题模块啦。

一.UI及功能设计

既然是用户答题,就要有一张表专门用来存放用户答题的答案。我的设想是这样的,我们点击答题按钮的时候,就显示出第一题,判断是否是模板下最后一题,来显示名为next按钮的字体样式为下一题还是完成。并且,对后台传过来的qsn_type进行区分,type=0的单选显示单选框,type=1的多选显示复选框,type=2的问答显示文本域,大概是如下效果。


img_0ef63710915e0d17bfdf46984071686b.png
单选.PNG
img_929c5816fb637e07eb884db96303b0d1.png
多选.PNG
img_e1b5477d60311455c1cb3ddb4540307e.png
问答.PNG

为此,next按钮要返回的json格式数据如下。


img_baecd6e6867e4277411940c82e15be90.png
构建json.PNG

用PHP构造一个二维关联数组,其中二维数组中,还有一个二维数组,第一索引表示题目的order_num排序,第二索引表示option_num选项内容以及order_num选项排序号,最后将这个内层二维数组与别的参数使用PHP的array_merge函数进行数组合并,返回给html页面。

二.数据库表设计(psg_qsn_r表)

img_19e69f53814d4b3cee5d11c062c29265.png
psg_qsn_r表.PNG

主要的就是choose对应用户选择的选项,1,2,3...对应A,B,C,如果是问答,存的就是一串字符串。

三.代码实现

首先是answer答题按钮的点击监听:

 $('#btn-answer').click(function() {
                // alert(id_array);
                layer.msg('加载中', {
                    icon: 16,
                    shade: 0.01,
                    time: '9999999'
                });
                var url = "{:url('survey/answer_list')}";
                var data = {
                    model_id: id_array //这里将当前的model_id数组传到后端
                }
                $.post(url, data, function(data) {
                    layer.close(layer.index); //关闭正在加载中弹出层
                    console.log(id_array);
                    if (data.code == 1) {
                        // alert(data.data[0].option_num);
                        if (data.data.bool_num == true) {
                            $('#next').text("完成");
                        }
                        $('#set-answer label[name="qsn_content1"]').css("width", "200px");
                        $('#set-answer label[name="qsn_content1"]').text(data.data.content);
                        if (data.data.qsn_type == 1) {
                            $.each(data.data, function(i, item) {
                                if (item.order_num == null) return false; //function中无法用break跳出 我们用return
                                //这边要将type也传过来 然后根据type来往anser_list中添加值

                                $('#answer_list').append(
                                    // ' <br/><label class="layui-form-label">' + item.order_num + ':</label>' +
                                    '<div class ="layui-input-block"><input type="checkbox" lay-skin="primary" name="checkbox[]" value="' + item.order_num + '" title="' + letter[item.order_num - 1] + ' : ' + item.option_num + '"></div>'

                                )
                            });
                            form.render('checkbox');
                        } else if (data.data.qsn_type == 0) {
                            $.each(data.data, function(i, item) {
                                if (item.order_num == null) return false; //function中无法用break跳出 我们用return
                                //这边要将type也传过来 然后根据type来往anser_list中添加值

                                $('#answer_list').append(
                                    // ' <br/><label class="layui-form-label">' + item.order_num + ':</label>' +
                                    '<div class ="layui-input-block"><input type="radio" lay-skin="primary" name="checkbox[]" value="' + item.order_num + '" title="' + letter[item.order_num - 1] + ' : ' + item.option_num + '"></div>'
                                )
                            });
                            form.render('radio');
                        } else if (data.data.qsn_type == 2) {

                            // if (item.order_num == null) return false; //function中无法用break跳出 我们用return
                            //这边要将type也传过来 然后根据type来往anser_list中添加值

                            $('#answer_list').append(
                                // ' <br/><label class="layui-form-label">' + item.order_num + ':</label>' +
                                ' <div class ="layui-input-block"><textarea name="text" id="text" required lay-verify="required" placeholder="请输入" class="layui-textarea"></textarea>'
                            )
                            form.render();

                        }



                        // alert(data.data.order_num);
                        getqsn_type(data.data.qsn_type);
                        getmodel_id(data.data.model_id);
                        getorder_num(data.data.order_num);
                        layer.open({
                            type: 1,
                            skin: 'layui-layer-rim', //加上边框
                            area: ['660px', '350px'], //宽高
                            content: $('#set-answer'),
                            cancel: function(index, layero) {
                                $('#answer_list').empty();
                                $('#next').text("下一题");
                                layer.close(index)
                                return false;
                            },
                            end: function() {
                                $('#answer_list').empty();
                                $('#next').text("下一题");
                                layer.closeAll();
                            }
                        });
                    } else {
                        layer.msg(data.msg, {
                            icon: 5
                        });
                    }
                }, "json");

            });

其中有对问题类型进行判别,并且对next样式作更改,然后是其对应的Controller层:

 public function answer_list()
    {//答题的首次加载
            $model_id = input('post.model_id/a'); //tp5提交数组用/a来实现
            if (empty($model_id)) {
                returnjson([3, '请选择模板答题', '']);
            }
        $str_device_id = implode(',', $model_id); //数组拆分
        $where['model_id'] = array('in', $str_device_id);
        $qsn_list = db('qsn')->where($where)->order('order_num')->field('content,qsn_id,order_num,model_id,qsn_type')->select(); //获取问题内容
        if (empty($qsn_list)) {
            returnjson([2, '暂无题目,无法答题', '']);
        }
        $bool_num = false;
        $max_order_num = db('qsn')->where($where)->max('order_num');
        if ($qsn_list[0]['order_num'] == $max_order_num) {
            $bool_num = true;
        }
        // $where1['qsn_id']=$qsn_list[0]['qsn_id'];
            // // $qsn_list[0]['qsn_id存在
            $option_list = db('qsn_detail')->where('qsn_id', $qsn_list[0]['qsn_id'])->field('option_num,order_num')->select(); //获取选项以及选项排序

        //array_merge()合成两个数组
        if ($option_list) {
            $return_list = array_merge($qsn_list[0], $option_list);
            $return_list['bool_num'] = $bool_num;
            returnjson([1, 'success', $return_list]);
        } else {//那就不是选项了 是问答题
            $return_list = $qsn_list[0];
            $return_list['bool_num'] = $bool_num;
            returnjson([1, '问答题', $return_list]);
        }
    }

然后是View层next按钮的监听事件,跟这个差不多。

 $('#next').click(function() {
                var qsn_type = t_qsn_type;

                var is_answered = false;
                if (qsn_type == 1) {
                    var count = $("#set-answer input[type='checkbox']:checked").length
                    if (count == 0) {
                        is_answered = true;
                    }
                    $("#set-answer input[type='checkbox']:checked").each(function() {
                        choice.push($(this).val());
                    });
                } else if (qsn_type == 0) {
                    var count = $("#set-answer input[type='radio']:checked").length
                    if (count == 0) {
                        is_answered = true;
                    }
                    $("#set-answer input[type='radio']:checked").each(function() {
                        choice.push($(this).val());
                    });
                } else if (qsn_type == 2) {
                    var count = $("#set-answer #text").length
                    if (count == 0) {
                        is_answered = true;
                    }
                    $("#set-answer #text").each(function() {
                        choice.push($(this).val());
                    });
                }
                if (is_answered == true) {
                    layer.msg('请选择答案');
                    return;
                }
                alert(choice);
                layer.msg('加载中', {
                    icon: 16,
                    shade: 0.01,
                    time: '9999999'
                });
                alert(choice);
                var url = "{:url('survey/next_qsn')}";
                var t_choice = choice;
                var model_id = t_model_id;
                var order_num = t_order_num;
                var data = {
                    model_id: model_id,
                    order_num: order_num,
                    choice: t_choice,
                    qsn_type: qsn_type
                }
                $.post(url, data, function(data) {
                    layer.close(layer.index); //关闭正在加载中弹出层
                    form.render(null, 'answer');
                    choice = [];
                    console.log(id_array);
                    if (data.code == 1) {
                        if (data.data.bool_num == true) {
                            $('#next').text("完成");
                        }
                        // alert(data.data[0].option_num);
                        $('#answer_list').empty();
                        $('#set-answer label[name="qsn_content1"]').text(data.data.content);
                        // alert(data.data.order_num);
                        if (data.data.qsn_type == 1) {
                            $.each(data.data, function(i, item) {
                                if (item.order_num == null) return false; //function中无法用break跳出 我们用return
                                $('#answer_list').append(
                                    // ' <br/><label class="layui-form-label">' + item.order_num + ':</label>' +
                                    '<div class ="layui-input-block"><input type="checkbox" lay-skin="primary" name="sex" value="' + item.order_num + '" title="' + letter[item.order_num - 1] + ' : ' + item.option_num + '"></div>'

                                )


                            });
                            form.render('checkbox');
                        } else if (data.data.qsn_type == 0) {
                            $.each(data.data, function(i, item) {
                                if (item.order_num == null) return false; //function中无法用break跳出 我们用return
                                //这边要将type也传过来 然后根据type来往anser_list中添加值

                                $('#answer_list').append(
                                    // ' <br/><label class="layui-form-label">' + item.order_num + ':</label>' +
                                    '<div class ="layui-input-block"><input type="radio" lay-skin="primary" name="checkbox[]" value="' + item.order_num + '" title="' + letter[item.order_num - 1] + ' : ' + item.option_num + '"></div>'
                                )
                            });
                            form.render('radio');
                        } else if (data.data.qsn_type == 2) {
                            $('#answer_list').append(
                                // ' <br/><label class="layui-form-label">' + item.order_num + ':</label>' +
                                ' <div class ="layui-input-block"><textarea name="text" id="text"  lay-verify="required" placeholder="请输入" class="layui-textarea"></textarea>'
                            )
                            form.render();

                        }
                        getqsn_type(data.data.qsn_type);
                        getmodel_id(data.data.model_id);
                        getorder_num(data.data.order_num);

                    } else if (data.code == 2) {
                        layer.msg(data.msg, {
                            icon: 6
                        });
                        setTimeout('layer.closeAll()', 2000);
                    } else if (data.code == 3) {
                        layer.msg(data.msg, {
                            icon: 5
                        });
                    }
                }, "json");

然后是Controller层代码。

 //找出同一套模板下的order_num+1的题目
    public function next_qsn()
    {
        $model_id = input('post.model_id');
        $order_num = input('post.order_num');
        $choice = input('post.choice/a');
        $count_choice = count($choice);
        $str_choice1 = implode('', $choice);
        if (empty($str_choice1)) {
            returnjson([3, '请答题', $choice]);
        }
        $qsn_type = (int) input('post.qsn_type');
        $order_num = (int) $order_num;
        $qsn_list = db('qsn')->where('model_id', $model_id)->where('order_num', $order_num)->field('content,qsn_id,order_num,model_id,flight_id,qsn_type')->find(); //获取问题内容
        $psg_list['qsn_id'] = $qsn_list['qsn_id'];
        $psg_list['model_id'] = $qsn_list['model_id'];
        $psg_list['flight_id'] = $qsn_list['flight_id'];
        $psg_list['qsn_type'] = $qsn_list['qsn_type'];
        //这里要改,这里的detailID不是随机生成的 而是读取出对应题目的detail_id
        $option_list = db('qsn_detail')->where('qsn_id', $qsn_list['qsn_id'])->field('detail_id')->select();//这里是二维数组
        //这里的detail ID和date就随机生成了
        //这里 我们应该count出option_list数组的长度,然后循环赋给psg_list中的detail_id,保证psg_qsn表中的detailID唯一
        // returnjson([2, '恭喜您完成了答题', $option_list]);
       

        $str_choice = implode(',', $choice);
        for ($x = 0; $x < $count_choice; $x++) {
            $psg_list['detail_id'] = $option_list[$x]['detail_id'];
            $psg_list['psg_qsn_r_id'] = uniqid('psg_qsn_r_id', true);
            $psg_list['choose'] = $choice[$x];
            $psg_res = db('psg_qsn_r')->insert($psg_list);
        }
        //先要将当前问题插入psg_qsn表中 所以我们要先判断 然后看看能否插入psg_qsn表 否则对应的字段就是下一个的字段
        $order_num = $order_num + 1;
        //只查询一个数据 用find 否则返回的数据就是二维数组
        $qsn_list = db('qsn')->where('model_id', $model_id)->where('order_num', $order_num)->field('content,qsn_id,order_num,model_id,flight_id,qsn_type')->find(); //获取问题内容
         $bool_num = false;
        $max_order_num = db('qsn')->where('model_id', $model_id)->max('order_num');
        if ($qsn_list['order_num'] == $max_order_num) {
            $bool_num = true;
        }
        if (empty($qsn_list)) {
            returnjson([2, '恭喜您完成了答题', $choice]);
        }

        //qsn_list已经是一个数组了
        $option_list = db('qsn_detail')->where('qsn_id', $qsn_list['qsn_id'])->field('option_num,order_num')->select();

        //一个bool_num来判单是否是最后一题
        //
        if ($option_list) {
            $return_list = array_merge($qsn_list, $option_list);
            $return_list['bool_num'] = $bool_num;
            returnjson([1, 'success', $return_list]);
        } else {//是文本域
            $return_list = $qsn_list;
            $return_list['bool_num'] = $bool_num;
            returnjson([1, '问答', $return_list]);
        }
    }

然后我们看看最终的效果。

四.效果一览

img_72b78d34dcb0c6fa71bedcbacc6ed20f.gif
1.gif

OK,完成啦

相关文章
|
3月前
|
小程序 前端开发
微信小程序商城,微信小程序微店 【毕业设计参考项目】
文章推荐了一个微信小程序商城项目作为毕业设计参考,该项目在Github上获得18.2k星,提供了详细的使用教程和前端页面实现,适合学习微信小程序开发和作为毕业设计项目。
微信小程序商城,微信小程序微店 【毕业设计参考项目】
|
5月前
|
PHP
Thinkphp校园新闻发布系统源码 毕业设计项目实例
Thinkphp校园新闻发布系统源码 毕业设计项目实例
46 6
|
5月前
基于thinkphp5的书店管理系统学习笔记分享
基于thinkphp5的书店管理系统学习笔记分享
19 0
|
6月前
|
小程序 JavaScript Java
商城|商城小程序|基于微信小程序的智慧商城系统设计与实现(源码+数据库+文档)
商城|商城小程序|基于微信小程序的智慧商城系统设计与实现(源码+数据库+文档)
140 1
|
6月前
|
JavaScript 小程序 Java
订餐|网上订餐系统|基于springboot的网上订餐系统设计与实现(源码+数据库+文档)
订餐|网上订餐系统|基于springboot的网上订餐系统设计与实现(源码+数据库+文档)
161 0
|
6月前
|
安全 JavaScript Java
爱心商城|爱心商城系统|基于Springboot的爱心商城系统设计与实现(源码+数据库+文档)
爱心商城|爱心商城系统|基于Springboot的爱心商城系统设计与实现(源码+数据库+文档)
46 0
|
6月前
|
小程序 JavaScript 前端开发
点餐小程序实战教程06-首页开发
点餐小程序实战教程06-首页开发
|
6月前
|
安全 关系型数据库 PHP
网上书城|基于PHP实现网上书店商城藉项目
网上书城|基于PHP实现网上书店商城藉项目
|
6月前
|
关系型数据库 MySQL 应用服务中间件
javaweb网上宠物商城管理系统分前后台(源码+数据库+开题报告+ppt+文档)
javaweb网上宠物商城管理系统分前后台(源码+数据库+开题报告+ppt+文档)
|
6月前
|
前端开发 Java 应用服务中间件
基于JavaWeb实现网上花店商城系统
基于JavaWeb实现网上花店商城系统
112 0