charsen/moo-banner

Banner management for Laravel applications, with reusable placement, media, publishing and ordering conventions.

Maintainers

Package info

github.com/charsen/moo-banner

pkg:composer/charsen/moo-banner

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

v0.1.0 2026-08-11 04:34 UTC

This package is auto-updated.

Last update: 2026-08-11 09:41:58 UTC


README

一个可被多个 Laravel admin 项目复用的 Banner 管理扩展包,统一提供展示位置、文案、桌面与移动图片、链接、启停、排序和软删除能力。

包依赖 charsen/moo-scaffold 提供 Snowflake、代码生成、后台资源和翻译合并能力;不依赖 moo-system 或 host 私有类。

字段、迁移、模型和管理面均以 scaffold/database/Banner.yaml 为设计源;包同时提供默认关闭的前台只读接口,频道目录和页面视觉由接入项目负责。

为什么有这个包

多个官网项目都需要相同的 Banner 管理骨架:上传桌面与移动图片、填写文案与跳转、按位置启停和排序。真正不同的通常只有频道目录、路由前缀和页面视觉。如果每个 host 分别维护表、上传转存、公开读取和后台 CRUD,同一类兼容问题会重复出现。

本包把稳定部分收口,差异通过窄契约交给 host,避免共享包反向依赖任一具体项目。

技术信息

  • PHP 8.2+,Laravel 10 / 11 / 12
  • Composer:charsen/moo-banner
  • 命名空间:Mooeen\Banner\
  • 业务表:moo_banners
  • Schema:scaffold/database/Banner.yaml

设计边界

  • banner_position = NULL 表示首页。
  • 非首页位置由 host 实现 BannerPositionResolver 声明,数据库存稳定字符串代码。
  • 状态由包固定为停用与启用,避免各 host 对公开读取产生不同语义。
  • 包提供默认关闭的公开只读接口;host 配置路由前缀、中间件和数量上限,旧系统可另做响应兼容层。
  • 图片默认通过 Laravel Filesystem 处理,host 可替换媒体契约接入其他存储实现。

所有语义字段都带 banner_ 前缀,避免各扩展包扁平合并 db.php 词条时相互覆盖;id、操作人字段、软删除与时间戳沿用跨包公共命名。

位置与状态的归属不同:

字段 归属 类型 原因
banner_position host 声明 varchar(50) 可空 各项目频道集合不同,字符串代码可自解释;NULL 固定表示首页
banner_status 包定义 tinyint 状态直接驱动公开读取,必须保持确定语义

对外边界

能力 入口
后台 CRUD 包内 api/admin/banners 资源路由
前台只读 显式开启后提供 GET {public.prefix}/banners
位置目录 host 实现 BannerPositionResolver
当前操作人 scaffold 共享 OperatorResolver
图片转存与 URL 包内媒体契约,默认 Laravel Filesystem 实现
公开读取 包内 Web Controller / Request / Resource,默认关闭
管理端页面 host 实现,并使用包返回的字段、options 与 action key

本地开发接入

在 Laravel host 的 composer.json 中添加 path repository:

{
  "repositories": {
    "moo-banner": {
      "type": "path",
      "url": "../moo-banner",
      "options": { "symlink": true }
    }
  }
}

安装开发版本后,将后台模块加入 host 的 scaffold 配置:

'extra_modules' => [
    'Banner' => 'Mooeen\\Banner\\Http\\Controllers\\Admin',
],

这一步不仅用于接口文档,也决定包控制器是否进入 ACL 扫描。模块名或 action 名改变会改变持久化授权 key,不能当作普通重命名。

host 可以绑定自己的位置目录:

use Mooeen\Banner\Contracts\BannerPositionResolver;

$this->app->bind(BannerPositionResolver::class, AppBannerPositions::class);

然后发布配置并执行迁移:

php artisan vendor:publish --tag=moo-banner-config
php artisan migrate

后台路由安全配置(必做)

config/moo-banner.php 中默认的 admin 仅是兼容性路由组名,扩展包无法知道 host 的认证实现,它不等于已经强制登录。host 必须在 bootstrap/app.php 为本包建立独立组,并让发布后的配置明确指向该组;不要借用需要放行登录接口的 admin,也不要复用 moo-system

// bootstrap/app.php -> withMiddleware()
$packageAdminMiddleware = [
    'jwt.assign.guard:admin',
    'jwt.guard.auth:admin',
    'jwt.auth.refresh',
    'throttle:admin',
    'set.locale',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
];

$middleware->appendToGroup('moo-banner', $packageAdminMiddleware);
// config/moo-banner.php
'admin' => [
    'prefix' => 'api/admin',
    'name' => 'admin.',
    'middleware' => 'moo-banner',
],

上面的中间件类名按 host 的真实认证栈调整,但必须保留“指定 admin 守卫 → 强制认证 → 续签/过期处理 → 限流 → 路由绑定”的完整边界。验收至少覆盖:匿名访问后台 Banner 返回 401、已登录但无对应 ACL 返回 403、授权账号成功。前台只读接口继续使用 public.middleware,不要套后台认证组。

前台只读接口

接口默认关闭,host 在发布后的配置中显式开启:

'public' => [
    'enabled'       => true,
    'prefix'        => 'api',
    'name'          => 'banner.',
    'middleware'    => ['api', 'throttle:120,1'],
    'default_limit' => 5,
    'max_limit'     => 20,
    'resource'      => \Mooeen\Banner\Http\Resources\PublicBannerResource::class,
],

启用后可读取首页或频道 Banner:

GET /api/banners
GET /api/banners?position=news&limit=5

空位置表示首页。接口只返回启用且未软删除的数据,并按 banner_sortid 倒序;响应仅包含展示字段和解析后的图片 URL,不暴露状态、排序、操作人及原始存储路径。

非首页位置必须存在于 host 的 BannerPositionResolver 目录,未知代码返回 422。既有站点需要保留旧响应字段时,可将 public.resource 配置为 host 自己的 JsonResource;这只适配响应形状,查询和公开范围仍由包统一处理。

管理端页面约定

Composer 包提供后端接口和 ACL 元数据,不向所有 host 强塞同一套前端页面。host 管理端至少需要:

  • 列表展示图片、位置、标题、启停和排序;
  • 创建/编辑表单消费包返回的位置与状态 options;
  • Snowflake ID 全程按字符串处理;
  • action 前缀与 Banner/BannerController 的真实 ACL key 保持一致;
  • 使用实际 HTTP 客户端能力调用路由,不为迁就前端封装擅自改变正确的 HTTP 语义。

Schema-first 工作流

  1. 修改 scaffold/database/Banner.yaml
  2. 在 path repository host 中运行 php artisan moo:fresh
  3. 运行 php artisan moo:free admin Banner -a,生成物应落入本包。
  4. 在生成区外深化查询、媒体和表单行为。
  5. 分别运行包测试与 host 集成验证,并复核两边完整 diff。

验证

composer ci

License

MIT