# dcat-saas **Repository Path**: techutter/dcat-saas ## Basic Information - **Project Name**: dcat-saas - **Description**: 这是一个 DcatAdmin 的扩展包,同时也是兼容的 composer 扩展。旨在为 DcatAdmin 构建的后台应用赋能多租户管理。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2024-12-21 - **Last Updated**: 2024-12-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## Dcat SaaS 这是一个 `DcatAdmin` 的扩展包,同时也是兼容的 `composer` 扩展。旨在为 `DcatAdmin` 构建的后台应用赋能多租户管理。`Dcat SaaS` 内建了一个多租户管理界面,可以一键开放租户空间和删除租户空间。 多租户逻辑实现通过 `Stancl/Tenancy` 实现。通过不同租户空间使用不同数据库来实现数据隔离,通过中间件 & Session 隔离的方式对访问请求进行隔离。 假设通过 `Dcat SaaS` 构建了一个 OA 系统,那么安装后的多租户架构案例如下: |空间名称|域名|路由|页面返回| |---|---|---|---| |SaaS管理控制台|admin.test|`/api/tenants`|管理控制台的租户列表接口| |租户 A 的 OA 应用|a.admin.test|`/api/users`|租户 A 的用户接口| |租户 B 的 OA 应用|b.admin.test|`/api/users`|租户 B 的用户接口| 访问 `admin.test/api/users` 将返回 404,因为管理控制台未定义 `/api/users` 的路由。 访问 `a.admin.test/api/users` 得到的是租户 A 的 OA 应用中的用户信息,因为其中与租户 B 是数据隔离的,所以返回的数据中是不包含租户 B 的 OA 应用中的用户信息。 访问 `a.admin.test/api/tenants` 将返回 404,因为租户应用未定义 `api/tenants` 的路由,即便管理控制台有这个路由,但是它被定义为是管理控制台的,所以租户是不能访问到管理控制台的对应路由。 ## 环境要求 PHP 8.0+ Laravel 8.0+ Dcat Admin 2.0+ ## 安装 虽然这是一个 `DcatAdmin` 的扩展包,但由于其和框架集成度较高,因此安装过程需要做一些手动的修正,所以建议直接通过 `composer require celaraze/dcat-saas` 来安装。 安装完成后在 `DcatAdmin` 的后台扩展中将会看到这个扩展包,但是其 `启用` 和 `禁用` 是无效的,建议通过 `composer` 进行管理。后续会对扩展友好做更多的适配。 在这之前,你确认已经安装好了 `DcatAdmin`。 1:`composer require celaraze/dcat-saas`。 2:`php artisan saas:install`。 3:更新 `config/app.php` 文件: ```PHP # 其它代码 'providers' => [ # 其它服务提供者 SaaS\SaaSServiceProvider::class ] # 其它代码 ``` 4:更新 `.env` 文件: ```dotenv # 定义你的 SaaS 管理控制台域名,后续创建的租户将在此域名的前提下使用二级域名 SAAS_CENTRAL_DOMAIN=saas.test ``` 5:访问 `http://your_site.com/admin/domains` 来访问 SaaS 控制台。 6:创建租户后,可以访问类似的二级域名 `a.admin.test/api` 来查看租户自己的独立路由。 ## 开发 ### 路由 在 `routes/tenant.php` 中,定义 web 和 api 两个路由分组即是为租户创建他们独立的路由。 ```PHP /** * Laravel中routes/web.php内的路由,迁移到这,如果迁移过来,那么在此的web路由将只能被实例访问 * 原先的routes/web.php中的路由将只能通过SaaS控制台的中心域访问 */ Route::middleware([ 'web', InitializeTenancyByDomain::class, PreventAccessFromCentralDomains::class, ])->group(function () { Route::get('/', function () { return '这里是每个实例的WEB中间件,当前实例是' . tenant('id'); }); }); /** * Laravel中routes/api.php内的路由,迁移到这,如果迁移过来,那么在此的api路由将只能被实例访问 * 原先的routes/api.php中的路由将只能通过SaaS控制台的中心域访问 */ Route::middleware([ 'api', InitializeTenancyByDomain::class, PreventAccessFromCentralDomains::class, ])->prefix('api')->group(function () { Route::get('/', function () { return '这里是每个实例的API中间件,当前实例是:' . tenant('id'); }); }); ``` ### 计划任务 由于租户和管理控制台隔离的存在,不能通过 Laravel 自带的计划任务去执行,不过我们提供了一个入口: `cd /www/wwwroot/saas && php artisan saas:schedule >> /dev/null 2>&1` 除此之外,计划任务的其它执行逻辑没有改变,其它的交给 Laravel 吧!