TermTemplate.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. <?php
  2. namespace App\Services\Templates;
  3. use Illuminate\Support\Facades\Log;
  4. use Illuminate\Support\Str;
  5. use App\Models\DhammaTerm;
  6. use App\Models\Channel;
  7. use App\Http\Api\ChannelApi;
  8. use App\Http\Api\MdRender;
  9. class TermTemplate extends AbstractTemplate
  10. {
  11. protected $glossaryKey = 'glossary';
  12. public function render(): array
  13. {
  14. $word = $this->getParam("word", 1);
  15. $props = $this->getTermProps($word, '');
  16. $output = $props['word'];
  17. switch ($this->options['format']) {
  18. case 'react':
  19. $output = [
  20. 'props' => base64_encode(\json_encode($props)),
  21. 'html' => $props['innerHtml'],
  22. 'tag' => 'span',
  23. 'tpl' => 'term',
  24. ];
  25. break;
  26. case 'unity':
  27. $output = [
  28. 'props' => base64_encode(\json_encode($props)),
  29. 'tpl' => 'term',
  30. ];
  31. break;
  32. case 'html':
  33. if (isset($props["meaning"])) {
  34. $GLOBALS[$this->glossaryKey][$props["word"]] = $props['meaning'];
  35. $key = 'term-' . $props["word"];
  36. $termHead = "<a href='#'>" . $props['meaning'] . "</a>";
  37. if (isset($GLOBALS[$key])) {
  38. $output = $termHead;
  39. } else {
  40. $GLOBALS[$key] = 1;
  41. $output = $termHead . '(<em>' . $props["word"] . '</em>)';
  42. }
  43. } else {
  44. $output = $props["word"];
  45. }
  46. break;
  47. case 'text':
  48. if (isset($props["meaning"])) {
  49. $key = 'term-' . $props["word"];
  50. if (isset($GLOBALS[$key])) {
  51. $output = $props["meaning"];
  52. } else {
  53. $GLOBALS[$key] = 1;
  54. $output = $props["meaning"] . '(' . $props["word"] . ')';
  55. }
  56. } else {
  57. $output = $props["word"];
  58. }
  59. break;
  60. case 'tex':
  61. if (isset($props["meaning"])) {
  62. $key = 'term-' . $props["word"];
  63. if (isset($GLOBALS[$key])) {
  64. $output = $props["meaning"];
  65. } else {
  66. $GLOBALS[$key] = 1;
  67. $output = $props["meaning"] . '(' . $props["word"] . ')';
  68. }
  69. } else {
  70. $output = $props["word"];
  71. }
  72. break;
  73. case 'simple':
  74. if (isset($props["meaning"])) {
  75. $output = $props["meaning"];
  76. } else {
  77. $output = $props["word"];
  78. }
  79. break;
  80. case 'markdown':
  81. if (isset($props["meaning"])) {
  82. $key = 'term-' . $props["word"];
  83. if (isset($GLOBALS[$key]) && $GLOBALS[$key] === 1) {
  84. $GLOBALS[$key]++;
  85. $output = $props["meaning"];
  86. } else {
  87. $GLOBALS[$key] = 1;
  88. $output = $props["meaning"] . '(' . $props["word"] . ')';
  89. }
  90. } else {
  91. $output = $props["word"];
  92. }
  93. //如果有内容且第一次出现,显示为脚注
  94. if (!empty($props["note"]) && $GLOBALS[$key] === 1) {
  95. if (isset($GLOBALS['note_sn'])) {
  96. $GLOBALS['note_sn']++;
  97. } else {
  98. $GLOBALS['note_sn'] = 1;
  99. $GLOBALS['note'] = array();
  100. }
  101. $content = $props["note"];
  102. $output .= '[^' . $GLOBALS['note_sn'] . ']';
  103. $GLOBALS['note'][] = [
  104. 'sn' => $GLOBALS['note_sn'],
  105. 'trigger' => '',
  106. 'content' => $content,
  107. ];
  108. }
  109. break;
  110. default:
  111. if (isset($props["meaning"])) {
  112. $output = $props["meaning"];
  113. } else {
  114. $output = $props["word"];
  115. }
  116. break;
  117. }
  118. return $output;
  119. }
  120. public function getTermProps($word, $tag = null, $channel = null)
  121. {
  122. if ($channel && !empty($channel)) {
  123. $channelId = $channel;
  124. } else {
  125. if (count($this->options['channel_id']) > 0) {
  126. $channelId = $this->options['channel_id'][0];
  127. } else {
  128. $channelId = null;
  129. }
  130. }
  131. if (count($this->options['channelInfo']) === 0) {
  132. if (!empty($channel)) {
  133. $channelInfo = Channel::where('uid', $channel)->first();
  134. if (!$channelInfo) {
  135. unset($channelInfo);
  136. }
  137. }
  138. if (!isset($channelInfo)) {
  139. Log::warning('channel is null');
  140. $output = [
  141. "word" => $word,
  142. 'innerHtml' => '',
  143. ];
  144. return $output;
  145. }
  146. } else {
  147. $channelInfo = $this->options['channelInfo'][0];
  148. }
  149. if (Str::isUuid($channelId)) {
  150. $lang = Channel::where('uid', $channelId)->value('lang');
  151. if (!empty($lang)) {
  152. $langFamily = explode('-', $lang)[0];
  153. } else {
  154. $langFamily = 'zh';
  155. }
  156. Log::info("term:{$word} 先查属于这个channel 的", 'term');
  157. Log::info('channel id' . $channelId, 'term');
  158. $table = DhammaTerm::where("word", $word)
  159. ->where('channal', $channelId);
  160. if ($tag && !empty($tag)) {
  161. $table = $table->where('tag', $tag);
  162. }
  163. $tplParam = $table->orderBy('updated_at', 'desc')
  164. ->first();
  165. $studioId = $channelInfo->owner_uid;
  166. } else {
  167. $tplParam = false;
  168. $lang = '';
  169. $langFamily = '';
  170. $studioId = $this->options['studioId'];
  171. }
  172. if (!$tplParam) {
  173. if (Str::isUuid($studioId)) {
  174. /**
  175. * 没有,再查这个studio的
  176. * 按照语言过滤
  177. * 完全匹配的优先
  178. * 语族匹配也行
  179. */
  180. Log::debug("没有-再查这个studio的", 'term');
  181. $table = DhammaTerm::where("word", $word);
  182. if (!empty($tag)) {
  183. $table = $table->where('tag', $tag);
  184. }
  185. $termsInStudio = $table->where('owner', $channelInfo->owner_uid)
  186. ->orderBy('updated_at', 'desc')
  187. ->get();
  188. if (count($termsInStudio) > 0) {
  189. $list = array();
  190. foreach ($termsInStudio as $key => $term) {
  191. if (empty($term->channal)) {
  192. if ($term->language === $lang) {
  193. $list[$term->guid] = 2;
  194. } else if (strpos($term->language, $langFamily) !== false) {
  195. $list[$term->guid] = 1;
  196. }
  197. }
  198. }
  199. if (count($list) > 0) {
  200. arsort($list);
  201. foreach ($list as $key => $one) {
  202. foreach ($termsInStudio as $term) {
  203. if ($term->guid === $key) {
  204. $tplParam = $term;
  205. break;
  206. }
  207. }
  208. break;
  209. }
  210. }
  211. }
  212. }
  213. }
  214. if (!$tplParam) {
  215. Log::debug("没有,再查社区", 'term');
  216. $community_channel = ChannelApi::getSysChannel("_community_term_zh-hans_");
  217. $table = DhammaTerm::where("word", $word);
  218. if (!empty($tag)) {
  219. $table = $table->where('tag', $tag);
  220. }
  221. $tplParam = $table->where('channal', $community_channel)
  222. ->first();
  223. if ($tplParam) {
  224. $isCommunity = true;
  225. } else {
  226. Log::debug("查社区没有", 'term');
  227. }
  228. }
  229. $output = [
  230. "word" => $word,
  231. "parentChannelId" => $channelId,
  232. "parentStudioId" => $channelInfo->owner_uid,
  233. ];
  234. $innerString = $output["word"];
  235. if ($tplParam) {
  236. $output["id"] = $tplParam->guid;
  237. $output["meaning"] = $tplParam->meaning;
  238. $output["channel"] = $tplParam->channal;
  239. if (!empty($tplParam->note)) {
  240. $mdRender = new MdRender(['format' => $this->options['format']]);
  241. $output['note'] = $mdRender->convert($tplParam->note, $this->options['channel_id']);
  242. }
  243. if (isset($isCommunity)) {
  244. $output["isCommunity"] = true;
  245. }
  246. $innerString = "{$output["meaning"]}({$output["word"]})";
  247. if (!empty($tplParam->other_meaning)) {
  248. $output["meaning2"] = $tplParam->other_meaning;
  249. }
  250. }
  251. $output['innerHtml'] = $innerString;
  252. return $output;
  253. }
  254. }