Browse Source

Merge pull request #2393 from visuddhinanda/development

Development
visuddhinanda 4 days ago
parent
commit
a288dfb86d
44 changed files with 526 additions and 565 deletions
  1. 1 1
      api-v13/app/Console/Commands/ExportChannel.php
  2. 1 1
      api-v13/app/Console/Commands/ExportChapterIndex.php
  3. 1 1
      api-v13/app/Console/Commands/ExportPalitext.php
  4. 1 1
      api-v13/app/Console/Commands/ExportSentence.php
  5. 1 1
      api-v13/app/Console/Commands/ExportTag.php
  6. 1 1
      api-v13/app/Console/Commands/ExportTagmap.php
  7. 1 1
      api-v13/app/Console/Commands/ExportTerm.php
  8. 63 64
      api-v13/app/Console/Commands/IndexTerm.php
  9. 0 2
      api-v13/app/Console/Commands/MqAiTranslate.php
  10. 43 9
      api-v13/app/Console/Commands/UpgradeProgress.php
  11. 296 259
      api-v13/app/Console/Commands/UpgradeProgressChapter.php
  12. 116 118
      api-v13/app/Console/Commands/UpgradeProgressPara.php
  13. 0 2
      api-v13/app/Http/Api/AiAssistantApi.php
  14. 0 6
      api-v13/app/Http/Api/AiTaskPrepare.php
  15. 0 2
      api-v13/app/Http/Api/TaskApi.php
  16. 0 3
      api-v13/app/Http/Api/TemplateRender.php
  17. 0 2
      api-v13/app/Http/Api/UserApi.php
  18. 0 2
      api-v13/app/Http/Api/WatchApi.php
  19. 0 2
      api-v13/app/Http/Controllers/AccessTokenController.php
  20. 0 2
      api-v13/app/Http/Controllers/AiModelController.php
  21. 1 16
      api-v13/app/Http/Controllers/ArticleController.php
  22. 0 1
      api-v13/app/Http/Controllers/ArticleFtsController.php
  23. 0 2
      api-v13/app/Http/Controllers/ArticleMapController.php
  24. 0 5
      api-v13/app/Http/Controllers/AuthController.php
  25. 0 3
      api-v13/app/Http/Controllers/ChannelController.php
  26. 0 6
      api-v13/app/Http/Controllers/CollectionController.php
  27. 0 5
      api-v13/app/Http/Controllers/DiscussionCountController.php
  28. 0 5
      api-v13/app/Http/Controllers/Library/BookController.php
  29. 0 2
      api-v13/app/Http/Controllers/Library/HomeController.php
  30. 0 4
      api-v13/app/Http/Controllers/ProjectController.php
  31. 0 2
      api-v13/app/Http/Controllers/SearchController.php
  32. 0 7
      api-v13/app/Http/Controllers/SentenceController.php
  33. 0 3
      api-v13/app/Http/Controllers/TaskController.php
  34. 0 2
      api-v13/app/Http/Controllers/TaskGroupController.php
  35. 0 3
      api-v13/app/Http/Controllers/TaskStatusController.php
  36. 0 3
      api-v13/app/Http/Controllers/WbwLookupController.php
  37. 0 1
      api-v13/app/Http/Controllers/WordIndexController.php
  38. 0 4
      api-v13/app/Http/Middleware/UserOperation.php
  39. 0 2
      api-v13/app/Http/Requests/StoreDiscussionRequest.php
  40. 0 1
      api-v13/app/Http/Resources/SearchBookResource.php
  41. 0 2
      api-v13/app/Http/Resources/SentenceAttachmentResource.php
  42. 0 2
      api-v13/app/Mail/EmailCertif.php
  43. 0 1
      api-v13/app/Services/AiTranslateService.php
  44. 0 3
      api-v13/app/Tools/PaliSearch.php

+ 1 - 1
api-v13/app/Console/Commands/ExportChannel.php

@@ -57,7 +57,7 @@ class ExportChannel extends Command
         try{
             $stmt = $dbh->prepare($query);
         }catch(PDOException $e){
-            Log::info($e);
+            Log::error($e->getMessage(), ['exception' => $e]);
             return 1;
         }
 

+ 1 - 1
api-v13/app/Console/Commands/ExportChapterIndex.php

@@ -58,7 +58,7 @@ class ExportChapterIndex extends Command
         try {
             $stmt = $dbh->prepare($query);
         } catch (\PDOException $e) {
-            Log::info($e);
+            Log::error($e->getMessage(), ['exception' => $e]);
             return 1;
         }
 

+ 1 - 1
api-v13/app/Console/Commands/ExportPalitext.php

@@ -55,7 +55,7 @@ class ExportPalitext extends Command
         try{
             $stmt = $dbh->prepare($query);
         }catch(PDOException $e){
-            Log::info($e);
+            Log::error($e->getMessage(), ['exception' => $e]);
             return 1;
         }
 

+ 1 - 1
api-v13/app/Console/Commands/ExportSentence.php

@@ -90,7 +90,7 @@ class ExportSentence extends Command
         try{
             $stmt = $dbh->prepare($query);
         }catch(PDOException $e){
-            Log::info($e);
+            Log::error($e->getMessage(), ['exception' => $e]);
             return 1;
         }
 

+ 1 - 1
api-v13/app/Console/Commands/ExportTag.php

@@ -55,7 +55,7 @@ class ExportTag extends Command
         try{
             $stmt = $dbh->prepare($query);
         }catch(PDOException $e){
-            Log::info($e);
+            Log::error($e->getMessage(), ['exception' => $e]);
             return 1;
         }
 

+ 1 - 1
api-v13/app/Console/Commands/ExportTagmap.php

@@ -54,7 +54,7 @@ class ExportTagmap extends Command
         try{
             $stmt = $dbh->prepare($query);
         }catch(PDOException $e){
-            Log::info($e);
+            Log::error($e->getMessage(), ['exception' => $e]);
             return 1;
         }
 

+ 1 - 1
api-v13/app/Console/Commands/ExportTerm.php

@@ -61,7 +61,7 @@ class ExportTerm extends Command
         try{
             $stmt = $dbh->prepare($query);
         }catch(PDOException $e){
-            Log::info($e);
+            Log::error($e->getMessage(), ['exception' => $e]);
             return 1;
         }
 

+ 63 - 64
api-v13/app/Console/Commands/IndexTerm.php

@@ -3,40 +3,26 @@
 namespace App\Console\Commands;
 
 use App\Models\DhammaTerm;
