diff --git a/.gitignore b/.gitignore index b1484a6..0d06702 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ /storage/*.key /vendor /fixer +/catch .env .env.backup .env.production diff --git a/README.md b/README.md index a04afdc..4b8fc3b 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ php artisan serve ### PHP 使用 fixer 进行代码检查, 具体请查看根目录下 `.php-cs-fixer.dist.php` 文件的规范,还需要进行以下两步骤 ```shell -mkdir path && cd path // any path name you set +mkdir path ``` ```shell composer require --working-dir=path friendsofphp/php-cs-fixer diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 881e291..383992f 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -2,6 +2,8 @@ namespace App\Exceptions; +use Catch\Enums\Code; +use Catch\Exceptions\CatchException; use Catch\Exceptions\FailedException; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Illuminate\Http\JsonResponse; @@ -70,7 +72,7 @@ class Handler extends ExceptionHandler } } - $e = new FailedException($message ?: 'Server Error'); + $e = new FailedException($message ?: 'Server Error', $e instanceof CatchException ? $e->getCode() : Code::FAILED); $response = parent::render($request, $e); diff --git a/catch/src/Base/CatchController.php b/catch/src/Base/CatchController.php index 101c176..54b73e7 100644 --- a/catch/src/Base/CatchController.php +++ b/catch/src/Base/CatchController.php @@ -14,6 +14,8 @@ declare(strict_types=1); namespace Catch\Base; +use Catch\Enums\Code; +use Catch\Exceptions\FailedException; use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Routing\Controller; use Illuminate\Support\Facades\Auth; @@ -29,6 +31,12 @@ abstract class CatchController extends Controller */ protected function getLoginUser($guard = null): Authenticatable { - return Auth::guard($guard ?: getGuardName())->user(); + $user = Auth::guard($guard ?: getGuardName())->user(); + + if (! $user) { + throw new FailedException('登录失效, 请重新登录', Code::LOST_LOGIN); + } + + return $user; } } diff --git a/catch/src/CatchAdmin.php b/catch/src/CatchAdmin.php index 8d95ff3..90261a1 100644 --- a/catch/src/CatchAdmin.php +++ b/catch/src/CatchAdmin.php @@ -14,6 +14,7 @@ declare(strict_types=1); namespace Catch; +use Catch\Support\Module\Installer; use Illuminate\Support\Facades\File; use Illuminate\Support\Str; @@ -360,4 +361,20 @@ class CatchAdmin { return Str::replaceFirst(base_path(), '.', $path); } + + /** + * + * @param string $module + * @return Installer + */ + public static function getModuleInstaller(string $module): Installer + { + $installer = self::getModuleServiceProviderNamespace($module).'Installer'; + + if (class_exists($installer)) { + return app($installer); + } + + throw new \RuntimeException("Installer [$installer] Not Found"); + } } diff --git a/catch/src/Commands/CatchCommand.php b/catch/src/Commands/CatchCommand.php index 289ee96..544462c 100644 --- a/catch/src/Commands/CatchCommand.php +++ b/catch/src/Commands/CatchCommand.php @@ -51,7 +51,7 @@ abstract class CatchCommand extends Command protected function initialize(InputInterface $input, OutputInterface $output): void { if ($input->hasArgument('module') - && ! Module::all()->pluck('name')->merge(Collection::make(config('catch.module.default')))->contains(lcfirst($input->getArgument('module'))) + && ! Module::getEnabled()->pluck('name')->merge(Collection::make(config('catch.module.default')))->contains(lcfirst($input->getArgument('module'))) ) { $this->error(sprintf('Module [%s] Not Found', $input->getArgument('module'))); exit; diff --git a/catch/src/Middleware/AuthMiddleware.php b/catch/src/Middleware/AuthMiddleware.php index b7b2dd8..f35b0c9 100644 --- a/catch/src/Middleware/AuthMiddleware.php +++ b/catch/src/Middleware/AuthMiddleware.php @@ -6,6 +6,7 @@ use Catch\Enums\Code; use Catch\Events\User as UserEvent; use Catch\Exceptions\FailedException; use Exception; +use Illuminate\Auth\AuthenticationException; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Event; @@ -20,11 +21,13 @@ class AuthMiddleware try { $guardName = getGuardName(); - if (Auth::guard($guardName)->check()) { - $user = Auth::guard($guardName)->user(); - - Event::dispatch(new UserEvent($user)); + if (! $user = Auth::guard($guardName)->user()) { + throw new AuthenticationException(); } + + Event::dispatch(new UserEvent($user)); + + return $next($request); } catch (Exception|Throwable $e) { if ($e instanceof TokenExpiredException) { throw new FailedException(Code::LOGIN_EXPIRED->message(), Code::LOGIN_EXPIRED); @@ -35,8 +38,6 @@ class AuthMiddleware } throw new FailedException(Code::LOST_LOGIN->message().":{$e->getMessage()}", Code::LOST_LOGIN); - } finally { - return $next($request); } } } diff --git a/catch/src/Providers/CatchAdminServiceProvider.php b/catch/src/Providers/CatchAdminServiceProvider.php index 1e77c47..ef29c6e 100644 --- a/catch/src/Providers/CatchAdminServiceProvider.php +++ b/catch/src/Providers/CatchAdminServiceProvider.php @@ -185,8 +185,8 @@ class CatchAdminServiceProvider extends ServiceProvider protected function bootModuleProviders() { foreach ($this->app->make(ModuleRepositoryInterface::class)->getEnabled() as $module) { - if (class_exists($module['service'])) { - $this->app->register($module['service']); + if (class_exists($module['provider'])) { + $this->app->register($module['provider']); } } } diff --git a/catch/src/Support/Module/Driver/DatabaseDriver.php b/catch/src/Support/Module/Driver/DatabaseDriver.php index dc78951..0294860 100644 --- a/catch/src/Support/Module/Driver/DatabaseDriver.php +++ b/catch/src/Support/Module/Driver/DatabaseDriver.php @@ -64,7 +64,7 @@ class DatabaseDriver implements ModuleRepositoryInterface 'path' => $module['path'], 'description' => $module['desc'], 'keywords' => $module['keywords'], - 'service' => sprintf('\\%s%s', CatchAdmin::getModuleNamespace($module['name']), ucfirst($module['name']).'ServiceProvider'), + 'provider' => sprintf('\\%s%s', CatchAdmin::getModuleNamespace($module['name']), ucfirst($module['name']).'ServiceProvider'), ]); } @@ -92,7 +92,7 @@ class DatabaseDriver implements ModuleRepositoryInterface ->update([ 'name' => $module['name'], - 'alias' => $module['alias'], + 'path' => $module['path'], 'description' => $module['desc'], 'keywords' => $module['keywords'], ]); @@ -146,7 +146,7 @@ class DatabaseDriver implements ModuleRepositoryInterface throw new FailedException(sprintf('Module [%s] has been created', $module['name'])); } - if ($this->model->where('alias', $module['alias'])->first()) { + if ($this->model->where('path', $module['path'])->first()) { throw new FailedException(sprintf('Module Alias [%s] has been exised', $module['alias'])); } } diff --git a/catch/src/Support/Module/Driver/FileDriver.php b/catch/src/Support/Module/Driver/FileDriver.php index 0ae6dd9..5aaeccf 100644 --- a/catch/src/Support/Module/Driver/FileDriver.php +++ b/catch/src/Support/Module/Driver/FileDriver.php @@ -78,7 +78,7 @@ class FileDriver implements ModuleRepositoryInterface $this->hasSameModule($module, $modules); - $module['service'] = sprintf('\\%s', CatchAdmin::getModuleServiceProvider($module['path'])); + $module['provider'] = sprintf('\\%s', CatchAdmin::getModuleServiceProvider($module['path'])); $module['version'] = '1.0.0'; $module['enable'] = true; diff --git a/catch/src/Support/Module/Installer.php b/catch/src/Support/Module/Installer.php index 8b38cbf..c9ecab5 100644 --- a/catch/src/Support/Module/Installer.php +++ b/catch/src/Support/Module/Installer.php @@ -73,7 +73,7 @@ abstract class Installer * * @return void */ - public function __invoke(): void + public function install(): void { // TODO: Implement __invoke() method. $this->moduleRepository->create($this->info()); diff --git a/catch/src/Traits/DB/BaseOperate.php b/catch/src/Traits/DB/BaseOperate.php index 7c29c80..e43bb96 100644 --- a/catch/src/Traits/DB/BaseOperate.php +++ b/catch/src/Traits/DB/BaseOperate.php @@ -23,6 +23,10 @@ use Illuminate\Support\Facades\Request; */ trait BaseOperate { + protected string $sortField = 'sort'; + + protected bool $sortDesc = true; + /** * * @@ -46,10 +50,18 @@ trait BaseOperate { $queryBuilder = self::query()->select($this->fieldsInList)->quickSearch(); + if (in_array($this->sortField, $this->getFillable())) { + $queryBuilder = $queryBuilder->orderBy($this->sortField, $this->sortDesc ? 'desc' : 'asc'); + } + + $queryBuilder = $queryBuilder->orderByDesc('id'); + if ($this->isPaginate) { return $queryBuilder->paginate(Request::get('limit', $this->perPage)); } + + return $queryBuilder->get(); } diff --git a/modules/Develop/Support/Generate/Create/FrontTable.php b/modules/Develop/Support/Generate/Create/FrontTable.php index aebf7d6..8c32e0d 100644 --- a/modules/Develop/Support/Generate/Create/FrontTable.php +++ b/modules/Develop/Support/Generate/Create/FrontTable.php @@ -93,8 +93,11 @@ class FrontTable extends Creator return Str::of(File::get($this->getTableStub()))->replace([ $this->table, $this->search, $this->api, $this->paginate, $this->useList ], [ - $this->getTableContent(), $this->getSearchContent(), - "'{$this->apiString}'", $this->getPaginateStubContent(), $this->getUseList() + $this->getTableContent(), + $this->getSearchContent(), + $this->apiString, + $this->getPaginateStubContent(), + $this->getUseList() ])->toString(); } @@ -215,15 +218,7 @@ HTML; */ protected function getPaginateStubContent(): string { - return $this->hasPaginate ? - File::get( - dirname(__DIR__).DIRECTORY_SEPARATOR - - .'stubs'.DIRECTORY_SEPARATOR.'vue'. - - DIRECTORY_SEPARATOR.'paginate.stub' - ) - : ''; + return $this->hasPaginate ? '' : ''; } /** @@ -232,9 +227,7 @@ HTML; */ protected function getUseList(): string { - return $this->hasPaginate ? - 'const { data, query, search, reset, changePage, changeLimit, loading } = useGetList(api)' : - 'const { data, query, search, reset, loading } = useGetList(api)'; + return 'const { data, query, search, reset, loading } = useGetList(api)'; } /** diff --git a/modules/Develop/Support/Generate/stubs/vue/paginate.stub b/modules/Develop/Support/Generate/stubs/vue/paginate.stub deleted file mode 100644 index 7058654..0000000 --- a/modules/Develop/Support/Generate/stubs/vue/paginate.stub +++ /dev/null @@ -1,12 +0,0 @@ -
- -
diff --git a/modules/Develop/Support/Generate/stubs/vue/table.stub b/modules/Develop/Support/Generate/stubs/vue/table.stub index 0e507b1..1bc726b 100644 --- a/modules/Develop/Support/Generate/stubs/vue/table.stub +++ b/modules/Develop/Support/Generate/stubs/vue/table.stub @@ -1,24 +1,12 @@ - {paginate} + + @@ -41,23 +30,18 @@ import { computed, onMounted, ref, watch } from 'vue' import Create from './create.vue' import { useGetList } from '/admin/composables/curd/useGetList' import { useDestroy } from '/admin/composables/curd/useDestroy' -import { useEnabled } from '/admin/composables/curd/useEnabled' import { t } from '/admin/support/helper' const visible = ref(false) const id = ref(null) -const api = {api} -const title = ref(''); +const api = '{api}' +const title = ref('') +// const { data, query, search, reset, loading } = useGetList(api) {useList} - -const { destroy, isDeleted } = useDestroy() -const { enabled } = useEnabled() - -onMounted(() => search()) +const { destroy, deleted } = useDestroy() const tableData = computed(() => data.value?.data) -const total = computed(() => data.value?.total) const close = () => { visible.value = false @@ -70,9 +54,9 @@ const show = primary => { visible.value = true } -watch(isDeleted, function (){ - // change origin status - isDeleted.value = false - reset(); +onMounted(() => { + search() + + deleted(reset) }) diff --git a/modules/Permissions/Enums/DataRange.php b/modules/Permissions/Enums/DataRange.php index cd4fc38..09eaa27 100644 --- a/modules/Permissions/Enums/DataRange.php +++ b/modules/Permissions/Enums/DataRange.php @@ -1,4 +1,5 @@ model->getList(); + } + + public function store(Request $request) + { + return $this->model->storeBy($request->all()); + } + + public function show($id) + { + return $this->model->firstBy($id); + } + + public function update($id, Request $request) + { + return $this->model->updateBy($id, $request->all()); + } + + public function destroy($id) + { + return $this->model->deleteBy($id); + } +} diff --git a/modules/Permissions/Http/Controllers/RolesController.php b/modules/Permissions/Http/Controllers/RolesController.php index b542ef7..b6c485b 100644 --- a/modules/Permissions/Http/Controllers/RolesController.php +++ b/modules/Permissions/Http/Controllers/RolesController.php @@ -1,19 +1,19 @@ sprintf('required|unique:%s,%s,%s', RolesModel::class, 'role_name', $this->get('id')), - 'identify' => sprintf('required|alpha|unique:%s,%s,%s', RolesModel::class, 'role_name', $this->get('id')), + 'identify' => sprintf('required|alpha|unique:%s,%s,%s', RolesModel::class, 'role_name', $this->get('id')), ]; } @@ -41,4 +41,4 @@ class RoleRequest extends FormRequest 'identify.unique' => '角色标识已存在', ]; } -} \ No newline at end of file +} diff --git a/modules/Permissions/Models/JobsModel.php b/modules/Permissions/Models/JobsModel.php new file mode 100644 index 0000000..71330f1 --- /dev/null +++ b/modules/Permissions/Models/JobsModel.php @@ -0,0 +1,45 @@ + 'like' + ]; + + +} diff --git a/modules/Permissions/Models/RolesModel.php b/modules/Permissions/Models/RolesModel.php index 228c3b8..d45b720 100644 --- a/modules/Permissions/Models/RolesModel.php +++ b/modules/Permissions/Models/RolesModel.php @@ -5,7 +5,6 @@ declare(strict_types=1); namespace Modules\Permissions\Models; use Catch\Base\CatchModel as Model; -use Illuminate\Support\Facades\Request; /** * @property $role_name @@ -22,7 +21,7 @@ class RolesModel extends Model { protected $table = 'roles'; - protected $fillable = [ 'id', 'role_name', 'identify', 'parent_id', 'description', 'data_range', 'creator_id', 'created_at', 'updated_at', 'deleted_at' ]; + protected $fillable = ['id', 'role_name', 'identify', 'parent_id', 'description', 'data_range', 'creator_id', 'created_at', 'updated_at', 'deleted_at']; /** * @var array @@ -49,5 +48,4 @@ class RolesModel extends Model { return self::query()->select($this->fieldsInList)->quickSearch()->get()->toTree(); } - } diff --git a/modules/Permissions/Providers/Installer.php b/modules/Permissions/Providers/Installer.php new file mode 100644 index 0000000..fc2c208 --- /dev/null +++ b/modules/Permissions/Providers/Installer.php @@ -0,0 +1,42 @@ + '权限管理', + 'path' => 'Permissions', + 'keywords' => '权限, 角色, 部门', + 'description' => '权限管理模块', + 'provider' => PermissionsServiceProvider::class + ]; + } + + protected function migration(): string + { + // TODO: Implement migration() method. + return ''; + } + + protected function seeder(): string + { + // TODO: Implement seeder() method. + return ''; + } + + protected function requirePackages(): void + { + // TODO: Implement requirePackages() method. + } + + protected function removePackages(): void + { + // TODO: Implement removePackages() method. + } +} diff --git a/modules/Permissions/database/migrations/2022_12_06_110551_create_jobs.php b/modules/Permissions/database/migrations/2022_12_06_110551_create_jobs.php new file mode 100644 index 0000000..53859fa --- /dev/null +++ b/modules/Permissions/database/migrations/2022_12_06_110551_create_jobs.php @@ -0,0 +1,42 @@ +increments('id'); +$table->string('job_name', 50)->comment('岗位名称'); +$table->string('coding', 30)->nullable()->comment('创建人ID'); +$table->tinyInteger('status')->default('1')->comment('1 正常 2 停用'); +$table->integer('sort')->default('1')->comment('排序'); +$table->string('description', 1000)->nullable()->comment('岗位描述'); +$table->creatorId(); +$table->createdAt(); +$table->updatedAt(); +$table->deletedAt(); + +$table->engine='InnoDB'; +$table->comment('岗位表'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('jobs'); + } +}; diff --git a/modules/Permissions/route.php b/modules/Permissions/route.php index d0ec417..89f5e44 100644 --- a/modules/Permissions/route.php +++ b/modules/Permissions/route.php @@ -2,10 +2,12 @@ use Illuminate\Support\Facades\Route; use Modules\Permissions\Http\Controllers\RolesController; +use Modules\Permissions\Http\Controllers\JobsController; Route::prefix('permissions')->group(function () { + Route::apiResource('roles', RolesController::class); - Route::apiResource('roles', RolesController::class); + Route::apiResource('jobs', JobsController::class); //next }); diff --git a/modules/Permissions/views/jobs/create.vue b/modules/Permissions/views/jobs/create.vue new file mode 100644 index 0000000..47f569d --- /dev/null +++ b/modules/Permissions/views/jobs/create.vue @@ -0,0 +1,62 @@ + + + diff --git a/modules/Permissions/views/jobs/index.vue b/modules/Permissions/views/jobs/index.vue new file mode 100644 index 0000000..53d884f --- /dev/null +++ b/modules/Permissions/views/jobs/index.vue @@ -0,0 +1,68 @@ + + + diff --git a/modules/Permissions/views/router.ts b/modules/Permissions/views/router.ts index 0d4cf16..6fda820 100644 --- a/modules/Permissions/views/router.ts +++ b/modules/Permissions/views/router.ts @@ -13,6 +13,12 @@ const router: RouteRecordRaw[] = [ meta: { title: '角色管理', icon: 'home' }, component: () => import('./roles/index.vue'), }, + { + path: 'jobs', + name: 'jobs', + meta: { title: '岗位管理', icon: 'home' }, + component: () => import('./jobs/index.vue'), + }, ], }, ] diff --git a/modules/User/Models/Users.php b/modules/User/Models/Users.php index 5d2e436..85bcf53 100644 --- a/modules/User/Models/Users.php +++ b/modules/User/Models/Users.php @@ -81,6 +81,16 @@ class Users extends Model implements AuthenticatableContract, JWTSubject ); } + /** + * is super admin + * + * @return bool + */ + public function isSuperAdmin(): bool + { + return $this->{$this->primaryKey} == config('catch.super_admin'); + } + /** * update * @param $id diff --git a/modules/User/database/migrations/2022_12_04_060250_create_users.php b/modules/User/database/migrations/2022_12_04_060250_create_users.php index 44bd3fe..902f34d 100644 --- a/modules/User/database/migrations/2022_12_04_060250_create_users.php +++ b/modules/User/database/migrations/2022_12_04_060250_create_users.php @@ -21,17 +21,17 @@ return new class () extends Migration { $table->string('email')->comment('邮箱'); - $table->string('avatar')->comment('头像'); + $table->string('avatar')->nullable()->comment('头像'); - $table->string('remember_token', 1000)->comment('token'); + $table->string('remember_token', 1000)->nullable()->comment('token'); - $table->integer('creator_id'); + $table->integer('creator_id')->default(0); $table->status(); - $table->string('login_ip')->comment('登录IP'); + $table->string('login_ip')->nullable()->comment('登录IP'); - $table->integer('login_at')->comment('登录时间'); + $table->integer('login_at')->default(0)->comment('登录时间'); $table->createdAt(); diff --git a/modules/User/views/user/index.vue b/modules/User/views/user/index.vue index 29b456c..44abf5f 100644 --- a/modules/User/views/user/index.vue +++ b/modules/User/views/user/index.vue @@ -1,7 +1,7 @@