| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- <?php
- namespace App\Models;
- use Illuminate\Database\Eloquent\Model;
- use Illuminate\Support\Facades\DB;
- /**
- * 用户优惠券模型
- *
- * 表: agent.dbo.user_coupons
- *
- * 状态常量:
- * STATUS_UNUSED = 0 未使用
- * STATUS_USED = 1 已使用
- * STATUS_EXPIRED = 2 已过期
- *
- * 类型常量:
- * TYPE_FIXED = 1 固定金额(单位:元)
- * TYPE_PERCENT = 2 充值百分比(单位:%)
- */
- class UserCoupon extends Model
- {
- const TABLE = 'agent.dbo.user_coupons';
- /** @var int 未使用 */
- const STATUS_UNUSED = 0;
- /** @var int 已使用 */
- const STATUS_USED = 1;
- /** @var int 已过期 */
- const STATUS_EXPIRED = 2;
- /** @var int 固定金额券 */
- const TYPE_FIXED = 1;
- /** @var int 百分比券 */
- const TYPE_PERCENT = 2;
- protected $table = self::TABLE;
- public $timestamps = false;
- protected $fillable = [
- 'user_id',
- 'coupon_name',
- 'coupon_type',
- 'coupon_value',
- 'min_recharge',
- 'max_bonus',
- 'bonus_coins',
- 'order_sn',
- 'status',
- 'issued_at',
- 'used_at',
- 'expire_at',
- ];
- /**
- * 获取用户当前可用的优惠券列表
- *
- * @param int $userId
- * @return \Illuminate\Support\Collection
- */
- public static function getAvailableList($userId)
- {
- $data = DB::connection('write')->table(self::TABLE)
- ->where('user_id', $userId)
- ->where('status', self::STATUS_UNUSED)
- ->where('expire_at', '>', date('Y-m-d H:i:s'))
- ->orderBy('expire_at', 'asc')
- ->get();
- // 过期时间改为距离当前秒数,前端展示更友好
- $data->transform(function ($item) {
- $item->expire_in_seconds = max(0, strtotime($item->expire_at) - time());
- return $item;
- });
- return $data;
- }
- /**
- * 根据 ID 获取单张优惠券,校验归属
- *
- * @param int $couponId
- * @param int $userId
- * @return object|null
- */
- public static function getUserCouponById($couponId, $userId)
- {
- return DB::connection('write')->table(self::TABLE)
- ->where('id', $couponId)
- ->where('user_id', $userId)
- ->first();
- }
- /**
- * 使用优惠券:标记已使用、绑定订单
- *
- * @param int $couponId
- * @param string $orderSn
- * @param int $bonusCoins 实际赠送金币数(分)
- * @return bool
- */
- public static function markUsed($couponId, $orderSn, $bonusCoins)
- {
- return DB::connection('write')->table(self::TABLE)
- ->where('id', $couponId)
- ->where('status', self::STATUS_UNUSED)
- ->update([
- 'status' => self::STATUS_USED,
- 'order_sn' => $orderSn,
- 'bonus_coins' => $bonusCoins,
- 'used_at' => date('Y-m-d H:i:s'),
- ]) > 0;
- }
- /**
- * 发放优惠券给用户
- *
- * @param array $data 优惠券数据
- * @return int 插入ID
- */
- public static function issueToUser(array $data)
- {
- return DB::connection('write')->table(self::TABLE)->insertGetId($data);
- }
- /**
- * 检查用户是否已持有同类型有效优惠券(防重复发放)
- *
- * @param int $userId
- * @param string $couponName
- * @return bool
- */
- public static function hasSameCoupon($userId, $couponName)
- {
- return DB::connection('write')->table(self::TABLE)
- ->where('user_id', $userId)
- ->where('coupon_name', $couponName)
- ->where('status', self::STATUS_UNUSED)
- ->where('expire_at', '>', date('Y-m-d H:i:s'))
- ->exists();
- }
- /**
- * 批量过期更新:将已过期但状态仍为未使用的优惠券标记为过期
- *
- * @param int $userId
- * @return int 影响行数
- */
- public static function expireByUser($userId)
- {
- return DB::connection('write')->table(self::TABLE)
- ->where('user_id', $userId)
- ->where('status', self::STATUS_UNUSED)
- ->where('expire_at', '<=', date('Y-m-d H:i:s'))
- ->update(['status' => self::STATUS_EXPIRED]);
- }
- /**
- * 绑定优惠券到订单(订单创建时调用)
- *
- * @param int $couponId
- * @param string $orderSn
- * @return bool
- */
- public static function bindOrderSn($couponId, $orderSn)
- {
- return DB::connection('write')->table(self::TABLE)
- ->where('id', $couponId)
- ->where('status', self::STATUS_UNUSED)
- ->update(['order_sn' => $orderSn]) > 0;
- }
- /**
- * 根据订单号查找关联的优惠券
- *
- * @param string $orderSn
- * @return object|null
- */
- public static function findByOrderSn($orderSn)
- {
- return DB::connection('write')->table(self::TABLE)
- ->where('order_sn', $orderSn)
- ->first();
- }
- }
|