-use Illuminate\Console\Command;
 use App\Services\OpenSearchService;
 use App\Services\TermService;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Log;
 
 class IndexTerm extends Command
 {
-    /**
-     * The name and signature of the console command.
-     *
-     * @var string
-     *
-     * @example
-     *   php artisan opensearch:index-term
-     *   php artisan opensearch:index-term --word=anomadassī
-     *   php artisan opensearch:index-term --test
-     */
     protected $signature = 'opensearch:index-term
         {--test}
-        {--word= : 指定单个词条进行索引,省略则索引全部}';
+        {--word= : 指定单个词条进行索引,省略则索引全部}
+        {--fresh : 清除缓存断点,从头开始}';
 
-    /**
-     * The console command description.
-     *
-     * @var string
-     */
-    protected $description = 'Index Term data into OpenSearch';
+    protected $description = 'Index Term data into OpenSearch(可重入:中断后重跑自动跳过已索引的词条)';
+
+    // 缓存键:记录最后成功索引的游标位置,48h 过期
+    private const CACHE_KEY = 'index-term:cursor';
 
-    /** @var bool 是否为测试模式(只打印,不写入 OpenSearch) */
     private bool $isTest = false;
 
-    /**
-     * Create a new command instance.
-     */
     public function __construct(
         protected OpenSearchService $openSearchService,
         protected TermService $termService,
@@ -44,14 +30,6 @@ class IndexTerm extends Command
         parent::__construct();
     }
 
-    /**
-     * Execute the console command.
-     *
-     * 遍历所有(或指定)DhammaTerm,逐条构建文档并写入 OpenSearch。
-     * 测试模式下(--test)只打印文档内容,不执行写入。
-     *
-     * @return int  0 表示成功,1 表示失败
-     */
     public function handle(): int
     {
         $word = $this->option('word');
@@ -61,33 +39,61 @@ class IndexTerm extends Command
             $this->info('test mode');
         }
 
+        if ($this->option('fresh')) {
+            Cache::forget(self::CACHE_KEY);
+            $this->info('Cleared cached cursor.');
+        }
+
         try {
             [$connected, $message] = $this->openSearchService->testConnection();
-            if (!$connected) {
+            if (! $connected) {
                 $this->error($message);
                 Log::error($message);
+
                 return 1;
             }
 
-            $total = DhammaTerm::count();
-            $terms = DhammaTerm::select(['guid', 'word'])->orderBy('updated_at', 'asc');
+            // 按自增 id 排序,保证游标稳定(updated_at 可能在运行中被修改)
+            $terms = DhammaTerm::select(['id', 'guid', 'word'])->orderBy('id');
 
             if ($word) {
                 $terms = $terms->where('word', $word);
             }
 
-            $overallStatus = 0;
+            // 从缓存恢复断点:跳过上次已处理的记录
+            $lastId = Cache::get(self::CACHE_KEY);
+            if ($lastId && ! $word) {
+                $terms = $terms->where('id', '>', $lastId);
+                $this->info("Resuming after id={$lastId}");
+            }
+
+            $total = $terms->count();
+            $this->info("terms to index: {$total}");
+
+            $curr = 0;
+
+            foreach ($terms->cursor() as $term) {
+                $curr++;
+                if ($curr % 10 === 0) {
+                    $percent = (int) ($curr * 100 / $total);
+                    $this->info("[{$percent}%]-{$curr}/{$total}  {$term->word}");
+
+                    // 每 10 条保存一次断点
+                    Cache::put(self::CACHE_KEY, $term->id, now()->addHours(48));
+                }
 
-            foreach ($terms->cursor() as $key => $term) {
-                $percent = (int) (($key * 100) / $total);
-                $this->info("[{$percent}%]-{$key}  " . $term->word);
                 $this->indexTerm($term->guid);
             }
 
-            return $overallStatus;
+            // 全部完成,清除断点缓存
+            Cache::forget(self::CACHE_KEY);
+            $this->info("index-term finished. total: {$curr}");
+
+            return 0;
         } catch (\Exception $e) {
-            $this->error('Failed to index Term data: ' . $e->getMessage());
+            $this->error('Failed to index Term data: '.$e->getMessage());
             Log::error('Failed to index Term data', ['error' => $e]);
+
             return 1;
         }
     }
@@ -101,14 +107,13 @@ class IndexTerm extends Command
      *   content.text.pali / content.text.zh   → 正文内容
      *
      * @param  string  $id  DhammaTerm 的 guid
-     * @return void
      */
     protected function indexTerm(string $id): void
     {
-        $termData    = $this->termService->find($id, 'text');
+        $termData = $this->termService->find($id, 'text');
         $channelName = $termData['channel']['name'] ?? '';
         $isCommunity = $this->termService->isCommunity($termData['channel_id']);
-        $content     = $termData['html'] ?? $termData['meaning'];
+        $content = $termData['html'] ?? $termData['meaning'];
 
         $categories = $this->extractCategories($termData['note'] ?? '');
         $quality = $this->extractFirstQuality($termData['note'] ?? '');
@@ -116,34 +121,34 @@ class IndexTerm extends Command
         foreach ($categories as $key => $category) {
             $tags[] = "category:{$category}";
         }
-        if (!empty($quality)) {
+        if (! empty($quality)) {
             $tags[] = "quality:{$quality}";
         }
         $document = [
-            'id'            => "term_{$id}",
-            'resource_id'   => $id,
+            'id' => "term_{$id}",
+            'resource_id' => $id,
             'resource_type' => 'term',
-            'title'         => [
+            'title' => [
                 'text' => [
                     'pali' => $termData['word'],
-                    'zh'   => $termData['meaning'],
+                    'zh' => $termData['meaning'],
                 ],
                 'suggest' => [
                     'pali' => [$termData['word']],
-                    'zh'   => [$termData['meaning']],
+                    'zh' => [$termData['meaning']],
                 ],
             ],
             'summary' => [
                 'text' => $termData['summary'] ?? '',
             ],
-            'content'     => [],
+            'content' => [],
             'bold_single' => [$termData['meaning'], $termData['word']],
-            'related_id'  => $termData['word'],
-            'category'    => null,
-            'tags'        => $tags,
-            'language'    => $termData['language'],
-            'updated_at'  => now()->toIso8601String(),
-            'path'        => $termData['studio']['realName'] . "/{$channelName}",
+            'related_id' => $termData['word'],
+            'category' => null,
+            'tags' => $tags,
+            'language' => $termData['language'],
+            'updated_at' => now()->toIso8601String(),
+            'path' => $termData['studio']['realName']."/{$channelName}",
             'metadata' => ['channel' => $termData['channel_id']],
         ];
 
@@ -154,11 +159,11 @@ class IndexTerm extends Command
         } else {
             $document['content']['text']['zh'] = $plainText;
         }
-        $document['content']['display']    = $content;             // 展示
+        $document['content']['display'] = $content;             // 展示
 
         if ($this->isTest) {
             $this->info($document['title']['text']['pali']);
-            $this->info($document['summary']['text']);
+            //$this->info($document['summary']['text']);
         } else {
             $this->openSearchService->create($document['id'], $document);
         }
@@ -166,9 +171,6 @@ class IndexTerm extends Command
 
     /**
      * 提取 Markdown 中的 {{category|...}} 分类标签
-     *
-     * @param string $content
-     * @return array
      */
     private function extractCategories(string $content): array
     {
@@ -178,16 +180,13 @@ class IndexTerm extends Command
         preg_match_all('/\{\{category\|([^}]+)\}\}/u', $content, $matches);
 
         return array_values(array_filter(array_map(
-            fn($item) => trim($item),
+            fn ($item) => trim($item),
             $matches[1] ?? []
         )));
     }
 
     /**
      * 提取 Markdown 中第一个 {{quality|...}} 标签内的内容
-     *
-     * @param string $content
-     * @return string
      */
     private function extractFirstQuality(string $content): string
     {

+ 0 - 2
api-v13/app/Console/Commands/MqAiTranslate.php

@@ -68,9 +68,7 @@ class MqAiTranslate extends Command
                 $pointer = Cache::get($pointerKey);
             }
 
-            Log::debug($queue . ' ai assistant token', ['user' => $first->model->uid]);
             $modelToken = $first->model->token;
-            Log::debug($queue . ' ai assistant token', ['token' => $modelToken]);
 
             $this->setTaskStatus($first->task->info->id, 'running', $modelToken);
 

+ 43 - 9
api-v13/app/Console/Commands/UpgradeProgress.php

@@ -5,18 +5,52 @@ namespace App\Console\Commands;
 use Illuminate\Console\Attributes\Description;
 use Illuminate\Console\Attributes\Signature;
 use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Cache;
 
-#[Signature('app:upgrade-progress')]
-#[Description('Command description')]
+#[Signature('app:upgrade-progress {--fresh : Clear cached progress and start from scratch}')]
+#[Description('Run upgrade progress commands (reentrant via Cache)')]
 class UpgradeProgress extends Command
 {
-    /**
-     * Execute the console command.
-     */
-    public function handle()
+    // 缓存已完成的步骤名,使命令可重入:中断后重跑会跳过已完成的子命令
+    private const CACHE_KEY = 'upgrade-progress:completed-steps';
+
+    public function handle(): int
     {
-        //
-        $this->call('upgrade:progress.para');
-        $this->call('upgrade:progress.chapter');
+        if ($this->option('fresh')) {
+            Cache::forget(self::CACHE_KEY);
+            $this->info('Cleared cached progress.');
+        }
+
+        $completedSteps = Cache::get(self::CACHE_KEY, []);
+
+        $steps = [
+            'para' => 'upgrade:progress.para',
+            'chapter' => 'upgrade:progress.chapter',
+        ];
+
+        foreach ($steps as $key => $command) {
+            if (in_array($key, $completedSteps)) {
+                $this->info("Skipping [{$command}] (already completed).");
+
+                continue;
+            }
+
+            $this->info("Running [{$command}]...");
+            $exitCode = $this->call($command);
+
+            if ($exitCode !== 0) {
+                $this->error("[{$command}] failed with exit code {$exitCode}. Re-run to resume.");
+
+                return $exitCode;
+            }
+
+            $completedSteps[] = $key;
+            Cache::put(self::CACHE_KEY, $completedSteps, now()->addHours(48));
+        }
+
+        Cache::forget(self::CACHE_KEY);
+        $this->info('All steps completed.');
+
+        return 0;
     }
 }

+ 296 - 259
api-v13/app/Console/Commands/UpgradeProgressChapter.php

@@ -2,308 +2,345 @@
 
 namespace App\Console\Commands;
 
-use Illuminate\Support\Facades\Log;
-
-use Carbon\Carbon;
-
-use Illuminate\Support\Facades\Validator;
-use Illuminate\Console\Command;
-use App\Models\Sentence;
+use App\Http\Api\MdRender;
+use App\Models\Channel;
 use App\Models\PaliSentence;
+use App\Models\PaliText;
 use App\Models\Progress;
 use App\Models\ProgressChapter;
-use App\Models\PaliText;
-use App\Models\Tag;
+use App\Models\Sentence;
 use App\Models\TagMap;
-use App\Models\Channel;
-use App\Http\Api\MdRender;
 use App\Services\PaliTextService;
+use App\Tools\Markdown;
+use App\Tools\Tools;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\Validator;
 
 class UpgradeProgressChapter extends Command
 {
-    /**
-     * The name and signature of the console command.
-     * php artisan upgrade:progress.chapter --book=168 --para=915 --channel=19f53a65-81db-4b7d-8144-ac33f1217d34
-     * @var string
-     */
-    protected $signature = 'upgrade:progress.chapter  {--book=} {--para=} {--channel=} {--driver=str} {--resume}';
-
-    /**
-     * The console command description.
-     *
-     * @var string
-     */
-    protected $description = '更新章节完成度,以channel为单位';
+    protected $signature = 'upgrade:progress.chapter {--book=} {--para=} {--channel=} {--driver=str} {--fresh : 清除缓存断点,从头开始}';
+
+    protected $description = '更新章节完成度(可重入:中断后重跑自动跳过已处理的 book)';
 
     const COMPLETION_RATE = 0.9;
 
-    /**
-     * Create a new command instance.
-     *
-     * @return void
-     */
-    public function __construct()
-    {
-        parent::__construct();
-    }
+    // 缓存键:记录最后处理完成的 book_id,48h 过期
+    private const CACHE_KEY = 'upgrade-progress-chapter:cursor';
 
-    /**
-     * Execute the console command.
-     *
-     * @return int
-     */
-    public function handle()
+    public function handle(): int
     {
-        if (\App\Tools\Tools::isStop()) {
+        if (Tools::isStop()) {
             return 0;
         }
+
+        if ($this->option('fresh')) {
+            Cache::forget(self::CACHE_KEY);
+            $this->info('Cleared cached cursor.');
+        }
+
         $paliTextService = app(PaliTextService::class);
 
-        $this->info("upgrade:progresschapter start.");
+        $this->info('upgrade:progress.chapter start.');
         $startTime = time();
+
         $book = $this->option('book');
         $para = $this->option('para');
         $channelId = $this->option('channel');
+
         if ($channelId) {
-            $this->line('channel=' . $channelId);
+            $this->line('channel='.$channelId);
         }
 
-        \App\Tools\Markdown::driver($this->option('driver'));
+        Markdown::driver($this->option('driver'));
 
         $tagCount = 0;
-        #第一步 查询有多少书有译文
-        if ($book) {
-            if ($this->option('resume')) {
-                $table = Sentence::whereBetween('book_id', [$book, 217]);
-            } else {
-                $table = Sentence::where('book_id', $book);
-            }
-            $books = $table->groupby('book_id')
-                ->select('book_id')
-                ->get();
-        } else {
-            $books = Sentence::where('strlen', '>', 0)
-                ->where('book_id', '<', 1000)
-                ->whereNotNull('channel_uid')
-                ->groupby('book_id')
-                ->select('book_id')
-                ->get();
+
+        // 第一步:查询有译文的 book 列表
+        $books = $this->buildBookList($book);
+
+        // 从缓存恢复断点:跳过上次已完成的 book
+        $lastBookId = Cache::get(self::CACHE_KEY);
+        if ($lastBookId && ! $book) {
+            $books = $books->filter(fn ($b) => $b->book_id > $lastBookId)->values();
+            $this->info("Resuming after book={$lastBookId}");
         }
 
+        $totalBook = $books->count();
 
-        $totalBook = count($books);
+        foreach ($books as $bookIdx => $bookRow) {
+            $this->info('['.($bookIdx + 1)."/{$totalBook}] book={$bookRow->book_id}");
 
-        foreach ($books as $book) {
-            $this->info("{$book->book_id} start total {$totalBook}");
-            if ($para) {
-                $table = PaliText::where('book', $book->book_id)
-                    ->where('paragraph', '<=', $para);
-            } else {
-                $table = PaliText::where('book', $book->book_id);
-            }
-            $chapters = $table->where('level', '>', 0)
-                ->where('level', '<', 8)
-                ->select('paragraph', 'chapter_strlen', 'chapter_len')
-                ->get();
-
-            foreach ($chapters as $key => $chapter) {
-                # code...
-                $chapter_strlen = PaliSentence::where('book', $book->book_id)
-                    ->whereBetween('paragraph', [$chapter->paragraph, $chapter->paragraph + $chapter->chapter_len - 1])
+            $chapters = $this->getChapters($bookRow->book_id, $para);
+
+            foreach ($chapters as $chapter) {
+                // 计算章节对应的巴利语总字符数
+                $chapterEnd = $chapter->paragraph + $chapter->chapter_len - 1;
+                $chapterStrlen = PaliSentence::where('book', $bookRow->book_id)
+                    ->whereBetween('paragraph', [$chapter->paragraph, $chapterEnd])
                     ->sum('length');
-                if ($chapter_strlen == 0) {
-                    $this->error('chapter_strlen is 0 book:' . $book->book_id . ' paragraph:' . $chapter->paragraph . '-' . ($chapter->paragraph + $chapter->chapter_len - 1));
+
+                if ($chapterStrlen == 0) {
+                    $this->error("chapter_strlen=0 book:{$bookRow->book_id} para:{$chapter->paragraph}-{$chapterEnd}");
+
                     continue;
                 }
-                $table = Progress::where('book', $book->book_id)
-                    ->whereBetween('para', [$chapter->paragraph, $chapter->paragraph + $chapter->chapter_len - 1]);
+
+                // 按 channel 分组统计已翻译字符数
+                $progressQuery = Progress::where('book', $bookRow->book_id)
+                    ->whereBetween('para', [$chapter->paragraph, $chapterEnd]);
+
                 if ($channelId) {
-                    $table->where('channel_id', $channelId);
+                    $progressQuery->where('channel_id', $channelId);
                 }
-                $strlen = $table->groupby('channel_id')
+
+                $channelProgress = $progressQuery->groupBy('channel_id')
                     ->selectRaw('channel_id, sum(all_strlen) as cp_len')
                     ->get();
-                foreach ($strlen as $final) {
-                    # code...
-                    # 计算此段落完成时间
-                    $finalAt = Progress::where('book', $book->book_id)
-                        ->whereBetween('para', [$chapter->paragraph, $chapter->paragraph + $chapter->chapter_len - 1])
-                        ->where('channel_id', $final->channel_id)
-                        ->max('created_at');
-                    $updateAt = Progress::where('book', $book->book_id)
-                        ->whereBetween('para', [$chapter->paragraph, $chapter->paragraph + $chapter->chapter_len - 1])
-                        ->where('channel_id', $final->channel_id)
-                        ->max('updated_at');
-                    $transTexts = Sentence::where('book_id', $book->book_id)
-                        ->whereBetween('paragraph', [$chapter->paragraph + 1, $chapter->paragraph + $chapter->chapter_len - 1])
-                        ->where('channel_uid', $final->channel_id)
-                        ->select('content')
-                        ->orderBy('paragraph')
-                        ->orderBy('word_start')
-                        ->get();
-
-                    $mdRender = new MdRender(['format' => 'simple']);
-
-                    #查询标题
-                    $title = Sentence::where('book_id', $book->book_id)
-                        ->where('paragraph', $chapter->paragraph)
-                        ->where('channel_uid', $final->channel_id)
-                        ->value('content');
-                    $title = $mdRender->convert($title, [$final->channel_id]);
-
-                    $summaryText = "";
-                    foreach ($transTexts as $text) {
-                        # code...
-                        $textContent = $mdRender->convert($text->content, [$final->channel_id]);
-                        $summaryText .= str_replace("\n", "", $textContent);
-                        if (mb_strlen($summaryText, "UTF-8") > 255) {
-                            break;
-                        }
-                    }
-
-                    //查询语言
-                    $channelLang = Channel::where('uid', $final->channel_id)->value('lang');
-                    $lang = explode('-', $channelLang)[0];
-                    $attributes = [
-                        'book' => $book->book_id,
-                        'para' => $chapter->paragraph,
-                        'channel_id' => $final->channel_id
-                    ];
-
-                    $rules = array(
-                        'book' => 'integer',
-                        'para' => 'integer',
-                        'channel_id' => 'uuid'
-                    );
 
-                    $validator = Validator::make($attributes, $rules);
-                    if ($validator->fails()) {
-                        $this->error("Validator is fails");
-                        return 0;
-                    }
-                    if (ProgressChapter::where($attributes)->exists()) {
-                        $chapterData = ProgressChapter::where($attributes)->first();
-                    } else {
-                        $chapterData = new ProgressChapter;
-                        $chapterData->book = $attributes["book"];
-                        $chapterData->para = $attributes["para"];
-                        $chapterData->channel_id = $attributes["channel_id"];
-                    }
-                    $progress = $final->cp_len / $chapter_strlen;
-                    $addChapter = false;
-                    if ($progress >= self::COMPLETION_RATE) {
-                        if (empty($chapterData->completed_at)) {
-                            // 添加新的章节了
-                            $chapterData->completed_at = $finalAt;
-                            $addChapter = true;
-                        }
-                    }
-
-                    $chapterData->lang = $lang;
-                    $chapterData->all_trans = $progress;
-                    $chapterData->public = $progress;
-                    $chapterData->progress = $progress;
-                    $chapterData->title = $title ? mb_substr($title, 0, 255, "UTF-8") : "";
-                    $chapterData->summary = $summaryText ? mb_substr($summaryText, 0, 255, "UTF-8") : "";
-                    $chapterData->created_at = $finalAt;
-                    $chapterData->updated_at = $updateAt;
-                    $chapterData->save();
-
-
-                    if ($addChapter) {
-                        // 添加新的章节了
-                        //修改父目录
-                        $loop = 0;
-                        $currBook = $attributes["book"];
-                        $currPara = $attributes["para"];
-                        while ($parent = $paliTextService->getParent($currBook, $currPara)) {
-                            $parentChapter = ProgressChapter::where('book', $currBook)
-                                ->where('para', $parent->paragraph)
-                                ->where('channel_id', $attributes["channel_id"])
-                                ->first();
-                            if ($parentChapter) {
-                                $currPara = $parent->paragraph;
-                                if (
-                                    is_null($parentChapter->last_chapter_completed_at) ||
-                                    Carbon::parse($finalAt)->gt(Carbon::parse($parentChapter->last_chapter_completed_at))
-                                ) {
-                                    $parentChapter->last_chapter_completed_at = $finalAt;
-                                    // 计算字章节有多少已经完成
-                                    $chapterEnd = $parent->paragraph + $parent->chapter_len - 1;
-                                    $totalCompleted = ProgressChapter::where('book', $currBook)
-                                        ->whereBetween('para', [$parent->paragraph, $chapterEnd])
-                                        ->where('channel_id', $attributes["channel_id"])
-                                        ->whereNotNull('completed_at')
-                                        ->count();
-                                    $parentChapter->completed_chapters = $totalCompleted;
-                                    $parentChapter->save();
-                                    /*
-                                    Log::info('update last_chapter_completed_at', [
-                                        'para' => $parent->paragraph,
-                                        'completed' => $totalCompleted
-                                    ]);
-                                    */
-                                }
-                            } else {
-                                break;
-                            }
-                            $loop++;
-                        }
-                        //Log::info('update parent completed loop ' . $loop);
-                    }
-
-
-                    $wasCreated = $chapterData->wasRecentlyCreated;
-                    $wasChanged = $chapterData->wasChanged();
-                    #查询路径
-                    $path = json_decode(
-                        PaliText::where('book', $book->book_id)
-                            ->where('paragraph', $chapter->paragraph)
-                            ->value('path')
+                foreach ($channelProgress as $final) {
+                    $tagCount += $this->processChapterChannel(
+                        $bookRow->book_id,
+                        $chapter,
+                        $chapterEnd,
+                        $chapterStrlen,
+                        $final,
+                        $paliTextService,
                     );
-
-                    if ($path) {
-                        //查询标签
-                        $tags = [];
-                        foreach ($path as $key => $value) {
-                            # code...
-                            if ($value->level > 0) {
-                                $paliTextUuid = PaliText::where('book', $value->book)
-                                    ->where('paragraph', $value->paragraph)
-                                    ->value('uid');
-                                $tagUuids = TagMap::where('table_name', 'pali_texts')
-                                    ->where('anchor_id', $paliTextUuid)
-                                    ->select(['tag_id'])
-                                    ->get();
-                                foreach ($tagUuids as $key => $taguuid) {
-                                    # code...
-                                    $tags[$taguuid['tag_id']] = 1;
-                                }
-                            }
-                        }
-
-                        //更新标签映射表
-                        //删除旧的标签映射表
-                        TagMap::where('table_name', 'progress_chapters')
-                            ->where('anchor_id', $chapterData->uid)
-                            ->delete();
-                        foreach ($tags as $key => $tag) {
-                            # code...
-                            $tagmap = TagMap::create([
-                                'table_name' => 'progress_chapters',
-                                'anchor_id' => $chapterData->uid,
-                                'tag_id' => $key
-                            ]);
-                            if ($tagmap) {
-                                $tagCount++;
-                            }
-                        }
-                    }
                 }
             }
+
+            // 每完成一本书,保存断点
+            Cache::put(self::CACHE_KEY, $bookRow->book_id, now()->addHours(48));
         }
+
+        // 全部完成,清除断点缓存
+        Cache::forget(self::CACHE_KEY);
+
         $time = time() - $startTime;
-        $this->info("upgrade:progresschapter finished in {$time}s tag count:{$tagCount}");
+        $this->info("upgrade:progress.chapter finished in {$time}s tag count:{$tagCount}");
+
         return 0;
     }
+
+    /** 查询有译文的 book 列表,按 book_id 排序 */
+    private function buildBookList(?string $book)
+    {
+        if ($book) {
+            $table = Sentence::where('book_id', $book);
+        } else {
+            $table = Sentence::where('strlen', '>', 0)
+                ->where('book_id', '<', 1000)
+                ->whereNotNull('channel_uid');
+        }
+
+        return $table->groupBy('book_id')
+            ->select('book_id')
+            ->orderBy('book_id')
+            ->get();
+    }
+
+    /** 获取某本书的章节列表(level 1-7) */
+    private function getChapters(int $bookId, ?string $para)
+    {
+        $table = PaliText::where('book', $bookId);
+
+        if ($para) {
+            $table = $table->where('paragraph', '<=', $para);
+        }
+
+        return $table->where('level', '>', 0)
+            ->where('level', '<', 8)
+            ->select('paragraph', 'chapter_strlen', 'chapter_len')
+            ->get();
+    }
+
+    /** 处理单个章节×channel 的进度更新,返回新增 tag 数 */
+    private function processChapterChannel(
+        int $bookId,
+        $chapter,
+        int $chapterEnd,
+        int $chapterStrlen,
+        $final,
+        PaliTextService $paliTextService,
+    ): int {
+        $tagCount = 0;
+
+        // 查询该 channel 在此章节范围内的完成时间
+        $baseProgress = Progress::where('book', $bookId)
+            ->whereBetween('para', [$chapter->paragraph, $chapterEnd])
+            ->where('channel_id', $final->channel_id);
+
+        $finalAt = (clone $baseProgress)->max('created_at');
+        $updateAt = (clone $baseProgress)->max('updated_at');
+
+        // 获取译文内容,用于生成摘要
+        $transTexts = Sentence::where('book_id', $bookId)
+            ->whereBetween('paragraph', [$chapter->paragraph + 1, $chapterEnd])
+            ->where('channel_uid', $final->channel_id)
+            ->select('content')
+            ->orderBy('paragraph')
+            ->orderBy('word_start')
+            ->get();
+
+        $mdRender = new MdRender(['format' => 'simple']);
+
+        // 章节标题
+        $title = Sentence::where('book_id', $bookId)
+            ->where('paragraph', $chapter->paragraph)
+            ->where('channel_uid', $final->channel_id)
+            ->value('content');
+        $title = $mdRender->convert($title, [$final->channel_id]);
+
+        // 拼接摘要,最多 255 字符
+        $summaryText = '';
+        foreach ($transTexts as $text) {
+            $textContent = $mdRender->convert($text->content, [$final->channel_id]);
+            $summaryText .= str_replace("\n", '', $textContent);
+            if (mb_strlen($summaryText, 'UTF-8') > 255) {
+                break;
+            }
+        }
+
+        // 查询 channel 语言
+        $channelLang = Channel::where('uid', $final->channel_id)->value('lang');
+        $lang = explode('-', $channelLang)[0];
+
+        $attributes = [
+            'book' => $bookId,
+            'para' => $chapter->paragraph,
+            'channel_id' => $final->channel_id,
+        ];
+
+        $validator = Validator::make($attributes, [
+            'book' => 'integer',
+            'para' => 'integer',
+            'channel_id' => 'uuid',
+        ]);
+
+        if ($validator->fails()) {
+            $this->error('Validator failed: '.json_encode($attributes));
+
+            return 0;
+        }
+
+        // firstOrNew:存在则更新,不存在则新建
+        $chapterData = ProgressChapter::firstOrNew($attributes);
+
+        $progress = $final->cp_len / $chapterStrlen;
+        $addChapter = false;
+
+        // 进度 >= 90% 视为完成
+        if ($progress >= self::COMPLETION_RATE && empty($chapterData->completed_at)) {
+            $chapterData->completed_at = $finalAt;
+            $addChapter = true;
+        }
+
+        $chapterData->lang = $lang;
+        $chapterData->all_trans = $progress;
+        $chapterData->public = $progress;
+        $chapterData->progress = $progress;
+        $chapterData->title = $title ? mb_substr($title, 0, 255, 'UTF-8') : '';
+        $chapterData->summary = $summaryText ? mb_substr($summaryText, 0, 255, 'UTF-8') : '';
+        $chapterData->created_at = $finalAt;
+        $chapterData->updated_at = $updateAt;
+        $chapterData->save();
+
+        // 新完成的章节:向上更新父级目录的 last_chapter_completed_at
+        if ($addChapter) {
+            $this->updateParentChapters($bookId, $chapter->paragraph, $final->channel_id, $finalAt, $paliTextService);
+        }
+
+        // 更新标签映射
+        $tagCount += $this->syncTags($bookId, $chapter->paragraph, $chapterData->uid);
+
+        return $tagCount;
+    }
+
+    /** 向上遍历父章节,更新 last_chapter_completed_at 和 completed_chapters 计数 */
+    private function updateParentChapters(int $bookId, int $para, string $channelId, $finalAt, PaliTextService $paliTextService): void
+    {
+        $currPara = $para;
+
+        while ($parent = $paliTextService->getParent($bookId, $currPara)) {
+            $parentChapter = ProgressChapter::where('book', $bookId)
+                ->where('para', $parent->paragraph)
+                ->where('channel_id', $channelId)
+                ->first();
+
+            if (! $parentChapter) {
+                break;
+            }
+
+            $currPara = $parent->paragraph;
+
+            if (
+                is_null($parentChapter->last_chapter_completed_at) ||
+                Carbon::parse($finalAt)->gt(Carbon::parse($parentChapter->last_chapter_completed_at))
+            ) {
+                $parentChapter->last_chapter_completed_at = $finalAt;
+
+                $chapterEnd = $parent->paragraph + $parent->chapter_len - 1;
+                $parentChapter->completed_chapters = ProgressChapter::where('book', $bookId)
+                    ->whereBetween('para', [$parent->paragraph, $chapterEnd])
+                    ->where('channel_id', $channelId)
+                    ->whereNotNull('completed_at')
+                    ->count();
+
+                $parentChapter->save();
+            }
+        }
+    }
+
+    /** 同步章节的标签映射,返回新增 tag 数 */
+    private function syncTags(int $bookId, int $para, string $chapterUid): int
+    {
+        $path = json_decode(
+            PaliText::where('book', $bookId)
+                ->where('paragraph', $para)
+                ->value('path')
+        );
+
+        if (! $path) {
+            return 0;
+        }
+
+        // 收集路径上所有层级的标签
+        $tags = [];
+        foreach ($path as $value) {
+            if ($value->level > 0) {
+                $paliTextUuid = PaliText::where('book', $value->book)
+                    ->where('paragraph', $value->paragraph)
+                    ->value('uid');
+
+                $tagIds = TagMap::where('table_name', 'pali_texts')
+                    ->where('anchor_id', $paliTextUuid)
+                    ->pluck('tag_id');
+
+                foreach ($tagIds as $tagId) {
+                    $tags[$tagId] = 1;
+                }
+            }
+        }
+
+        // 先删后建:重建标签映射
+        TagMap::where('table_name', 'progress_chapters')
+            ->where('anchor_id', $chapterUid)
+            ->delete();
+
+        $count = 0;
+        foreach ($tags as $tagId => $_) {
+            $tagmap = TagMap::create([
+                'table_name' => 'progress_chapters',
+                'anchor_id' => $chapterUid,
+                'tag_id' => $tagId,
+            ]);
+            if ($tagmap) {
+                $count++;
+            }
+        }
+
+        return $count;
+    }
 }

+ 116 - 118
api-v13/app/Console/Commands/UpgradeProgressPara.php

@@ -2,156 +2,154 @@
 
 namespace App\Console\Commands;
 
-use Illuminate\Console\Command;
-
-use Illuminate\Support\Facades\DB;
-
-
-use App\Models\Sentence;
 use App\Models\PaliSentence;
 use App\Models\Progress;
-use Illuminate\Support\Facades\Log;
+use App\Models\Sentence;
+use App\Tools\Tools;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\DB;
 
 class UpgradeProgressPara extends Command
 {
-    /**
-     * The name and signature of the console command.
-     * php artisan upgrade:progress --book=152 --channel=19f53a65-81db-4b7d-8144-ac33f1217d34
-     * @var string
-     */
-    protected $signature = 'upgrade:progress.para {--book=} {--para=} {--channel=} {--resume}';
-
-    /**
-     * The console command description.
-     *
-     * @var string
-     */
-    protected $description = 'Command description';
-
-    /**
-     * Create a new command instance.
-     *
-     * @return void
-     */
-    public function __construct()
-    {
-        parent::__construct();
-    }
+    protected $signature = 'upgrade:progress.para {--book=} {--para=} {--channel=} {--fresh : 清除缓存断点,从头开始}';
+
+    protected $description = '更新段落翻译进度(可重入:中断后重跑自动跳过已处理的段落)';
+
+    // 缓存键:记录最后处理到的位置 (book_id, paragraph, channel_uid),48h 过期
+    private const CACHE_KEY = 'upgrade-progress-para:cursor';
 
-    /**
-     * Execute the console command.
-     *
-     * @return int
-     */
-    public function handle()
+    public function handle(): int
     {
-        if (\App\Tools\Tools::isStop()) {
+        if (Tools::isStop()) {
             return 0;
         }
-        $this->info('upgrade:progress start');
+
+        if ($this->option('fresh')) {
+            Cache::forget(self::CACHE_KEY);
+            $this->info('Cleared cached cursor.');
+        }
+
+        $this->info('upgrade:progress.para start');
         $startTime = time();
+
         $book = $this->option('book');
         $para = $this->option('para');
         $channelId = $this->option('channel');
+
         if ($channelId) {
-            $this->line('channel=' . $channelId);
+            $this->line('channel='.$channelId);
         }
-        $table = Sentence::where('strlen', '>', 0);
-        if ($book || $para || $channelId) {
-            if ($book) {
-                $table = $table->where('book_id', $book);
-            }
-            if ($para) {
-                $table = $table->where('paragraph', $para);
-            }
-            if ($channelId) {
-                $table = $table->where('channel_uid', $channelId);
-            }
-            $sentences = $table->groupby('book_id', 'paragraph', 'channel_uid')
-                ->select('book_id', 'paragraph', 'channel_uid');
-        } else {
-            if ($this->option('resume')) {
-                $sentences = Sentence::where('strlen', '>', 0)
-                    ->whereBetween('book_id', [$book, 1000])
-                    ->where('paragraph', '>=', $para)
-                    ->whereNotNull('channel_uid')
-                    ->groupby('book_id', 'paragraph', 'channel_uid')
-                    ->select('book_id', 'paragraph', 'channel_uid');
-            } else {
-                $sentences = Sentence::where('strlen', '>', 0)
-                    ->where('book_id', '<', 1000)
-                    ->whereNotNull('channel_uid')
-                    ->groupby('book_id', 'paragraph', 'channel_uid')
-                    ->select('book_id', 'paragraph', 'channel_uid');
-            }
+
+        // 构建查询:按 (book_id, paragraph, channel_uid) 分组
+        $sentences = $this->buildQuery($book, $para, $channelId);
+
+        // 从缓存恢复断点:跳过上次已处理的记录
+        $cursor = Cache::get(self::CACHE_KEY);
+        if ($cursor && ! $this->option('book')) {
+            $sentences = $this->applyResumeFilter($sentences, $cursor);
+            $this->info("Resuming from book={$cursor['book']}, para={$cursor['para']}");
         }
-        $total = DB::query()
-            ->fromSub($sentences, 't')
-            ->count();
-        $sentences = $sentences->cursor();
-        $this->info('sentences:' . $total);
+
+        $total = DB::query()->fromSub($sentences, 't')->count();
+        $this->info("sentences: {$total}");
+
         $curr = 0;
-        #第二步 更新段落表
-        foreach ($sentences as $sentence) {
 
-            # 第二步 生成para progress 1,2,15,zh-tw
-            # 计算此段落完成时间
-            $finalAt = Sentence::where('strlen', '>', 0)
-                ->where('book_id', $sentence->book_id)
-                ->where('paragraph', $sentence->paragraph)
-                ->where('channel_uid', $sentence->channel_uid)
-                ->max('created_at');
-            $updateAt = Sentence::where('strlen', '>', 0)
+        foreach ($sentences->cursor() as $sentence) {
+            // 计算此段落的完成时间和最后更新时间
+            $baseQuery = Sentence::where('strlen', '>', 0)
                 ->where('book_id', $sentence->book_id)
                 ->where('paragraph', $sentence->paragraph)
-                ->where('channel_uid', $sentence->channel_uid)
-                ->max('updated_at');
-            # 查询每个段落的等效巴利语字符数
-            $result_sent = Sentence::where('strlen', '>', 0)
-                ->where('book_id', $sentence->book_id)
-                ->where('paragraph', $sentence->paragraph)
-                ->where('channel_uid', $sentence->channel_uid)
-                ->select('word_start')
-                ->get();
-
-            $paraInfo = [
-                'book' => $sentence->book_id,
-                'para' => $sentence->paragraph,
-                'channel_id' => $sentence->channel_uid
-            ];
-            if (count($result_sent) > 0) {
-                #查询这些句子的总共等效巴利语字符数
-                $para_strlen = 0;
-                foreach ($result_sent as $sent) {
-                    # code...
-                    $para_strlen += PaliSentence::where('book', $sentence->book_id)
-                        ->where('paragraph', $sentence->paragraph)
-                        ->where('word_begin', $sent->word_start)
-                        ->value('length');
-                }
-
-                $paraData = [
+                ->where('channel_uid', $sentence->channel_uid);
+
+            $finalAt = (clone $baseQuery)->max('created_at');
+            $updateAt = (clone $baseQuery)->max('updated_at');
+
+            // 查询段落内每个句子的起始词位置
+            $wordStarts = (clone $baseQuery)->pluck('word_start');
+
+            if ($wordStarts->isNotEmpty()) {
+                // 累加等效巴利语字符数:每个句子对应的 PaliSentence.length
+                $paraStrlen = PaliSentence::where('book', $sentence->book_id)
+                    ->where('paragraph', $sentence->paragraph)
+                    ->whereIn('word_begin', $wordStarts)
+                    ->sum('length');
+
+                $paraInfo = [
+                    'book' => $sentence->book_id,
+                    'para' => $sentence->paragraph,
+                    'channel_id' => $sentence->channel_uid,
+                ];
+
+                Progress::updateOrInsert($paraInfo, [
                     'lang' => 'en',
-                    'all_strlen' => $para_strlen,
-                    'public_strlen' => $para_strlen,
+                    'all_strlen' => $paraStrlen,
+                    'public_strlen' => $paraStrlen,
                     'created_at' => $finalAt,
                     'updated_at' => $updateAt,
-                ];
-
-
-                Progress::updateOrInsert($paraInfo, $paraData);
+                ]);
             }
+
             $curr++;
+
+            // 每 500 条保存一次断点到缓存
             if ($curr % 500 === 0) {
-                $present = (int)($curr * 100 / $total);
-                $this->info("[{$present}%] Progress " . json_encode($paraInfo));
+                Cache::put(self::CACHE_KEY, [
+                    'book' => $sentence->book_id,
+                    'para' => $sentence->paragraph,
+                ], now()->addHours(48));
+
+                $percent = (int) ($curr * 100 / $total);
+                $this->info("[{$percent}%] book={$sentence->book_id} para={$sentence->paragraph}");
                 sleep(1);
             }
         }
 
+        // 全部完成,清除断点缓存
+        Cache::forget(self::CACHE_KEY);
+
         $time = time() - $startTime;
-        $this->info("upgrade progress finished in {$time}s");
+        $this->info("upgrade:progress.para finished in {$time}s");
 
         return 0;
     }
+
+    /** 构建分组查询 */
+    private function buildQuery(?string $book, ?string $para, ?string $channelId)
+    {
+        $table = Sentence::where('strlen', '>', 0);
+
+        if ($book || $para || $channelId) {
+            if ($book) {
+                $table = $table->where('book_id', $book);
+            }
+            if ($para) {
+                $table = $table->where('paragraph', $para);
+            }
+            if ($channelId) {
+                $table = $table->where('channel_uid', $channelId);
+            }
+        } else {
+            $table = $table->where('book_id', '<', 1000)
+                ->whereNotNull('channel_uid');
+        }
+
+        return $table->groupBy('book_id', 'paragraph', 'channel_uid')
+            ->select('book_id', 'paragraph', 'channel_uid')
+            ->orderBy('book_id')
+            ->orderBy('paragraph');
+    }
+
+    /** 从断点位置之后继续:跳过 (book < X) 或 (book = X and para <= Y) 的记录 */
+    private function applyResumeFilter($query, array $cursor)
+    {
+        return $query->where(function ($q) use ($cursor) {
+            $q->where('book_id', '>', $cursor['book'])
+                ->orWhere(function ($q2) use ($cursor) {
+                    $q2->where('book_id', $cursor['book'])
+                        ->where('paragraph', '>', $cursor['para']);
+                });
+        });
+    }
 }

+ 0 - 2
api-v13/app/Http/Api/AiAssistantApi.php

@@ -3,7 +3,6 @@
 namespace App\Http\Api;
 
 use App\Models\AiModel;
-use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Storage;
 use Illuminate\Support\Facades\App;
 
@@ -17,7 +16,6 @@ class AiAssistantApi
     public static function userInfo($user)
     {
         if (!$user) {
-            Log::warning('$user=null;');
             return [
                 'id' => 0,
                 'nickName' => 'unknown',

+ 0 - 6
api-v13/app/Http/Api/AiTaskPrepare.php

@@ -11,7 +11,6 @@ use App\Models\Sentence;
 use App\Http\Api\Mq;
 use App\Http\Api\ChannelApi;
 
-use Illuminate\Support\Facades\Log;
 use App\Services\AuthService;
 
 class AiTaskPrepare
@@ -35,7 +34,6 @@ class AiTaskPrepare
             }
         }
         if (!isset($params['type'])) {
-            Log::error('no $params.type');
             return false;
         }
 
@@ -45,14 +43,12 @@ class AiTaskPrepare
         switch ($params['type']) {
             case 'sentence':
                 if (!isset($params['id'])) {
-                    Log::error('no $params.id');
                     return false;
                 }
                 $sentences[] = explode('-', $params['id']);
                 break;
             case 'para':
                 if (!isset($params['book']) || !isset($params['paragraphs'])) {
-                    Log::error('no $params.book or paragraphs');
                     return false;
                 }
                 $sent = PaliSentence::where('book', $params['book'])
@@ -72,7 +68,6 @@ class AiTaskPrepare
                 break;
             case 'chapter':
                 if (!isset($params['book']) || !isset($params['paragraphs'])) {
-                    Log::error('no $params.book or paragraphs');
                     return false;
                 }
                 $chapterLen = PaliText::where('book', $params['book'])
@@ -121,7 +116,6 @@ class AiTaskPrepare
         foreach ($sentences as $key => $sentence) {
             $sumLen += $sentence['strlen'];
             $sid = implode('-', $sentence['id']);
-            Log::debug($sid);
             $sentChannelInfo = explode('@', $params['channel']);
             $channelId = $sentChannelInfo[0];
             $data = [];

+ 0 - 2
api-v13/app/Http/Api/TaskApi.php

@@ -4,7 +4,6 @@ namespace App\Http\Api;
 
 use App\Models\Task;
 use App\Models\TaskRelation;
-use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\App;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Str;
@@ -86,7 +85,6 @@ class TaskApi
         $key = TaskApi::taskRelationRedisKey($taskId, $relation);
         //Log::debug('task redis key=' . $key . ' has=' . Cache::has($key));
         $data = Cache::remember($key,  24 * 3600, function () use ($taskId, $relation) {
-            Log::debug('getRelationTasks task=' . $taskId . ' relation=' . $relation);
             if ($relation === 'pre') {
                 $where = 'next_task_id';
                 $select = 'task_id';

+ 0 - 3
api-v13/app/Http/Api/TemplateRender.php

@@ -851,7 +851,6 @@ class TemplateRender
             for ($i = mb_strlen($title, 'UTF-8'); $i > 0; $i--) {
                 $mTitle = mb_substr($title, 0, $i);
                 $has = array_search($mTitle, array_column(BookTitle::my(), 'title2'));
-                Log::debug('run', ['title' => $mTitle, 'has' => $has]);
                 if ($has !== false) {
                     $tmpBookTitle = $mTitle;
                     $tmpBookPage = mb_substr($title, $i);
@@ -861,7 +860,6 @@ class TemplateRender
             }
 
             if (isset($tmpBookTitle)) {
-                Log::debug('book title found', ['title' => $tmpBookTitle, 'page' => $tmpBookPage]);
                 //$tmpBookTitle = $tmpTitle[0];
                 //$tmpBookPage = $tmpTitle[1];
                 $tmpBookPage = (int)str_replace(
@@ -889,7 +887,6 @@ class TemplateRender
                 }
             }
         } else {
-            Log::debug('book title not found');
             $props['found'] = false;
         }
 

+ 0 - 2
api-v13/app/Http/Api/UserApi.php

@@ -5,7 +5,6 @@ namespace App\Http\Api;
 use App\Http\Resources\AiAssistant;
 use App\Models\AiModel;
 use App\Models\UserInfo;
-use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Storage;
 use Illuminate\Support\Facades\App;
 
@@ -69,7 +68,6 @@ class UserApi
     public static function userInfo($user)
     {
         if (!$user) {
-            Log::warning('$user=null;');
             return [
                 'id' => 0,
                 'nickName' => 'unknown',

+ 0 - 2
api-v13/app/Http/Api/WatchApi.php

@@ -4,7 +4,6 @@ declare(strict_types=1);
 
 namespace App\Http\Api;
 
-use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Str;
 use App\Models\Like;
 use App\Models\Notification;
@@ -32,7 +31,6 @@ class WatchApi
                 'updated_at' => now(),
             ];
         }
-        Log::debug('notification insert', ['data' => $notifications]);
         $new = Notification::insert($notifications);
         return $new;
     }

+ 0 - 2
api-v13/app/Http/Controllers/AccessTokenController.php

@@ -35,12 +35,10 @@ class AccessTokenController extends Controller
         //
         $user = AuthService::current($request);
         if (!$user) {
-            Log::error('未登录');
             return $this->error(__('auth.failed'), [], 401);
         }
         $payload = $request->input('payload');
         $result = array();
-        Log::debug('token', ['payload' => $payload]);
         foreach ($payload as $key => $value) {
             //鉴权
             switch ($value['res_type']) {

+ 0 - 2
api-v13/app/Http/Controllers/AiModelController.php

@@ -8,7 +8,6 @@ use App\Models\AiModel;
 use Illuminate\Http\Request;
 use App\Services\AuthService;
 use Illuminate\Support\Str;
-use Illuminate\Support\Facades\Log;
 use App\Http\Api\StudioApi;
 use App\Http\Resources\AiModelResource;
 
@@ -80,7 +79,6 @@ class AiModelController extends Controller
             return $this->error(__('auth.failed'), 401, 401);
         }
         $studioId = StudioApi::getIdByName($request->input('studio_name'));
-        Log::debug('store', ['studioId' => $studioId, 'user' => $user]);
         if (!self::canEdit($user['user_uid'], $studioId)) {
             return $this->error(__('auth.failed'), 403, 403);
         }

+ 1 - 16
api-v13/app/Http/Controllers/ArticleController.php

@@ -278,7 +278,6 @@ class ArticleController extends Controller
         //判断权限
         $user = AuthService::current($request);
         if (!$user) {
-            Log::error('未登录');
             return $this->error(__('auth.failed'), [], 401);
         } else {
             $user_uid = $user['user_uid'];
@@ -286,16 +285,13 @@ class ArticleController extends Controller
 
         $canManage = ArticleController::userCanManage($user_uid, $request->input('studio'));
         if (!$canManage) {
-            Log::error('userCanManage 失败');
             //判断是否有文集权限
             if ($request->has('anthologyId')) {
                 $currPower = ShareApi::getResPower($user_uid, $request->input('anthologyId'));
                 if ($currPower <= 10) {
-                    Log::error('没有文集编辑权限');
                     return $this->error(__('auth.failed'), [], 403);
                 }
             } else {
-                Log::error('没有文集id');
                 return $this->error(__('auth.failed'), [], 403);
             }
         }
@@ -306,8 +302,6 @@ class ArticleController extends Controller
         if(Article::where('title',$request->input('title'))->where('owner',$studioUuid)->exists()){
             return $this->error(__('validation.exists'));
         }*/
-        Log::debug('开始新建' . $request->input('title'));
-
         $newArticle = new Article;
         DB::transaction(function () use ($user, $request, $newArticle) {
             $studioUuid = StudioApi::getIdByName($request->input('studio'));
@@ -328,15 +322,12 @@ class ArticleController extends Controller
             $newArticle->save();
             OpsLog::debug($user['user_uid'], $newArticle);
 
-            Log::debug('开始挂接 id=' . $newArticle->uid);
             $anthologyId = $request->input('anthologyId');
             if (Str::isUuid($anthologyId)) {
                 $parentNode = $request->input('parentNode');
                 if (Str::isUuid($parentNode)) {
-                    Log::debug('有挂接点' . $parentNode);
                     $map = ArticleCollection::where('collect_id', $anthologyId)
                         ->orderBy('id')->get();
-                    Log::debug('查询到原map数据' . count($map));
                     $newMap = array();
                     $parentNodeLevel = -1;
                     $appended = false;
@@ -353,7 +344,6 @@ class ArticleController extends Controller
                                     $newNode['title'] = $newArticle->title;
                                     $newNode['children'] = 0;
                                     $newMap[] = $newNode;
-                                    Log::debug('新增节点', ['node' => $newNode]);
                                     $appended = true;
                                 }
                             } else {
@@ -367,8 +357,6 @@ class ArticleController extends Controller
                     }
                     if ($parentNodeLevel > 0) {
                         if ($appended === false) {
-                            //
-                            Log::debug('没挂上 挂到结尾');
                             $newNode = array();
                             $newNode['collect_id'] = $anthologyId;
                             $newNode['article_id'] = $newArticle->uid;
@@ -378,12 +366,10 @@ class ArticleController extends Controller
                             $newMap[] = $newNode;
                         }
                     } else {
-                        Log::error('没找到挂接点' . $parentNode);
+                        Log::warning('没找到挂接点' . $parentNode);
                     }
-                    Log::debug('新map数据' . count($newMap));
 
                     $delete = ArticleCollection::where('collect_id', $anthologyId)->delete();
-                    Log::debug('删除旧map数据' . $delete);
                     $count = 0;
                     foreach ($newMap as $key => $row) {
                         $new = new ArticleCollection;
@@ -400,7 +386,6 @@ class ArticleController extends Controller
                         $new->save();
                         $count++;
                     }
-                    Log::debug('新map数据' . $count);
                     ArticleMapController::updateCollection($anthologyId);
                 } else {
                     $articleMap = new ArticleCollection();

+ 0 - 1
api-v13/app/Http/Controllers/ArticleFtsController.php

@@ -100,7 +100,6 @@ class ArticleFtsController extends Controller
                 'format' => 'text',
                 'channel' => $channel,
             ];
-            Log::debug('http request', ['url' => $url, 'param' => $urlParam]);
             if ($token) {
                 $response = Http::withToken($this->option('token'))->get($url, $urlParam);
             } else {

+ 0 - 2
api-v13/app/Http/Controllers/ArticleMapController.php

@@ -9,7 +9,6 @@ use App\Http\Api\ShareApi;
 use App\Services\AuthService;
 use Illuminate\Http\Request;
 use App\Http\Resources\ArticleMapResource;
-use Illuminate\Support\Facades\Log;
 
 class ArticleMapController extends Controller
 {
@@ -96,7 +95,6 @@ class ArticleMapController extends Controller
             return $this->error(__('auth.failed'));
         }
         if (!CollectionController::UserCanEdit($user["user_uid"], $collection)) {
-            Log::error($user["user_uid"] . '无文集编辑权限' . $collection->uid);
             return $this->error(__('auth.failed'));
         }
         switch ($validated['operation']) {

+ 0 - 5
api-v13/app/Http/Controllers/AuthController.php

@@ -9,7 +9,6 @@ use App\Services\AuthService;
 use Illuminate\Support\Facades\Storage;
 use Illuminate\Support\Facades\App;
 
-use Illuminate\Support\Facades\Log;
 
 class AuthController extends Controller
 {
@@ -91,9 +90,6 @@ class AuthController extends Controller
                 'id' => $user->id,
             ];
             $jwt = JWT::encode($payload, $key, 'HS512');
-            if (app()->isLocal()) {
-                Log::debug('sing in token' . $jwt);
-            }
             return $this->ok($jwt);
         } else {
             return $this->error('invalid token');
@@ -106,7 +102,6 @@ class AuthController extends Controller
     {
         $curr = AuthService::current($request);
         if (!$curr) {
-            Log::warning('invalid token');
             return $this->error('invalid token', 401, 401);
         }
         $userInfo = UserInfo::where('userid', $curr['user_uid'])

+ 0 - 3
api-v13/app/Http/Controllers/ChannelController.php

@@ -3,7 +3,6 @@
 namespace App\Http\Controllers;
 
 use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Arr;
 use Illuminate\Support\Facades\DB;
 
@@ -180,7 +179,6 @@ class ChannelController extends Controller
                 $channels = Sentence::where('book_id', $request->input('book_id'))
                     ->whereIn('paragraph', explode(',', $request->input('para')))
                     ->groupBy('channel_uid')->select('channel_uid')->get();
-                Log::debug('channel paragraphs', ['channels' => $channels]);
                 if (count($channels) > 0) {
                     $channelIds = array_map(fn($item) => $item['channel_uid'], $channels->toArray());
                     $table = Channel::select($indexCol)
@@ -230,7 +228,6 @@ class ChannelController extends Controller
         //处理分页
         $table = $table->skip($request->input("offset", 0))
             ->take($request->input("limit", 200));
-        Log::debug('channel sql ' . $table->toSql());
         //获取数据
         $result = $table->get();
         //TODO 将下面代码转移到resource

+ 0 - 6
api-v13/app/Http/Controllers/CollectionController.php

@@ -5,7 +5,6 @@ namespace App\Http\Controllers;
 use App\Models\Collection;
 use Illuminate\Http\Request;
 use Illuminate\Support\Str;
-use Illuminate\Support\Facades\Log;
 use App\Services\AuthService;
 use App\Http\Api\StudioApi;
 use App\Http\Resources\CollectionResource;
@@ -126,22 +125,17 @@ class CollectionController extends Controller
     {
         $result = Collection::where('uid', $id)->first();
         if (!$result) {
-            Log::warning("没有查询到数据 id={$id}");
             return $this->error("没有查询到数据 id={$id}");
         }
 
         if ($result->status < 30) {
-            Log::info('私有文章,判断权限' . $id);
             $user = AuthService::current($request);
             if (!$user) {
-                Log::warning('未登录');
                 return $this->error(__('auth.failed'), 403, 403);
             }
 
             if ($user['user_uid'] !== $result->owner) {
-                Log::info($user['user_uid'] . '私有文章,判断权限' . $id);
                 if (!$this->service->userCanRead($user['user_uid'], $result)) {
-                    Log::warning($user['user_uid'] . '没有读取权限');
                     return $this->error(__('auth.failed'), 403, 403);
                 }
             }

+ 0 - 5
api-v13/app/Http/Controllers/DiscussionCountController.php

@@ -7,7 +7,6 @@ use App\Services\AuthService;
 use App\Http\Api\ChannelApi;
 use App\Http\Resources\DiscussionCountResource;
 use App\Http\Resources\TagMapResource;
-use Illuminate\Support\Facades\Log;
 use App\Models\Discussion;
 use App\Models\CourseMember;
 use App\Models\Course;
@@ -82,7 +81,6 @@ class DiscussionCountController extends Controller
                 ->where('course_id', $request->input('course_id'))
                 ->select('user_id')
                 ->get();
-            Log::debug('allMembers', ['members' => $allMembers]);
             //找到全部相关channel
             $channels = array();
             //获取答案 channel
@@ -153,7 +151,6 @@ class DiscussionCountController extends Controller
                 }
             }
         }
-        Log::debug('res id', ['res' => $resId]);
         //全部资源id获取完毕
         //获取discussion
         $table = Discussion::select(['id', 'res_id', 'res_type', 'type', 'editor_uid'])
@@ -173,7 +170,6 @@ class DiscussionCountController extends Controller
             ->where('owner_uid', $studioIdForTag)
             ->leftJoin('tags', 'tags.id', '=', 'tag_maps.tag_id')
             ->get();
-        Log::debug('response', ['data' => $discussions]);
         return $this->ok([
             'discussions' => $discussions,
             'tags' => $tags,
@@ -202,7 +198,6 @@ class DiscussionCountController extends Controller
 
         $allTags = $table->get();
         $tags = TagMapResource::collection($allTags);
-        Log::debug('response', ['discussions' => $discussions]);
         return $this->ok([
             'discussions' => $discussions,
             'tags' => $tags,

+ 0 - 5
api-v13/app/Http/Controllers/Library/BookController.php

@@ -4,7 +4,6 @@ namespace App\Http\Controllers\Library;
 
 use App\Http\Controllers\Controller;
 
-use Illuminate\Support\Facades\Log;
 
 
 use Illuminate\Http\Request;
@@ -73,7 +72,6 @@ class BookController extends Controller
             ->whereBetween('paragraph', [$paraStart, $paraEnd])
             ->where('channel_uid', $channelId)
             ->select(['uid', 'book_id', 'paragraph', 'word_start', 'word_end'])->get()->toArray();
-        Log::debug('fetchCommentary', ['data' => $notes]);
         return $notes;
     }
 
@@ -108,7 +106,6 @@ class BookController extends Controller
             $notesMap = collect($commentaries)->keyBy(function ($note) {
                 return "{$note['book_id']}-{$note['paragraph']}-{$note['word_start']}-{$note['word_end']}";
             })->map(fn($note) => $note['uid'])->toArray();
-            Log::debug('note map', ['data' => $notesMap]);
         }
 
 
@@ -131,8 +128,6 @@ class BookController extends Controller
         } else {
             $book['content'] = $chapter['display'];
         }
-        Log::debug($book['content']);
-
         $allChannels = $chapterService->publicChannels((int)$bookId, (int)$paraId);
         $commentaryChannels = array_filter($allChannels, function ($channel) {
             return $channel['type'] === 'commentary';

+ 0 - 2
api-v13/app/Http/Controllers/Library/HomeController.php

@@ -2,7 +2,6 @@
 
 namespace App\Http\Controllers\Library;
 
-use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Cookie;
 use Illuminate\Support\Facades\File;
 
@@ -39,7 +38,6 @@ class HomeController extends Controller
     {
         $categories = $this->loadCategories();
         $locale = Cookie::get('language') ?? 'en';
-        Log::debug('$locale=' . $locale);
         // 获取一级分类和对应的书籍
         $categoryData = [];
         foreach ($categories as $category) {

+ 0 - 4
api-v13/app/Http/Controllers/ProjectController.php

@@ -10,7 +10,6 @@ use App\Http\Api\ShareApi;
 
 use App\Http\Resources\ProjectResource;
 use Illuminate\Support\Str;
-use Illuminate\Support\Facades\Log;
 
 class ProjectController extends Controller
 {
@@ -69,9 +68,6 @@ class ProjectController extends Controller
         }
         $count = $table->count();
 
-        $sql = $table->toSql();
-        Log::debug('sql', ['sql' => $sql]);
-
         $table = $table->orderBy($request->input('order', 'id'), $request->input('dir', 'asc'));
 
         $table = $table->skip($request->input("offset", 0))

+ 0 - 2
api-v13/app/Http/Controllers/SearchController.php

@@ -13,7 +13,6 @@ use Illuminate\Support\Facades\DB;
 use App\Http\Resources\SearchResource;
 use App\Http\Resources\SearchTitleResource;
 use App\Http\Resources\SearchBookResource;
-use Illuminate\Support\Facades\Log;
 use App\Tools\Tools;
 use App\Models\WbwTemplate;
 use App\Models\PageNumber;
@@ -50,7 +49,6 @@ class SearchController extends Controller
                         $query->where('title_en', 'like', "%{$key}%")
                             ->orWhere('title', 'like', "%{$key}%");
                     });
-                Log::info($table->toSql());
                 if ($request->has('tags')) {
                     //查询搜索范围
                     $tagItems = explode(';', $request->input('tags'));

+ 0 - 7
api-v13/app/Http/Controllers/SentenceController.php

@@ -9,7 +9,6 @@ use App\Models\WbwAnalysis;
 
 use Illuminate\Http\Request;
 use Illuminate\Support\Str;
-use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Redis;
 
@@ -272,14 +271,11 @@ class SentenceController extends Controller
             if ($power < 20) {
                 //判断token
                 if (!$access_token) {
-                    Log::error('no access token');
                     return false;
                 }
                 $key = AccessToken::where('res_id', $channelId)->value('token');
                 $jwt = JWT::decode($access_token, new Key($key . $key, 'HS512'));
-                Log::debug('access token', ['jwt' => $jwt]);
                 if ($jwt->book && $jwt->book !== $book) {
-                    Log::error('access token error');
                     return false;
                 }
             }
@@ -344,14 +340,11 @@ class SentenceController extends Controller
                 if ($power < 20) {
                     //判断token
                     if (!isset($sent['access_token'])) {
-                        Log::error('no access token');
                         continue;
                     }
                     $key = AccessToken::where('res_id', $destChannel->uid)->value('token');
                     $jwt = JWT::decode($sent['access_token'], new Key($key, 'HS512'));
-                    Log::debug('access token', ['jwt' => $jwt]);
                     if ($jwt->book !== $sent['book_id']) {
-                        Log::error('access token error');
                         continue;
                     }
                 }

+ 0 - 3
api-v13/app/Http/Controllers/TaskController.php

@@ -4,7 +4,6 @@ namespace App\Http\Controllers;
 
 use Illuminate\Http\Request;
 use Illuminate\Support\Str;
-use Illuminate\Support\Facades\Log;
 
 use App\Models\Task;
 use App\Models\TaskAssignee;
@@ -123,8 +122,6 @@ class TaskController extends Controller
         $table = $table->skip($request->input("offset", 0))
             ->take($request->input('limit', 1000));
 
-        Log::debug('sql', ['sql' => $table->toSql()]);
-
         $result = $table->get();
 
         return $this->ok(

+ 0 - 2
api-v13/app/Http/Controllers/TaskGroupController.php

@@ -7,7 +7,6 @@ use App\Models\Project;
 use App\Models\TaskRelation;
 use App\Models\TaskAssignee;
 
-use Illuminate\Support\Facades\Log;
 
 use Illuminate\Http\Request;
 use App\Services\AuthService;
@@ -54,7 +53,6 @@ class TaskGroupController extends Controller
         foreach ($projects as $key => $project) {
             $id[$project->uid] = $project->owner_id;
             if (!TaskController::canEdit($user['user_uid'], $project->owner_id)) {
-                Log::error(__('auth.failed'), ['user' => $user['user_uid'], 'owner' => $project->owner_id]);
                 return $this->error(__('auth.failed'), 403, 403);
             }
         }

+ 0 - 3
api-v13/app/Http/Controllers/TaskStatusController.php

@@ -243,9 +243,6 @@ class TaskStatusController extends Controller
                     from: $user['user_uid'],
                     message: "任务状态变为 {$key}",
                 );
-                Log::debug('watch message', [
-                    'send-to' => $send,
-                ]);
                 $editor = UserApi::getByUuid($user['user_uid']);
                 foreach ($tasksId as $taskId) {
                     $discussion->create([

+ 0 - 3
api-v13/app/Http/Controllers/WbwLookupController.php

@@ -8,7 +8,6 @@ use App\Models\WbwTemplate;
 use App\Models\Channel;
 use Illuminate\Http\Request;
 use App\Tools\CaseMan;
-use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Cache;
 use App\Http\Api\DictApi;
 use App\Services\AuthService;
@@ -173,12 +172,10 @@ class WbwLookupController extends Controller
         $fieldId = $fieldMap[$field];
         $myPreference = Cache::get("{$prefix}/{$word}/{$fieldId}/{$userId}");
         if (!empty($myPreference)) {
-            Log::debug($word . '命中我的wbw-' . $field, ['data' => $myPreference]);
             return ['value' => $myPreference, 'status' => 5];
         } else {
             $myPreference = Cache::get("{$prefix}/{$word}/3/0");
             if (!empty($myPreference)) {
-                Log::debug($word . '命中社区wbw-' . $field, ['data' => $myPreference]);
                 return ['value' => $myPreference, 'status' => 5];
             }
         }

+ 0 - 1
api-v13/app/Http/Controllers/WordIndexController.php

@@ -31,7 +31,6 @@ class WordIndexController extends Controller
                                    ->orderBy('len')
                                    ->orderBy('word_en')
                                    ->take(10);
-                Log::info($table->toSql());
                 $result = $table->get();
 */
                 $result = DB::select("SELECT * from  word_indices where word like ? or word_en like ? order by len, word_en limit 10", [$key . "%", $key . "%"]);

+ 0 - 4
api-v13/app/Http/Middleware/UserOperation.php

@@ -6,7 +6,6 @@ use Closure;
 use Illuminate\Http\Request;
 use Symfony\Component\HttpFoundation\Response;
 
-use Illuminate\Support\Facades\Log;
 
 use App\Models\UserOperationLog;
 use App\Models\UserOperationFrame;
@@ -119,9 +118,6 @@ class UserOperation
             $daily->increment('hit');
         } else {
             $id = app('snowflake')->id();
-            if (app()->isLocal()) {
-                Log::debug('snowflake ' . $id);
-            }
             $daily->forceFill([
                 'id'       => $id,
                 'duration' => self::MIN_INTERVAL,

+ 0 - 2
api-v13/app/Http/Requests/StoreDiscussionRequest.php

@@ -4,7 +4,6 @@ namespace App\Http\Requests;
 
 use Illuminate\Foundation\Http\FormRequest;
 use App\Services\AuthService;
-use Illuminate\Support\Facades\Log;
 
 class StoreDiscussionRequest extends FormRequest
 {
@@ -18,7 +17,6 @@ class StoreDiscussionRequest extends FormRequest
     {
         $user = AuthService::current($this);
         if (!$user) {
-            Log::warning('discussion store auth failed', ['request' => $this]);
             return false;
         }
         $this->user = $user;

+ 0 - 1
api-v13/app/Http/Resources/SearchBookResource.php

@@ -52,7 +52,6 @@ class SearchBookResource extends JsonResource
             ->select('tags.name')
             ->get();
 
-        Log::info('tag name', ['data' => $tagsName]);
         return $tagsName;
     }
 }

+ 0 - 2
api-v13/app/Http/Resources/SentenceAttachmentResource.php

@@ -4,7 +4,6 @@ namespace App\Http\Resources;
 
 use Illuminate\Http\Resources\Json\JsonResource;
 use Illuminate\Support\Facades\Http;
-use Illuminate\Support\Facades\Log;
 use App\Models\Attachment;
 use Illuminate\Support\Facades\Storage;
 use Illuminate\Support\Facades\App;
@@ -20,7 +19,6 @@ class SentenceAttachmentResource extends JsonResource
     public function toArray($request)
     {
         $url = config('app.url') . '/api/v2/attachment/' . $this->attachment_id;
-        Log::info($url);
         //$response = Http::get($url);
 
 

+ 0 - 2
api-v13/app/Mail/EmailCertif.php

@@ -6,7 +6,6 @@ use Illuminate\Bus\Queueable;
 use Illuminate\Mail\Mailable;
 use Illuminate\Queue\SerializesModels;
 use Illuminate\Support\Facades\Cache;
-use Illuminate\Support\Facades\Log;
 
 class EmailCertif extends Mailable
 {
@@ -36,7 +35,6 @@ class EmailCertif extends Mailable
         // 生成一个介于 1000 到 9999 之间的随机整数
         $randomNumber = random_int(1000, 9999);
         $key = "/email/certification/" . $this->uuid;
-        Log::debug('email certification', ['key' => $key, 'value' => $randomNumber]);
         Cache::put($key, $randomNumber,  30 * 60);
         return $this->view('emails.certification.' . $this->lang)
             ->with([

+ 0 - 1
api-v13/app/Services/AiTranslateService.php

@@ -72,7 +72,6 @@ class AiTranslateService
 
         //获取model token
         $this->modelToken = $first->model->token;
-        Log::debug($this->queue . ' ai assistant token', ['token' => $this->modelToken]);
 
         $this->setTaskStatus($this->task->id, 'running');
 

+ 0 - 3
api-v13/app/Tools/PaliSearch.php

@@ -7,7 +7,6 @@ class PaliSearch
 {
     public static function connect(){
         $host = config('mint.server.rpc.tulip.host') . ':' . config('mint.server.rpc.tulip.port');
-        Log::debug('tulip host='.$host);
         $client = new \Mint\Tulip\V1\SearchClient($host, [
             'credentials' => \Grpc\ChannelCredentials::createInsecure(),
         ]);
@@ -78,7 +77,6 @@ class PaliSearch
                                   $bold1,$bold2,$bold3,
                                   $content,$pcd_book_id){
         $client = PaliSearch::connect();
-        Log::debug('tulip update',['book'=>$book,'paragraph'=>$paragraph]);
         $request = new \Mint\Tulip\V1\UpdateRequest();
         $request->setBook($book);
         $request->setParagraph($paragraph);
@@ -94,7 +92,6 @@ class PaliSearch
             Log::error("ERROR: " . $status->code . ", " . $status->details);
             return false;
         }
-        Log::debug('tulip update success',['book'=>$book,'paragraph'=>$paragraph]);
         return $response->getCount();
     }
 }