From 1af1e9cc1bbd5d387cd46ab2336257763d4b494e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E4=B8=96=E7=95=8C?= <642747453@qq.com> Date: Tue, 26 Jul 2022 20:05:14 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20#20220726=20=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E6=9E=84=E5=BB=BA=E4=BB=A5=E5=8F=8A=E8=BF=81?= =?UTF-8?q?=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +- .../Controllers/Auth/RegisterController.php | 4 +- app/Models/DailyStockRecord.php | 8 + app/Models/FailedJob.php | 8 + app/Models/Goods.php | 8 + app/Models/GoodsBrand.php | 8 + app/Models/GoodsSku.php | 8 + app/Models/GoodsType.php | 8 + app/Models/Log.php | 8 + app/Models/Model.php | 23 +++ app/Models/ModelHasPermissions.php | 8 + app/Models/ModelHasRoles.php | 8 + app/Models/PasswordReset.php | 8 + app/Models/Permission.php | 8 + app/Models/Role.php | 8 + app/Models/RoleHasPermission.php | 8 + app/{ => Models}/User.php | 3 +- composer.json | 3 +- composer.lock | 84 ++++++++- config/app.php | 4 +- config/auth.php | 2 +- config/permission.php | 161 ++++++++++++++++++ database/factories/UserFactory.php | 2 +- ..._07_25_060932_create_permission_tables.php | 141 +++++++++++++++ ..._07_26_061712_create_goods_types_table.php | 35 ++++ ...07_26_085847_create_goods_brands_table.php | 35 ++++ .../2022_07_26_090143_create_goods_table.php | 38 +++++ ...2_07_26_090150_create_goods_skus_table.php | 43 +++++ ...03559_create_daily_stock_records_table.php | 36 ++++ .../2022_07_26_105818_create_logs_table.php | 39 +++++ 30 files changed, 756 insertions(+), 15 deletions(-) create mode 100644 app/Models/DailyStockRecord.php create mode 100644 app/Models/FailedJob.php create mode 100644 app/Models/Goods.php create mode 100644 app/Models/GoodsBrand.php create mode 100644 app/Models/GoodsSku.php create mode 100644 app/Models/GoodsType.php create mode 100644 app/Models/Log.php create mode 100644 app/Models/Model.php create mode 100644 app/Models/ModelHasPermissions.php create mode 100644 app/Models/ModelHasRoles.php create mode 100644 app/Models/PasswordReset.php create mode 100644 app/Models/Permission.php create mode 100644 app/Models/Role.php create mode 100644 app/Models/RoleHasPermission.php rename app/{ => Models}/User.php (91%) create mode 100644 config/permission.php create mode 100644 database/migrations/2022_07_25_060932_create_permission_tables.php create mode 100644 database/migrations/2022_07_26_061712_create_goods_types_table.php create mode 100644 database/migrations/2022_07_26_085847_create_goods_brands_table.php create mode 100644 database/migrations/2022_07_26_090143_create_goods_table.php create mode 100644 database/migrations/2022_07_26_090150_create_goods_skus_table.php create mode 100644 database/migrations/2022_07_26_103559_create_daily_stock_records_table.php create mode 100644 database/migrations/2022_07_26_105818_create_logs_table.php diff --git a/README.md b/README.md index 1e0745e..a25de4b 100644 --- a/README.md +++ b/README.md @@ -2,21 +2,25 @@ #### 介绍 +主要为鲜花售卖提供一个统一的商品管理平台,支持对接第三方平台,包括商品管理,库存同步,订单管理,发货等 + #### 软件架构 - laravel 6.* - vue2.* - element-ui -#### 安装教程 +#### 本地开发安装教程 -1. xxxx -2. xxxx -3. xxxx +1. `composer install` +2. `cp .env.example .env` +3. 创建数据库 `CREATE DATABASE IF NOT EXISTS `erp` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci;` +4. 修改 .env 配置项为本地配置 +5. `php artisan migration` #### 使用说明 -1. xxxx +1. 阅读并遵守<<[Laravel项目开发规范](https://learnku.com/docs/laravel-specification/9.x/whats-the-use-of-standards/12720)>> 2. xxxx 3. xxxx diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index c6a6de6..69efd5f 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -3,8 +3,8 @@ namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; +use App\Models\User; use App\Providers\RouteServiceProvider; -use App\User; use Illuminate\Foundation\Auth\RegistersUsers; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Validator; @@ -60,7 +60,7 @@ class RegisterController extends Controller * Create a new user instance after a valid registration. * * @param array $data - * @return \App\User + * @return \App\Models\User */ protected function create(array $data) { diff --git a/app/Models/DailyStockRecord.php b/app/Models/DailyStockRecord.php new file mode 100644 index 0000000..7f609c6 --- /dev/null +++ b/app/Models/DailyStockRecord.php @@ -0,0 +1,8 @@ +orderBy('id', 'desc'); + } + + public function scopeOlder($query) + { + return $query->orderBy('id', 'asc'); + } + + public function scopeByUser($query, User $user) + { + return $query->where('user_id', $user->id); + } +} diff --git a/app/Models/ModelHasPermissions.php b/app/Models/ModelHasPermissions.php new file mode 100644 index 0000000..a4fca01 --- /dev/null +++ b/app/Models/ModelHasPermissions.php @@ -0,0 +1,8 @@ + env('APP_NAME', 'Laravel'), + 'name' => env('APP_NAME', 'CFen Erp'), /* |-------------------------------------------------------------------------- @@ -52,7 +52,7 @@ return [ | */ - 'url' => env('APP_URL', 'http://localhost'), + 'url' => env('APP_URL', 'http://erp.ii090.com'), 'asset_url' => env('ASSET_URL', null), diff --git a/config/auth.php b/config/auth.php index aaf982b..068a52b 100644 --- a/config/auth.php +++ b/config/auth.php @@ -68,7 +68,7 @@ return [ 'providers' => [ 'users' => [ 'driver' => 'eloquent', - 'model' => App\User::class, + 'model' => \App\Models\User::class, ], // 'users' => [ diff --git a/config/permission.php b/config/permission.php new file mode 100644 index 0000000..5b6e184 --- /dev/null +++ b/config/permission.php @@ -0,0 +1,161 @@ + [ + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * Eloquent model should be used to retrieve your permissions. Of course, it + * is often just the "Permission" model but you may use whatever you like. + * + * The model you want to use as a Permission model needs to implement the + * `Spatie\Permission\Contracts\Permission` contract. + */ + + 'permission' => Spatie\Permission\Models\Permission::class, + + /* + * When using the "HasRoles" trait from this package, we need to know which + * Eloquent model should be used to retrieve your roles. Of course, it + * is often just the "Role" model but you may use whatever you like. + * + * The model you want to use as a Role model needs to implement the + * `Spatie\Permission\Contracts\Role` contract. + */ + + 'role' => Spatie\Permission\Models\Role::class, + + ], + + 'table_names' => [ + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your roles. We have chosen a basic + * default value but you may easily change it to any table you like. + */ + + 'roles' => 'roles', + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * table should be used to retrieve your permissions. We have chosen a basic + * default value but you may easily change it to any table you like. + */ + + 'permissions' => 'permissions', + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * table should be used to retrieve your models permissions. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'model_has_permissions' => 'model_has_permissions', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your models roles. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'model_has_roles' => 'model_has_roles', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your roles permissions. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'role_has_permissions' => 'role_has_permissions', + ], + + 'column_names' => [ + /* + * Change this if you want to name the related pivots other than defaults + */ + 'role_pivot_key' => null, //default 'role_id', + 'permission_pivot_key' => null, //default 'permission_id', + + /* + * Change this if you want to name the related model primary key other than + * `model_id`. + * + * For example, this would be nice if your primary keys are all UUIDs. In + * that case, name this `model_uuid`. + */ + + 'model_morph_key' => 'model_id', + + /* + * Change this if you want to use the teams feature and your related model's + * foreign key is other than `team_id`. + */ + + 'team_foreign_key' => 'team_id', + ], + + /* + * When set to true, the method for checking permissions will be registered on the gate. + * Set this to false, if you want to implement custom logic for checking permissions. + */ + + 'register_permission_check_method' => true, + + /* + * When set to true the package implements teams using the 'team_foreign_key'. If you want + * the migrations to register the 'team_foreign_key', you must set this to true + * before doing the migration. If you already did the migration then you must make a new + * migration to also add 'team_foreign_key' to 'roles', 'model_has_roles', and + * 'model_has_permissions'(view the latest version of package's migration file) + */ + + 'teams' => false, + + /* + * When set to true, the required permission names are added to the exception + * message. This could be considered an information leak in some contexts, so + * the default setting is false here for optimum safety. + */ + + 'display_permission_in_exception' => false, + + /* + * When set to true, the required role names are added to the exception + * message. This could be considered an information leak in some contexts, so + * the default setting is false here for optimum safety. + */ + + 'display_role_in_exception' => false, + + /* + * By default wildcard permission lookups are disabled. + */ + + 'enable_wildcard_permission' => false, + + 'cache' => [ + + /* + * By default all permissions are cached for 24 hours to speed up performance. + * When permissions or roles are updated the cache is flushed automatically. + */ + + 'expiration_time' => \DateInterval::createFromDateString('24 hours'), + + /* + * The cache key used to store all permissions. + */ + + 'key' => 'spatie.permission.cache', + + /* + * You may optionally indicate a specific cache driver to use for permission and + * role caching using any of the `store` drivers listed in the cache.php config + * file. Using 'default' here means to use the `default` set in cache.php. + */ + + 'store' => 'default', + ], +]; diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 741edea..fa9360e 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -2,7 +2,7 @@ /** @var \Illuminate\Database\Eloquent\Factory $factory */ -use App\User; +use App\Models\User; use Faker\Generator as Faker; use Illuminate\Support\Str; diff --git a/database/migrations/2022_07_25_060932_create_permission_tables.php b/database/migrations/2022_07_25_060932_create_permission_tables.php new file mode 100644 index 0000000..f20ef75 --- /dev/null +++ b/database/migrations/2022_07_25_060932_create_permission_tables.php @@ -0,0 +1,141 @@ +bigIncrements('id'); + $table->string('name'); // For MySQL 8.0 use string('name', 125); + $table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125); + $table->timestamps(); + + $table->unique(['name', 'guard_name']); + }); + + Schema::create($tableNames['roles'], function (Blueprint $table) use ($teams, $columnNames) { + $table->bigIncrements('id'); + if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing + $table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable(); + $table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index'); + } + $table->string('name'); // For MySQL 8.0 use string('name', 125); + $table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125); + $table->timestamps(); + if ($teams || config('permission.testing')) { + $table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']); + } else { + $table->unique(['name', 'guard_name']); + } + }); + + Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) { + $table->unsignedBigInteger(PermissionRegistrar::$pivotPermission); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index'); + + $table->foreign(PermissionRegistrar::$pivotPermission) + ->references('id') + ->on($tableNames['permissions']) + ->onDelete('cascade'); + if ($teams) { + $table->unsignedBigInteger($columnNames['team_foreign_key']); + $table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index'); + + $table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotPermission, $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary'); + } else { + $table->primary([PermissionRegistrar::$pivotPermission, $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary'); + } + + }); + + Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) { + $table->unsignedBigInteger(PermissionRegistrar::$pivotRole); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index'); + + $table->foreign(PermissionRegistrar::$pivotRole) + ->references('id') + ->on($tableNames['roles']) + ->onDelete('cascade'); + if ($teams) { + $table->unsignedBigInteger($columnNames['team_foreign_key']); + $table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index'); + + $table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotRole, $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary'); + } else { + $table->primary([PermissionRegistrar::$pivotRole, $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary'); + } + }); + + Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames) { + $table->unsignedBigInteger(PermissionRegistrar::$pivotPermission); + $table->unsignedBigInteger(PermissionRegistrar::$pivotRole); + + $table->foreign(PermissionRegistrar::$pivotPermission) + ->references('id') + ->on($tableNames['permissions']) + ->onDelete('cascade'); + + $table->foreign(PermissionRegistrar::$pivotRole) + ->references('id') + ->on($tableNames['roles']) + ->onDelete('cascade'); + + $table->primary([PermissionRegistrar::$pivotPermission, PermissionRegistrar::$pivotRole], 'role_has_permissions_permission_id_role_id_primary'); + }); + + app('cache') + ->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null) + ->forget(config('permission.cache.key')); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $tableNames = config('permission.table_names'); + + if (empty($tableNames)) { + throw new \Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.'); + } + + Schema::drop($tableNames['role_has_permissions']); + Schema::drop($tableNames['model_has_roles']); + Schema::drop($tableNames['model_has_permissions']); + Schema::drop($tableNames['roles']); + Schema::drop($tableNames['permissions']); + } +} diff --git a/database/migrations/2022_07_26_061712_create_goods_types_table.php b/database/migrations/2022_07_26_061712_create_goods_types_table.php new file mode 100644 index 0000000..7ba17c9 --- /dev/null +++ b/database/migrations/2022_07_26_061712_create_goods_types_table.php @@ -0,0 +1,35 @@ +bigIncrements('id'); + $table->string('name')->nullable(false); + $table->unsignedTinyInteger('is_delete')->default(0); + $table->timestamps(); + // 索引 + $table->unique('name'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('goods_types'); + } +} diff --git a/database/migrations/2022_07_26_085847_create_goods_brands_table.php b/database/migrations/2022_07_26_085847_create_goods_brands_table.php new file mode 100644 index 0000000..ed85d2a --- /dev/null +++ b/database/migrations/2022_07_26_085847_create_goods_brands_table.php @@ -0,0 +1,35 @@ +bigIncrements('id'); + $table->string('name')->nullable(false); + $table->unsignedTinyInteger('is_delete')->default(0); + $table->timestamps(); + // 索引 + $table->unique('name'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('goods_brands'); + } +} diff --git a/database/migrations/2022_07_26_090143_create_goods_table.php b/database/migrations/2022_07_26_090143_create_goods_table.php new file mode 100644 index 0000000..c82e352 --- /dev/null +++ b/database/migrations/2022_07_26_090143_create_goods_table.php @@ -0,0 +1,38 @@ +bigIncrements('id'); + $table->string('title')->nullable(false); + $table->string('img_url')->nullable(false)->comment('商品图片'); + $table->unsignedBigInteger('type_id')->nullable(false)->comment('商品种类id'); + $table->unsignedBigInteger('brand_id')->nullable()->comment('商品品牌id'); + $table->string('goods_code', 32)->nullable(false)->comment('商品编码'); + $table->timestamps(); + // 索引 + $table->unique('goods_code'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('goods'); + } +} diff --git a/database/migrations/2022_07_26_090150_create_goods_skus_table.php b/database/migrations/2022_07_26_090150_create_goods_skus_table.php new file mode 100644 index 0000000..af6bd93 --- /dev/null +++ b/database/migrations/2022_07_26_090150_create_goods_skus_table.php @@ -0,0 +1,43 @@ +bigIncrements('id'); + $table->string('title')->nullable(false)->comment('商品规格'); + $table->string('sku_code', 32)->nullable(false)->comment('规格编码'); + $table->unsignedTinyInteger('status')->default(0)->comment('规格状态(0-下架,1在售,2预警)'); + $table->unsignedInteger('num')->default(0)->comment('总量'); + $table->unsignedInteger('stock')->default(0)->comment('库存'); + $table->unsignedDecimal('cost')->default(0)->comment('成本'); + $table->unsignedInteger('two_days_ago_num')->default(0)->comment('2天前库存'); + $table->unsignedInteger('yesterday_num')->default(0)->comment('1天前库存'); + $table->unsignedDecimal('reference_price')->default(0)->comment('参考售价'); + $table->unsignedInteger('reserve')->default(0)->comment('预留量'); + $table->timestamps(); + // 索引 + $table->unique('sku_code'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('goods_skus'); + } +} diff --git a/database/migrations/2022_07_26_103559_create_daily_stock_records_table.php b/database/migrations/2022_07_26_103559_create_daily_stock_records_table.php new file mode 100644 index 0000000..1c4706d --- /dev/null +++ b/database/migrations/2022_07_26_103559_create_daily_stock_records_table.php @@ -0,0 +1,36 @@ +bigIncrements('id'); + $table->bigInteger('sku_id')->nullable(false); + $table->date('day')->nullable(false); + $table->unsignedInteger('arrived_today_num')->default(0)->comment('今日到货'); + $table->unsignedInteger('loss_num')->default(0)->comment('损耗'); + $table->unsignedInteger('inventory')->default(0)->comment('库存盘点'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('daily_stock_records'); + } +} diff --git a/database/migrations/2022_07_26_105818_create_logs_table.php b/database/migrations/2022_07_26_105818_create_logs_table.php new file mode 100644 index 0000000..6f0820c --- /dev/null +++ b/database/migrations/2022_07_26_105818_create_logs_table.php @@ -0,0 +1,39 @@ +bigIncrements('id'); + $table->string('module')->comment('模块'); + $table->string('action')->comment('操作'); + $table->string('target_type')->comment('目标类型'); + $table->bigInteger('target_id')->comment('目标id'); + $table->string('target_field')->comment('目标字段'); + $table->text('before_update')->comment('更新前数据'); + $table->text('after_update')->comment('更新后数据'); + $table->bigInteger('user_id')->comment('操作人id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('logs'); + } +}