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(); } }