bucket = env('OSS_BUCKET'); } /** * 获取章节内容 * @param $bid * @param $chapter_id * @return array|bool|mixed|null|string */ public static function getChapter($bid,$chapter_id){ if(empty($bid) || empty($chapter_id)) return false; //Redis::incr('book_'.$bid.'_click_count'); //从redis获取 try{ $res = self::getChapterFromRedis($bid,$chapter_id); if($res) { return json_decode($res); } }catch (\Exception $e){ Log::info($e); } //从oss获取 try{ $res = self::getChapterFromOss($bid,$chapter_id); if($res) { try{ self::saveChapterToRedis($bid,json_decode($res)); }catch (\Exception $redis){ Log::info($redis); } return json_decode($res); } }catch (\Exception $e){ Log::info($e); } $res = self::getChapterFromDb($bid,$chapter_id); if(empty($res)) return false; try{ self::saveChapterToRedis($bid,$res); self::saveChapterToOss($bid,$res); }catch (\Exception $e){ Log::info($e); } return $res; } /** * 根据cid获取章节内容 * @param $chapter_id * @return mixed */ public static function getChapterById($chapter_id){ return Chapter::getChapterById($chapter_id); } /** * 获取目录不分页 * @param $bid * @return mixed */ public static function getChapterLists($bid) { $lists = Chapter::getChapterLists($bid); return $lists; } /** * 获取目录分页 * @param $bid * @param int $page_size * @return mixed */ public static function getChapterListsPage($bid,$page_size=15){ $lists = Chapter::getChapterListsPage($bid,$page_size); return $lists; } /** * 获取章节信息没有内容 * @param $chapter_id * @return mixed */ public static function getChapterNameById($chapter_id,$bid) { $chapter = Chapter::getChapterNameById($chapter_id); if($chapter && $chapter->bid == $bid){ return $chapter; } return false; } /** * 获取章节信息没有内容 不做bid的验证 * @param $chapter_id * @return mixed */ public static function getChapterNameByIdNoCheck($chapter_id){ return Chapter::getChapterNameById($chapter_id); } /** * 获取前五章内容(推广需要) * @param $bid * @return mixed */ public static function getTopFiveChapter($bid) { $res = Chapter::getTopFiveChapter($bid); return $res; } /** * 从oss获取章节内容 * @param $chapter_id * @param $bid */ public static function getChapterFromOss($bid, $chapter_id) { $bucket = env('OSS_BUCKET'); $oss = self::ossObject(); $path_format = 'book/chapters/%s/%s.json'; $path = sprintf($path_format, $bid, $chapter_id); if ($oss->doesObjectExist($bucket, $path)) { return $oss->getObject($bucket, $path); } return null; } /** * 从redis获取章节内容 * @param $chapter_id * @param $bid */ public static function getChapterFromRedis($bid, $chapter_id) { $key = sprintf('book_chapter_%s_%s', $bid, $chapter_id); //Redis::connection('chapter') return Redis::connection('chapter')->get($key); } /** * 从db获取章节内容 * @param $chapter_id * @param $bid */ public static function getChapterFromDb($bid, $chapter_id) { $chapter = self::getChapterById($chapter_id); if ($chapter->bid != $bid) { return []; } return $chapter; } /** * 章节内容保存到oss * @param $chapter * @param $bid */ public static function saveChapterToOss($bid, $chapter) { $bucket = env('OSS_BUCKET'); $file = ('book/' . $bid . '_' . $chapter->id . '.json'); Storage::put($file, json_encode($chapter)); $path_format = 'book/chapters/%s/%s.json'; self::ossObject()->uploadFile($bucket, sprintf($path_format, $bid, $chapter->id), storage_path('app/' . $file)); Storage::delete($file); } /** * 章节内容保存到redis * @param $chapter * @param $bid */ public static function saveChapterToRedis($bid, $chapter) { return Redis::connection('chapter')->setex(sprintf('book_chapter_%s_%s', $bid, $chapter->id),3600, json_encode($chapter)); } /** * oss 对象 * @return null|OssClient */ public static function ossObject() { $accessKeyId = env('OSS_ACCESS_ID'); $accessKeySecret = env('OSS_ACCESS_KEY'); $endpoint = env('OSS_END_POINT'); $ossClient = null; try { $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint); } catch (OssException $e) { return null; } return $ossClient; } //编辑vip章节 public static function editVip($bid,$seq){ return Chapter::editVip($bid,$seq); } public static function editChapter($chapter){ $bucket = env('OSS_BUCKET'); $bid = $chapter->bid; $res_db = Chapter::where('id',$chapter->id)->update(['content'=>$chapter->content,'size'=>$chapter->size]); //$res_db = true; if(self::getChapterFromOss($bid,$chapter->id)){ $oss = self::ossObject(); $path_format = 'book/chapters/%s/%s.json'; $oss->deleteObject($bucket,sprintf($path_format, $bid, $chapter->id)); } self::saveChapterToOss($bid,$chapter); $res_redis = self::saveChapterToRedis($bid,$chapter); return $res_db && $res_redis; } //章节列表和内容 public static function getChapterPage($bid,$page_size=15){ return Chapter::getChapterPage($bid,$page_size); } /** * 根据bid和顺序获取章节信息 * @param $bid * @param $seq * @return mixed */ public static function getChapterInfoByBidAndSeq($bid,$seq){ return Chapter::where('bid',$bid)->where('sequence',$seq)->select('id','name')->first(); } public static function updateSequence(int $bid,int $sequence){ Chapter::where('bid',$bid)->where('sequence','>',$sequence)->decrement('sequence',1); } public static function updateSequenceIncr(int $bid,int $sequence){ Chapter::where('bid',$bid)->where('sequence','>=',$sequence)->increment('sequence',1); } public static function updateChapterName($cid,$name){ Chapter::where('id',$cid)->update(['name'=>$name]); } public static function createChapter($param){ return Chapter::create($param); } public static function updateOne(int $id,array $param){ if($param){ return Chapter::where('id',$id)->update($param); } return null; } public static function splitContentAll($bid,$sequence){ $chapters = Chapter::where('bid',$bid) ->where('size','>=',3300) ->where('sequence','>=',$sequence) ->select('id','sequence')->orderBy('sequence')->get(); $i = 0; $count = 0; $end_sequence = 0; $start_sequence = 0; foreach ($chapters as $k=>$chapter){ if($k == 0){ $start_sequence = $chapter->sequence; } $content = self::splitContent($chapter->id); if(!$content) continue; //\Log::info($chapter); $count += self::createSplitContent($chapter->id,$content,false); $end_sequence = $chapter->sequence; $i++; } //\Log::info('$start_sequence is: '.$start_sequence); //\Log::info('$end_sequence is: '.($end_sequence+$i+$count)); self::adjustSequent($bid,$start_sequence,$end_sequence+$i+$count); return $count; } public static function splitContent($chapter_id) { $chapter = self::getChapterById($chapter_id); if(!$chapter || $chapter->bid <0 || $chapter->size < 3300) return []; $content_list = explode("\r\n",$chapter->content); //print_r($content_list); $count = 1; $temp_size= 0; $temp_content = ''; $data = []; foreach ($content_list as $item){ if($temp_size >2500){ $count++; $temp_content = ''; $temp_size = 0; } $temp_size += mb_strlen($item); $temp_content .= $item."\r\n"; $data[$count-1] = [ 'bid'=>$chapter->bid, 'is_vip'=>$chapter->is_vip, 'name'=>sprintf('%s(%s)',$chapter->name,$count), 'sequence'=>$chapter->sequence+$count-1, 'size'=>$temp_size, 'prev_cid'=>0, 'next_cid'=>0, 'recent_update_at'=>$chapter->recent_update_at, 'content'=>$temp_content, ]; } if($data && $data[$count-1]['size'] <800){ $data[$count-2]['content'] = $data[$count-2]['content'].$data[$count-1]['content']; $data[$count-2]['size'] = $data[$count-2]['size']+$data[$count-1]['size']; unset($data[$count-1]); } return $data; } public static function createSplitContent($chapter_id,$data,$is_adjust = true) { if(count($data) <= 1){ return 0; } Chapter::where('bid',$data[0]['bid'])->where('sequence','>=',$data[0]['sequence']+1)->increment('sequence',count($data)-1); Chapter::where('id',$chapter_id)->update([ 'content'=>$data[0]['content'], 'size'=>$data[0]['size'], 'name'=>$data[0]['name'] ]); $i = 0; foreach ($data as $kye=>$item){ if($kye == 0) continue; $i++; self::createChapter($item); } if($is_adjust){ self::adjustSequent($data[0]['bid'],$data[0]['sequence'],$data[0]['sequence']+count($data)+5); } if(self::getChapterFromOss($data[0]['bid'],$chapter_id)){ $oss = self::ossObject(); $bucket = env('OSS_BUCKET'); $path_format = 'book/chapters/%s/%s.json'; $oss->deleteObject($bucket,sprintf($path_format, $data[0]['bid'], $chapter_id)); } $key = sprintf('book_chapter_%s_%s', $data[0]['bid'], $chapter_id); //Redis::connection('chapter') try{ Redis::connection('chapter')->delete($key); }catch (\Exception $e){} $last = Chapter::where('bid',$data[0]['bid']) ->select('id','bid','name','sequence') ->orderBy('sequence','desc') ->limit(1) ->first(); Book::where('id',$data[0]['bid'])->update([ 'chapter_count'=>$last->sequence, 'last_chapter'=>$last->name, 'last_cid'=>$last->id, ]); return $i; } public static function adjustSequent($bid,$start_sequence,$end_sequence){ $chapter_list = Chapter::where('bid',$bid); if($start_sequence){ $chapter_list = $chapter_list->where('sequence','>=',$start_sequence); } if($end_sequence){ $chapter_list = $chapter_list->where('sequence','<=',$end_sequence); } $chapter_list = $chapter_list->orderBy('sequence')->select('id')->get(); $prev = 0; foreach ($chapter_list as $chapter){ if($prev){ Chapter::where('id',$chapter->id)->update(['prev_cid'=>$prev]); Chapter::where('id',$prev)->update(['next_cid'=>$chapter->id]); } $prev = $chapter->id; } } }