Files
YwxAppThink/ywxapp/model/Notice.php
T

155 lines
5.6 KiB
PHP

<?php
declare(strict_types=1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
use think\model\concern\SoftDelete;
/**
* 站点公告
*/
class Notice extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_at';
protected $defaultSoftDelete = 0;
// 类型:1系统维护 2活动公告 3版本更新 4其他
public const TYPE_MAINTAIN = 1;
public const TYPE_ACTIVITY = 2;
public const TYPE_UPDATE = 3;
public const TYPE_OTHER = 4;
// 字段类型转换
protected $type = [
'type' => 'integer',
'is_top' => 'integer',
'start_time' => 'integer',
'end_time' => 'integer',
'view_count' => 'integer',
'sort' => 'integer',
'status' => 'integer',
'create_at' => 'integer',
'update_at' => 'integer',
'delete_at' => 'integer',
];
// 只读字段
protected $readonly = ['view_count'];
/**
* 模型配置(BaseModel::applyOptions 约定)
*/
protected function getOptions(): array
{
return [
'strict' => true,
'name' => 'notice',
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
];
}
/**
* 公告类型映射
*/
public static function typeList(): array
{
return [
self::TYPE_MAINTAIN => '系统维护',
self::TYPE_ACTIVITY => '活动公告',
self::TYPE_UPDATE => '版本更新',
self::TYPE_OTHER => '其他',
];
}
/**
* 取全站生效的置顶公告(用于前台公告条)。
* 过滤:status=1 + 在有效期内(start_time<=now<=end_time 或 0=长期) + is_top=1
*/
public static function getActiveTopNotices(): array
{
self::ensureSchema();
$now = time();
return (new self())
->where('status', 1)
->where('is_top', 1)
->where(function ($q) use ($now) {
$q->where('start_time', 0)->whereOr('start_time', '<=', $now);
})
->where(function ($q) use ($now) {
$q->where('end_time', 0)->whereOr('end_time', '>=', $now);
})
->order('sort', 'desc')
->order('id', 'desc')
->limit(5)
->select()
->toArray();
}
/**
* 取前台公告列表(分页),按置顶优先 + 排序 + 时间倒序
*/
public static function getList(int $page = 1, int $limit = 10, int $type = 0): \think\Paginator
{
self::ensureSchema();
$now = time();
$query = (new self())
->where('status', 1)
->where(function ($q) use ($now) {
$q->where('start_time', 0)->whereOr('start_time', '<=', $now);
})
->where(function ($q) use ($now) {
$q->where('end_time', 0)->whereOr('end_time', '>=', $now);
});
if ($type > 0) {
$query->where('type', $type);
}
return $query->order('is_top', 'desc')
->order('sort', 'desc')
->order('id', 'desc')
->paginate(['page' => $page, 'list_rows' => $limit]);
}
/**
* 运行时结构自愈:老库缺新列时自动补齐(install.sql 为唯一事实源,此处兜底)
*/
public static function ensureSchema(): void
{
try {
$p = self::currentPrefix();
$prefix = $p;
$table = $prefix . 'notice';
// 缺表建表(install.sql L618 同款 DDL,运行时前缀兜底)
self::ensureTable($table, "CREATE TABLE IF NOT EXISTS `{$p}notice` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(200) NOT NULL DEFAULT '' COMMENT '公告标题',
`content` text COMMENT '公告内容',
`author` varchar(50) NOT NULL DEFAULT '' COMMENT '发布人',
`type` tinyint(1) NOT NULL DEFAULT 1 COMMENT '类型 1系统维护 2活动公告 3版本更新 4其他',
`is_top` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否置顶 0否 1是',
`start_time` int(11) NOT NULL DEFAULT 0 COMMENT '展示开始时间 0=长期',
`end_time` int(11) NOT NULL DEFAULT 0 COMMENT '展示结束时间 0=长期',
`view_count` int(11) NOT NULL DEFAULT 0 COMMENT '浏览量',
`sort` int(11) NOT NULL DEFAULT 0 COMMENT '排序',
`status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '状态 0禁用 1启用',
`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_type` (`type`),
KEY `idx_is_top` (`is_top`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='站点公告'");
// 老库扩展列兜底(幂等)
self::ensureColumn($table, 'type', "tinyint(1) NOT NULL DEFAULT 1 COMMENT '公告类型 1系统维护 2活动公告 3版本更新 4其他'");
self::ensureColumn($table, 'is_top', "tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否置顶 0否 1是'");
self::ensureColumn($table, 'start_time', "int(11) NOT NULL DEFAULT 0 COMMENT '展示开始时间 0=长期'");
self::ensureColumn($table, 'end_time', "int(11) NOT NULL DEFAULT 0 COMMENT '展示结束时间 0=长期'");
self::ensureColumn($table, 'view_count', "int(11) NOT NULL DEFAULT 0 COMMENT '浏览量'");
} catch (\Throwable $e) {
// 忽略自愈失败,由业务暴露
}
}
}