AnswerAnalysisController.class.php 12.7 KB
<?php
/**
 * 【考试中心-后台】试题分析答案人数分布接口
 * AnswerAnalysisController.class.php
 * @author : wanghuan
 * @date   : 2017-07-18
 * @version: $Id$
 */

namespace Apicp\Controller\Topic;

use Common\Service\TopicService;
use Common\Service\PaperService;
use Common\Service\SnapshotService;
use Common\Service\AnswerService;
use Common\Service\AnswerDetailService;
use Common\Service\RandomSnapshotService;
use Common\Service\StatisticsService;

class AnswerAnalysisController extends AbstractController
{
    // 旧数据
    const OLD_DATA = 1;
    // 新数据
    const NEW_DATA = 2;

    /** @var PaperService */
    protected $paper_serv;
    /** @var SnapshotService */
    protected $snapshot_serv;
    /** @var AnswerService */
    protected $answer_serv;
    /** @var AnswerDetailService */
    protected $answer_detail_serv;
    /** @var RandomSnapshotService */
    protected $random_snapshot_serv;
    /** @var StatisticsService */
    protected $statistics_serv;

    public function before_action($action = '')
    {
        if (!parent::before_action($action)) {

            return false;
        }

        // 实例化试题service
        $this->paper_serv = new PaperService();
        // 实例化试题快照service
        $this->snapshot_serv = new SnapshotService();
        // 实例化答卷service
        $this->answer_serv = new AnswerService();
        // 实例化答卷详情service
        $this->answer_detail_serv = new AnswerDetailService();
        // 实例化随机试题快照service
        $this->random_snapshot_serv = new RandomSnapshotService();
        // 实例化题目统计service
        $this->statistics_serv = new StatisticsService();

        return true;
    }

