Skip to content

安装指南

购买提示

多租户扩展是 CatchAdmin 的高级功能模块,作为单独额外的扩展包提供,需要额外购买。如果您是 CatchAdmin 专业版用户,可以单独购买该扩展模块。

安装步骤

多租户扩展的安装过程非常简便,只需要几个简单的命令即可完成。下面是详细的安装步骤:

1. 安装扩展包

首先,使用 Composer 安装多租户扩展包:

shell
composer require catchadmin/tenancy

该命令将会下载并安装所有必要的依赖包和文件。

2. 初始化租户数据

安装完成后,需要运行以下命令来初始化租户系统所需的数据结构和配置:

shell
php artisan catch:tenant:install

该命令将执行以下操作:

  • 发布必要的配置文件
  • 发布数据库迁移文件
  • 创建租户相关的数据表
  • 准备前端所需的视图文件

配置文件详解

安装多租户扩展后,系统会自动将配置文件发布到 config/tenancy.php 路径。该配置文件包含了多租户系统的所有核心设置,您可以根据实际需求进行自定义调整。

下面是配置文件的完整内容,并附有每个配置项的详细说明:

php

return [
    'tenant_model' => Tenant::class, // 租户模型
    'id_generator' => UUIDGenerator::class, // ID 生成器
    'domain_model' => Domain::class, // 域名模型

    /**
     * 是否缓存租户域名,可以减少租户上下文切换查询,默认开启
     *
     */
    'is_cache_tenant_domains' => [
        'enable' => true,

        'ttl' => 3600, // 秒
    ],

    /**
     * 托管您的中央应用程序的域名列表。
     *
     * 仅在您使用域或子域识别中间件时相关。
     */
    'central_domains' => [
        '127.0.0.1',
        'localhost',
        'pro.test',
    ],

    /**
     * 租户引导程序在租户初始化时执行。
     * 它们的职责是使 Laravel 功能具有租户意识。
     *
     * 要配置它们的行为,请参见下面的配置键。
     */
    'bootstrappers' => [
        CatchTenant\Bootstrappers\DatabaseTenancyBootstrapper::class, // 数据库租户引导程序
        CatchTenant\Bootstrappers\CacheTenancyBootstrapper::class, // 缓存租户引导程序
        CatchTenant\Bootstrappers\LogTenancyBootstrappper::class, // 日志租户引导程序
        CatchTenant\Bootstrappers\FilesystemTenancyBootstrapper::class, // 文件系统租户引导程序
        CatchTenant\Bootstrappers\QueueTenancyBootstrapper::class, // 队列租户引导程序
    ],

    /**
     * 租户中间件
     *
     * 中间件,在请求处理之前执行。
     */
    'tenancy_middlewares' => [
        InitializeTenancyByDomain::class, // 租户初始化
        InitializeTenancySystemSetting::class, // 租户系统配置初始化
    ],

    /**
     * 数据库租户配置。由 DatabaseTenancyBootstrapper 使用。
     */
    'database' => [
        'central_connection' => env('DB_CONNECTION', 'central'), // 中央数据库连接

        /**
         * 用作动态创建的租户数据库连接的"模板"的连接。
         * 注意:不要将模板连接命名为 tenant。该名称被包保留。
         */
        'template_tenant_connection' => null,

        /**
         * 租户数据库名称的创建方式:
         * 前缀 + 租户 ID + 后缀。
         */
        'prefix' => 'tenant',
        'suffix' => '',

        /**
         * 租户数据库管理器类,处理租户数据库的创建和删除。
         */
        'managers' => [
            'sqlite' => Stancl\Tenancy\TenantDatabaseManagers\SQLiteDatabaseManager::class, // SQLite 数据库管理器
            'mysql' => Stancl\Tenancy\TenantDatabaseManagers\MySQLDatabaseManager::class, // MySQL 数据库管理器
            'pgsql' => Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLDatabaseManager::class, // PostgreSQL 数据库管理器

        /**
         * 对于 MySQL 使用此数据库管理器,以便为每个租户数据库创建一个数据库用户。
         * 您可以通过更改 $grants 属性来自定义授予这些用户的权限。
         */
            // 'mysql' => Stancl\Tenancy\TenantDatabaseManagers\PermissionControlledMySQLDatabaseManager::class,

        /**
         * 禁用上面的 pgsql 管理器,并启用下面的管理器,
         * 如果您希望通过模式而不是数据库来区分租户数据库。
         */
            // 'pgsql' => Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLSchemaManager::class, // 通过模式而不是数据库分隔
        ],
    ],

    /**
     * 缓存租户配置。由 CacheTenancyBootstrapper 使用。
     */
    'cache' => [
        'prefix' => 'tenant:%tenant%:', // 缓存键的前缀,%tenant% 将被替换为租户键,并在原始存储前缀之前添加。
        'stores' => [
            env('CACHE_STORE'),
        ],

        /*
         * 是否使会话具有租户意识(仅在会话驱动程序基于缓存时使用)。
         *
         * 注意:这将隐式地将您的配置会话存储添加到上面的前缀存储列表中。
         */
        'scope_sessions' => true,

        'tag_base' => 'tenant', // 缓存标签的基础名称,后跟租户 ID。
    ],

    /**
     * Log 日志记录
     *
     * 这里设置需要隔离租户日志的日志通道
     */
    'logging' => [
        'channels' => [
            'daily', 'single', 'query',
        ],

        'suffix_base' => 'tenant-',
    ],

    /**
     * 文件系统租户配置。由 FilesystemTenancyBootstrapper 使用。
     * https://tenancyforlaravel.com/docs/v3/tenancy-bootstrappers/#filesystem-tenancy-boostrapper.
     */
    'filesystem' => [
        /**
         * 在 'disks' 数组中列出的每个磁盘将以 suffix_base 作为后缀,后跟租户 ID。
         */
        'suffix_base' => 'tenant-',
        'disks' => [
            'uploads', // 上传磁盘
            'static', // 静态文件存储磁盘
            'certs', // 证书磁盘
        ],

        /**
         * 对于本地磁盘使用此设置。
         *
         * 请参见 https://tenancyforlaravel.com/docs/v3/tenancy-bootstrappers/#filesystem-tenancy-boostrapper
         */
        'root_override' => [
            // 根目录在 storage_path() 后面加上后缀的磁盘。
            'uploads' => '%storage_path%',
            'static' => '%storage_path%',
            'certs' => '%storage_path%',
        ],

        /**
         * storage_path() 是否应被后缀化。
         *
         * 注意:禁用此设置可能会破坏本地磁盘租户功能。只有在您使用外部文件存储服务(如 S3)时才禁用此设置。
         *
         * 对于绝大多数应用程序,此功能应启用。但在某些边缘情况下,它可能会导致问题(例如在 Vapor 中使用 Passport - 见 #196),因此
         * 如果您遇到这些边缘情况问题,您可能希望禁用此功能。
         */
        'suffix_storage_path' => true,

        /**
         * 默认情况下,asset() 调用也会进行多租户处理。您可以使用 global_asset() 和 mix()
         * 来获取全局的、非租户特定的资产。然而,当您在租户应用程序中使用
         * asset() 调用的包时,可能会遇到一些问题。为避免此类问题,您可以
         * 禁用 asset() 辅助函数的租户处理,并在您希望使用租户特定资产(产品图像、头像等)的位置
         * 明确使用 tenant_asset() 调用。
         */
        'asset_helper_tenancy' => true,
    ],

    /**
     * Redis 租户配置。由 RedisTenancyBootstrapper 使用。
     *
     * 注意:您需要 phpredis 来使用 Redis 租户。
     *
     * 注意:如果您仅将 Redis 用于缓存,则不需要使用此设置。
     * Redis 租户仅在您直接进行 Redis 调用时相关,
     * 无论是使用 Redis 门面还是通过注入作为依赖项。
     */
    'redis' => [
        'prefix_base' => 'tenant:', // Redis 中的每个键都将以此 prefix_base 开头,后跟租户 ID。
        'prefixed_connections' => [ // Redis 连接,其键被加上前缀,以区分一个租户的键与另一个租户的键。
            // 'default',
        ],
    ],

    /**
     * Queue 租户配置
     */
    'queue' => [
        // 租户默认使用 tenant 链接,php artisan make:tenant:job 命令会自动创建
        'tenant_connection' => env('TENANT_QUEUE_CONNECTION', 'tenant'),

        // Queue 队列
        'connections' => [
            // 主域名
            'central' => [
                'driver' => 'database',
                'connection' => env('DB_CONNECTION', 'mysql'),
                'table' => 'jobs',
                'queue' => 'default',
                'retry_after' => 90,
                'central' => true,
            ],

            // 租户
            'tenant' => [
                'driver' => 'database',
                'table' => 'jobs',
                'connection' => env('DB_CONNECTION', 'mysql'),
                'queue' => 'tenant',
                'retry_after' => 90,
            ],
        ],
    ],

    /**
     * 租户用到的事件
     */
    'events' => [
        // 租户上下文切换前
        Events\InitializingTenancy::class => [
            Initializing\TenancyAvailableListener::class, // 租户是否可用,
            Initializing\TenancyPermissionListener::class, // 租户权限控制,
        ],
        // 租户上下人切换后
        Events\TenancyInitialized::class => [
            Listeners\BootstrapTenancy::class, // 启动租户
        ],
        // 租户上下文切换失败
        Events\TenancyEnded::class => [
            Listeners\RevertToCentralContext::class, // 退出租户
        ],
    ],

    /**
     * 是否注册租户路由。
     *
     * 租户路由包括租户资产路由。默认情况下,此路由是
     * 启用的。但如果您使用外部
     * 存储(例如 S3 / Dropbox)或有自定义资产控制器,则可能需要禁用它们。
     */
    'routes' => true,

    /**
     * 租户迁移命令使用的参数。
     */
    'migration_parameters' => [
        '--force' => true, // 在生产中运行迁移时,此设置需要为 true。
        '--path' => [database_path('migrations/tenant')], // 租户迁移路径
        '--realpath' => true,
    ],

    /**
     * 租户填充命令使用的参数。
     */
    'seeder_parameters' => [
        '--class' => 'DatabaseSeeder', // 根填充类
        // '--force' => true,
    ],
];

