22
33namespace App \Console \Commands ;
44
5+ use App \Services \NameFtsProgressService ;
56use Illuminate \Console \Command ;
67use Illuminate \Support \Facades \DB ;
7- use Illuminate \Support \Facades \Log ;
88use Illuminate \Support \Facades \Schema ;
99
1010class RebuildNameSearchIndex extends Command
@@ -19,7 +19,8 @@ class RebuildNameSearchIndex extends Command
1919 {--batch=500 : Number of records to insert per batch}
2020 {--commit-interval=5000 : Number of records to commit per transaction}
2121 {--id-from= : Start from this c_personid (inclusive)}
22- {--id-to= : End at this c_personid (inclusive)} ' ;
22+ {--id-to= : End at this c_personid (inclusive)}
23+ {--task-id= : 內部使用:前端輪詢的進度任務編號} ' ;
2324
2425 /**
2526 * The console command description.
@@ -35,6 +36,27 @@ class RebuildNameSearchIndex extends Command
3536 */
3637 protected $ tradSimpMap = [];
3738
39+ /**
40+ * 目前進行中的進度任務
41+ *
42+ * @var string|null
43+ */
44+ protected $ taskId ;
45+
46+ /**
47+ * 上一次回報進度時已處理的姓名數
48+ *
49+ * @var int
50+ */
51+ protected $ lastProgressCount = 0 ;
52+
53+ /**
54+ * 回報進度的最小間隔
55+ *
56+ * @var int
57+ */
58+ protected $ progressReportInterval = 1000 ;
59+
3860 /**
3961 * Execute the console command.
4062 *
@@ -47,6 +69,12 @@ public function handle()
4769 return 1 ;
4870 }
4971
72+ $ this ->taskId = $ this ->option ('task-id ' ) ? (string ) $ this ->option ('task-id ' ) : null ;
73+ $ this ->lastProgressCount = 0 ;
74+ if ($ this ->taskId ) {
75+ NameFtsProgressService::update ($ this ->taskId , 12 , '正在初始化索引重建作業… ' , 'running ' );
76+ }
77+
5078 $ batchSize = max (1 , (int ) $ this ->option ('batch ' ));
5179 $ commitInterval = max (100 , (int ) $ this ->option ('commit-interval ' ));
5280 $ idFrom = $ this ->option ('id-from ' ) ? (int ) $ this ->option ('id-from ' ) : null ;
@@ -73,7 +101,7 @@ public function handle()
73101
74102 // 流式處理:邊收集邊生成邊插入
75103 $ this ->info ('流式處理姓名資料... ' );
76- $ this ->streamProcessNames ($ batchSize , $ commitInterval , $ idFrom , $ idTo );
104+ $ this ->streamProcessNames ($ batchSize , $ commitInterval , $ idFrom , $ idTo, $ this -> taskId );
77105
78106 $ this ->info ('索引重建完成! ' );
79107 $ this ->displayStatistics ();
@@ -89,12 +117,12 @@ public function handle()
89117 * @param int|null $idFrom
90118 * @param int|null $idTo
91119 */
92- protected function streamProcessNames (int $ batchSize , int $ commitInterval , ?int $ idFrom = null , ?int $ idTo = null )
120+ protected function streamProcessNames (int $ batchSize , int $ commitInterval , ?int $ idFrom = null , ?int $ idTo = null , ? string $ taskId = null )
93121 {
94122 $ recordBuffer = [];
95123 $ totalInserted = 0 ;
96124
97- $ this ->streamProcessNamesInTransaction ($ batchSize , $ recordBuffer , $ totalInserted , $ commitInterval , $ idFrom , $ idTo );
125+ $ this ->streamProcessNamesInTransaction ($ batchSize , $ recordBuffer , $ totalInserted , $ commitInterval , $ idFrom , $ idTo, $ taskId );
98126
99127 $ this ->info (sprintf ('成功插入 %s 條倒排記錄 ' , number_format ($ totalInserted )));
100128 }
@@ -109,7 +137,7 @@ protected function streamProcessNames(int $batchSize, int $commitInterval, ?int
109137 * @param int|null $idFrom
110138 * @param int|null $idTo
111139 */
112- protected function streamProcessNamesInTransaction (int $ batchSize , array &$ recordBuffer , int &$ totalInserted , int $ commitInterval , ?int $ idFrom = null , ?int $ idTo = null )
140+ protected function streamProcessNamesInTransaction (int $ batchSize , array &$ recordBuffer , int &$ totalInserted , int $ commitInterval , ?int $ idFrom = null , ?int $ idTo = null , ? string $ taskId = null )
113141 {
114142 // 禁用查詢日誌以避免記憶體累積
115143 DB ::connection ()->disableQueryLog ();
@@ -140,11 +168,12 @@ protected function streamProcessNamesInTransaction(int $batchSize, array &$recor
140168 $ totalAltNames = $ altQuery ->count ();
141169 $ totalNames = $ totalMainNames + $ totalAltNames ;
142170
143- $ bar = $ this ->output ->createProgressBar ($ totalNames );
171+ $ bar = $ this ->output ->createProgressBar ($ totalNames ?: 1 );
144172 $ bar ->start ();
145173
146174 $ lastCommitCount = 0 ; // 上次提交時的記錄數
147175 $ timestamp = now (); // 快取時間戳,避免每次都創建新物件
176+ $ processedNames = 0 ;
148177
149178 // 開始第一個事務
150179 DB ::beginTransaction ();
@@ -163,11 +192,13 @@ protected function streamProcessNamesInTransaction(int $batchSize, array &$recor
163192 }
164193 $ mainProcessQuery
165194 ->orderBy ('c_personid ' )
166- ->chunkById (1000 , function ($ rows ) use (&$ recordBuffer , &$ totalInserted , &$ lastCommitCount , $ batchSize , $ commitInterval , &$ bar , $ totalNames , $ timestamp ) {
195+ ->chunkById (1000 , function ($ rows ) use (&$ recordBuffer , &$ totalInserted , &$ lastCommitCount , $ batchSize , $ commitInterval , &$ bar , $ totalNames , $ timestamp, & $ processedNames , $ taskId ) {
167196 foreach ($ rows as $ row ) {
168197 $ fullName = $ this ->normalizeName ($ row ->c_name_chn );
198+ $ processedNames ++;
169199 if (!$ fullName ) {
170200 $ bar ->advance ();
201+ $ this ->reportProgressIfNeeded ($ taskId , $ processedNames , $ totalNames , '正在處理本名資料… ' );
171202 continue ;
172203 }
173204
@@ -206,6 +237,7 @@ protected function streamProcessNamesInTransaction(int $batchSize, array &$recor
206237 }
207238
208239 $ bar ->advance ();
240+ $ this ->reportProgressIfNeeded ($ taskId , $ processedNames , $ totalNames , '正在處理本名資料… ' );
209241 }
210242 }, 'c_personid ' );
211243
@@ -230,11 +262,13 @@ protected function streamProcessNamesInTransaction(int $batchSize, array &$recor
230262 }
231263 $ altProcessQuery
232264 ->orderBy ('ad.c_personid ' )
233- ->chunk (1000 , function ($ rows ) use (&$ recordBuffer , &$ totalInserted , &$ lastCommitCount , $ batchSize , $ commitInterval , &$ bar , $ totalNames , $ timestamp ) {
265+ ->chunk (1000 , function ($ rows ) use (&$ recordBuffer , &$ totalInserted , &$ lastCommitCount , $ batchSize , $ commitInterval , &$ bar , $ totalNames , $ timestamp, & $ processedNames , $ taskId ) {
234266 foreach ($ rows as $ row ) {
235267 $ fullName = $ this ->normalizeName ($ row ->c_alt_name_chn );
268+ $ processedNames ++;
236269 if (!$ fullName ) {
237270 $ bar ->advance ();
271+ $ this ->reportProgressIfNeeded ($ taskId , $ processedNames , $ totalNames , '正在處理別名資料… ' );
238272 continue ;
239273 }
240274
@@ -277,6 +311,7 @@ protected function streamProcessNamesInTransaction(int $batchSize, array &$recor
277311 }
278312
279313 $ bar ->advance ();
314+ $ this ->reportProgressIfNeeded ($ taskId , $ processedNames , $ totalNames , '正在處理別名資料… ' );
280315 }
281316 });
282317
@@ -291,6 +326,30 @@ protected function streamProcessNamesInTransaction(int $batchSize, array &$recor
291326
292327 $ bar ->finish ();
293328 $ this ->line ('' );
329+
330+ $ this ->reportProgressIfNeeded ($ taskId , $ processedNames , $ totalNames , '姓名資料已全部處理,正在整理索引結果… ' );
331+ }
332+
333+ protected function reportProgressIfNeeded (?string $ taskId , int $ processed , int $ total , string $ message = null ): void
334+ {
335+ if (!$ taskId || $ total <= 0 ) {
336+ return ;
337+ }
338+
339+ $ shouldReport = $ processed === $ total || ($ processed - $ this ->lastProgressCount ) >= $ this ->progressReportInterval ;
340+ if (!$ shouldReport ) {
341+ return ;
342+ }
343+
344+ $ percent = (int ) floor (($ processed / $ total ) * 75 ) + 15 ;
345+ $ percent = max (12 , min (90 , $ percent ));
346+ $ message = $ message ?? sprintf ('已處理 %s / %s 筆姓名… ' ,
347+ number_format ($ processed ),
348+ number_format ($ total )
349+ );
350+
351+ NameFtsProgressService::update ($ taskId , $ percent , $ message , 'running ' );
352+ $ this ->lastProgressCount = $ processed ;
294353 }
295354
296355 /**
0 commit comments