    public function Index_post()
    {
        // 接收post参数
        $params = I('post.');
        // 参数为空,返回提示"参数不能为空"
        if (empty($params)) {

            E('_ERR_PARAMS_NOT_NULL');
        }

        // 试卷id
        $ep_id = intval($params['ep_id']);
        // 试卷id为空,返回提示"试卷ID不能为空"
        if (!$ep_id) {

            E('_EMPTY_EP_ID');
        }

        // 题目id
        $esr_id = intval($params['esr_id']);
        // 题目id为空,返回提示"题目ID不能为空"
        if (!$esr_id) {

            E('_EMPTY_ESR_ID');
        }

        // 根据试卷id获取试卷详情
        $paper = $this->paper_serv->get($ep_id);
        if (empty($paper)) {

            E('_ERR_PAPER_NOT_FOUND');
        }

        // 新老数据标识
        $is_old = $paper['is_old'];
        // 试卷类型:1=自主,2=规则,3=随机
        $ep_type = $paper['ep_type'];

        $options = [];
        $answer_list = [];
        $count = 0;
        $et_types = [
            TopicService::TOPIC_TYPE_SINGLE,
            TopicService::TOPIC_TYPE_JUDGMENT,
            TopicService::TOPIC_TYPE_MULTIPLE
        ];

        // 随机抽题
        if (PaperService::TOPIC_RANDOM == $ep_type) {


            // oa_exam_random_snapshot
            $random_conds = [
                'ep_id' => $ep_id,
                'er_id' => $esr_id
            ];
            $topic = $this->random_snapshot_serv->get_by_conds($random_conds);

            // 题目类型:1=单选,2=判断,3=问答,4=多选,5=语音
            $et_type = $topic['et_type'];
            $stat_conds = [
                'ep_id' => $ep_id,
                'esr_id' => $esr_id
            ];

            $statistics = $this->statistics_serv->get_by_conds($stat_conds);

            // 单选、判断、多选,统计各选项使用率
            if (in_array($et_type, $et_types)) {

                if (!empty($statistics)) {

                    $this->get_options($et_type, $topic, $statistics, $options);
                    $count = $statistics['answer_num'];
                }
            } else {
                $answer_list = $this->answer_serv->list_by_conds([
                    'ep_id' => $ep_id,
                    'answer_status' => AnswerService::READ_OVER
                ]);
                $ea_ids = array_column($answer_list, 'ea_id');
                $answer_conds = [
                    'ea_id' => $ea_ids,
                    'ep_id' => $paper['ep_id'],
                    'esr_id' => $esr_id,
                    'is_status' => AnswerService::DO_STATE
                ];
                $answer_list = $this->get_answer_list($answer_conds, $paper);
                $count = $statistics['answer_num'];
            }


        } else { // 自主或规则选题

            // oa_exam_snapshot
            $snapshot_conds = [
                'ep_id' => $ep_id,
                'es_id' => $esr_id
            ];
            // 查询题
            $topic = $this->snapshot_serv->get_by_conds($snapshot_conds);
            // 题目类型:1=单选,2=判断,3=问答,4=多选,5=语音
            $et_type = $topic['et_type'];
            $stat_conds = array(
                'ep_id' => $ep_id,
                'esr_id' => $esr_id
            );
            // 查询统计
            $statistics = $this->statistics_serv->get_by_conds($stat_conds);
            // 单选、判断、多选,统计各选项使用率
            if (in_array($et_type, $et_types)) {

                if (!empty($statistics)) {

                    $this->get_options($et_type, $topic, $statistics, $options);
                    $count = $statistics['answer_num'];
                }
            } else {
                $answer_list = $this->answer_serv->list_by_conds([
                    'ep_id' => $ep_id,
                    'answer_status=?' => AnswerService::READ_OVER
                ]);
                $ea_ids = array_column($answer_list, 'ea_id');

                // 新数据查询条件
                $snapshot_conds = [
                    'ea_id' => $ea_ids,
                    'ep_id' => $ep_id,
                    'esr_id' => $esr_id,
                    'is_status' => AnswerService::DO_STATE
                ];

                $answer_list = $this->get_answer_list($snapshot_conds, $paper);
                $count = $statistics['answer_num'];
            }
        }

        // 返回结果
        $this->_result = [
            'esr_id' => $esr_id,
            'title' => $topic['title'],
            'et_type' => $topic['et_type'],
            'count' => intval($count),
            'answer' => $topic['answer'],
            'answer_resolve' => $topic['answer_resolve'],
            'options' => $options,
            'answer_list' => $answer_list
        ];
    }

    /**
     * 组装options数据
     *
     * @param $et_type int 试题类型
     * @param $topic array 试题快照
     * @param $statistics array 试题统计
     * @param $options array 需要格式化的数据
     *
     * @return bool
     */
    protected function get_options($et_type, $topic, $statistics, &$options)
    {
        if (!empty($statistics)) {

            $options_count = unserialize($statistics['options']);
            $answer_count = array_sum($options_count);
            if (intval($answer_count) == 0) {
                $answer_count = 1; // 被除数不能为0
            }

            // 判断题
            if (TopicService::TOPIC_TYPE_JUDGMENT == $et_type) {

                foreach ($options_count as $k => $v) {
                    // 文字转换:right->对,error->错
                    if ('right' == $k) {

                        $k = '对';
                    } elseif ('error' == $k) {

                        $k = '错';
                    }
                    $option['option_name'] = $k;
                    $option['option_value'] = '';
                    $option['option_image_url'] = '';
                    $option['option_image_id'] = '';

                    $option['count'] = $v;
                    $rate = $v / $answer_count;
                    $option['percentage'] = round($rate * 100, 2) . '%';
                    array_push($options, $option);
                }
            } else { // 选择题

                $options_data = unserialize($topic['options']);

                // 循环组装选项数据
                foreach ($options_data as $k => $v) {
                    $options[$k]['option_name'] = $v['option_name'];
                    $options[$k]['option_value'] = $v['option_value'];
                    $options[$k]['option_image_url'] = $v['option_image_url'];
                    $options[$k]['option_image_id'] = $v['option_image_id'];

                    $options[$k]['count'] = $options_count[$v['option_name']];
                    $rate = $options_count[$v['option_name']] / $answer_count;
                    $options[$k]['percentage'] = round($rate * 100, 2) . '%';
                }
            }
        }

        return true;
    }

