<?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; } }