ExportDownload.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <?php
  2. namespace App\Tools;
  3. use Illuminate\Support\Str;
  4. use Illuminate\Support\Facades\Log;
  5. use Illuminate\Support\Facades\Storage;
  6. use Illuminate\Support\Facades\App;
  7. use App\Tools\RedisClusters;
  8. use App\Tools\Export;
  9. class ExportDownload
  10. {
  11. protected $statusKey = 'export/status';
  12. protected $statusExpiry = 3600;
  13. protected $currStatusKey = '';
  14. protected $queryId = 'id';
  15. protected $realFilename = 'index';//压缩包里的文件名
  16. protected $zipFilename = 'file.zip';
  17. protected $downloadUrl = null;
  18. protected $format = 'tex';
  19. protected $debug = false;
  20. protected $logs = [];
  21. /**
  22. * Create a new command instance.
  23. *
  24. * @return void
  25. */
  26. public function __construct($options=[])
  27. {
  28. if(isset($options['format'])){
  29. $this->format = $options['format'];
  30. }
  31. if(isset($options['debug'])){
  32. $this->debug = $options['debug'];
  33. }
  34. if(isset($options['filename'])){
  35. $this->realFilename = $options['filename'];
  36. }
  37. $this->queryId = $options['queryId'];
  38. $this->zipFilename = $this->queryId.'.zip';
  39. $this->currStatusKey = $this->statusKey . '/' . $this->queryId;
  40. }
  41. /**
  42. * progress: 0-1, error -1
  43. * message: string
  44. */
  45. public function setStatus($progress,$message=''){
  46. $this->logs[] = $message;
  47. $data = [
  48. 'progress'=>$progress,
  49. 'message'=>$message,
  50. 'log'=>$this->logs,
  51. 'content-type'=>'application/zip',
  52. ];
  53. if($this->downloadUrl){
  54. $data['url'] = $this->downloadUrl;
  55. }
  56. RedisClusters::put($this->currStatusKey,
  57. $data,
  58. $this->statusExpiry);
  59. $percent = (int)($progress * 100);
  60. return "[{$percent}%]".$message;
  61. }
  62. public function getStatus(){
  63. return RedisClusters::get($this->currStatusKey);
  64. }
  65. public function upload(string $type,$sections,$bookMeta){
  66. $m = new \Mustache_Engine(array('entity_flags'=>ENT_QUOTES,
  67. 'delimiters' => '[[ ]]',
  68. 'escape'=>function ($value){
  69. return $value;
  70. }));
  71. $tex = array();
  72. $tplFile = resource_path("mustache/".$type.'/'.$this->format."/main.".$this->format);
  73. $tpl = file_get_contents($tplFile);
  74. $texContent = $m->render($tpl,$bookMeta);
  75. $tex[] = ['name'=>'main.'.$this->format,
  76. 'content'=>$texContent
  77. ];
  78. foreach ($sections as $key => $section) {
  79. $tplFile = resource_path("mustache/".$type.'/'.$this->format."/section.".$this->format);
  80. $tpl = file_get_contents($tplFile);
  81. $texContent = $m->render($tpl,$section['body']);
  82. $tex[] = ['name'=>$section['name'],
  83. 'content'=>$texContent
  84. ];
  85. }
  86. Log::debug('footnote start');
  87. //footnote
  88. $tplFile = resource_path("mustache/".$this->format."/footnote.".$this->format);
  89. if(isset($GLOBALS['note']) &&
  90. is_array($GLOBALS['note']) &&
  91. count($GLOBALS['note'])>0 &&
  92. file_exists($tplFile)){
  93. $tpl = file_get_contents($tplFile);
  94. $texContent = $m->render($tpl,['footnote'=>$GLOBALS['note']]);
  95. $tex[] = ['name'=>'footnote.'.$this->format,
  96. 'content'=>$texContent
  97. ];
  98. }
  99. if($this->debug){
  100. $dir = "export/{$type}/".$this->format."/".$this->zipFilename."/";
  101. foreach ($tex as $key => $section) {
  102. Storage::disk('local')->put($dir.$section['name'], $section['content']);
  103. }
  104. }
  105. Log::debug('footnote finished');
  106. $this->setStatus(0.95,'export content done.');
  107. //upload
  108. $fileDate = '';
  109. switch ($this->format) {
  110. case 'tex':
  111. $data = Export::ToPdf($tex);
  112. if($data['ok']){
  113. $this->info($data['content-type']);
  114. $fileDate = $data['data'];
  115. }else{
  116. $this->error($data['code'].'-'.$data['message']);
  117. }
  118. break;
  119. case 'html':
  120. $file = array();
  121. foreach ($tex as $key => $section) {
  122. $file[] = $section['content'];
  123. }
  124. $fileDate = implode('',$file);
  125. break;
  126. }
  127. $zipDir = storage_path('app/export/zip');
  128. if(!is_dir($zipDir)){
  129. $res = mkdir($zipDir,0755,true);
  130. if(!$res){
  131. Log::error('mkdir fail path='.$zipDir);
  132. return 1;
  133. }
  134. }
  135. $zipFile = $zipDir.'/'.Str::uuid().'.zip';
  136. Log::debug('export chapter start zip file='.$zipFile);
  137. //zip压缩包里面的文件名
  138. $realFilename = $this->realFilename.".".$this->format;
  139. $zipOk = \App\Tools\Tools::zip($zipFile,[$realFilename=>$fileDate]);
  140. if(!$zipOk){
  141. Log::error('export chapter zip fail zip file='.$zipFile);
  142. $this->setStatus(0.99,'export chapter zip fail');
  143. $this->error('export chapter zip fail zip file='.$zipFile);
  144. //TODO 给客户端返回错误状态
  145. return 1;
  146. }
  147. $this->setStatus(0.96,'export chapter zip success');
  148. $bucket = config('mint.attachments.bucket_name.temporary');
  149. $tmpFile = $bucket.'/'. $this->zipFilename ;
  150. Log::debug('upload start filename='.$tmpFile);
  151. $this->setStatus(0.97,'upload start ');
  152. $zipData = file_get_contents($zipFile);
  153. Storage::put($tmpFile, $zipData);
  154. if (App::environment('local')) {
  155. $s3Link = Storage::url($tmpFile);
  156. }else{
  157. try{
  158. $s3Link = Storage::temporaryUrl($tmpFile, now()->addDays(7));
  159. }catch(\Exception $e){
  160. Log::error('export {Exception}',['exception'=>$e]);
  161. return false;
  162. }
  163. }
  164. $this->downloadUrl = $s3Link;
  165. $this->setStatus(1,'export chapter done');
  166. Log::debug('export chapter done, upload filename='.$tmpFile);
  167. unlink($zipFile);
  168. return true;
  169. }
  170. }