    /**
     * 组装answer_list数据
     *
     * @param $answer_conds array 查询答卷详情的条件兼容新新旧数据 如
     *       新    where =array('ep_id' => $paper['ep_id'],'esr_id' => $esr_id)
     *       旧    where =array('ep_id' => $paper['ep_id'],'order_num' => $order_num)
     * @param $paper array 试题详情
     *
     * @return mixed 格式化后的answer_list数据
     */
    protected function get_answer_list($answer_conds, $paper)
    {
        // 答案详情
        $answer_detail = $this->answer_detail_serv->list_by_conds($answer_conds);
        // 初始化返回结果
        $answer_list = [];
        if (!empty($answer_detail)) {

            $conds = [
                'ea_id' => array_column($answer_detail, 'ea_id'),
                'answer_status' => [AnswerService::READ_OVER, AnswerService::READ_WAITING] // 已交卷
            ];

            $fields = 'ea_id,uid,ep_id,my_score,my_begin_time,my_time,my_end_time';
            $join = $this->answer_serv->list_by_conds($conds, null, [], $fields);
            $join = array_combine_by_key($join, 'ea_id');

            // 参与考试的所有人的UID
            $uids = array_column($join, 'uid');
            // 参与考试的人员的详细信息列表
            $userlist = $this->answer_serv->getUser($uids);

            $res_answer_list = $this->answer_detail_serv->question_list_format($answer_detail, $paper['marking_type'],
                AnswerService::ANSWER_PC_ANALYSIS);
            foreach ($answer_detail as $k => $v) {
                // 初始化
                $my_answer_data = [
                    'txt' => '',
                    'pic' => [],
                    'voice' => []
                ];
                // 试题类型
                $et_type = $v['et_type'];
                // 语音题
                if (TopicService::TOPIC_TYPE_VOICE == $et_type) {

                    $my_answer_temp = [];
                    // 语音答案转换
                    foreach ($res_answer_list as $key => $val) {
                        if ($val['ead_id'] == $v['ead_id']) {

                            // 我的答案
                            $my_answer = $val['my_answer'];
                            foreach ($my_answer as $_key => $_val) {
                                // 语音
                                if (isset($_val['type']) && $_val['type'] == AnswerService::ANSWER_TYPE_VOICE) {

                                    $my_answer_temp['voice'][] = $_val['opt'];
                                }

                                // 文字
                                if (isset($_val['type']) && $_val['type'] == AnswerService::ANSWER_TYPE_TEXT) {

                                    $my_answer_temp['txt'] = $_val['opt'];
                                }

                                // 图片
                                if (isset($_val['type']) && $_val['type'] == AnswerService::ANSWER_TYPE_IMG) {

                                    $my_answer_temp['pic'][] = $_val['opt'];
                                }
                            }
                        }
                    }

                    $my_answer_data = $my_answer_temp;
                } elseif (TopicService::TOPIC_TYPE_QUESTION == $et_type) { // 问答题

                    $my_answer_data['txt'] = $v['my_answer'];
                }

                // 答卷信息
                $answer_info = $join[$v['ea_id']];

                // 姓名
                $memUsername = $userlist[$answer_info['uid']]['memUsername'];
                // 部门
                $dp_arr = $userlist[$answer_info['uid']]['dpName'];
                $dpNames = array_column($dp_arr, 'dpName');

                $answer_list[$k]['ea_id'] = $v['ea_id'];
                $answer_list[$k]['memUsername'] = $memUsername;
                $answer_list[$k]['dpName'] = implode(',', $dpNames);
                $answer_list[$k]['my_answer'] = $my_answer_data;
                $answer_list[$k]['answer_time'] = $v['created'];
            }
        }

        return $answer_list;
    }
}