Files
coolcoth.com/app/Models/Product.php
T
Lucanlee d5c1edefae perf: V0.9.4 商品列表分页 + sitemap 文件缓存 + banner/asset/gzip/类型修复
- P1: Product::listing() 分页(WHERE status=1+LIMIT/OFFSET+总数),ProductController 改用并加翻页器,消除列表全表
- P1: outputSitemap() 加 storage/cache/sitemap.xml 文件缓存(TTL 3600s),消除每次爬虫全表
- P2: 首页 banner 改 whereLimit('status',1,20)
- P2: asset() 追加 ?v=filemtime 版本串,theme.css 改后自动击穿 1y 浏览器缓存
- P2: nginx 启用 gzip(文本资源压缩)
- P2: Model::count() $val 隐式可空改 mixed(PHP 8.4+ 弃用)
2026-08-08 23:53:52 +08:00

64 lines
2.5 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\Models;
use Core\Model;
class Product extends Model
{
protected $table = 'products';
protected $orderBy = 'sort_order';
public function byCategory(int $catId): array
{
return $this->whereAll('category_id', $catId);
}
public function featured(int $limit = 6): array
{
// V0.9.1:改用 whereLimit('status',1,$limit)MySQL 下走带 LIMIT 的索引查询,
// 不再 SELECT * 全表拉回再 array_filter(原写法每次请求都全表扫描)。
return $this->whereLimit('status', 1, $limit);
}
/**
* V0.9.4:产品列表分页。仅取 status=1 的活跃商品,按 $orderBy 排序,带 LIMIT/OFFSET
* 同时返回总数用于翻页。避免每次列表请求都 SELECT * 全表拉回再 array_filter(原写法随 SKU 增长变重)。
* 文件模式回退为全表过滤 + array_slice。
* @return array{items:array,total:int}
*/
public function listing(int $page, int $perPage, ?int $catId = null): array
{
$page = max(1, $page);
$perPage = max(1, $perPage);
$offset = ($page - 1) * $perPage;
if (\Core\Db::driver() === 'mysql') {
$where = 'WHERE status = 1';
$args = [];
if ($catId !== null) { $where .= ' AND category_id = ?'; $args[] = $catId; }
$items = \Core\Db::query(
"SELECT * FROM `{$this->table}` {$where} ORDER BY `{$this->orderBy}` ASC LIMIT ? OFFSET ?",
array_merge($args, [$perPage, $offset])
)->fetchAll();
$total = (int) \Core\Db::query("SELECT COUNT(*) FROM `{$this->table}` {$where}", $args)->fetchColumn();
return ['items' => $items, 'total' => $total];
}
// 文件模式兜底
$all = array_filter($this->all(), fn($p) => ($p['status'] ?? 1) == 1);
if ($catId !== null) $all = array_filter($all, fn($p) => ($p['category_id'] ?? 0) == $catId);
$all = array_values($all);
return ['items' => array_slice($all, $offset, $perPage), 'total' => count($all)];
}
public function specsArray($p): array
{
$s = $p['specs'] ?? '';
if (is_array($s)) return $s;
$dec = json_decode((string)$s, true);
return is_array($dec) ? $dec : [];
}
public function galleryArray($p): array
{
$g = $p['gallery'] ?? '';
if (is_array($g)) return $g;
$dec = json_decode((string)$g, true);
return is_array($dec) ? $g : [];
}
}