ExportAnswerListController.class.php 10.8 KB
<?php
/**
 * 【调研中心-后台】导出问题的回答列表
 * ExportAnswerListController.class.php
 * CreateBy:pw
 * Date:2018-05-18
 */

namespace Apicp\Controller\Export;

use Com\PythonExcel;
use Common\Common\ExportDownload;
use Common\Common\User;
use Common\Service\AnswerService;
use Common\Service\BaseinfoService;
use Common\Service\QuestionService;
use Common\Service\RecordService;

class ExportAnswerListController extends \Apicp\Controller\AbstractController
{
    // 导出excel文件名
    const QUESTIONNAIRE_XLS_FILE_NAME = '培训调研数据导出';

    // 客观题型(1单选,2复选,3下拉选择,9评分)
    const OBJECTIVE = [1, 2, 3, 9];

    public function Index()
    {
        // 验证参数
        $qu_id = (int)I('post.qu_id');
        if (empty($qu_id) || !is_int($qu_id) || 0 >= $qu_id) {
            E('_EMPTY_BASEINFO_ID');
        }

        $zip_name = self::QUESTIONNAIRE_XLS_FILE_NAME;
        // 生成压缩文件夹名称
        $zip_dir = ExportDownload::get_down_dir($this->_login->user['eaId'] .'PW'. microtime(true) . microtime(true));

        // 根据qu_id查出该调研基础信息
        $baseinfo_s = new BaseinfoService();
        $qu_data = $baseinfo_s->get($qu_id);

        if (!$qu_data) {
            E('_ERR_BASEINFOID_NO_EXISTENT');
        }

        // 检查是否有人作答
        $answer_s = new AnswerService();
        $answers = $answer_s->count_by_conds(['qu_id'=>$qu_id]);

        if (!$answers || 0>=(int)$answers) {
            E('_EMPTY_QUESTION_ANSWER_JOIN');
        }

        try{
            // 生成客观问题excel
            $this->_objective($qu_data, $zip_dir);

            // 生成主观问题excel
            $this->_subjective($qu_data, $zip_dir);

            // 压缩数据写入到下载中心
            $condition = [
                'title' => $zip_name,
                'ea_id' => $this->_login->user['eaId'],
                'type' => ExportDownload::ZIP_TYPE,
                'size' => filesize($zip_dir),
                'url' => $zip_dir,
                'username' => $this->_login->user['eaRealname'],
                'app_dir' => APP_DIR
            ];
            ExportDownload::insert_down_load($condition);

        } catch (\Think\Exception $e) {
            \Think\Log::record($e);
        }

        return true;
    }

    /**
     * 处理客观问题数据
     *
     * @param array $qu_data 调研详情
     * @param integer $zip_dir 统一打包文件夹
     */
    private function _objective($qu_data, $zip_dir)
    {
        $qu_id = (int)$qu_data['qu_id'];

        // 实例化调研问题信息Service
        $question_s = new QuestionService();

        // 根据qu_id查出该问卷客观问题
        $objective_question_list = $question_s->list_by_conds(['qu_id' => $qu_id, 'q_type IN (?)' => self::OBJECTIVE]);

        // 客观题列表
        $list[] = [' ', ' ', ' ', ' '];
        if (!empty($objective_question_list)) {
            $p = 1;
            foreach ($objective_question_list as $k=>$question) {

                // 获取统计结果数据并格式化(包含选择和评分类型)
                if (QuestionService::SCORE_TYPE == $question['q_type']) {
                    $objective_answer = $question_s->get_stars_answer_result($question);
                } else {
                    $objective_answer = $question_s->get_option_answer_result($question);
                }

                $type_name =  '【'.QuestionService::QUESTION_TYPES[$question['q_type']].'】';
                // 第一行数据
                $list[] = [
                    $p, // 序号
                    !empty($question['q_title']) ? $type_name . $question['q_title'] : ' ', // 问题名称
                    !empty($qu_data['involved_num']) ? $qu_data['involved_num'] . '人填写' : ' ', // 填写人数
                    ' ' // 留空
                ];

                // 第二行数据
                $list[] = [' ', '选项', '小计', '百分比%'];

                // 选项数据
                foreach ($objective_answer['q_option'] as $option) {
                    $list[] = [
                        '',
                        !empty($option['option']) ? $option['option'] : ' ', // 选项名称
                        !empty($option['option_num']) ? $option['option_num'] : 0, // 填写人数
                        !empty($option['option_percent']) ? $option['option_percent'] : ' ', // 所占百分比
                    ];
                }

                // 插入空行
                $list[] = [' ', ' ', ' ', ' '];

                $p ++;
            }
        }

        // 生成客观问题excel文件
        $this->_objective_download($qu_data, $list, $zip_dir);
    }

