'', 'title' => '', 'path' => [], 'sub_title' => '', 'summary' => '', 'content' => '', 'content_type' => 'html', 'toc' => [], 'status' => 30, 'lang' => '', 'created_at' => '', 'updated_at' => '', ]; protected $wbwChannels = []; // 句子需要查询的列 protected $selectCol = [ 'uid', 'book_id', 'paragraph', 'word_start', 'word_end', 'channel_uid', 'content', 'content_type', 'editor_uid', 'acceptor_uid', 'pr_edit_at', 'fork_at', 'create_time', 'modify_time', 'created_at', 'updated_at', ]; protected $userUuid = null; protected $debug = []; public function __construct() {} /** * Display a listing of the resource. * * @return Response */ public function index(Request $request) { // switch ($request->get('view')) { case 'para': return $this->showPara($request); break; default: // code... break; } } /** * Store a newly created resource in storage. * * @return Response */ public function store(Request $request) { // } /** * Display the specified resource. * * @return Response */ public function show(Sentence $sentence) { // } public function getSentTpl( string $id, array $inputChannels, $mode = 'edit', $onlyProps = false, $format = 'react' ) { $sent = []; $channels = $inputChannels; $sentId = \explode('-', $id); if (count($sentId) !== 4) { return false; } $bookId = (int) $sentId[0]; if ($bookId < 1000) { if ($mode === 'read') { $originalChannelId = ChannelApi::getSysChannel('_System_Pali_VRI_'); } else { $originalChannelId = ChannelApi::getSysChannel('_System_Wbw_VRI_'); } } else { $originalChannelId = CustomBook::where('book_id', $bookId)->value('channel_id'); } if (isset($originalChannelId) && $originalChannelId) { array_push($channels, $originalChannelId); } $record = Sentence::select($this->selectCol) ->where('book_id', $sentId[0]) ->where('paragraph', $sentId[1]) ->where('word_start', (int) $sentId[2]) ->where('word_end', (int) $sentId[3]) ->whereIn('channel_uid', $channels) ->get(); $channelIndex = $this->getChannelIndex($channels); if (isset($toSentFormat)) { foreach ($toSentFormat as $key => $org) { $record[] = $org; } } // 获取wbw channel // 目前默认的 wbw channel 是第一个translation channel foreach ($channels as $channel) { // code... if ($channelIndex[$channel]->type === 'translation') { $this->wbwChannels[] = $channel; break; } } return $this->makeContent($record, $mode, $channelIndex, [], $onlyProps, false, $format); } /** * Display the specified resource. * * @return Response */ public function showSent(Request $request, string $id) { $user = AuthService::current($request); if ($user) { $this->userUuid = $user['user_uid']; } $channels = \explode('_', $request->get('channels')); $this->result['uid'] = ''; $this->result['title'] = ''; $this->result['subtitle'] = ''; $this->result['summary'] = ''; $this->result['lang'] = ''; $this->result['status'] = 30; $this->result['content'] = $this->getSentTpl($id, $channels, $request->get('mode', 'edit')); return $this->ok($this->result); } /** * 获取某句子的全部译文 * * @return Response */ public function showSentences(Request $request, string $type, string $id) { $user = AuthService::current($request); if ($user) { $this->userUuid = $user['user_uid']; } $param = \explode('_', $id); $sentId = \explode('-', $param[0]); $channels = []; // 获取channel类型 $sentChannel = Sentence::select('channel_uid') ->where('book_id', $sentId[0]) ->where('paragraph', $sentId[1]) ->where('word_start', $sentId[2]) ->where('word_end', $sentId[3]) ->get(); foreach ($sentChannel as $key => $value) { // code... $channels[] = $value->channel_uid; } $channelInfo = Channel::whereIn('uid', $channels)->select(['uid', 'type', 'lang', 'name'])->get(); $indexChannel = []; $channels = []; foreach ($channelInfo as $key => $value) { // code... if ($value->type === $type) { $indexChannel[$value->uid] = $value; $channels[] = $value->uid; } } // 获取句子数据 $record = Sentence::select($this->selectCol) ->where('book_id', $sentId[0]) ->where('paragraph', $sentId[1]) ->where('word_start', $sentId[2]) ->where('word_end', $sentId[3]) ->whereIn('channel_uid', $channels) ->orderBy('paragraph') ->orderBy('word_start') ->get(); if (count($record) === 0) { return $this->error('no data'); } $this->result['uid'] = ''; $this->result['title'] = ''; $this->result['subtitle'] = ''; $this->result['summary'] = ''; $this->result['lang'] = ''; $this->result['status'] = 30; $this->result['content'] = $this->makeContent($record, 'read', $indexChannel); // TODO 检查一下这个read为什么要写死 return $this->ok($this->result); } /** * Store a newly created resource in storage. * * @param string $id * @param string $mode * @return Response */ public function showPara(Request $request) { if ($request->has('debug')) { $this->debug = explode(',', $request->get('debug')); } $user = AuthService::current($request); if ($user) { $this->userUuid = $user['user_uid']; } // $channels = []; if ($request->get('mode') === 'edit') { // 翻译模式加载json格式原文 $channels[] = ChannelApi::getSysChannel('_System_Wbw_VRI_'); } else { // 阅读模式加载html格式原文 $channels[] = ChannelApi::getSysChannel('_System_Pali_VRI_'); } if ($request->has('channels')) { if (strpos($request->get('channels'), ',') === false) { $getChannel = explode('_', $request->get('channels')); } else { $getChannel = explode(',', $request->get('channels')); } $channels = array_merge($channels, $getChannel); } $para = explode(',', $request->get('par')); // 段落所在章节 $parent = PaliText::where('book', $request->get('book')) ->where('paragraph', $para[0])->first(); $chapter = PaliText::where('book', $request->get('book')) ->where('paragraph', $parent->parent)->first(); if ($chapter) { if (empty($chapter->toc)) { $this->result['title'] = 'unknown'; } else { $this->result['title'] = $chapter->toc; $this->result['sub_title'] = $chapter->toc; $this->result['path'] = json_decode($parent->path); } } $paraFrom = $para[0]; $paraTo = end($para); $indexedHeading = []; // 获取channel索引表 $tranChannels = []; $channelInfo = Channel::whereIn('uid', $channels) ->select(['uid', 'type', 'lang', 'name'])->get(); foreach ($channelInfo as $key => $value) { // code... if ($value->type === 'translation') { $tranChannels[] = $value->uid; } } $indexChannel = []; $indexChannel = $this->getChannelIndex($channels); // 获取wbw channel // 目前默认的 wbw channel 是第一个translation channel foreach ($channels as $key => $value) { // code... if ( isset($indexChannel[$value]) && $indexChannel[$value]->type === 'translation' ) { $this->wbwChannels[] = $value; break; } } // 章节译文标题 $title = Sentence::select($this->selectCol) ->where('book_id', $parent->book) ->where('paragraph', $parent->parent) ->whereIn('channel_uid', $tranChannels) ->first(); if ($title) { $this->result['title'] = MdRender::render($title->content, [$title->channel_uid]); } /** * 获取句子数据 */ $record = Sentence::select($this->selectCol) ->where('book_id', $request->get('book')) ->whereIn('paragraph', $para) ->whereIn('channel_uid', $channels) ->orderBy('paragraph') ->orderBy('word_start') ->get(); if (count($record) === 0) { $this->result['content'] = 'No Data'; } else { $this->result['content'] = $this->makeContent($record, $request->get('mode', 'read'), $indexChannel, $indexedHeading, false, true); } return $this->ok($this->result); } /** * Store a newly created resource in storage. * * @return Response */ public function showChapter(Request $request, string $id) { if ($request->has('debug')) { $this->debug = explode(',', $request->get('debug')); } $user = AuthService::current($request); if ($user) { $this->userUuid = $user['user_uid']; } // $sentId = \explode('-', $id); $channels = []; if ($request->has('channels')) { if (strpos($request->get('channels'), ',') === false) { $_channels = explode('_', $request->get('channels')); } else { $_channels = explode(',', $request->get('channels')); } foreach ($_channels as $key => $channel) { if (Str::isUuid($channel)) { $channels[] = $channel; } } } $mode = $request->get('mode', 'read'); if ($mode === 'read') { // 阅读模式加载html格式原文 $channelId = ChannelApi::getSysChannel('_System_Pali_VRI_'); } else { // 翻译模式加载json格式原文 $channelId = ChannelApi::getSysChannel('_System_Wbw_VRI_'); } if ($channelId !== false) { $channels[] = $channelId; } $chapter = PaliText::where('book', $sentId[0])->where('paragraph', $sentId[1])->first(); if (! $chapter) { return $this->error('no data'); } $paraFrom = $sentId[1]; $paraTo = $sentId[1] + $chapter->chapter_len - 1; if (empty($chapter->toc)) { $this->result['title'] = 'unknown'; } else { $this->result['title'] = $chapter->toc; $this->result['sub_title'] = $chapter->toc; $this->result['path'] = json_decode($chapter->path); } // 获取标题 $heading = PaliText::select(['book', 'paragraph', 'level']) ->where('book', $sentId[0]) ->whereBetween('paragraph', [$paraFrom, $paraTo]) ->where('level', '<', 8) ->get(); // 将标题段落转成索引数组 以便输出标题层级 $indexedHeading = []; foreach ($heading as $key => $value) { // code... $indexedHeading["{$value->book}-{$value->paragraph}"] = $value->level; } // 获取channel索引表 $tranChannels = []; $channelInfo = Channel::whereIn('uid', $channels) ->select(['uid', 'type', 'lang', 'name'])->get(); foreach ($channelInfo as $key => $value) { // code... if ($value->type === 'translation') { $tranChannels[] = $value->uid; } } $indexChannel = []; $indexChannel = $this->getChannelIndex($channels); // 获取wbw channel // 目前默认的 wbw channel 是第一个translation channel // TODO 处理不存在的channel id foreach ($channels as $key => $value) { // code... if ( isset($indexChannel[$value]) && $indexChannel[$value]->type === 'translation' ) { $this->wbwChannels[] = $value; break; } } $title = Sentence::select($this->selectCol) ->where('book_id', $sentId[0]) ->where('paragraph', $sentId[1]) ->whereIn('channel_uid', $tranChannels) ->first(); if ($title) { $this->result['title'] = MdRender::render($title->content, [$title->channel_uid]); $mdRender = new MdRender(['format' => 'simple']); $this->result['title_text'] = $mdRender->convert($title->content, [$title->channel_uid]); } /** * 获取句子数据 * 算法: * 1. 如果标题和下一级第一个标题之间有段落。只输出这些段落和子目录 * 2. 如果标题和下一级第一个标题之间没有间隔 且 chapter 长度大于10000个字符 且有子目录,只输出子目录 * 3. 如果二者都不是,lazy load */ // 1. 计算 标题和下一级第一个标题之间 是否有间隔 $nextChapter = PaliText::where('book', $sentId[0]) ->where('paragraph', '>', $sentId[1]) ->where('level', '<', 8) ->orderBy('paragraph') ->value('paragraph'); $between = $nextChapter - $sentId[1]; // 查找子目录 $chapterLen = $chapter->chapter_len; $toc = PaliText::where('book', $sentId[0]) ->whereBetween('paragraph', [$paraFrom + 1, $paraFrom + $chapterLen - 1]) ->where('level', '<', 8) ->orderBy('paragraph') ->select(['book', 'paragraph', 'level', 'toc']) ->get(); $maxLen = 3000; if ($between > 1) { // 有间隔 $paraTo = $nextChapter - 1; } else { if ($chapter->chapter_strlen > $maxLen) { if (count($toc) > 0) { // 有子目录只输出标题和目录 $paraTo = $paraFrom; } else { // 没有子目录 全部输出 } } else { // 章节小。全部输出 不输出子目录 $toc = []; } } $pFrom = $request->get('from', $paraFrom); $pTo = $request->get('to', $paraTo); // 根据句子的长度找到这次应该加载的段落 $paliText = PaliText::select(['paragraph', 'lenght']) ->where('book', $sentId[0]) ->whereBetween('paragraph', [$pFrom, $pTo]) ->orderBy('paragraph') ->get(); $sumLen = 0; $currTo = $pTo; foreach ($paliText as $para) { $sumLen += $para->lenght; if ($sumLen > $maxLen) { $currTo = $para->paragraph; break; } } $record = Sentence::select($this->selectCol) ->where('book_id', $sentId[0]) ->whereBetween('paragraph', [$pFrom, $currTo]) ->whereIn('channel_uid', $channels) ->orderBy('paragraph') ->orderBy('word_start') ->get(); if (count($record) === 0) { return $this->error('no data'); } $this->result['content'] = $this->makeContent($record, $mode, $indexChannel, $indexedHeading, false, true); if (! $request->has('from')) { // 第一次才显示toc $this->result['toc'] = TocResource::collection($toc); } if ($currTo < $pTo) { $this->result['from'] = $currTo + 1; $this->result['to'] = $pTo; $this->result['paraId'] = $id; $this->result['channels'] = $request->get('channels'); $this->result['mode'] = $request->get('mode'); } return $this->ok($this->result); } private function getChannelIndex($channels, $type = null) { // 获取channel索引表 $channelInfo = Channel::whereIn('uid', $channels) ->select(['uid', 'type', 'name', 'lang', 'owner_uid']) ->get(); $indexChannel = []; foreach ($channels as $key => $channelId) { $channelInfo = Channel::where('uid', $channelId) ->select(['uid', 'type', 'name', 'lang', 'owner_uid'])->first(); if (! $channelInfo) { Log::error('no channel id'.$channelId); continue; } if ($type !== null && $channelInfo->type !== $type) { continue; } $indexChannel[$channelId] = $channelInfo; $indexChannel[$channelId]->studio = StudioApi::getById($channelInfo->owner_uid); } return $indexChannel; } /** * 根据句子库数据生成文章内容 * $record 句子数据 * $mode read | edit | wbw * $indexChannel channel索引 * $indexedHeading 标题索引 用于给段落加标题标签

