<?php /** * Created by PhpStorm. * User: zhoutao * Date: 2018/1/18 * Time: 上午10:56 */ namespace Frontend\Controller\Callback; use Com\IM\TimRestAPI; use Common\Service\ImRecordService; /** * Class ImMsgHistoryController * @package Frontend\Controller\Callback * @property TimRestAPI $imSdk */ class ImMsgHistoryController extends AbstractController { protected $imSdk = null; /** * 获取远端聊天室历史记录 */ public function Index() { set_time_limit(0); // 获取时间范围 $timeRangeStart = empty($this->callBackData['timeRangeStart']) ? I('post.timeRangeStart') : $this->callBackData['timeRangeStart']; $timeRangeEnd = empty($this->callBackData['timeRangeEnd']) ? I('post.timeRangeEnd') : $this->callBackData['timeRangeEnd']; if (empty($timeRangeStart) || empty($timeRangeEnd)) { exit('SUCCESS'); } // 获取开始时间的小时整点 $startWholePoint = rgmdate($timeRangeStart, 'Y-m-d H:00:00'); $startWholePointTimestamp = rstrtotime($startWholePoint); // 获取时间段内的每个时间批次 $this->imSdk = new TimRestAPI(); for ($i = $startWholePointTimestamp; $i < $timeRangeEnd; $i += 60 * 60 * 1000) { // 处理单个时间批次聊天记录 $this->dealWithSingleTimeBatch(rgmdate($i, 'YmdH')); } exit('SUCCESS'); } /** * 处理单个时间批次聊天记录 * @param string $timeBatch 时间批次 比如: 2018011812 * @return bool */ private function dealWithSingleTimeBatch($timeBatch) { // 判断是否已经拉取过了 $imRecordServ = new ImRecordService(); $imRecordSingle = $imRecordServ->get_by_conds(['time_batch' => $timeBatch], [], true); if (!empty($imRecordSingle)) { return true; } $res = $this->imSdk->get_history('Group', $timeBatch); \Think\Log::record('腾讯云返回(历史记录文件列表):::' . var_export($res, true)); if (!isset($res['File'])) { return true; } // 先检查文件夹是否存在 if (!file_exists(TEMP_PATH)) { @mkdir(TEMP_PATH); } $insertData = []; foreach ($res['File'] as $key => $file) { // 下载远端文件 $fileName = TEMP_PATH . $res['MsgTime'] . '-' . $key; $fileNameAddSuffix = TEMP_PATH . $res['MsgTime'] . '-' . $key . '.gz'; // 如果有文件存在了 说明并发时有别的进程在处理 if (is_file($fileNameAddSuffix)) { break; } file_put_contents($fileNameAddSuffix, file_get_contents($file['URL'])); // 解压 $this->unZip($fileNameAddSuffix); // 读取文件并写入数据库 foreach (json_decode(file_get_contents($fileName), true)['MsgList'] as $msg) { foreach ($msg['MsgBody'] as $singleMsg) { $insertData[] = [ 'time_batch' => $timeBatch, 'from_account' => $msg['From_Account'], 'group_id' => $msg['GroupId'], 'msg_timestamp' => $msg['MsgTimestamp'], 'msg_type' => $singleMsg['MsgType'], 'msg_content' => $singleMsg['MsgContent']['Text'], 'msg_seq' => $msg['MsgSeq'], ]; } // 到数量先写入数据库 防止内存溢出 if (count($insertData) >= 500) { // 写入数据库 $imRecordServ->insert_all($insertData); // 清空数组 $insertData = []; } }; // 上面写入数据库会有 少于 500 的情况 这里补漏 if (!empty($insertData)) { // 写入数据库 $imRecordServ->insert_all($insertData); } // 删除文件 @unlink($fileNameAddSuffix); @unlink($fileName); } return true; } /** * 解压文件 * @param $filePath * @return bool */ private function unZip($filePath) { $bufferSize = 4096; $outFileName = str_replace('.gz', '', $filePath); $file = gzopen($filePath, 'rb'); $outFile = fopen($outFileName, 'wb'); while (!gzeof($file)) { fwrite($outFile, gzread($file, $bufferSize)); } fclose($outFile); gzclose($file); return true; } }