    /**
     * 处理主观题数据
     *
     * @param array $qu_data 调研详情
     * @param integer $zip_dir 统一打包文件夹
     */
    private function _subjective($qu_data, $zip_dir)
    {
        $qu_id = (int)$qu_data['qu_id'];

        // 实例化调研问题信息Service
        $question_s = new QuestionService();
        // 实例化调研回答详情信息Service
        $record_s = new RecordService();
        // 实例化调研回答用户记录Service
        $answer_s = new AnswerService();

        // 根据qu_id查出该问卷主观问题列表
        $subjective_list = $question_s->list_by_conds(['qu_id' => $qu_id, 'q_type NOT IN (?)' => self::OBJECTIVE]);

        if (!empty($subjective_list)) {
            foreach ($subjective_list as $k => $sub_question) {
                // 问题id
                $q_id = $sub_question['qid'];

                // 获取问题的回答详情
                $record_list = $record_s->list_by_conds(['q_id' => $q_id]);

                $list = [];
                // 匿名
                if (BaseinfoService::ANONYMOUS == (int)$qu_data['anonymous']) {

                    $q = 1;
                    foreach ($record_list as $v) {
                        // 排序
                        $list[] = [
                            $q, // 序号
                            '', // 部门
                            '匿名' . $q, // 姓名
                            '', // 邮箱
                            '', // 手机
                            $v['answer'] . ' ' . $v['other'],
                            rgmdate(strval($v['created']), 'Y-m-d H:i')
                        ];

                        $q++;
                    }
                } else {

                    // 获取问题的回答记录
                    $answer_list = $answer_s->list_by_conds(['qu_id' => $sub_question['qu_id']]);
                    // 组成以回答ID为主键的二维数组
                    $answer_list = array_combine_by_key($answer_list, 'a_id');

                    // 获取回答该调研的用户的ID集合
                    $uids = array_column($answer_list, 'uid');

                    $user = User::instance();
                    // 查询用户列表
                    $user_list = $user->listAll(['memUids' => $uids]);
                    // 组成以用户ID为主键的二维数据
                    $user_list = array_combine_by_key($user_list, 'memUid');

                    // 序号
                    $i = 1;
                    foreach ($record_list as $v) {

                        if ($v['answer'] == '' && $v['other'] == '') {
                            // 如果答案为空,则不导出该条记录
                            continue;
                        }

                        // 获取当前的回答记录
                        $answer_data = $answer_list[$v['a_id']];

                        // 获取用户信息和部门
                        $user_data = [];
                        $dp_name = '';
                        if (!empty($answer_data['uid'])) {

                            $user_data = $user_list[$answer_data['uid']];
                            $dp_list = $user_data['dpName'];

                            if (!empty($dp_list)) {

                                $dp_names = array_column($dp_list, 'dpName');
                                $dp_name = implode(',', $dp_names);
                            }
                        }

                        // 性别
                        if (QuestionService::SEX == $sub_question['q_type']) {
                            $sex_info = unserialize($v['answer']);
                            $answer = $sex_info[0]['option'];
                        // 图片
                        } elseif (QuestionService::PICTURE == $sub_question['q_type']) {
                            $pic_info = unserialize($v['answer']);
                            $answer = '=HYPERLINK("'.$pic_info[0]['option_img_url'].'","'.time().rand(0, 9999).'.png")';
                        } else {
                            $answer = $v['answer'] . ' ' . $v['other'];
                        }

                        $list[] = [
                            $i, // 序号
                            $dp_name, // 部门
                            !empty($user_data['memUsername']) ? $user_data['memUsername'] : $answer_data['username'], // 姓名
                            !empty($user_data['memEmail']) ? $user_data['memEmail'] : '', // 邮箱
                            !empty($user_data['memMobile']) ? $user_data['memMobile'] : '', // 手机
                            $answer,
                            rgmdate(strval($v['created']), 'Y-m-d H:i')
                        ];
                        unset($answer);

                        $i++;
                    }
                }

                // 生成指定主观题excel
                $this->_subjective_download($sub_question, $list, $zip_dir);
            }
        }
    }

    /**
     * 导出主观问题模板信息
     *
     * @param array $q_data 问题基本信息
     * @param array $list 问题列表
     * @param string $zip_dir 生成文件目录
     */
    private function _subjective_download($q_data, $list, $zip_dir)
    {
        $fileName = $q_data['q_title'] . '-统计分析[主观题]' . date('_YmdHi');

        $titles = ['序号', '组织', '姓名', '邮箱', '手机', '填写内容', '填写时间'];

        // 生成Excel
        $real_path = $zip_dir . $fileName . '.xls';

        PythonExcel::instance()->write($real_path, $titles, $list);
    }

    /**
     * 导出客观题模板信息
     *
     * @param array $qu_data 问卷基本信息
     * @param array $list 问题列表
     * @param string $zip_dir 生成文件目录
     */
    private function _objective_download($qu_data, $list, $zip_dir)
    {
        $fileName = $qu_data['title'] . '-统计分析[客观题]' . date('_YmdHi');

        $titles = [' ', $qu_data['title'], '累计'. $qu_data['involved_num'] .'人填写', ' '];

        // 生成Excel
        $real_path = $zip_dir . $fileName . '.xls';

        PythonExcel::instance()->write($real_path, $titles, $list);
    }
}