ImportArticleMap.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. namespace App\Console\Commands;
  3. use Illuminate\Console\Command;
  4. use Illuminate\Support\Facades\Http;
  5. use Illuminate\Support\Facades\Log;
  6. use App\Http\Api\StudioApi;
  7. use App\Models\Article;
  8. use App\Models\Collection;
  9. class ImportArticleMap extends Command
  10. {
  11. /**
  12. * The name and signature of the console command.
  13. * php artisan import:article.map visuddhinanda --studio=visuddhinanda --size=30000 --anthology=4c6b661b-fd68-44c5-8918-2e327c870b9a --token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJuYmYiOjE2OTc3Mjg2ODUsImV4cCI6MTcyOTI2NDY4NSwidWlkIjoiYmE1NDYzZjMtNzJkMS00NDEwLTg1OGUtZWFkZDEwODg0NzEzIiwiaWQiOjR9.fiXhnY2LczZ9kKVHV0FfD3AJPZt-uqM5wrDe4EhToVexdd007ebPFYssZefmchfL0mx9nF0rgHSqjNhx4P0yDA
  14. *
  15. * @var string
  16. */
  17. protected $signature = 'import:article.map {src_studio} {--token=} {--studio=} {--anthology=} {--size=}';
  18. /**
  19. * The console command description.
  20. *
  21. * @var string
  22. */
  23. protected $description = '重置缅文tipitaka sarupa文章目录';
  24. /**
  25. * Create a new command instance.
  26. *
  27. * @return void
  28. */
  29. public function __construct()
  30. {
  31. parent::__construct();
  32. }
  33. /**
  34. * Execute the console command.
  35. *
  36. * @return int
  37. */
  38. public function handle()
  39. {
  40. $token = $this->option('token');
  41. $studioName = $this->option('studio');
  42. $anthologyId = $this->option('anthology');
  43. $srcStudio = $this->argument('src_studio');
  44. if (!$this->confirm('Do you wish to continue?')) {
  45. return 0;
  46. }
  47. $studioId = StudioApi::getIdByName($studioName);
  48. if(!$studioId){
  49. $this->error("can not found studio name {$studioName}");
  50. return 0;
  51. }
  52. $srcStudioId = StudioApi::getIdByName($srcStudio);
  53. if(!$srcStudioId){
  54. $this->error("can not found src studio name {$srcStudio}");
  55. return 0;
  56. }
  57. //先获取文章列表,建立全部目录
  58. $url = config('app.url').'/api/v2/article-map';
  59. $this->info('打开csv文件并读取数据');
  60. $head = array();
  61. $strFileName = __DIR__."/tipitaka-sarupa.csv";
  62. if(!file_exists($strFileName)){
  63. $this->error($strFileName.'文件不存在');
  64. return 1;
  65. }
  66. if (($fp = fopen($strFileName, "r")) === false) {
  67. $this->error("can not open csv {$strFileName}");
  68. return 0;
  69. }
  70. //查询文集语言
  71. $lang = Collection::where('uid',$anthologyId)->value('lang');
  72. if(empty($lang)){
  73. $this->error("文集语言不能为空 anthologyId=".$anthologyId);
  74. return 0;
  75. }
  76. $inputRow = 0;
  77. $currSize=0;
  78. $currBlock=1;
  79. $currDir='';
  80. $success = 0;
  81. $fail = 0;
  82. $articleMap = array();
  83. while (($data = fgetcsv($fp, 0, ',')) !== false) {
  84. if($inputRow>0){
  85. $id = $data[0];
  86. $dir = $data[1];
  87. $title = $data[2];
  88. $realTitle = "[{$id}]{$title}";
  89. $realTitle = mb_substr($realTitle,0,128,'UTF-8');
  90. $reference = $data[5];
  91. $percent = (int)($inputRow*100/6984);
  92. $this->info("[{$percent}%] doing ".$realTitle);
  93. if($this->option('size')){
  94. $currDir = 'tipitaka-sarupa-'.$currBlock;
  95. if($currSize > $this->option('size')){
  96. $currBlock++;
  97. $currSize=0;
  98. }
  99. }else{
  100. $currDir = $dir;
  101. }
  102. //查找目录文章是否存在
  103. $dirArticle = Article::where('owner',$studioId)
  104. ->where('title',$currDir)
  105. ->first();
  106. if($dirArticle){
  107. $dirId = $dirArticle->uid;
  108. }else{
  109. $this->info('不存在目录'.$currDir.'新建');
  110. $url = config('app.url').'/api/v2/article';
  111. sleep(2);
  112. $response = Http::withToken($token)->post($url,
  113. [
  114. 'title'=> $currDir,
  115. 'lang'=> $lang,
  116. 'studio'=> $studioName,
  117. 'anthologyId'=> $anthologyId,
  118. ]);
  119. if($response->ok()){
  120. $this->info('dir create ok title='.$currDir);
  121. $dirId = $response->json('data.uid');
  122. }else{
  123. $this->error('create dir fail.'.$currDir);
  124. Log::error('create dir fail title='.$currDir);
  125. $fail++;
  126. continue;
  127. }
  128. }
  129. //创建目录结束
  130. if(!isset($articleMap[$dirId])){
  131. $articleMap[$dirId] = ['name'=>$currDir,'children'=>[]];
  132. }
  133. //查找文章
  134. $article = Article::where('owner',$srcStudioId)
  135. ->where('title',$realTitle)
  136. ->first();
  137. if(!$article){
  138. $this->error('文章没找到.'.$realTitle);
  139. Log::error('文章没找到 title='.$realTitle);
  140. $fail++;
  141. continue;
  142. }
  143. $articleMap[$dirId]['children'][] = [
  144. 'id'=>$article->uid,
  145. 'title'=>$article->title,
  146. ];
  147. if($this->option('size')){
  148. $currSize += mb_strlen($title,'UTF-8') +
  149. mb_strlen($data[4],'UTF-8') +
  150. mb_strlen($reference,'UTF-8');
  151. }
  152. $success++;
  153. }
  154. $inputRow++;
  155. }
  156. $this->info("找到文章=" .$success);
  157. $this->info("目录=" .count($articleMap));
  158. $this->info('正在准备map数据');
  159. $data = array();
  160. foreach ($articleMap as $dirId => $dir) {
  161. $data[] = [
  162. 'article_id'=> $dirId,
  163. 'level'=> 1,
  164. 'title'=> $dir['name'],
  165. 'children'=> count($dir['children']),
  166. 'deleted_at'=> null,
  167. ];
  168. foreach ($dir['children'] as $key => $child) {
  169. $data[] = [
  170. 'article_id'=> $child['id'],
  171. 'level'=> 2,
  172. 'title'=> $child['title'],
  173. 'children'=> 0,
  174. 'deleted_at'=> null,
  175. ];
  176. }
  177. }
  178. $this->info('map data='.count($data));
  179. //目录写入db
  180. $url = config('app.url').'/api/v2/article-map/'.$anthologyId;
  181. $response = Http::withToken($token)->put($url,
  182. [
  183. 'data'=> $data,
  184. 'operation' => "anthology",
  185. ]);
  186. if($response->ok()){
  187. $this->info('map update ok ');
  188. }else{
  189. $this->error('map update fail.');
  190. Log::error('map update fail ');
  191. }
  192. return 0;
  193. }
  194. }