getNeedSchoolExam(); if (!$schoolRelExam) { $this->showMsg(1, '没有需要处理的考试'); return ''; } $schoolIds = array_keys($schoolRelExam); $this->showMsg(1, '共有' . count($schoolIds) . '个学校需要处理 .....'); //查询学校数据库连接地址 $schoolDatabases = $this->getSchoolDatabases($schoolIds); foreach ($schoolRelExam as $schoolId => $examRelClass) { $this->showMsg(1, '当前学校ID:' . $schoolId . ' .......'); $this->databaseInfo = isset($schoolDatabases[$schoolId]) ? $schoolDatabases[$schoolId] : array(); if (!$this->databaseInfo) { $this->showMsg(1, '学校ID:' . $schoolId . '没有数据库连接信息'); continue; } //连接学校数据库 $this->schConnObj = null; $this->schConnObj = $this->getSchConnObj(); if (!$this->schConnObj) { $this->showMsg(1, '学校ID:' . $schoolId . '数据库连接失败!!!!!'); continue; } MyActiveRecord::$schoolId = $schoolId; foreach ($examRelClass as $examGroupId => $classAndId) { $classStr = $classAndId['class_ids']; $tableId = $classAndId['id'];//表主键ID $classNameArr = $this->getClassName($classAndId); $this->showMsg(1, '当前考试组ID:' . $examGroupId . ' .......'); $examInfoArr = $this->getNeedExamIds($examGroupId, $classStr); if (!$examInfoArr) { $this->showMsg(1, '当前考试组ID:' . $examGroupId . '没有可以生产的教学宝'); continue; } $pdfPathArr = array(); foreach ($examInfoArr as $examId => $examInfo) { $time = microtime(true); $this->showMsg(1, '当前考试ID:' . $examId . ' .......'); //更新生成中状态 $bool = $this->updateStatus($tableId, 4); if ($bool === false) { $pdfPathArr = array(); break; } echo '开始生成教学宝PDF......' . PHP_EOL; //生成PDF $bool = $this->getPdf($pdfPathArr,$tableId,$schoolId,$examId,$examInfo['class_id']); if ($bool === false) { $pdfPathArr = array(); break; } echo '生成一个PDF耗时:' . round(microtime(true) - $time, 2) . 's' . PHP_EOL; } //打包PDF $successArr = array(); if ($pdfPathArr) { $examName = $examInfo['name']; $filenamePath = dirname(dirname(dirname(__FILE__))) . '/upload/tmpDir/academicr_batch/' . $examGroupId . "/" . $tableId; if (!is_dir($filenamePath)) { if (!mkdir($filenamePath, 0777, true)) { $bool = $this->updateStatus($tableId, 3,'创建压缩文件目录失败: ' . $filenamePath); }else{ exec('chown -R www:www '.$filenamePath); } } $filename = $filenamePath ."/".$examGroupId.".zip"; // file_put_contents($filename, ''); $successArr = $this->zipPdf($pdfPathArr, $filename, $examName, $classNameArr); } //全部成功更新状态 if ($successArr && count($successArr) == array_sum($successArr)) { //上传qcloud文件 $filename = $this->characet($filename); $ucloud = new Qcloud(); $filename = iconv("UTF-8","GBK//IGNORE",$filename); $examName = $this->characet($examName); $putRs = $ucloud->putFile('zsyas2/academicr_batch/'.$examGroupId.'/'.$tableId.'/'.$examName.'.zip',$filename); if(isset($putRs['status']) && $putRs['status'] == 1){ $url = $putRs['url']; $url = str_replace("%2F","/",$url); $bool = $this->updateStatus($tableId, 2,'',$url); $this->showMsg(1, 'zip文件上传Ucloud成功!,地址:'.$url); }else{ $msg = 'zip文件上传Ucloud失败!!!,错误信息:' . $putRs['msg']; $bool = $this->updateStatus($tableId, 3,$msg); } @unlink($filename); }else{ $bool = $this->updateStatus($tableId, 3,'生成zip文件失败'); } } //关闭数据库 if ($this->schConnObj) { $this->getSchConnObj()->close(); } echo '下一个学校' . PHP_EOL; } echo 'End.' . PHP_EOL; } public function getDbConnection($databaseHost,$databaseName,$databaseUser,$databasePassword) { if($databaseHost && $databaseName && $databaseUser && $databasePassword){ $myDbDsn = 'mysql:host=' . $databaseHost . ';dbname=' . $databaseName; $myConnection = new CDbConnection($myDbDsn, $databaseUser, $databasePassword); $myConnection->emulatePrepare = true; $myConnection->enableProfiling = true; $myConnection->enableParamLogging = true; $myDbDsn = null; return $myConnection; }else{ return null; } } /** * 获取学校数据库 * @param $schoolIds * @return array */ protected function getSchoolDatabases($schoolIds) { $schoolDatabases = array(); $sql = "select school_id,database_host,database_user,database_password,database_name,group_id from `database` where school_id in (" . implode(',', $schoolIds) . ")"; $rs = $this->getBusConn()->createCommand($sql)->queryAll(); if ($rs) { foreach ($rs as $value) { $schoolDatabases[$value['school_id']] = $value; } } return $schoolDatabases; } /** * 业务数据库对象 * @return CDbConnection|null */ protected function getBusConn() { $time = time(); if ($this->busConnObj) { if ($time - $this->busDbTime > $this->dbTimeout) { echo '关闭超时业务数据库重新连接' . PHP_EOL; }else{ return $this->busConnObj; } } $dbParams = Yii::app()->params["default_server"]; $busConnObj = $this->getDbConnection($dbParams['addr'], Yii::app()->params["default_db"]['name'], $dbParams['username'], $dbParams['password']); $this->busConnObj = $busConnObj; $this->busDbTime = $time; return $busConnObj; } /** * 学校数据库对象 * @return mixed */ public function getSchConnObj() { $time = time(); if ($this->schConnObj) { if ($time - $this->schDbTime > $this->dbTimeout) { echo '关闭超时学校数据库重新连接' . PHP_EOL; }else{ return $this->schConnObj; } } $databaseInfo = $this->databaseInfo; $schConnObj = $this->getDbConnection($databaseInfo['database_host'], $databaseInfo['database_name'], $databaseInfo['database_user'], $databaseInfo['database_password']); $this->schConnObj = $schConnObj; $this->schDbTime = $time; return $schConnObj; } /** * 查询需要处理的考试 * @param $examGroupId * @param $classStr * @return array */ protected function getNeedExamIds($examGroupId, $classStr) { $examInfoArr = array(); $rs = array(); $sql = "SELECT exam_id,class_id,`name` FROM exam WHERE exam_group_id = '{$examGroupId}' AND class_id IN ({$classStr}) AND `status` = 1"; $result = $this->getSchConnObj()->createCommand($sql)->queryAll(); if (!$result) { return $examInfoArr; } foreach ($result as $value) { $examInfoArr[$value['exam_id']] = $value; } unset($result); if ($examInfoArr) { $sql = "SELECT exam_id FROM paper WHERE exam_id in (" . implode(',', array_keys($examInfoArr)) . ") and is_labelled = 1"; $result = $this->getSchConnObj()->createCommand($sql)->queryAll(); if ($result) { foreach ($result as $value) { $rs[$value['exam_id']] = isset($examInfoArr[$value['exam_id']])?$examInfoArr[$value['exam_id']]:0; } } } unset($examInfoArr); return $rs; } /** * 需要处理的学校考试 * @return array|CDbDataReader */ protected function getNeedSchoolExam() { $schoolRelExam = array(); $time = time(); //获取要生成教师讲案的数据 $sql = "select id,school_id,exam_group_id,class_ids,class_names from download_table_setting where download_type = 3 and status = 1 and error_msg = '' and subject_id = 12 and is_labelled>0 "; $result = $this->getBusConn()->createCommand($sql)->queryAll(); //超过20分钟默认生成失败 $sql = "update download_table_setting set status = 3,error_msg ='系统错误,建议单个生成' where status = 4 and error_msg = '' and update_time <" . ($time - 1200); $this->getBusConn()->createCommand($sql)->execute(); if ($result) { foreach ($result as $value) { $schoolId = $value['school_id']; if (!isset($schoolRelExam[$schoolId])) { $schoolRelExam[$schoolId] = array(); } $schoolRelExam[$schoolId][$value['exam_group_id']] = array( 'class_ids' => $value['class_ids'], 'class_names' => $value['class_names'], 'id' => $value['id'], ); } } return $schoolRelExam; } /** * 更新生成状态 状态:1等待生成中,2-已生成 , 3-生成失败 4-生成中 * @param $tableId * @param $status * @param string $errorMsg * @param string $zipUrl * @return int */ protected function updateStatus($tableId, $status,$errorMsg = '',$zipUrl = '') { $time = time(); $sql = "update download_table_setting set update_time = {$time},`status` = {$status}"; if ($errorMsg) { $errorMsg = addslashes($errorMsg); $sql .= ",`error_msg` = '{$errorMsg}'"; $this->showMsg(0, $errorMsg); } if ($zipUrl) { $sql .= ",`zip_url` = '{$zipUrl}'"; } $sql .= " where id = {$tableId}"; $bool = $this->getBusConn()->createCommand($sql)->execute(); if ($bool === false) { $this->showMsg(0, '更新生成状态' . $status . '失败!!!!'); } return $bool; } /** * 显示信息 * @param $status * @param $msg */ protected function showMsg($status,$msg) { echo $msg . PHP_EOL; } /** * client 渲染HTML * @param $viewName * @param $data * @return string */ public function viewRender($viewName, $data) { extract($data, EXTR_PREFIX_SAME,'data'); ob_start(); ob_implicit_flush(0); $filePath=dirname(dirname(dirname(__FILE__))).'/protected/views/teaching/'.$viewName . '.php'; require($filePath); return ob_get_clean(); } /** * 生成pdf */ protected function getPdf(&$pdfPathArr,$tableId,$schoolId,$examId,$classId) { $teachingPhysicsObj = new TeachingPhysics($this); $result = $teachingPhysicsObj->getTeachingPdf($schoolId, $examId, 1); if (isset($result['status']) && $result['status'] == 0) { $pdfPathArr[$classId] = $result['pdf_path']; $this->showMsg(1, '教学宝PDF生成成功!地址:'.$result['pdf_url']); $this->showMsg(1, ',PDF文件路径地址:'.$result['pdf_path']); $bool = true; }else{ $errorMsg = isset($result['error']) ? $result['error'] : '生成失败!!'; $this->showMsg(0, $errorMsg); $bool = $this->updateStatus($tableId, 3, $errorMsg); } return $bool; } /** * 打包PDF * @param $pdfPathArr * @param $filename * @param $examName * @return array */ protected function zipPdf($pdfPathArr,$filename,$examName,$classNameArr) { $successArr = array(); $examName = iconv("UTF-8","GBK//IGNORE",$examName); //最终生成的文件名(含路径) $zip = new ZipArchive(); if ($zip->open($filename, ZIPARCHIVE::OVERWRITE)!==TRUE) { $this->showMsg(0, $examName . 'zip生成失败!'); }else { foreach ($pdfPathArr as $classId => $val) { $className = isset($classNameArr[$classId]) ? $classNameArr[$classId] : ''; $pdfname = '-'.$className.'-教师讲案'; $pdfname = iconv("UTF-8", "GBK//IGNORE", $pdfname); $res = $zip->addFile($val, $examName . $pdfname . '.pdf'); if (!$res) { $this->showMsg(0, '添加zip文件失败:'.$val); } $successArr[] = $res ? 1 : 0; } $zip->close();//关闭 foreach ($pdfPathArr as $k => $val) { @unlink($val); } } return $successArr; } /** * 字符转换 * @param $data * @return string */ protected function characet($data){ if( !empty($data) ){ $fileType = mb_detect_encoding($data , array('UTF-8','GBK','LATIN1','BIG5')) ; if( $fileType != 'UTF-8'){ $data = mb_convert_encoding($data ,'utf-8' , $fileType); } } return $data; } /** * 获取班级名称 * @param $classAndId * @return array */ protected function getClassName($classAndId) { $classNameArr = array(); $classIds = explode(',',$classAndId['class_ids']); $classNames = explode(',',$classAndId['class_names']); foreach ($classIds as $key => $classId) { $classNameArr[$classId] = isset($classNames[$key]) ? $classNames[$key] : ''; } return $classNameArr; } }