所以我正在实现“最近查看”功能,我将查看的产品的 UUID 存储在 cookie 中:
public function setRecentlyViewedCookie(Product $product): void
{
$cookieName = self::PRODUCT_RECENTLY_VIEWED_COOKIE_NAME;
$cookieValue = $this->getRecentlyViewedCookie();
$cookieValue[now()->timestamp] = $product->getKey();
$cookieValue = collect($cookieValue)
->unique()
->sortKeysDesc()
->take(self::PRODUCT_RECENTLY_VIEWED_COOKIE_QTY_LIMIT)
->toJson();
$minutes = 60 * 24 * self::PRODUCT_RECENTLY_VIEWED_COOKIE_TTL_DAYS;
$this->cookieFactory->queue(
$cookieName,
$cookieValue,
$minutes,
);
}
这个效果很好。
当我从 cookie 获取这个数组时,我会:
public function getRecentlyViewedCookie(): array
{
$cookieName = self::PRODUCT_RECENTLY_VIEWED_COOKIE_NAME;
try {
$cookieValue = request()->cookie($cookieName);
$cookieValue = json_decode($cookieValue, true);
} catch (Exception) {
$cookieValue = [];
}
return (array) $cookieValue;
}
我得到:
array:12 [▼ // app/Services/ProductService.php:221
1733159352 => "9d9e9b2b-0974-4577-b75e-60d647f88bbf"
1733159348 => "9d9e9b2a-fe8f-44f3-b383-2eaa3614456c"
1733159341 => "9d9e9b2a-fcf6-419c-9e4b-b7c3f4ec8757"
1733159331 => "9d9e9b2a-f60f-42e1-9371-f831b1a28593"
1733159328 => "9d9e9b2a-f422-4faa-baad-16d9a147aaaf"
1733159326 => "9d9e9b2a-f121-4a46-a85d-8e0021172c52"
1733159175 => "9d989879-ddfc-48be-a581-f41036133017"
1733159163 => "9d989878-c8e9-4b75-af30-799ec780cfa7"
1733159161 => "9d989878-c69f-4833-add1-12b7d0f43c1f"
1733159157 => "9d989878-c320-4579-b261-e97b15dc5227"
1733159153 => "9d989878-b9f0-485d-bca3-304b7ef38f83"
1733159148 => "9d989878-b64c-49b3-92f4-fd8b01e84dcb"
]
所以我也知道这些产品,当我看到每个产品时我知道顺序,因为我有时间戳。我将这些 UUID 传递到存储库的
whereIn()
,但我怀疑顺序是否正确反映。
有任何关于如何使用这些时间戳订购获取产品的提示吗?
为了实现这一点,我们可以使用
orderByRaw
和 MySQL 的 FIELD
。
获取已正确排序的数组的所有 UUID:
$productUuids = array_values($cookieValue);
将每个 UUID 用引号引起来:
$implodedProductUuids = implode(',', array_map(fn($uuid) => "'$uuid'", $productUuids));
传递到存储库:
return $this->productRepository
->whereIn('uuid', $productUuids)
->orderByRaw('FIELD(uuid, ' . $implodedProductUuids . ')')
->get()
->take(self::PRODUCT_RECENTLY_VIEWED_PRODUCTS_MIN_QTY);