导出任务:按自增顺序取数提速、时间统一北京时间、运行中显示「取数中」

This commit is contained in:
yueyang 2026-10-08 15:22:06 +08:00
parent daf3fd64d8
commit 4d5b9bf440
4 changed files with 18 additions and 7 deletions

View File

@ -37,7 +37,7 @@ class RunAccountBillsExportTask extends Command
return self::FAILURE;
}
$task = $tasks->patch($task, ['status' => 'running', 'started_at' => now()->toDateTimeString()]);
$task = $tasks->patch($task, ['status' => 'running', 'started_at' => AccountBillsExportTasks::beijingNow()]);
try {
$columns = array_values((array) ($task['columns'] ?? []));
@ -70,7 +70,7 @@ class RunAccountBillsExportTask extends Command
'status' => 'done',
'rows' => $written,
'size' => (int) @filesize($tasks->csvPath($task)),
'finished_at' => now()->toDateTimeString(),
'finished_at' => AccountBillsExportTasks::beijingNow(),
'error' => null,
]);
$this->info('导出完成:' . $written . ' 行');
@ -79,7 +79,7 @@ class RunAccountBillsExportTask extends Command
} catch (Throwable $exception) {
$tasks->patch($task, [
'status' => 'failed',
'finished_at' => now()->toDateTimeString(),
'finished_at' => AccountBillsExportTasks::beijingNow(),
'error' => mb_substr($exception->getMessage(), 0, 200),
]);
$this->error('导出失败:' . $exception->getMessage());
@ -106,7 +106,9 @@ class RunAccountBillsExportTask extends Command
{
$tab = (string) ($task['tab'] ?? '');
$filters = (array) ($task['filters'] ?? []);
$sort = (string) ($filters['sort'] ?? 'occurred_at');
// 后台导出固定按「记录编码」(数据库自增列)顺序取数:
// 整月按「发生时间」排序要先对上千万行排序,首批数据要几分钟,阶段进度长时间是 0;按自增列取数快很多。
$sort = 'record_code';
$dir = strtolower((string) ($filters['dir'] ?? 'desc')) === 'asc' ? 'asc' : 'desc';
unset($filters['sort'], $filters['dir'], $filters['export'], $filters['token'], $filters['total'], $filters['columns']);

View File

@ -18,6 +18,15 @@ class AccountBillsExportTasks
/** 任务类型(列表里的「类型」列)。 */
public const TYPE_LABEL = '平台原始账单导出';
/**
* 统一的「北京时间」时间戳:Web(Apache)和后台 CLI 的默认时区可能不一致,
* 任务列表里必须统一成北京时间,避免计划时间/执行时间差 8 小时。
*/
public static function beijingNow(): string
{
return Carbon::now('Asia/Shanghai')->toDateTimeString();
}
public function baseDir(int $userId): string
{
return storage_path('app/account-bills-exports/' . $userId);
@ -53,7 +62,7 @@ class AccountBillsExportTasks
'filters' => $filters,
'columns' => $columns,
'error' => null,
'planned_at' => Carbon::now()->toDateTimeString(),
'planned_at' => self::beijingNow(),
'started_at' => null,
'finished_at' => null,
'size' => 0,

View File

@ -78,7 +78,7 @@
<td>{{ task.planned_at || '—' }}</td>
<td>{{ task.finished_at || task.started_at || '—' }}</td>
<td><span class="tw-export-status" :class="'is-' + task.status">{{ statusLabel(task) }}</span></td>
<td>{{ Number(task.rows || 0).toLocaleString('zh-CN') }}</td>
<td>{{ task.status === 'running' && !task.rows ? '取数中…' : Number(task.rows || 0).toLocaleString('zh-CN') }}</td>
<td>
<a v-if="task.status === 'done'" :href="downloadUrl(task)" class="tw-modal__link">下载</a>
<span v-else-if="task.status === 'failed'">{{ task.error || '失败' }}</span>

View File

@ -86,7 +86,7 @@
<td>{{ task.planned_at || '—' }}</td>
<td>{{ task.finished_at || task.started_at || '—' }}</td>
<td><span class="tw-export-status" :class="'is-' + task.status">{{ statusLabel(task) }}</span></td>
<td>{{ Number(task.rows || 0).toLocaleString('zh-CN') }}</td>
<td>{{ task.status === 'running' && !task.rows ? '取数中…' : Number(task.rows || 0).toLocaleString('zh-CN') }}</td>
<td>
<a v-if="task.status === 'done'" :href="downloadUrl(task)" class="tw-modal__link">下载</a>
<span v-else-if="task.status === 'failed'">{{ task.error || '失败' }}</span>