# think-library **Repository Path**: topextend/think-library ## Basic Information - **Project Name**: think-library - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-08 - **Last Updated**: 2026-07-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # think-library A **layered scaffolding + infrastructure** library for ThinkPHP 8 admin/API projects. This package provides reusable conventions and utilities (controller base classes, Application/Repository abstractions, JWT, middleware, storage, operation logs, etc.). It does **not** ship business tables, tenants, plugins, menu seeds, or other platform/SaaS logic. For a full admin stack, see the consuming app [cloud/apps/admin-api](https://gitee.com/topextend/cloud) (`app/platform` for generic admin, `app/cloud` for SaaS extensions). ## Requirements - PHP >= 8.1 - ThinkPHP ^8.0 - think-orm ^3.0|^4.0 ## Installation ```bash composer require topextend/think-library ``` With ThinkPHP service discovery enabled (default), `think\library\bootstrap\Library` is registered automatically. For monorepo development, point Composer path repository to `packages/think-library`. ## Directory layout ``` src/ ├── bootstrap/ # Library service, Runtime ├── common.php # syspath(), sysvar() helpers ├── foundation/ │ ├── ApiController.php # JSON API controller base │ ├── BaseService.php # Singleton service base │ └── BaseApplication.php # Use-case layer base ├── domain/ │ ├── contract/ # RepositoryInterface, OplogWriterInterface │ ├── oplog/ # OplogEntry │ ├── result/ # PageResult │ ├── storage/ # Storage facade │ ├── PluginRegistry.php # Multi-app / plugin registry │ └── AppNamespace.php ├── application/ │ ├── RbacMatcher.php # RBAC path/menu matching (pure logic) │ └── CronMatcher.php # Cron expression matcher └── infrastructure/ ├── persistence/ # AbstractRepository ├── storage/ # LocalPublicStorage drivers ├── middleware/ # See «Middleware» ├── oplog/ # OplogWriter, ApiOplogRecorder ├── Jwt.php ├── Validate.php ├── Tools.php └── DatabaseSupport.php ``` ## Layering Recommended call chain: ``` Controller → Application (*Manage) → Repository → Db ``` | Layer | Base class | Responsibility | |-------|------------|----------------| | Controller | `ApiController` | HTTP I/O, `success`/`error`, validation | | Application | `BaseApplication` | Use cases, orchestrates repositories | | Repository | `AbstractRepository` | Table access, pagination, CRUD | ### Controller example ```php namespace app\demo\controller; use think\library\foundation\ApiController; use app\demo\application\ArticleManage; class Article extends ApiController { public function list() { $page = max(1, (int) $this->request->get('page', 1)); $pageSize = max(1, min(100, (int) $this->request->get('pageSize', 20))); $this->success('ok', ArticleManage::instance()->list($page, $pageSize)); } public function save() { $data = $this->_vali(['title.require' => 'Title is required']); ArticleManage::instance()->save($data); $this->writeOplog('Articles', 'Save', $data['title'] ?? ''); $this->success('Saved'); } } ``` ### Application example ```php namespace app\demo\application; use think\library\foundation\BaseApplication; use app\demo\persistence\ArticleRepository; class ArticleManage extends BaseApplication { public function list(int $page, int $limit): array { return ArticleRepository::instance()->paginate($page, $limit)->toArray(); } } ``` ### Repository example ```php namespace app\demo\persistence; use think\library\infrastructure\persistence\AbstractRepository; class ArticleRepository extends AbstractRepository { protected function table(): string { return 'article'; } protected function query() { return \think\facade\Db::name($this->table())->where('is_deleted', 0); } } ``` `AbstractRepository` provides `instance()` so subclasses can use `ArticleRepository::instance()`. ## Auto-registered service `Library::register()`: 1. Loads app `sys.php`, `common.php`, `provider.php`, `event.php`, `middleware.php` 2. Registers global CORS middleware 3. Registers `LangPackAccess`, `LoadLangPack`, `JwtAccess`, `RbacAccess`, `ApiOplogAccess` (boot addons before lang/JWT so `public_api_prefixes` and lang packs apply) `Library::boot()` registers `MultAccess` on `HttpRun` for multi-app routing. ## Middleware | Middleware | Description | |------------|-------------| | `MultAccess` | Multi-app URL parsing and `app/{name}/` bootstrap | | `JwtAccess` | JWT auth (supports named scopes, e.g. `:platform`) | | `RbacAccess` | RBAC check (run after JWT) | | `LangPackAccess` | Language pack loading (config-driven) | | `ApiOplogAccess` | Auto API operation logs (named scopes) | | `AppRequestUtil` | App path detection and normalization | Business rules (tenant resolution, etc.) are injected via `config/library.php` in the host application. ### config/library.php example ```php [ 'ignore' => ['auth/login', 'login/index'], 'scope_matcher' => fn (Request $r) => str_starts_with($r->pathinfo(), 'api'), 'secret' => fn () => (string) config('jwt.secret'), 'user_resolver' => function (array $payload, Request $r) { // return user array or null }, 'scopes' => [ 'admin' => [ 'scope_matcher' => fn (Request $r) => app()->http->getName() === 'platform', 'secret' => fn () => 'your-platform-secret', 'user_alias' => 'adminUser', ], ], ], 'rbac' => [ 'guard' => \app\cloud\application\RbacGuard::class, 'scope_id' => fn () => tenant()->id(), ], 'lang_pack' => [ 'register' => fn (Request $r) => /* load lang packs */, ], 'oplog' => [ 'default_scope' => 'tenant', 'writers' => [ 'platform' => \app\\admin\infrastructure\AdminOplogWriter::class, 'tenant' => \app\cloud\infrastructure\TenantOplogWriter::class, ], ], ]; ``` Register scoped middleware in the app: ```php // app/admin/middleware.php return [ \think\library\infrastructure\middleware\JwtAccess::class . ':platform', \think\library\infrastructure\middleware\RbacAccess::class . ':platform', \think\library\infrastructure\middleware\ApiOplogAccess::class . ':platform', ]; ``` ## Operation log (OplogWriter) ```php use think\library\infrastructure\oplog\OplogWriter; OplogWriter::write('Users', 'Save', 'Created admin', 'admin', 'platform'); // In controllers (built into ApiController) $this->writeOplog('Users', 'Save', 'Created admin', null, 'platform'); ``` Implement `OplogWriterInterface` and register it under `oplog.writers` in config. ## Multi-app & plugins Extend `think\library\domain\PluginRegistry`: ```php namespace app\mall; class Service extends \think\library\domain\PluginRegistry { protected string $appName = 'Mall'; protected string $package = 'topextend/plugin-mall'; } ``` Register the service in `app/service.php`; `MultAccess` routes requests to `app/mall/`. ## Utilities | Component | Purpose | |-----------|---------| | `Jwt` | Sign and verify JWT tokens | | `Validate` | Request validation for `_vali()` | | `Storage` | File storage facade | | `PageResult` | Pagination DTO | | `RbacMatcher` | Path/menu node matching for guards | | `CronMatcher` | Cron due-time check | | `DatabaseSupport` | DB install/migration helpers | | `syspath()` / `sysvar()` | Project path and per-request variables | ## Relationship with admin-api | Package | Role | |---------|------| | **think-library** | Scaffolding, JWT/middleware, storage, oplog, multi-app routing | | **admin-api** | Generic admin + Cloud SaaS built on this library | SQL scripts live in the monorepo under `cloud/database/mysql/` and `cloud/database/pgsql/` (root copies for backward compatibility). ## License MIT