数据库迁移文件

安装多租户扩展后,系统会自动发布三个重要的数据库迁移文件,这些文件用于创建多租户系统所需的数据表结构:

核心数据表

  • 租户表database/migrations/tenancy/2019_09_15_000010_create_tenants_table.php

    • 存储所有租户的基本信息
    • 包含租户名称、唯一标识符、状态等字段
    • 作为多租户系统的核心数据结构
  • 域名表database/migrations/tenancy/2019_09_15_000020_create_domains_table.php

    • 管理租户绑定的自定义域名
    • 实现域名与租户的关联映射
    • 支持多域名绑定到同一租户
  • 套餐表database/migrations/tenancy/2025_06_21_105037_tenant_plan.php

    • 管理不同级别的租户套餐方案
    • 定义套餐的功能限制、价格等信息
    • 支持租户套餐的升级和降级

这些迁移文件在运行 php artisan catch:tenant:install 命令时会自动执行,创建相应的数据表结构。如果您需要自定义这些表的结构,可以在执行迁移前对这些文件进行修改。

前端视图文件

多租户扩展需要相应的前端视图文件来支持用户界面的展示和交互。安装过程中,系统会自动发布这些视图文件到指定的目录。

视图文件路径配置

视图文件的发布路径由 config/catch.php 配置文件中的 views_path 项决定:

