Files
YwxAppThink/ywxapp/model/Ad.php
T

159 lines
5.8 KiB
PHP

<?php
namespace ywxapp\model;
use think\facade\Db;
use ywxapp\model\BaseModel;
class Ad extends BaseModel
{
protected $name = 'ad';
// 广告类型
const TYPE_IMAGE = 1; // 图片
const TYPE_TEXT = 2; // 文字
const TYPE_CODE = 3; // 代码
// 广告位标识(预埋位:已挂模板的 4 个 + 预留候选,随时可在前台 include 使用)
const POS_HOME_TOP = 'home_top'; // 首页顶部横幅(已挂)
const POS_HOME_SIDE = 'home_side'; // 首页侧边(已挂)
const POS_POPUP = 'popup'; // 全站弹窗(已挂)
const POS_LIST_BOTTOM = 'list_bottom'; // 列表底部(已挂)
// —— 以下为预埋预留位,前台模板尚未挂载,需要时在对应页面加:
// {assign name="slot" value="home_bottom" /}{include file="common/adslot" /}
const POS_HOME_BOTTOM = 'home_bottom'; // 首页底部
const POS_CONTENT_TOP = 'content_top'; // 内容详情页顶部
const POS_CONTENT_BOTTOM = 'content_bottom'; // 内容详情页底部
const POS_SIDEBAR = 'sidebar'; // 通用侧边栏
const POS_FLOAT = 'float'; // 全站悬浮角标
public function getOptions(): array
{
return [
'name' => 'ad',
'strict' => true,
'autoWriteTimestamp' => true,
'createTime' => 'create_at',
'updateTime' => 'update_at',
'deleteTime' => 'delete_at',
];
}
protected $type = [
'id' => 'integer',
'type' => 'integer',
'sort' => 'integer',
'status' => 'integer',
'create_at' => 'integer',
'update_at' => 'integer',
'delete_at' => 'integer',
];
protected $readonly = [];
public static function typeList(): array
{
return [
self::TYPE_IMAGE => '图片',
self::TYPE_TEXT => '文字',
self::TYPE_CODE => '代码',
];
}
public static function positionList(): array
{
return [
self::POS_HOME_TOP => '首页顶部横幅',
self::POS_HOME_SIDE => '首页侧边',
self::POS_POPUP => '全站弹窗',
self::POS_LIST_BOTTOM => '列表底部',
self::POS_HOME_BOTTOM => '首页底部',
self::POS_CONTENT_TOP => '内容页顶部',
self::POS_CONTENT_BOTTOM => '内容页底部',
self::POS_SIDEBAR => '通用侧边栏',
self::POS_FLOAT => '全站悬浮角标',
];
}
/**
* 运行时自愈:确保 ad 表存在 position 列,避免老库缺列导致列表/取数报错
*/
public static function ensureSchema(): void
{
try {
$p = self::currentPrefix();
$prefix = $p;
$table = $prefix . 'ad';
// 缺表建表(install.sql L638 同款 DDL,运行时前缀兜底)
BaseModel::ensureTable($table, "CREATE TABLE IF NOT EXISTS `{$p}ad` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(200) NOT NULL DEFAULT '' COMMENT '广告标题',
`type` tinyint(1) NOT NULL DEFAULT 1 COMMENT '类型 1图片2文字3代码',
`position` varchar(50) NOT NULL DEFAULT '' COMMENT '广告位标识 home_top首页顶部 home_side首页侧边 popup全站弹窗 list_bottom列表底部',
`content` text COMMENT '广告内容/代码',
`url` varchar(255) NOT NULL DEFAULT '' COMMENT '跳转链接',
`image` varchar(255) NOT NULL DEFAULT '' COMMENT '图片地址',
`sort` int(11) NOT NULL DEFAULT 0 COMMENT '排序',
`status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '状态',
`create_at` int(11) NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_at` int(11) NOT NULL DEFAULT 0 COMMENT '更新时间',
`delete_at` int(11) NOT NULL DEFAULT 0 COMMENT '删除时间',
PRIMARY KEY (`id`),
KEY `idx_position` (`position`),
KEY `idx_status_sort` (`status`,`sort`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='站点广告'");
// 老库扩展列兜底(幂等)
BaseModel::ensureColumn($table, 'position', "varchar(50) NOT NULL DEFAULT '' COMMENT '广告位标识'");
} catch (\Throwable $e) {
// 自愈失败不影响主流程
}
}
/**
* 按广告位取启用广告(按 sort 升序)
* @param string $position 广告位标识
* @return array
*/
public static function getByPosition(string $position): array
{
self::ensureSchema();
$rows = Db::name('ad')
->where('status', 1)
->where('position', $position)
->where('delete_at', 0)
->order('sort', 'asc')
->order('id', 'desc')
->select()
->toArray();
$typeList = self::typeList();
foreach ($rows as &$row) {
$row['type_text'] = $typeList[$row['type']] ?? '图片';
}
return $rows;
}
/**
* 取全部启用广告,按 position 分组,便于前台模板随处调用
* @return array [position => [ad, ...]]
*/
public static function getSlots(): array
{
self::ensureSchema();
$positions = array_keys(self::positionList());
$slots = array_fill_keys($positions, []);
$rows = Db::name('ad')
->where('status', 1)
->where('position', 'in', $positions)
->where('delete_at', 0)
->order('sort', 'asc')
->order('id', 'desc')
->select()
->toArray();
$typeList = self::typeList();
foreach ($rows as $row) {
$row['type_text'] = $typeList[$row['type']] ?? '图片';
$slots[$row['position']][] = $row;
}
return $slots;
}
}