有些 Laravel 应用在销售产品或服务时,需要的折扣不仅仅是固定的百分比。例如,电商平台可能会安排季节性促销,SaaS 产品可能会发放新品发布优惠券,而从 10% 起步的折扣可以设置上限,例如最低订单金额、每个客户的折扣次数限制以及有效期。Laravel 折扣 米尔瓦德·科斯拉维 将所有这些信息存储在 Eloquent 模型中,并通过单一外观对其进行评估。
套餐包含以下内容:
- 两种折扣类型
:
DiscountType::Percentage和DiscountType::Fixed(可选)max_discount_amount帽。 - 优惠券代码
:折扣
code可作为优惠券使用,而无码折扣则会自动应用。 - 时间窗口
:
starts_at和expires_at列,与valid()查询范围。 - 使用限制
: 全部的
usage_limit按客户计费usage_limit_per_user执法。 - 访客支持 :传递会话 ID 以对未经身份验证的用户强制执行每个用户的限制。
- 堆叠规则
标记折扣
is_stackable该软件包会计算出哪种组合能为客户节省最多费用。 - 折扣款
: 这
HasDiscounts该特性可为任何 Eloquent 模型附加折扣。 - 购物车集成
:A
CartDiscount为 Laravel 购物车总金额或单个购物车商品应用代码的服务。
百分比折扣和固定折扣
折扣是 Eloquent 中的一个标准模型,因此您可以像创建其他任何记录一样创建它:
使用
Binafy\LaravelDiscount\Enums\DiscountType
;使用
Binafy\LaravelDiscount\Models\Discount
;$折扣
=
折扣
::
询问
()
->
创造
([
'姓名'
=>
“夏季促销”
,
'类型'
=>
折扣类型
::
百分比
,
'价值'
=>
20
,]);
应用它需要经过……
LaravelDiscount
门面会在计算任何内容之前验证折扣,然后返回一个
DiscountResult
:
使用
Binafy\LaravelDiscount\Facades\LaravelDiscount
;$结果
=
Laravel折扣
::
申请
(折扣)
200
(英文):$结果
->
原金额;
// 200.0$结果
->
折扣金额;
// 40.0$结果
->
应付金额
();
// 160.0
这
DiscountResult
该对象包含已应用的折扣、原始总额和计算出的折扣值。
payableAmount()
从原始总额中减去折扣,并将结果限制在最小值为零,以确保固定折扣永远不会产生负总额。
任何类型的折扣都可能存在上限。
max_discount_amount
这就涵盖了“最高优惠 100 美元,享受 20% 折扣”的情况,否则这种情况最终会被硬编码到控制器中:
$折扣
=
折扣
::
询问
()
->
创造
([
'代码'
=>
“节省20元”
,
'类型'
=>
折扣类型
::
百分比
,
'价值'
=>
20
,
'max_discount_amount'
=>
100
,]);Laravel折扣
::
申请
(折扣)
300
)
->
折扣金额;
// 60.0Laravel折扣
::
申请
(折扣)
1000
)
->
折扣金额;
// 100.0
折扣码、有效期和使用限制
设置
code
专栏将折扣转换为促销优惠券。
applyCode()
验证代码并抛出异常
DiscountNotFoundException
如果没有匹配项:
$结果
=
Laravel折扣
::
applyCode
(
'WELCOME10'
,
200
,$user);
对于每个客户都需要自己代码的营销活动,该软件包会使用以下方式构建代码:
random_int()
并省略了模棱两可的角色,例如
0
/
O
和
1
/
I
这样就不会有人误读打印卡片上的代码了:
Laravel折扣
::
生成代码
();
// "8FJ2K9QW"Laravel折扣
::
生成代码
(
100
,
“VIP”
(英文):
// 包含 100 个唯一代码的集合
长度、字母、前缀和分隔符都属于以下范畴:
codes
键入
config/laravel-discount.php
。
限时优惠使用
starts_at
和
expires_at
在窗口弹出之前申请
DiscountNotStartedException
,在抛出后应用
DiscountExpiredException
并开火
DiscountExpired
事件。查询当前正在直播的内容是一个范围:
折扣
::
询问
()
->
有效的
()
->
得到
();
usage_limit
限制总兑换额,以及
usage_limit_per_user
对每位客户设定上限,但这些上限并非仅在申请时就确定。您致电
redeem()
当订单最终确定时:
Laravel折扣
::
赎回
(折扣,用户,结果)
->
折扣金额);
该操作在事务中运行并递增。
used_count
受限于
where
子句决定数据库是否执行增量更新。如果更新零行,则已达到限制,这会表现为:
DiscountUsageLimitReachedException
两个顾客同时声称自己是第一百名顾客,不可能同时获得该名额。
访客通过会话 ID 而非用户模型获得相同的待遇,该 ID 会在跟踪过程中进行记录。
session_id
列
discount_usages
与可空对象一起
user_id
:
$结果
=
Laravel折扣
::
applyCode
(
'GUEST10'
总计
会话 ID
:
会议
()
->
获取 ID
());Laravel折扣
::
赎回
(折扣)
数量
:$result
->
折扣金额
会话 ID
:
会议
()
->
获取 ID
());
条件折扣和可叠加折扣
A
min_order_value
专栏设置了消费门槛,达到一定金额后即可享受折扣,并会抛出一些问题。
MinimumOrderValueException
当总数不足时。还有一种情况是……
conditions
用于存储自定义条件数据的 JSON 列,您可以将软件包本身未原生支持的所有内容都放在这里。如果您希望条件以可组合的 PHP 对象形式表示,则需要使用 JSON 列。
Discountify套餐
采取这种方法。
折扣也可以适用于特定型号。添加
HasDiscounts
性状,并由此获得由以下因素支持的多态关系:
discountables
桌子:
使用
Binafy\LaravelDiscount\Traits\HasDiscounts
;班级
产品
延伸
模型{
使用
有折扣
;}
$产品
->
折扣
()
->
附
(折扣)$产品
->
有效折扣
();$产品
->
有折扣
(
'TECH10'
(英文):$结果
=
$产品
->
应用折扣
(产品)
->
价格);
最后一个呼叫通过
applyMany()
这是堆叠解析器。它会丢弃任何未通过验证的折扣,将剩余的折扣拆分为可堆叠折扣和不可堆叠折扣,将可堆叠折扣相加(上限为订单总额),找到最佳的不可堆叠折扣,并返回节省金额更多的一方:
$结果
=
Laravel折扣
::
应用多个
([$tenPercent, $tenFixed, $bigSolo],
100
(英文):$结果
->
折扣;
// 实际应用的那些$结果
->
折扣金额;
// 获胜总额
这
discounts
收集结果至关重要。在做出堆叠决策后,您通常需要向客户展示哪些代码最终入选,而收集结果就是答案。
Laravel 购物车集成
安装
binafy/laravel-cart
购物车包来自同一作者,我们
之前已介绍过
,和一个
CartDiscount
该服务支持购物车级别和商品级别折扣:
使用
Binafy\LaravelDiscount\Integrations\LaravelCart\CartDiscount
;购物车折扣
=
应用程序
(
购物车折扣
::班级
(英文):$结果
=
购物车折扣
->
添加到购物车
(购物车,
'SUMMER-8FJ2K9QW'
(英文):$结果
=
购物车折扣
->
应用于项目
($购物车商品,$折扣);$结果
=
购物车折扣
->
应用商品折扣
(购物车)
applyToCart()
检查购物车总额是否与预期相符
min_order_value
并根据每个用户的限制,从购物车中提取用户,这样你自己就不会超过这两个限制。
applyToItem()
单行价格乘以数量计算。
applyItemDiscounts()
它遍历购物车,并应用每个物品底层模型所附加的任何内容。
HasDiscounts
也就是说,你可以在不改变购物车总额的情况下,对整个购物篮中的商品进行产品级销售。
验证、异常和事件
结账表单需要先拒绝无效代码,然后才能进行其他操作,并且该软件包包含一个
ValidDiscountCode
这条规则就是如此。它的错误消息会明确指出实际原因,而不是泛泛地报错:
使用
Binafy\LaravelDiscount\Rules\ValidDiscountCode
;民众
功能
规则
()
:
大批{
返回
[
'代码'
=>
[
'必需的'
,
新的
有效折扣码
(
订单金额
:
$this
->
购物车总计
(),
用户
:
$this
->
用户
(),)],];}
这是一个标准规则对象,因此它与其他表单请求元素的组合方式与任何其他规则对象相同。 自定义验证规则 做。
除了验证之外,每个失败案例都有其自身的异常扩展。
DiscountException
:
DiscountNotFoundException
,
DiscountNotActiveException
,
DiscountNotStartedException
,
DiscountExpiredException
,
DiscountUsageLimitReachedException
, 和
MinimumOrderValueException
每一项都暴露了折扣失败的真相。
getDiscount()
这样,你就可以针对需要特殊处理的情况进行单独消息传递,而让基类处理其余部分:
尝试
{$结果
=
Laravel折扣
::
applyCode
($代码,$总计,$用户);}
抓住
(
折扣过期异常
$e) {
返回
后退
()
->
带有错误
(
“代码 {
$e
->
获取折扣
()
->
代码
已过期。
(英文):}
抓住
(
折扣例外
$e) {
返回
后退
()
->
带有错误
($e
->
获取消息
());}
生命周期包含三个事件:
DiscountApplied
当折扣应用于某个金额时,
DiscountRedeemed
赎回交易提交后,并且
DiscountExpired
当验证过程中发现折扣已过期时,兑换事件会同时包含折扣信息和使用记录,这足以驱动分析或发送通知,无需再次查询。
安装
Laravel Discount 需要 PHP 8.1+ 和 Laravel 9-13。通过 Composer 安装该软件包并运行迁移:
作曲家
要求
binafy/laravel-discountphp
工匠
迁移
服务提供商注册自身,迁移过程创建
discounts
,
discount_usages
, 和
discountables
发布配置是可选的,只有当您需要更改表名、指向不同的用户模型或调整代码生成默认值时才值得这样做:
php
工匠
供应商:发布
--标签=
"laravel-discount-config"
它还附带两条工匠指令。
discount:generate
从终端生成代码,并且
discount:prune
删除过期折扣及其使用记录,这是计划任务中应该包含的一项合理内容:
日程
::
命令
(
'discount:prune --days=30'
)
->
日常的
();
完整的文档,包括配置参考,位于…… Laravel 折扣 GitHub 仓库 。