php
  /*
   |--------------------------------------------------------------------------
   | 前端 Vue 视图文件夹路径
   |
   | 如果不设置,将不会生成相关的 Vue 文件
   |--------------------------------------------------------------------------
   */
    'views_path' => base_path('web'.DIRECTORY_SEPARATOR.'src'.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR),

默认发布路径

根据上述配置,多租户相关的前端视图文件将默认发布到项目根目录下的 web/src/views/tenancy 文件夹中。这些文件包含了租户管理、域名配置、套餐管理等功能的前端实现。

自定义视图路径

注意事项

如果您的前端项目不在默认的 web 目录中,或者您使用了不同的目录结构,可以手动将生成的 tenancy 文件夹复制到您实际前端项目的 views 目录下。这样可以确保多租户功能在前端正常展示。

视图文件结构

发布的视图文件包含以下主要组件:

  • 租户管理:用于创建、编辑和管理租户
  • 域名管理:用于配置租户的自定义域名
  • 套餐管理:用于设置和管理不同的租户套餐

前端配置

完成后端安装和配置后,还需要对前端应用进行相应的配置,以使前端能够正确识别和处理多租户模式。

环境变量配置

在前端项目的环境变量文件中添加多租户模式的配置。根据您的部署环境,可以选择在开发环境文件 .env 或生产环境文件 .env.production 中进行配置:

shell
# 启用多租户模式
VITE_TENANCY_MODE=true

配置说明

设置 VITE_TENANCY_MODE=true 后,前端应用将启用以下功能:

  • 域名识别:自动识别当前访问的域名,并将其与相应的租户关联
  • 租户特定界面:根据当前租户加载相应的界面和配置
  • 权限控制:根据租户的套餐和权限设置显示或隐藏特定功能
  • 资源隔离:确保前端请求正确访问当前租户的资源

前端路由配置

启用多租户模式后,前端路由系统会自动加载租户相关的路由配置,这些配置在之前发布的视图文件中已经包含。

验证配置

完成上述配置后,重新启动前端应用,并访问租户管理页面(通常位于系统设置或管理员菜单中),确认多租户功能是否正常加载。