ExportUserListController.class.php 12 KB
<?php
/**
 * Created by PhpStorm.
 * User: liyifei2012it
 * Date: 17/10/14
 * Time: 14:50
 */

namespace Frontend\Controller\Callback;

use Com\PythonExcel;
use Common\Common\Constant;
use Common\Common\CourseHelper;
use Common\Common\ExportDownload;
use Common\Common\User;
use Common\Model\CourseArticleModel;
use Common\Model\CourseCompleteModel;
use Common\Model\CourseClassModel;
use Common\Model\CourseStudyTimeModel;
use Org\Net\PHPZip;
use Think\Log;

class ExportUserListController extends AbstractController
{

    /**
     * @desc 导出员工学习数据列表接口
     * @param String dp_ids 组织ID(多个值时,以英文逗号分隔)
     * @param String role_ids 角色ID(多个值时,以英文逗号分隔)
     * @param String job_ids 岗位ID(多个值时,以英文逗号分隔)
     * @param String username 姓名
     * @param Int class_id 课程分类ID
     * @param String article_title 课程名称
     * @param Int is_complete 是否学习完成
     * @return bool
     */
    public function Index()
    {

        $postData = $this->callBackData;

        Log::write('=========批量生成员工学习数据列表=====文件ID==' . $postData['id'], 'ERR', '', C('LOG_PATH') . date('y_m_d') . '.txt');
        Log::write('=========批量生成员工学习数据列表=====参数==' . print_r($postData, true), 'ERR', '', C('LOG_PATH') . date('y_m_d') . '.txt');

        // 分页(限制1000条数据)
        list($pageSql, $limitSql) = page_limit($postData['page'], 1000, 1000);

        // 人员条件(当uids有值时,则忽略人员其他筛选条件)
        $userConds = [];
        if (!empty($postData['uids'])) {
            $userConds['memUids'] = $postData['uids'];

        } else {
            if (isset($postData['dp_ids'])) {
                $userConds['dpIdList'] = $postData['dp_ids'];
                $userConds['departmentChildrenFlag'] = 1;
            }
            if (isset($postData['role_ids'])) {
                $userConds['roleIdList'] = $postData['role_ids'];

            }
            if (isset($postData['job_ids'])) {
                $userConds['jobIdList'] = $postData['role_ids'];
            }
            if (isset($postData['username'])) {
                $userConds['memUsername'] = $postData['username'];
            }
        }

        // 课程条件
        $articleConds = [];
        if (isset($postData['article_title'])) {
            $articleConds['article_title LIke ?'] = '%'.$postData['article_title'].'%';

        }
        if (isset($postData['class_id'])) {
            $classModel = new CourseClassModel();
            $classIds = $classModel->getChildClassIds($postData['class_id']);
            $articleConds['class_id'] = $classIds;
        }

        $userList = [];
        $articleList = [];
        $courseHelper = &CourseHelper::instance();
        // 仅搜索课程
        if (!empty($articleConds) && empty($userConds)) {
            $articleList = $courseHelper->userStudyListByArticle($articleConds);
        }
        // 仅搜索人员
        if (!empty($userConds) && empty($articleConds)) {
            $userList = $courseHelper->userStudyListByUser($userConds);
        }
        // 搜索人员及课程
        if (!empty($userConds) && !empty($articleConds)) {
            list($userList, $articleList) = $courseHelper->userStudyListByUserArticle($userConds, $articleConds);
        }

        $uids = [];
        if (!empty($userList)) {
            $uids = array_keys($userList);
        }

        // 查询常规课程id集合
        $course_article = new CourseArticleModel();
        $course_article_list = $course_article->list_by_conds(['course_type' => Constant::COURSE_TYPE_NORMAL], null, [], 'article_id,data_id,article_type');
        $articles = array_column($course_article_list, 'article_id');

        if (!empty($articleList)) {
            $articleIds = array_keys($articleList);
            // 对常规课程id 和 搜索课程所获取的课程id取交集
            $articleIds = array_intersect($articles, $articleIds);
        } else {
            $articleIds = $articles;
        }

        // 获取数据列表
        $datas = [];
        $completeModel = new CourseCompleteModel();
        $studyTimeModel = new CourseStudyTimeModel();
        if (isset($postData['is_complete'])) {
            switch ($postData['is_complete']) {
                // 是否完成学习:已完成(course_complete)
                case Constant::COURSE_IS_COMPLETE_TRUE:
                    $datas = $completeModel->list_by_conds(['uid' => $uids, 'article_id' => $articleIds], [$pageSql, $limitSql], ['created' => 'desc']);

                    // 最近学习情况
                    $studyList = $studyTimeModel->listUserStudy($datas);

                    break;

                // 是否完成学习:未完成(在course_study_time,但不在course_complete)连表查询
                case Constant::COURSE_IS_COMPLETE_FALSE:
                    $datas = $studyTimeModel->listUserUnCompleteCourse(['uids' => $uids, 'article_ids' => $articleIds], [$pageSql, $limitSql]);
                    break;
            }
        } else {
            // 是否完成学习:全部,已完成+未完成(course_study_time)分表查询
            $conds = [
                'uid' => $uids,
                'article_id' => $articleIds,
            ];
            $datas = $studyTimeModel->listUserAllowStudy($conds, [$pageSql, $limitSql]);
            // 课程完成情况
            $completeList = $completeModel->listUserComplete($datas);
        }

        // 补全人员信息
        $list = [];
        if (!empty($datas)) {
            // 获取课程信息
            if (empty($articleList)) {
                $articleIds = array_column($datas, 'article_id');
                $articleList = $courseHelper->userStudyListByArticle(['article_id' => $articleIds]);
            }

            // 获取人员信息
            if (empty($userList)) {
                $uids = array_column($datas, 'uid');
                $userList = $courseHelper->userStudyListByUser(['memUids' => $uids]);
            }

            foreach ($datas as $v) {
                $uid = $v['uid'];
                $user = $userList[$uid];
                if (empty($user)) {
                    continue;
                    // 如果用户被删除,需要重新获取
                    $user = User::instance()->getByUid($uid);
                }
                $articleId = $v['article_id'];

                // 组织
                $dpNames = !empty($user['dpName']) ? implode(',', array_column($user['dpName'], 'dpName')) : '';

                // 格式化"已完成"数据时,补全最近学习时间
                $completeTime = 0;
                $latestStudyTime = 0;
                if (isset($studyList) && !empty($studyList)) {
                    // 当数据列表未课程完成列表时,创建时间即为课程完成时间;
                    $completeTime = $v['created'];
                    foreach ($studyList as $study) {
                        if ($articleId == $study['article_id'] && $uid == $study['uid']) {
                            $latestStudyTime = $study['latest_study_time'];
                            break;
                        }
                    }
                }

                // 格式化"全部"数据时,补全课程完成情况
                if (isset($completeList) && !empty($completeList)) {
                    foreach ($completeList as $complete) {
                        if ($articleId == $complete['article_id'] && $uid == $complete['uid']) {
                            $completeTime = $complete['complete_time'];
                            break;
                        }
                    }
                }

                // 最近学习时间
                $latestTime = isset($v['latest_study_time']) ? $v['latest_study_time'] : $latestStudyTime;
                $latestTime = $latestTime > 0 ? rgmdate($latestTime, 'Y-m-d H:i') : '-';

                // 学习时长
                $times = $studyTimeModel->listStudyTime($uid, $articleId);
                $study_time = $this->secToTime((int)$times[0]['study_time']);

                $list[] = [
                    $user['memUsername'],
                    $dpNames,
                    $user['memJob'],
                    $user['memRole'],
                    $articleList[$articleId]['article_title'],
                    $study_time,
                    $latestTime,
                    (int)$completeTime > 0 ? '是' : '否',
                    $completeTime > 0 ? rgmdate($completeTime, 'Y-m-d H:i') : '-',
                ];
            }
        }

        Log::write('=========批量生成员工学习数据列表=====生成文件数据==' . print_r($list, true), 'ERR', '', C('LOG_PATH') . date('y_m_d') . '.txt');

        // 如果无数据了
        if (empty($list)) {

            Log::write('=========批量生成员工学习数据列表已生成完成=====文件ID==' . $postData['id'], 'ERR', '', C('LOG_PATH') . date('y_m_d') . '.txt');
            // 获取需要打包的目录
            $dir_tmp = ExportDownload::get_down_dir($postData['user_id'] . $postData['time'] . D_S . $postData['time'] . $postData['id'] . $postData['user_id']);

            $phpzip = new PHPZip();

            // 组装压缩文件名称
            $filename = ExportDownload::get_down_dir($postData['user_id'] . 'D' . microtime(true)) . microtime(true) . '.zip';

            // 打包文件
            $phpzip->zipDir($dir_tmp, $filename, false);

            // 更新状态
            $data = [
                'url' => $dir_tmp,
                'id' => $postData['id'],
                'size' => filesize($filename)
            ];

            ExportDownload::update_down_load($data);

            unlink($filename);

            return false;
        }


        // Excel首行标题
        $titles = ['姓名', '组织', '岗位', '角色', '课程名称', '用时', '最近学习时间', '是否学习完成', '学习完成时间'];

        $this->_download_by_python($postData, $titles, $list);

        $params = [
            'user_id' => $postData['user_id'],
            'time' => $postData['time'],
            'id' => $postData['id'],
            'username' => $postData['username'],
            'class_id' => $postData['class_id'],
            'article_title' => $postData['article_title'],
            'is_complete' => $postData['is_complete'],
            'dp_ids' => $postData['dp_ids'],
            'role_ids' => $postData['role_ids'],
            'job_ids' => $postData['job_ids'],
            'page' => intval($postData['page']) + 1
        ];

        $url = oaUrl('Frontend/Callback/ExportUserList');

        // 生成定时任务
        ExportDownload::set_Cron($params, $url, '员工学习数据_批量下载', 'USERSTUDYDATA_DOWN_Excel_' . $postData['id']);

        return true;
    }

    /**
     * 通过python导出数据
     * @param array $postData 数据
     * @param array $titles 标题
     * @param array $rows 数据列表
     */
    private function _download_by_python($postData = [], $titles, $rows)
    {
        $realpath = ExportDownload::get_down_dir($postData['user_id'] . $postData['time'] . D_S . $postData['time'] . $postData['id'] . $postData['user_id']) . $postData['page'] . '.xls';
        // 生成 Excel 并输出
        PythonExcel::instance()->write($realpath, $titles, $rows);

        return true;
    }

    /**
     * 把秒数转换为时分秒的格式
     * @author liyifei
     * @param Int $times 时间,单位 秒
     * @return String
     */
    private function secToTime($times)
    {
        $result = '';

        if ($times > 0) {
            $hour = floor($times / 3600);
            $minute = floor(($times - 3600 * $hour) / 60);
            $second = floor((($times - 3600 * $hour) - 60 * $minute) % 60);
            if ($hour > 0) {
                $result .= "{$hour}时";
            }
            if ($minute > 0) {
                $result .= "{$minute}分";
            }
            if ($second > 0) {
                $result .= "{$second}秒";
            }
        }

        return empty($result) ? 0 : $result;
    }
}