CaiWuXiTong/app/Business/JstOrderLabelOptions.php
qiuxiang c46a439d73 聚水潭订单标签明细分页总数改为缓存
无筛选时 COUNT(*) 在 233 万行上要 2 秒(冷缓存更久);改为缓存总数(30 分钟,导入时预热)并手工构造分页器,翻页不再重复统计。
2026-09-30 17:48:35 +08:00

97 lines
2.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Business;
use App\Models\Business\JstOrderLabel;
use Illuminate\Support\Facades\Cache;
/**
* 聚水潭订单标签明细的筛选下拉选项。
*
* 表里有 200 万行以上,distinct 扫描一次要几秒;这里按公司缓存 24 小时,
* 导入命令结束时会主动预热,避免每次打开页面都慢。
*/
class JstOrderLabelOptions
{
private const TTL_HOURS = 24;
private const TOTAL_TTL_MINUTES = 30;
private const LIMIT = 500;
/** @return list<string> */
public function labels(int $companyId): array
{
return $this->remember($companyId, 'label');
}
/** @return list<string> */
public function shops(int $companyId): array
{
return $this->remember($companyId, 'shop_name');
}
public function warm(int $companyId): void
{
$this->labels($companyId);
$this->shops($companyId);
$this->total($companyId);
}
public function forget(int $companyId): void
{
Cache::forget($this->key($companyId, 'label'));
Cache::forget($this->key($companyId, 'shop_name'));
Cache::forget($this->totalKey($companyId));
}
/** 无筛选时的总行数:233 万行上 COUNT(*) 要 2 秒,缓存后翻页不再重复统计。 */
public function total(int $companyId): int
{
$key = $this->totalKey($companyId);
$cached = Cache::get($key);
if (is_numeric($cached)) {
return (int) $cached;
}
$count = (int) JstOrderLabel::query()->where('company_id', $companyId)->count();
Cache::put($key, $count, now()->addMinutes(self::TOTAL_TTL_MINUTES));
return $count;
}
/** @return list<string> */
private function remember(int $companyId, string $column): array
{
$key = $this->key($companyId, $column);
$cached = Cache::get($key);
if (is_array($cached)) {
return $cached;
}
$values = JstOrderLabel::query()
->where('company_id', $companyId)
->whereNotNull($column)
->where($column, '<>', '')
->distinct()
->orderBy($column)
->limit(self::LIMIT)
->pluck($column)
->all();
Cache::put($key, $values, now()->addHours(self::TTL_HOURS));
return $values;
}
private function key(int $companyId, string $column): string
{
return "jst-order-labels:options:v1:{$companyId}:{$column}";
}
private function totalKey(int $companyId): string
{
return "jst-order-labels:total:v1:{$companyId}";
}
}