// +---------------------------------------------------------------------- declare(strict_types=1); namespace addon\haonav\model; use think\facade\Cache; use ywxapp\model\BaseModel; /** * 广告位模型 * 支持多广告位(首页顶部/底部、详情页内联、侧边栏),可投放图片广告或自定义代码(联盟广告)。 * 表在首次访问时由 BaseModel 自愈引擎建立,无需重跑 install.sql。 */ class Ad extends BaseModel { // 广告位标识 const SLOT_HOME_TOP = 'home_top'; const SLOT_HOME_BOTTOM = 'home_bottom'; const SLOT_DETAIL_INLINE = 'detail_inline'; const SLOT_SIDEBAR = 'sidebar'; // 类型:1=图片广告 2=代码广告 const TYPE_IMAGE = 1; const TYPE_CODE = 2; /** * 广告位字典(标识 => 中文名) */ public static function slots(): array { return [ self::SLOT_HOME_TOP => '首页顶部', self::SLOT_HOME_BOTTOM => '首页底部', self::SLOT_DETAIL_INLINE => '详情页内联', self::SLOT_SIDEBAR => '侧边栏', ]; } protected function getOptions(): array { return [ 'strict' => false, 'name' => 'haonav_ads', 'autoRelation' => [], 'createTime' => 'create_at', 'updateTime' => 'update_at', 'dateFormat' => 'Y-m-d H:i:s', ]; } /** * 取某广告位当前生效的广告列表(状态启用 + 在生效时间范围内) */ public static function getBySlot(string $slot): array { $now = time(); return self::where('slot', $slot) ->where('status', 1) ->where(function ($q) use ($now) { $q->whereNull('start_at')->whereOr('start_at', '<=', $now); }) ->where(function ($q) use ($now) { $q->whereNull('end_at')->whereOr('end_at', '>=', $now); }) ->order('sort', 'desc') ->order('id', 'desc') ->select() ->toArray(); } /** * 所有广告位当前生效广告(按 slot 分组),带 60s 缓存,供前台统一 assign */ public static function allActiveBySlot(): array { $cacheKey = 'haonav_ads_all'; $out = Cache::get($cacheKey); if (is_array($out)) { return $out; } $out = []; foreach (self::slots() as $k => $v) { $out[$k] = self::getBySlot($k); } Cache::set($cacheKey, $out, 60); return $out; } /** * 清除广告缓存(后台增删改时调用) */ public static function clearCache(): void { Cache::delete('haonav_ads_all'); } }