ect. */ private function makeContent($record, $mode, $indexChannel, $indexedHeading = [], $onlyProps = false, $paraMark = false, $format = 'react') { $content = []; $lastSent = '0-0'; $sentCount = 0; $sent = []; $sent['origin'] = []; $sent['translation'] = []; $sent['commentaries'] = []; // 获取句子编号列表 $sentList = []; foreach ($record as $key => $value) { $currSentId = "{$value->book_id}-{$value->paragraph}-{$value->word_start}-{$value->word_end}"; $sentList[$currSentId] = [$value->book_id, $value->paragraph, $value->word_start, $value->word_end]; $value->sid = "{$currSentId}_{$value->channel_uid}"; } $channelsId = []; foreach ($indexChannel as $channelId => $info) { $channelsId[] = $channelId; } array_pop($channelsId); // 遍历列表查找每个句子的所有channel的数据,并填充 $currPara = ''; foreach ($sentList as $currSentId => $arrSentId) { $para = $arrSentId[0].'-'.$arrSentId[1]; if ($currPara !== $para) { $currPara = $para; // 输出段落标记 if ($paraMark) { $sentInPara = []; foreach ($sentList as $sentId => $sentParam) { if ( $sentParam[0] === $arrSentId[0] && $sentParam[1] === $arrSentId[1] ) { $sentInPara[] = $sentId; } } // 输出段落起始 if (! empty($currPara)) { $content[] = ''; } $markProps = base64_encode(\json_encode([ 'book' => $arrSentId[0], 'para' => $arrSentId[1], 'channels' => $channelsId, 'sentences' => $sentInPara, 'mode' => $mode, ])); $content[] = ""; } } $sent = $this->newSent($arrSentId[0], $arrSentId[1], $arrSentId[2], $arrSentId[3]); foreach ($indexChannel as $channelId => $info) { // code... $sid = "{$currSentId}_{$channelId}"; if (isset($info->studio)) { $studioInfo = $info->studio; } else { $studioInfo = null; } $newSent = [ 'content' => '', 'html' => '', 'book' => $arrSentId[0], 'para' => $arrSentId[1], 'wordStart' => $arrSentId[2], 'wordEnd' => $arrSentId[3], 'channel' => [ 'name' => $info->name, 'type' => $info->type, 'id' => $info->uid, 'lang' => $info->lang, ], 'studio' => $studioInfo, 'updateAt' => '', 'suggestionCount' => SuggestionApi::getCountBySent($arrSentId[0], $arrSentId[1], $arrSentId[2], $arrSentId[3], $channelId), ]; $row = Arr::first($record, function ($value, $key) use ($sid) { return $value->sid === $sid; }); if ($row) { $newSent['id'] = $row->uid; $newSent['content'] = $row->content; $newSent['contentType'] = $row->content_type; $newSent['html'] = ''; $newSent['editor'] = UserApi::getByUuid($row->editor_uid); /** * TODO 刷库改数据 * 旧版api没有更新updated_at所以造成旧版的数据updated_at数据比modify_time 要晚 */ $newSent['forkAt'] = $row->fork_at; // $newSent['updateAt'] = $row->updated_at; // $newSent['updateAt'] = date('Y-m-d H:i:s.', $row->modify_time / 1000).($row->modify_time % 1000).' UTC'; $newSent['createdAt'] = $row->created_at; if ($mode !== 'read') { if (isset($row->acceptor_uid) && ! empty($row->acceptor_uid)) { $newSent['acceptor'] = UserApi::getByUuid($row->acceptor_uid); $newSent['prEditAt'] = $row->pr_edit_at; } } switch ($info->type) { case 'wbw': case 'original': // // 在编辑模式下。 // 如果是原文,查看是否有逐词解析数据, // 有的话优先显示。 // 阅读模式直接显示html原文 // 传过来的数据一定有一个原文channel // if ($mode === 'read') { $newSent['content'] = ''; $newSent['html'] = MdRender::render( $row->content, [$row->channel_uid], null, $mode, 'translation', $row->content_type, $format ); } else { if ($row->content_type === 'json') { $newSent['channel']['type'] = 'wbw'; if (isset($this->wbwChannels[0])) { $newSent['channel']['name'] = $indexChannel[$this->wbwChannels[0]]->name; $newSent['channel']['lang'] = $indexChannel[$this->wbwChannels[0]]->lang; $newSent['channel']['id'] = $this->wbwChannels[0]; // 存在一个translation channel // 尝试查找逐词解析数据。找到,替换现有数据 $wbwData = $this->getWbw( $arrSentId[0], $arrSentId[1], $arrSentId[2], $arrSentId[3], $this->wbwChannels[0] ); if ($wbwData) { $newSent['content'] = $wbwData; $newSent['contentType'] = 'json'; $newSent['html'] = ''; $newSent['studio'] = $indexChannel[$this->wbwChannels[0]]->studio; } } } else { $newSent['content'] = $row->content; $newSent['html'] = MdRender::render( $row->content, [$row->channel_uid], null, $mode, 'translation', $row->content_type, $format ); } } break; case 'nissaya': $newSent['html'] = Cache::remember( "/sent/{$channelId}/{$currSentId}/{$format}", config('mint.cache.expire'), function () use ($row, $mode, $format) { return MdRender::render( $row->content, [$row->channel_uid], null, $mode, 'nissaya', $row->content_type, $format ); } ); break; case 'commentary': $options = [ 'debug' => $this->debug, 'format' => $format, 'mode' => $mode, 'channelType' => 'translation', 'contentType' => $row->content_type, ]; $mdRender = new MdRender($options); $newSent['html'] = $mdRender->convert($row->content, $channelsId); break; default: $options = [ 'debug' => $this->debug, 'format' => $format, 'mode' => $mode, 'channelType' => 'translation', 'contentType' => $row->content_type, ]; $mdRender = new MdRender($options); $newSent['html'] = $mdRender->convert($row->content, [$row->channel_uid]); // Log::debug('md render', ['content' => $row->content, 'options' => $options, 'render' => $newSent['html']]); break; } } switch ($info->type) { case 'wbw': case 'original': array_push($sent['origin'], $newSent); break; case 'commentary': array_push($sent['commentaries'], $newSent); break; default: array_push($sent['translation'], $newSent); break; } } if ($onlyProps) { return $sent; } $content = $this->pushSent($content, $sent, 0, $mode); } if ($paraMark) { $content[] = ''; } $output = \implode('', $content); return "
{$output}
"; } public function getWbw($book, $para, $start, $end, $channel) { /** * 非阅读模式下。原文使用逐词解析数据。 * 优先加载第一个translation channel 如果没有。加载默认逐词解析。 */ // 获取逐词解析数据 $wbwBlock = WbwBlock::where('channel_uid', $channel) ->where('book_id', $book) ->where('paragraph', $para) ->select('uid') ->first(); if (! $wbwBlock) { return false; } // 找到逐词解析数据 $wbwData = Wbw::where('block_uid', $wbwBlock->uid) ->whereBetween('wid', [$start, $end]) ->select(['book_id', 'paragraph', 'wid', 'data', 'uid', 'editor_id', 'created_at', 'updated_at']) ->orderBy('wid') ->get(); $wbwContent = []; foreach ($wbwData as $wbwrow) { $wbw = str_replace(' ', ' ', $wbwrow->data); $wbw = str_replace('
', ' ', $wbw); $xmlString = ''.$wbw.''; try { $xmlWord = simplexml_load_string($xmlString); $wordsList = $xmlWord->xpath('//word'); } catch (\Exception $e) { Log::error('corpus getWbw', ['error' => $e, 'data' => $xmlString]); return false; } foreach ($wordsList as $word) { $case = \str_replace(['#', '.'], ['$', ''], $word->case->__toString()); $case = \str_replace('$$', '$', $case); $case = trim($case); $case = trim($case, '$'); $wbwId = explode('-', $word->id->__toString()); $wbwData = [ 'uid' => $wbwrow->uid, 'book' => $wbwrow->book_id, 'para' => $wbwrow->paragraph, 'sn' => array_slice($wbwId, 2), 'word' => ['value' => $word->pali->__toString(), 'status' => 0], 'real' => ['value' => $word->real->__toString(), 'status' => 0], 'meaning' => ['value' => $word->mean->__toString(), 'status' => 0], 'type' => ['value' => $word->type->__toString(), 'status' => 0], 'grammar' => ['value' => $word->gramma->__toString(), 'status' => 0], 'case' => ['value' => $word->case->__toString(), 'status' => 0], 'parent' => ['value' => $word->parent->__toString(), 'status' => 0], 'style' => ['value' => $word->style->__toString(), 'status' => 0], 'factors' => ['value' => $word->org->__toString(), 'status' => 0], 'factorMeaning' => ['value' => $word->om->__toString(), 'status' => 0], 'confidence' => $word->cf->__toString(), 'created_at' => $wbwrow->created_at, 'updated_at' => $wbwrow->updated_at, 'hasComment' => Discussion::where('res_id', $wbwrow->uid)->exists(), ]; if (isset($word->parent2)) { $wbwData['parent2']['value'] = $word->parent2->__toString(); if (isset($word->parent2['status'])) { $wbwData['parent2']['status'] = (int) $word->parent2['status']; } else { $wbwData['parent2']['status'] = 0; } } if (isset($word->pg)) { $wbwData['grammar2']['value'] = $word->pg->__toString(); if (isset($word->pg['status'])) { $wbwData['grammar2']['status'] = (int) $word->pg['status']; } else { $wbwData['grammar2']['status'] = 0; } } if (isset($word->rela)) { $wbwData['relation']['value'] = $word->rela->__toString(); if (isset($word->rela['status'])) { $wbwData['relation']['status'] = (int) $word->rela['status']; } else { $wbwData['relation']['status'] = 7; } } if (isset($word->bmt)) { $wbwData['bookMarkText']['value'] = $word->bmt->__toString(); if (isset($word->bmt['status'])) { $wbwData['bookMarkText']['status'] = (int) $word->bmt['status']; } else { $wbwData['bookMarkText']['status'] = 7; } } if (isset($word->bmc)) { $wbwData['bookMarkColor']['value'] = $word->bmc->__toString(); if (isset($word->bmc['status'])) { $wbwData['bookMarkColor']['status'] = (int) $word->bmc['status']; } else { $wbwData['bookMarkColor']['status'] = 7; } } if (isset($word->note)) { $wbwData['note']['value'] = $word->note->__toString(); if (isset($word->note['status'])) { $wbwData['note']['status'] = (int) $word->note['status']; } else { $wbwData['note']['status'] = 7; } } if (isset($word->cf)) { $wbwData['confidence'] = (float) $word->cf->__toString(); } if (isset($word->attachments)) { $wbwData['attachments'] = json_decode($word->attachments->__toString()); } if (isset($word->pali['status'])) { $wbwData['word']['status'] = (int) $word->pali['status']; } if (isset($word->real['status'])) { $wbwData['real']['status'] = (int) $word->real['status']; } if (isset($word->mean['status'])) { $wbwData['meaning']['status'] = (int) $word->mean['status']; } if (isset($word->type['status'])) { $wbwData['type']['status'] = (int) $word->type['status']; } if (isset($word->gramma['status'])) { $wbwData['grammar']['status'] = (int) $word->gramma['status']; } if (isset($word->case['status'])) { $wbwData['case']['status'] = (int) $word->case['status']; } if (isset($word->parent['status'])) { $wbwData['parent']['status'] = (int) $word->parent['status']; } if (isset($word->org['status'])) { $wbwData['factors']['status'] = (int) $word->org['status']; } if (isset($word->om['status'])) { $wbwData['factorMeaning']['status'] = (int) $word->om['status']; } $wbwContent[] = $wbwData; } } if (count($wbwContent) === 0) { return false; } return \json_encode($wbwContent, JSON_UNESCAPED_UNICODE); } /** * 将句子放进结果列表 */ private function pushSent($result, $sent, $level = 0, $mode = 'read') { $sentProps = base64_encode(\json_encode($sent)); if ($mode === 'read') { $sentWidget = ""; } else { $sentWidget = ""; } // 增加标题的html标记 if ($level > 0) { $sentWidget = "".$sentWidget.""; } array_push($result, $sentWidget); return $result; } private function newSent($book, $para, $word_start, $word_end) { $sent = [ 'id' => "{$book}-{$para}-{$word_start}-{$word_end}", 'book' => $book, 'para' => $para, 'wordStart' => $word_start, 'wordEnd' => $word_end, 'origin' => [], 'translation' => [], 'commentaries' => [], ]; if ($book < 1000) { // 生成channel 数量列表 $sentId = "{$book}-{$para}-{$word_start}-{$word_end}"; $channelCount = CorpusController::_sentCanReadCount($book, $para, $word_start, $word_end, $this->userUuid); $path = json_decode(PaliText::where('book', $book)->where('paragraph', $para)->value('path'), true); $sent['path'] = []; foreach ($path as $key => $value) { // code... $value['paliTitle'] = $value['title']; $sent['path'][] = $value; } $sent['tranNum'] = $channelCount['tranNum']; $sent['nissayaNum'] = $channelCount['nissayaNum']; $sent['commNum'] = $channelCount['commNum']; $sent['originNum'] = $channelCount['originNum']; $sent['simNum'] = $channelCount['simNum']; } return $sent; } public static function _sentCanReadCount($book, $para, $start, $end, $userUuid = null) { $keyCanRead = '/channel/can-read/'; if ($userUuid) { $keyCanRead .= $userUuid; } else { $keyCanRead .= 'guest'; } $channelCanRead = Cache::remember( $keyCanRead, config('mint.cache.expire'), function () use ($userUuid) { return ChannelApi::getCanReadByUser($userUuid); } ); $channels = Sentence::where('book_id', $book) ->where('paragraph', $para) ->where('word_start', $start) ->where('word_end', $end) ->where('strlen', '<>', 0) ->whereIn('channel_uid', $channelCanRead) ->select('channel_uid') ->groupBy('channel_uid') ->get(); $channelList = []; foreach ($channels as $key => $value) { // code... if (Str::isUuid($value->channel_uid)) { $channelList[] = $value->channel_uid; } } $simId = PaliSentence::where('book', $book) ->where('paragraph', $para) ->where('word_begin', $start) ->where('word_end', $end) ->value('id'); if ($simId) { $output['simNum'] = SentSimIndex::where('sent_id', $simId)->value('count'); } else { $output['simNum'] = 0; } $channelInfo = Channel::whereIn('uid', $channelList)->select('type')->get(); $output['tranNum'] = 0; $output['nissayaNum'] = 0; $output['commNum'] = 0; $output['originNum'] = 0; foreach ($channelInfo as $key => $value) { // code... switch ($value->type) { case 'translation': $output['tranNum']++; break; case 'nissaya': $output['nissayaNum']++; break; case 'commentary': $output['commNum']++; break; case 'original': $output['originNum']++; break; } } return $output; } /** * 获取某个句子的相关资源的句子数量 */ public static function sentCanReadCount($book, $para, $start, $end, $userUuid = null) { $sentId = "{$book}-{$para}-{$start}-{$end}"; $hKey = "/sentence/res-count/{$sentId}/"; if ($userUuid) { $key = $userUuid; } else { $key = 'guest'; } if (Redis::hExists($hKey, $key)) { return json_decode(Redis::hGet($hKey, $key), true); } else { $channelCount = CorpusController::_sentCanReadCount($book, $para, $start, $end, $userUuid); Redis::hSet($hKey, $key, json_encode($channelCount)); return $channelCount; } } private function markdownRender($input) {} /** * Update the specified resource in storage. * * @return Response */ public function update(Request $request, Sentence $sentence) { // } /** * Remove the specified resource from storage. * * @return Response */ public function destroy(Sentence $sentence) { // } }