savannabits / charaza-ui
Savannabit的Admin CRUD生成器的Laravel 7 Scaffold
Requires
- php: ^7.4
- ext-json: *
- fideloper/proxy: ^4.4.1
- fruitcake/laravel-cors: ^v2.0.3
- guzzlehttp/guzzle: ^7.2.0
- laravel/framework: ^v8.11.2
- laravel/helpers: ^v1.3.0
- laravel/jetstream: ^1.5
- laravel/sanctum: ^2.6
- laravel/tinker: ^v2.4.2
- laravel/ui: ^v3.0.0
- livewire/livewire: ^2.0
- rennokki/laravel-eloquent-query-cache: ^2.4.2
- savannabits/savadmin: ^v1.5.0
- spatie/laravel-medialibrary: ^8.10.1
- spatie/laravel-permission: ^3.17.0
- yajra/laravel-datatables-oracle: ^v9.11.1
Requires (Dev)
- barryvdh/laravel-ide-helper: ^v2.8.1
- facade/ignition: ^2.5.0
- fzaninotto/faker: ^v1.9.1
- mockery/mockery: ^1.4.2
- nunomaduro/collision: ^v5.0.2
- phpunit/phpunit: ^9.3.8
This package is auto-updated.
Last update: 2024-09-19 23:26:51 UTC
README
正在寻找一个Jetstream Tailwindcss,Inertia和Vue3 CRUD生成器?查看我们的姐妹项目,Jetstream Inertia Generator (Jig)
Charaza UI是一个集成了savannabits/savadmin Admin生成器的Laravel Starter,可以帮助您快速启动并快速开发您的下一个laravel项目。Charaza UI配备了最新的laravel工具,不需要您完成太多样板工作。认证模块已经为您搭建。模板已经为您设置。路由也已经为您设置。您只需要开始编写您模块的代码即可。更好的是:您不需要费太多力气就能生成包括模型、API控制器、Datatable控制器、API和后端路由、编辑和显示视图、删除代码在内的完全可操作的模块。savadmin生成器只需一个命令就可以为您完成所有这些
php artisan sv:generate table_name
特性
- 使用savannabits/savadmin进行代码生成
- Laravel 8 Scaffold
- Laravel Jetstream 前端
- Livewire 2 Scaffold
- Laravel Fortify 用户管理
- Alpine.js配合Livewire,只需Laravel blade即可为您提供真正的SPA体验!
- 使用Laravel和Vue.js(使用BootstrapVue)进行后端和API生成
- 个人资料和更新信息
- 使用Jetstream和Laravel Sanctum的API密钥
- 可选数据库缓存
- 使用Laravel TNTSearch进行模糊搜索
安装
Charaza UI旨在简化您开始新项目时的工作。要启动一个全功能的新项目,只需从charaza创建它,如下所示
composer create-project savannabits/charaza-ui my-project
使用方法
该软件包附带可选的Docker配置。强烈建议使用此配置以最小配置体验全部功能。设置好.env变量后,运行以下命令以构建并启动Docker容器
docker-compose build app docker-compose up -d
这将启动应用程序服务器,该服务器在您在env中配置的端口下公开。要进入容器的shell,有一个简单的shell脚本可以启用此功能
bash app-exec [yoru command] bash app-exec bash
然而,如果您不想使用Docker,不要担心!您只需根据需要配置数据库变量,然后继续下一步
接下来,按照正常的laravel设置步骤进行
composer install
yarn install
php artisan key:generate
php artisan migrate
php artisan optimize:clear
yarn back-dev (or back-prod)
yarn css-prod (or css-prod)
yarn dev (or prod or watch)
好了!您的系统现在已经设置好,您准备好创建下一个令人惊叹的应用了!
代码生成器
使用代码生成器生成您的命令很容易
- 创建您的迁移文件并相应地编辑它
- 运行迁移
- 使用生成器生成模型、控制器、路由、菜单、视图和js资源。
- 根据需要修改它们(自定义)
- 如果您没有运行
yarn back-watch
,则运行yarn back-dev
重新构建资源
示例
让我们从articles
表生成一个Articles
模块
- 创建
articles
表
bash app-exec bash #(If you are using docker)
php artisan make:migration create_articles_table
- 根据需要编辑
articles
迁移
/** * Run the migrations. * * @return void */ public function up() { Schema::create('articles', function (Blueprint $table) { $table->id(); $table->string('title'); $table->string('description'); $table->text('body'); $table->foreignId('author_id')->constrained('users')->restrictOnDelete(); $table->timestamps(); }); }
- 运行迁移
bash app-exec 'php artisan migrate' #(For docker users) php artisan migrate #(Non-docker users)
- 使用生成器生成模型、控制器、路由、菜单、视图和资源
bash app-exec bash #Enter the container's bash - for Docker users php artisan sv:generate articles # The code generator
注意如果您已生成文件但想强制覆盖,请使用 ```--force```
php artisan sv:generate articles --force
生成的文件
app/Models/Article.php
<?php namespace App\Models; /* Imports */ use DateTimeInterface; use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Searchable; use Rennokki\QueryCache\Traits\QueryCacheable; class Article extends Model { use Searchable; use QueryCacheable; public $cacheFor=60*60*24; //cache for 1 day protected static $flushCacheOnUpdate=true; //invalidate the cache when the database is changed protected $fillable = [ 'title', 'description', 'body', 'author_id', ]; protected $searchable = [ 'id', 'title', 'description', 'body', 'author_id', ]; protected $dates = [ 'created_at', 'updated_at', ]; protected $appends = ["api_route"]; public function toSearchableArray() { return collect($this->only($this->searchable))->merge([ // Add more keys here ])->toArray(); } /* ************************ ACCESSOR ************************* */ public function getApiRouteAttribute() { return route("api.articles.index"); } protected function serializeDate(DateTimeInterface $date) { return $date->format('Y-m-d H:i:s'); } /* ************************ RELATIONS ************************ */ /** * Many to One Relationship to \App\Models\User::class * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function author() { return $this->belongsTo(\App\Models\User::class,"author_id","id"); } }
app/Http/Controllers/Api/ArticleController.php
<?php namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use App\Http\Requests\Api\Article\IndexArticle; use App\Http\Requests\Api\Article\StoreArticle; use App\Http\Requests\Api\Article\UpdateArticle; use App\Models\Article; use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\Request; use Illuminate\Support\Str; use Savannabits\Savadmin\Helpers\ApiResponse; use Savannabits\Savadmin\Helpers\SavbitsHelper; use Yajra\DataTables\Facades\DataTables; class ArticleController extends Controller { private $api, $helper; public function __construct(ApiResponse $apiResponse, SavbitsHelper $helper) { $this->api = $apiResponse; $this->helper = $helper; } /** * Display a listing of the resource (paginated). * * @return \Illuminate\Http\JsonResponse */ public function index(IndexArticle $request) { $data = $this->helper::listing(Article::class, $request)->customQuery(function ($builder) use($request) { /**@var Article|Builder $builder*/ // Add custom queries here })->process(); return $this->api->success()->message("List of Articles")->payload($data)->send(); } public function dt(Request $request) { return DataTables::of(Article::query()) ->addColumn("actions",function($model) { $actions = ''; if (\Auth::user()->can('articles.show')) $actions .= '<button class="btn btn-outline-primary btn-square action-button mr-2" title="View Details" data-action="show-article" data-tag="button" data-id="'.$model->id.'"><i class="mdi mdi-eye"></i></button>'; if (\Auth::user()->can('articles.edit')) $actions .= '<button class="btn btn-outline-warning btn-square action-button mr-2" title="Edit Item" data-action="edit-article" data-tag="button" data-id="'.$model->id.'"><i class="mdi mdi-pencil"></i></button>'; if (\Auth::user()->can('articles.delete')) $actions .= '<button class="btn btn-outline-danger btn-square action-button mr-2" title="Delete Item" data-action="delete-article" data-tag="button" data-id="'.$model->id.'"><i class="mdi mdi-delete"></i></button>'; return $actions; }) ->rawColumns(['actions']) ->make(); } /** * Store a newly created resource in storage. * * @param StoreArticle $request * @return \Illuminate\Http\JsonResponse */ public function store(StoreArticle $request) { try { $array = $request->sanitizedArray(); $article = new Article($array); // Save Relationships $object = $request->sanitizedObject(); if (isset($object->author)) { $article->author() ->associate($object->author->id); } $article->saveOrFail(); return $this->api->success()->message('Article Created')->payload($article)->send(); } catch (\Throwable $exception) { \Log::error($exception); return $this->api->failed()->message($exception->getMessage())->payload([])->code(500)->send(); } } /** * Display the specified resource. * * @param Request $request * @param Article $article * @return \Illuminate\Http\JsonResponse */ public function show(Request $request, Article $article) { try { //Fetch relationships $article->load([ 'author', ]); return $this->api->success()->message("Article $article->id")->payload($article)->send(); } catch (\Throwable $exception) { return $this->api->failed()->message($exception->getMessage())->send(); } } /** * Update the specified resource in storage. * * @param UpdateArticle $request * @param {$modelBaseName} $article * @return \Illuminate\Http\JsonResponse */ public function update(UpdateArticle $request, Article $article) { try { $data = $request->sanitizedArray(); $article->update($data); // Save Relationships $object = $request->sanitizedObject(); if (isset($object->author)) { $article->author() ->associate($object->author->id); } $article->saveOrFail(); return $this->api->success()->message("Article has been updated")->payload($article)->code(200)->send(); } catch (\Throwable $exception) { \Log::error($exception); return $this->api->failed()->code(400)->message($exception->getMessage())->send(); } } /** * Remove the specified resource from storage. * * @param Article $article * @return \Illuminate\Http\JsonResponse * @throws \Exception */ public function destroy(Article $article) { $article->delete(); return $this->api->success()->message("Article has been deleted")->payload($article)->code(200)->send(); } }
附加路由: api.php
/* Auto-generated articles api routes */ Route::group(['prefix' => $apiPrefix,'as' => 'api.', 'namespace' => $apiNamespace], function() { Route::group(['middleware' => ["auth:sanctum","verified"]], function() { Route::group(['prefix' => "articles", 'as' => 'articles.'],function() { Route::get("dt", "ArticleController@dt")->name('dt'); }); Route::apiResource('articles',"ArticleController")->parameters(["articles" => "article"]); }); });
web.php
/* Auto-generated admin routes */ Route::group(["prefix" => config('savadmin.app.prefix',''), "namespace" => "Admin", "as" => config('savadmin.app.prefix').".",'middleware' => ['auth','verified']],function() { Route::group(['as' => "articles.", 'prefix' => "articles"], function() { Route::get('','ArticleController@index')->name('index'); }); });
您可以通过以下方式检查其余的文件
- app/Http/Controllers/Admin/ArticleController.php
- resources/js/backend/articles.js
- resources/views/backend/articles/*
贡献
感谢您考虑为CharazaUI做出贡献!请通过savannabits@gmail.com联系Savannabits获取更多信息。
行为准则
为了确保Charaza社区对所有成员都友好,请阅读并遵守行为准则。
安全漏洞
如果您在Charaza中发现安全漏洞,请通过maosa.sam@gmail.com给Sam Maosa发送电子邮件。所有安全漏洞都将得到及时处理。
许可证
Charaza UI Starter是开源软件,许可协议为MIT许可证。