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

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

一.UI及功能设计

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


单选.PNG
多选.PNG
问答.PNG

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


构建json.PNG

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

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

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]);
        }
    }

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

四.效果一览

1.gif

OK,完成啦

项目仅供测试学习使用,拒绝任何形式的商业用途,转侵删。
项目源码关注公众号Code In Java,回复"答题管理系统ThinkPHP版本"即可获取。除此之外,还有Java学习图谱,数据结构与算法资料等各种资料都可以在后台获取。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容