ArticleResource.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <?php
  2. namespace App\Http\Resources;
  3. use App\Http\Api\ChannelApi;
  4. use App\Http\Api\MdRender;
  5. use App\Http\Api\StudioApi;
  6. use App\Http\Api\UserApi;
  7. use App\Http\Controllers\ArticleController;
  8. use App\Models\ArticleCollection;
  9. use App\Models\Channel;
  10. use App\Models\Collection;
  11. use App\Models\Course;
  12. use App\Models\CourseMember;
  13. use App\Services\AuthService;
  14. use Illuminate\Contracts\Support\Arrayable;
  15. use Illuminate\Http\Request;
  16. use Illuminate\Http\Resources\Json\JsonResource;
  17. use Illuminate\Support\Facades\Log;
  18. use Illuminate\Support\Str;
  19. class ArticleResource extends JsonResource
  20. {
  21. /**
  22. * Transform the resource into an array.
  23. *
  24. * @param Request $request
  25. * @return array|Arrayable|\JsonSerializable
  26. */
  27. public function toArray($request)
  28. {
  29. $data = [
  30. 'uid' => $this->uid,
  31. 'title' => $this->title,
  32. 'subtitle' => $this->subtitle,
  33. 'summary' => $this->summary,
  34. 'studio' => StudioApi::getById($this->owner),
  35. 'editor' => UserApi::getById($this->editor_id),
  36. 'status' => $this->status,
  37. 'lang' => $this->lang,
  38. 'parent_uid' => $this->parent,
  39. 'created_at' => $this->created_at,
  40. 'updated_at' => $this->updated_at,
  41. ];
  42. $user = AuthService::current($request);
  43. if ($user) {
  44. $canEdit = ArticleController::userCanEdit($user['user_uid'], $this);
  45. if ($canEdit) {
  46. $data['role'] = 'editor';
  47. }
  48. }
  49. // 查询该文章在哪些文集中出现
  50. $collectionCount = ArticleCollection::where('article_id', $this->uid)->count();
  51. if ($collectionCount > 0) {
  52. $data['anthology_count'] = $collectionCount;
  53. $collection = ArticleCollection::where('article_id', $this->uid)->first();
  54. $data['anthology_first'] = Collection::find($collection->collect_id);
  55. }
  56. if ($request->has('anthology') && Str::isUuid($request->input('anthology'))) {
  57. $anthology = Collection::where('uid', $request->input('anthology'))->first();
  58. }
  59. // 渲染简化版标题
  60. $channels = [];
  61. if ($request->has('channel')) {
  62. // 有channel
  63. $channels = explode('_', $request->input('channel'));
  64. } elseif (isset($anthology) && $anthology && ! empty($anthology->default_channel)) {
  65. // 没有channel,使用文集channel
  66. $channels[] = $anthology->default_channel;
  67. }
  68. $mdRender = new MdRender(['format' => 'simple']);
  69. // path
  70. if ($request->has('anthology') && Str::isUuid($request->input('anthology'))) {
  71. $data['path'] = [];
  72. if (isset($anthology) && $anthology) {
  73. $data['path'][] = [
  74. 'key' => $anthology->uid,
  75. 'title' => $anthology->title,
  76. 'level' => 0,
  77. ];
  78. }
  79. $currLevel = -1;
  80. $aList = ArticleCollection::where('collect_id', $request->input('anthology'))
  81. ->orderBy('id', 'desc')
  82. ->select(['article_id', 'title', 'level'])->get();
  83. $path = [];
  84. foreach ($aList as $article) {
  85. if (
  86. $article->article_id === $this->uid ||
  87. ($currLevel >= 0 && $article->level < $currLevel)
  88. ) {
  89. $currLevel = $article->level;
  90. $path[] = [
  91. 'key' => $article->article_id,
  92. 'title' => $mdRender->convert($article->title, $channels),
  93. 'level' => $article->level,
  94. ];
  95. }
  96. }
  97. for ($i = count($path) - 1; $i >= 0; $i--) {
  98. $data['path'][] = $path[$i];
  99. }
  100. // 下级目录
  101. $level = -1;
  102. $subToc = [];
  103. for ($i = count($aList) - 1; $i >= 0; $i--) {
  104. $article = $aList[$i];
  105. if ($level >= 0) {
  106. if ($article->level > $level) {
  107. $subToc[] = [
  108. 'key' => $article->article_id,
  109. 'title' => $mdRender->convert($article->title, $channels),
  110. 'level' => $article->level,
  111. ];
  112. } else {
  113. break;
  114. }
  115. }
  116. if ($article->article_id === $this->uid) {
  117. $level = $article->level;
  118. }
  119. }
  120. $data['toc'] = $subToc;
  121. }
  122. $data['title_text'] = $mdRender->convert($this->title, $channels);
  123. // render html
  124. $channels = [];
  125. if (isset($this->content) && ! empty($this->content)) {
  126. if ($request->has('channel')) {
  127. $channels = explode('_', $request->input('channel'));
  128. } elseif ($request->has('anthology')) {
  129. $defaultChannel = Collection::where('uid', $request->input('anthology'))
  130. ->value('default_channel');
  131. if ($defaultChannel) {
  132. $channels[] = $defaultChannel;
  133. }
  134. }
  135. if (count($channels) === 0) {
  136. // 查找用户默认channel
  137. $studioChannel = Channel::where('owner_uid', $this->owner)
  138. ->where('type', 'translation')
  139. ->get();
  140. if ($studioChannel) {
  141. $channelId = $studioChannel[0]->uid;
  142. $channels = [$channelId];
  143. } else {
  144. $channelId = ChannelApi::getSysChannel(
  145. '_community_translation_'.strtolower($this->lang).'_',
  146. '_community_translation_en_'
  147. );
  148. if ($channelId) {
  149. $channels = [$channelId];
  150. }
  151. }
  152. }
  153. $data['content'] = $this->content;
  154. $data['content_type'] = $this->content_type;
  155. $query_id = null;
  156. if ($request->has('course')) {
  157. if ($request->has('exercise')) {
  158. $query_id = $request->input('exercise');
  159. if ($request->has('user')) {
  160. /**
  161. * 显示指定用户作业
  162. * 查询用户在课程中的channel
  163. */
  164. $userId = UserApi::getIdByName($request->input('user'));
  165. $userInCourse = CourseMember::where('course_id', $request->input('course'))
  166. ->where('user_id', $userId)
  167. ->first();
  168. if ($userInCourse) {
  169. $channelId = $userInCourse->channel_id;
  170. $channels = [$channelId];
  171. }
  172. } elseif ($request->input('view') === 'answer') {
  173. /**
  174. * 显示答案
  175. * 算法:查询course 答案 channel
  176. */
  177. $channelId = Course::where('id', $request->input('course'))->value('channel_id');
  178. $channels = [$channelId];
  179. } else {
  180. // 显示答案
  181. $channelId = Course::where('id', $request->input('course'))->value('channel_id');
  182. $channels = [$channelId];
  183. }
  184. } else {
  185. $channelId = Course::where('id', $request->input('course'))->value('channel_id');
  186. $channels = [$channelId];
  187. }
  188. }
  189. $mode = $request->input('mode', 'read');
  190. $format = $request->input('format', 'react');
  191. $htmlRender = new MdRender([
  192. 'mode' => $mode,
  193. 'format' => $format,
  194. 'footnote' => true,
  195. 'origin' => $request->input('origin', true),
  196. 'paragraph' => $request->input('paragraph', false),
  197. ]);
  198. // Log::debug('article render',['content'=>$this->content,'format'=>$format,'html'=>$html]);
  199. $data['html'] = $htmlRender->convert($this->content, $channels);
  200. if (empty($this->summary)) {
  201. $data['_summary'] = MdRender::render(
  202. $this->content,
  203. $channels,
  204. $query_id,
  205. $mode,
  206. 'translation',
  207. 'markdown',
  208. 'text'
  209. );
  210. }
  211. }
  212. return $data;
  213. }
  214. }