articleService = $article; $this->paliContentService = $paliContent; $this->translateService = $translateService; $this->sentenceService = $sentenceService; } /** * 设置模型配置 * * @param string $model * @return self */ public function setModel(string $model): self { $this->modelId = $model; return $this; } /** * 设置模型配置 * * @param string $model * @return self */ public function setChannel(string $id): self { $this->outputChannelId = $id; return $this; } public function translateAnthology($anthologyId, ?callable $onEach = null): int { $articles = $this->articleService->articlesInAnthology($anthologyId); foreach ($articles as $article) { $sentences = $this->translateArticle($article)->save(); if ($onEach) { $onEach($article, $sentences); } } return count($articles); } public function translateArticle(string $articleId) { //获取文章中的句子id $sentenceIds = $this->articleService->sentenceIds($articleId); if (!$sentenceIds || count($sentenceIds) === 0) { $this->translation = []; return $this; } $bookId = (int)explode('-', $sentenceIds[0])[0]; //提取原文 $originalChannelId = CustomBook::where('book_id', $bookId)->value('channel_id'); $original = $this->paliContentService->sentences($sentenceIds, [$originalChannelId], 'read'); $orgData = []; foreach ($original as $key => $paragraph) { foreach ($paragraph['children'] as $key => $sent) { $org = $sent['origin'][0]; $orgData[] = [ 'id' => "{$org['book']}-{$org['para']}-{$org['wordStart']}-{$org['wordEnd']}", 'content' => !empty($org['content']) ? $org['content'] : $org['html'], ]; } } //翻译 $result = $this->translateService->setModel($this->modelId) ->setSystemPrompt($this->systemPrompt) ->setTranslatePrompt("# 原文\n\n" . "```json\n" . json_encode($orgData, JSON_UNESCAPED_UNICODE) . "\n```") ->translate(); Log::debug('ai translation', ['data' => $result->toArray()['data']]); $this->translation = $result->toArray()['data']; return $this; } //写入结果channel public function save() { if ( !is_array($this->translation) || count($this->translation) === 0 ) { return 0; } $channelInfo = ChannelApi::getById($this->outputChannelId); $sentData = []; $sentData = array_map(function ($n) use ($channelInfo) { $sId = explode('-', $n['id']); return [ 'book_id' => $sId[0], 'paragraph' => $sId[1], 'word_start' => $sId[2], 'word_end' => $sId[3], 'channel_uid' => $channelInfo['id'], 'content' => $n['content'], 'content_type' => $n['content_type'] ?? 'markdown', 'lang' => $channelInfo['lang'], 'status' => $channelInfo['status'], 'editor_uid' => $this->modelId, ]; }, $this->translation); foreach ($sentData as $value) { $this->sentenceService->save($value); } return count($sentData); } public function get() { return $this->translation; } }