catchadmin/core
CatchAdmin Core is the foundation package for the CatchAdmin Laravel admin framework, supplying shared utilities, base classes, and infrastructure for building backend management systems. It supports rapid CRUD scaffolding and permission handling, though community adoption remains limited.
catchadmin/core is the backend backbone of CatchAdmin — a modular Laravel admin framework. The package itself is small; the value is in the base classes (Catch\Base\CatchController, Catch\Base\CatchModel) and support layer (Catch\Support\Excel, async contracts) that every module in the repo builds on. Plan to learn the framework through the repo's modules, not through this package alone.
Bootstrap order:
web: git clone -b v5 https://gitee.com/catchadmin/catch-admin-vue.git web. The branch tag matters — it must match the backend major version..env for DB_DATABASE, DB_USERNAME, DB_PASSWORD. Do not test the DB early; let Laravel migrations surface connection errors during install.php artisan catch:module:install --all --no-interaction.modules/System/ is the canonical reference for controllers, models, routes, and Excel classes.First use case: build a CRUD resource end-to-end. Scaffold the module skeleton (Installer.php, Providers/{ModuleName}ServiceProvider.php, routes/route.php, storage/app/modules.json entry), then generate CRUD from a CREATE TABLE statement, then wire the list page. The whole point of the package is that this path is turnkey — you should not be hand-writing list/search/pagination plumbing.
Module layout. Everything lives under modules/{ModuleName}/. Controllers, models, routes/route.php, Providers/, and Excel/{Import,Export}/ are the standard subfolders. Registration is via storage/app/modules.json — that file is the module registry the framework reads.
Thin controllers. Extend Catch\Base\CatchController. Route requests, delegate to model or service, return data. Use protected readonly constructor injection for dependencies.
Fat models. Extend Catch\Base\CatchModel. Declare:
$table, $fillable, $fields, $form — the field/form contract the base CRUD flow reads.$searchable — quick search fields.creator_id in fillable when the model tracks creator.$dataRange when data-permission filtering applies.setBeforeGetList() for query tweaks scoped to the list query — this is the hook to use instead of overriding list methods.Routes. Follow the target module's existing style. Prefer Route::adminResource for new admin CRUD; fall back to Route::apiResource when explicit only/except/names are needed. Keep prefixes lowercase. When editing a generator-managed route file, add new routes before the //next marker — the generator appends there.
Codegen workflow. SQL CREATE TABLE in → generated list page, dialog form, page form, and route file out. Output paths are fixed: web/src/views/{module}/{resource}/index.vue, .../{resource}/form/create.vue, modules/{Module}/routes/route.php. Trust the generated shape; adjust after, not instead.
Import/export. Import classes go in modules/{Module}/Excel/Import/, extend Catch\Support\Excel\Import, implement collection(Collection $rows): void and rules(): array. Export classes go in modules/{Module}/Excel/Export/; keep the controller export() action thin and wire catch-table with the exports prop to the export URL. Both have an async path (AsyncTaskInterface + AsyncTaskDispatch); use it for anything that can run long.
Frontend contract. catch-table for list pages, dialog slot for create/edit, <Create :primary="row?.id" :api="api" />. Forms use useCreate(props.api, props.primary), useShow(...) when editing, inject('closeDialog') to close. primary (not id) is the prop name. Admin components are auto-imported. Shared utilities live in web/src/support/ — http for custom/blob requests, helper, cache, message, options.
Uploads. Pick the component from web/src/components/admin/upload/ by storage target: UploadImage/UploadFile/UploadFiles/UploadAttach/index.vue for local, OssUpload/CosUpload/QiniuUpload for cloud, ChunkUpload for large files, AttachUpload for system attachments. Prefer useUpload.ts and useChunkUpload.ts over re-implementing.
1 = Enabled, 2 = Disabled. Deviating from this will confuse every generated form and filter.datetime. Soft-delete columns follow the same rule. Laravel's default timestamps() and date casting will not behave as expected — check migrations against this before debugging weird list ordering or date filters.declare(strict_types=1); is required in every PHP file. Not stylistic; strict typing assumptions leak into the base classes.//next route marker is load-bearing. The route generator appends at that marker. Delete it or move business routes after it and regeneration silently duplicates or misplaces routes.primary is the form prop name, not id. :primary="row?.id" is correct; :id will leave edit forms in create mode with no error.closeDialog and register it via onMounted(() => close(() => closeDialog())). Skip it and the dialog stays open after submit — a silent UX bug.$row[0], $row[1] in collection(), and rules keyed '0', '1'. Also set $start to match the first real data row; off-by-one here is the most common import bug. Keep $importMaxNum in place as a hard guard.setBeforeGetList() first; overriding list will break pagination/search formatters in non-obvious ways.$dataRange filtering is silent. If a user sees an empty list unexpectedly, check permissions and $dataRange before touching queries.storage/app/modules.json is the registry. A module that "isn't loading" is almost always missing from this file, or the file is stale after a manual copy. Clear caches after touching it.catch:module:install --all blindly.-b v5 on the frontend clone is not optional; API shape and composables drift across versions.Catch\Base\CatchController and Catch\Base\CatchModel for base behavior, Catch\Support\Excel\Import/Export for tabular flows, AsyncTaskInterface + AsyncTaskDispatch for background work. When stuck, read the closest existing module — the framework's real documentation is its own modules/System/ code.How can I help you explore Laravel packages today?