ImportArticleMap.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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. $srcAnthology = Collection::where('uid',$anthologyId)->first();
  72. if(!$srcAnthology){
  73. $this->error("文集不存在 anthologyId=".$anthologyId);
  74. return 0;
  75. }
  76. $lang = $srcAnthology->lang;
  77. if(empty($lang)){
  78. $this->error("文集语言不能为空 anthologyId=".$anthologyId);
  79. return 0;
  80. }
  81. $inputRow = 0;
  82. $currSize=0;
  83. $currBlock=1;
  84. $currDir='';
  85. $success = 0;
  86. $fail = 0;
  87. $articleMap = array();
  88. while (($data = fgetcsv($fp, 0, ',')) !== false) {
  89. if($inputRow>0){
  90. $id = $data[0];
  91. $dir = $data[1];
  92. $title = $data[2];
  93. $realTitle = "[{$id}]{$title}";
  94. $realTitle = mb_substr($realTitle,0,128,'UTF-8');
  95. $reference = $data[5];
  96. $percent = (int)($inputRow*100/6984);
  97. $this->info("[{$percent}%] doing ".$realTitle);
  98. if($this->option('size')){
  99. $currDir = $srcAnthology->title . '-' . $currBlock;
  100. if($currSize > $this->option('size')){
  101. $currBlock++;
  102. $currSize=0;
  103. }
  104. }else{
  105. $currDir = $dir;
  106. }
  107. //查找目录文章是否存在
  108. $dirArticle = Article::where('owner',$studioId)
  109. ->where('title',$currDir)
  110. ->first();
  111. if($dirArticle){
  112. $dirId = $dirArticle->uid;
  113. }else{
  114. $this->info('不存在目录'.$currDir.'新建');
  115. $url = config('app.url').'/api/v2/article';
  116. sleep(2);
  117. $response = Http::withToken($token)->post($url,
  118. [
  119. 'title'=> $currDir,
  120. 'lang'=> $lang,
  121. 'studio'=> $studioName,
  122. 'anthologyId'=> $anthologyId,
  123. ]);
  124. if($response->ok()){
  125. $this->info('dir create ok title='.$currDir);
  126. $dirId = $response->json('data.uid');
  127. }else{
  128. $this->error('create dir fail.'.$currDir);
  129. Log::error('create dir fail title='.$currDir);
  130. $fail++;
  131. continue;
  132. }
  133. }
  134. //创建目录结束
  135. if(!isset($articleMap[$dirId])){
  136. $articleMap[$dirId] = ['name'=>$currDir,'children'=>[]];
  137. }
  138. //查找文章
  139. $article = Article::where('owner',$srcStudioId)
  140. ->where('title',$realTitle)
  141. ->first();
  142. if(!$article){
  143. $this->error('文章没找到.'.$realTitle);
  144. Log::error('文章没找到 title='.$realTitle);
  145. $fail++;
  146. continue;
  147. }
  148. $articleMap[$dirId]['children'][] = [
  149. 'id'=>$article->uid,
  150. 'title'=>$article->title,
  151. ];
  152. if($this->option('size')){
  153. $currSize += mb_strlen($title,'UTF-8') +
  154. mb_strlen($data[4],'UTF-8') +
  155. mb_strlen($reference,'UTF-8');
  156. }
  157. $success++;
  158. }
  159. $inputRow++;
  160. }
  161. $this->info("找到文章=" .$success);
  162. $this->info("目录=" .count($articleMap));
  163. $this->info('正在准备map数据');
  164. $data = array();
  165. foreach ($articleMap as $dirId => $dir) {
  166. $data[] = [
  167. 'article_id'=> $dirId,
  168. 'level'=> 1,
  169. 'title'=> $dir['name'],
  170. 'children'=> count($dir['children']),
  171. 'deleted_at'=> null,
  172. ];
  173. foreach ($dir['children'] as $key => $child) {
  174. $data[] = [
  175. 'article_id'=> $child['id'],
  176. 'level'=> 2,
  177. 'title'=> $child['title'],
  178. 'children'=> 0,
  179. 'deleted_at'=> null,
  180. ];
  181. }
  182. }
  183. $this->info('map data='.count($data));
  184. //目录写入db
  185. $url = config('app.url').'/api/v2/article-map/'.$anthologyId;
  186. $response = Http::withToken($token)->put($url,
  187. [
  188. 'data'=> $data,
  189. 'operation' => "anthology",
  190. ]);
  191. if($response->ok()){
  192. $this->info('map update ok ');
  193. }else{
  194. $this->error('map update fail.');
  195. Log::error('map update fail ');
  196. }
  197. return 0;
  198. }
  199. }