mirror of
https://gitee.com/hzchunfen/erp.git
synced 2025-12-01 06:30:49 +00:00
commit
c847b42653
@ -1,15 +1,15 @@
|
|||||||
APP_NAME=Laravel
|
APP_NAME=ERP
|
||||||
APP_ENV=local
|
APP_ENV=local
|
||||||
APP_KEY=
|
APP_KEY=
|
||||||
APP_DEBUG=true
|
APP_DEBUG=true
|
||||||
APP_URL=http://localhost
|
APP_URL=http://erp.test
|
||||||
|
|
||||||
LOG_CHANNEL=stack
|
LOG_CHANNEL=stack
|
||||||
|
|
||||||
DB_CONNECTION=mysql
|
DB_CONNECTION=mysql
|
||||||
DB_HOST=127.0.0.1
|
DB_HOST=127.0.0.1
|
||||||
DB_PORT=3306
|
DB_PORT=3306
|
||||||
DB_DATABASE=laravel
|
DB_DATABASE=erp
|
||||||
DB_USERNAME=root
|
DB_USERNAME=root
|
||||||
DB_PASSWORD=
|
DB_PASSWORD=
|
||||||
|
|
||||||
|
|||||||
16
README.md
16
README.md
@ -2,21 +2,27 @@
|
|||||||
|
|
||||||
#### 介绍
|
#### 介绍
|
||||||
|
|
||||||
|
主要为鲜花售卖提供一个统一的商品管理平台,支持对接第三方平台,包括商品管理,库存同步,订单管理,发货等
|
||||||
|
|
||||||
#### 软件架构
|
#### 软件架构
|
||||||
|
|
||||||
- laravel 6.*
|
- laravel 6.*
|
||||||
- vue2.*
|
- vue2.*
|
||||||
- element-ui
|
- element-ui
|
||||||
|
|
||||||
#### 安装教程
|
#### 本地开发安装教程
|
||||||
|
|
||||||
1. xxxx
|
1. `composer install`
|
||||||
2. xxxx
|
2. `cp .env.example .env`
|
||||||
3. xxxx
|
3. 修改 .env 配置项为本地配置
|
||||||
|
4. 创建数据库 `CREATE DATABASE IF NOT EXISTS `erp` DEFAULT CHARACTER SET utf8;`
|
||||||
|
5. `php artisan migrate` 如果数据填充没有执行成功,则需要再次执行 `php artisan migrate:fresh --seed`
|
||||||
|
6. `php artisan key:generate`
|
||||||
|
7. `php artisan update:super_admin_permissions` 更新超级管理员角色权限
|
||||||
|
|
||||||
#### 使用说明
|
#### 使用说明
|
||||||
|
|
||||||
1. xxxx
|
1. 阅读并遵守<<[Laravel项目开发规范](https://learnku.com/docs/laravel-specification/9.x/whats-the-use-of-standards/12720)>>
|
||||||
2. xxxx
|
2. xxxx
|
||||||
3. xxxx
|
3. xxxx
|
||||||
|
|
||||||
|
|||||||
79
app/Console/Commands/Inventory.php
Normal file
79
app/Console/Commands/Inventory.php
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use App\Models\DailyStockRecord;
|
||||||
|
use App\Models\GoodsSku;
|
||||||
|
use App\Models\Log;
|
||||||
|
|
||||||
|
class Inventory extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'timing:inventory';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = '定时盘点';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new command instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
DB::beginTransaction();
|
||||||
|
try {
|
||||||
|
// 数据库存储过程,7点定时执行
|
||||||
|
$skus = GoodsSku::query()->get(['id', 'stock', 'two_days_ago_num', 'yesterday_num']);
|
||||||
|
$data = [];
|
||||||
|
$date = date('Y-m-d');
|
||||||
|
foreach ($skus as $sku) {
|
||||||
|
$data[] = [
|
||||||
|
'sku_id' => $sku->id,
|
||||||
|
'day' => $date,
|
||||||
|
];
|
||||||
|
GoodsSku::where('id', $sku->id)->update([
|
||||||
|
'stock' => $sku->stock + $sku->two_days_ago_num + $sku->yesterday_num,
|
||||||
|
'yesterday_num' => $sku->stock,
|
||||||
|
'two_days_ago_num' => $sku->two_days_ago_num + $sku->yesterday_num,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$log = new Log();
|
||||||
|
$log->module = 'goods';
|
||||||
|
$log->action = 'PATCH';
|
||||||
|
$log->target_type = 'goods_sku';
|
||||||
|
$log->target_id = 0;
|
||||||
|
$log->target_field = 'timingInventory';
|
||||||
|
$log->user_id = 1;
|
||||||
|
$record = new DailyStockRecord();
|
||||||
|
$record->batchInsert($data);
|
||||||
|
$log->message = '成功';
|
||||||
|
DB::commit();
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
$log->message = '失败';
|
||||||
|
DB::rollBack();
|
||||||
|
}
|
||||||
|
$log->save();
|
||||||
|
$this->info($log->message);
|
||||||
|
}
|
||||||
|
}
|
||||||
51
app/Console/Commands/UpdateSuperPermissions.php
Normal file
51
app/Console/Commands/UpdateSuperPermissions.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Spatie\Permission\Models\Permission;
|
||||||
|
use Spatie\Permission\Models\Role;
|
||||||
|
|
||||||
|
class UpdateSuperPermissions extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'update:super_admin_permissions';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = '更新超级管理员权限';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new command instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$roleName = '超级管理员';
|
||||||
|
$role = Role::query()->where('name', $roleName)->find(1);
|
||||||
|
$permissions = Permission::query()->get();
|
||||||
|
$role->syncPermissions($permissions);
|
||||||
|
$user = User::query()->find(1);
|
||||||
|
$user->assignRole($role);
|
||||||
|
$this->info('更新成功');
|
||||||
|
}
|
||||||
|
}
|
||||||
75
app/Exports/GoodsSkusExport.php
Normal file
75
app/Exports/GoodsSkusExport.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\Log;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||||
|
use App\Models\GoodsSku;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
class GoodsSkusExport implements FromCollection, ShouldAutoSize
|
||||||
|
{
|
||||||
|
private $data;
|
||||||
|
private $type;
|
||||||
|
|
||||||
|
public function __construct($type)
|
||||||
|
{
|
||||||
|
$this->type = $type;
|
||||||
|
$this->data = $this->createData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
return new Collection($this->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createData()
|
||||||
|
{
|
||||||
|
$headTitle = [
|
||||||
|
'商品编码',
|
||||||
|
'商品名称',
|
||||||
|
'商品种类',
|
||||||
|
'商品品牌',
|
||||||
|
'规格编码',
|
||||||
|
'规格名称',
|
||||||
|
'成本',
|
||||||
|
'库存',
|
||||||
|
];
|
||||||
|
$inventoryTime = strtotime(date('Y-m-d 07:00:00'));
|
||||||
|
$ids = Log::query()->where('target_type', 'sku')
|
||||||
|
->where('target_field', $this->type)
|
||||||
|
->where('created_at', '>', $inventoryTime)
|
||||||
|
->pluck('sku_id')
|
||||||
|
->toArray();
|
||||||
|
$data = GoodsSku::query()
|
||||||
|
->when($ids, function ($query, $ids) {
|
||||||
|
return $query->whereIn('id', $ids);
|
||||||
|
})
|
||||||
|
->with(['goods' => function ($query) {
|
||||||
|
$query->with(['type:id,name', 'brand:id,name']);
|
||||||
|
}])
|
||||||
|
->get()
|
||||||
|
->toArray();
|
||||||
|
if (empty($data)) {
|
||||||
|
return [$headTitle];
|
||||||
|
}
|
||||||
|
$bodyData = [];
|
||||||
|
foreach ($data as $item) {
|
||||||
|
$arr[0] = $item['goods']['goods_code'];
|
||||||
|
$arr[1] = $item['goods']['title'];
|
||||||
|
$arr[2] = $item['goods']['type']['name'];
|
||||||
|
$arr[3] = $item['goods']['brand']['name'];
|
||||||
|
$arr[4] = $item['goods']['sku_code'];
|
||||||
|
$arr[5] = $item['goods']['title'];
|
||||||
|
$arr[6] = $item['goods']['cost'];
|
||||||
|
$arr[7] = $item['goods']['stock'];
|
||||||
|
$bodyData[] = $arr;
|
||||||
|
}
|
||||||
|
unset($arr);
|
||||||
|
return [$headTitle, $bodyData];
|
||||||
|
}
|
||||||
|
}
|
||||||
121
app/Filters/Filters.php
Normal file
121
app/Filters/Filters.php
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filters;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
class Filters
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Request
|
||||||
|
*/
|
||||||
|
protected $request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Eloquent builder.
|
||||||
|
*
|
||||||
|
* @var \Illuminate\Database\Eloquent\Builder
|
||||||
|
*/
|
||||||
|
protected $builder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registered filters to operate upon.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $filters = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ThreadFilters instance.
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->request = Request();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the filters.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\Eloquent\Builder $builder
|
||||||
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
|
*/
|
||||||
|
public function apply($builder)
|
||||||
|
{
|
||||||
|
$this->builder = $builder;
|
||||||
|
$fieldsSearchable = $this->getFieldsSearchable();
|
||||||
|
$fields = $this->getFilters($fieldsSearchable);
|
||||||
|
if (is_array($fields) && count($fields) && is_array($fieldsSearchable) && count($fieldsSearchable)) {
|
||||||
|
foreach ($fields as $field => $value) {
|
||||||
|
$method = Str::camel($field);
|
||||||
|
if (method_exists($this, $method)) {
|
||||||
|
$this->$method($value);
|
||||||
|
} elseif (isset($fieldsSearchable[$field])) {
|
||||||
|
$condition = $fieldsSearchable[$field];
|
||||||
|
$value = $condition == "like" ? "%{$value}%" : $value;
|
||||||
|
$relation = null;
|
||||||
|
if (stripos($field, '.')) {
|
||||||
|
$explode = explode('.', $field);
|
||||||
|
$field = array_pop($explode);
|
||||||
|
$relation = implode('.', $explode);
|
||||||
|
}
|
||||||
|
$modelTableName = $builder->getModel()->getTable();
|
||||||
|
$field = Str::snake($field);
|
||||||
|
if (!is_null($value)) {
|
||||||
|
if (!is_null($relation)) {
|
||||||
|
$builder->whereHas($relation, function ($query) use ($field, $condition, $value) {
|
||||||
|
$query->where($field, $condition, $value);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$builder->where($modelTableName . '.' . $field, $condition, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch all relevant filters from the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getFilters($fieldsSearchable)
|
||||||
|
{
|
||||||
|
if (!is_array($fieldsSearchable) || count($fieldsSearchable) == 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
$keys = array_keys($fieldsSearchable);
|
||||||
|
//$this->request->only() 会把user.nickname参数里包含"." 转换成数组
|
||||||
|
//Arr::dot 方法使用「.」号将将多维数组转化为一维数组:
|
||||||
|
|
||||||
|
return array_filter(Arr::dot($this->request->only($keys)), function ($value) {
|
||||||
|
return !is_null($value) && $value != '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取model 可以查询的参数
|
||||||
|
protected function getFieldsSearchable()
|
||||||
|
{
|
||||||
|
$model = $this->builder->getModel();
|
||||||
|
if (!property_exists($model, 'fieldSearchable')) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
$fieldSearchable = $model->fieldSearchable;
|
||||||
|
$fields = [];
|
||||||
|
foreach ($fieldSearchable as $field => $condition) {
|
||||||
|
if (is_numeric($field)) {
|
||||||
|
$field = $condition;
|
||||||
|
$condition = "=";
|
||||||
|
}
|
||||||
|
$fields[$field] = $condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
app/Filters/GoodsFilter.php
Normal file
21
app/Filters/GoodsFilter.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filters;
|
||||||
|
|
||||||
|
class GoodsFilter extends Filters
|
||||||
|
{
|
||||||
|
protected function goodsTitle($value)
|
||||||
|
{
|
||||||
|
return $this->builder->where('title', 'like', "%$value%");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function typeId($value)
|
||||||
|
{
|
||||||
|
return $this->builder->where('type_id', '=', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function brandId($value)
|
||||||
|
{
|
||||||
|
return $this->builder->where('brand_id', '=', $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
app/Filters/GoodsSkuFilter.php
Normal file
16
app/Filters/GoodsSkuFilter.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filters;
|
||||||
|
|
||||||
|
class GoodsSkuFilter extends Filters
|
||||||
|
{
|
||||||
|
protected function skuTitle($value)
|
||||||
|
{
|
||||||
|
return $this->builder->where('title', '=', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function status($value)
|
||||||
|
{
|
||||||
|
return $this->builder->where('status', '=', $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
46
app/Filters/LogFilter.php
Normal file
46
app/Filters/LogFilter.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filters;
|
||||||
|
|
||||||
|
class LogFilter extends Filters
|
||||||
|
{
|
||||||
|
protected function module($value)
|
||||||
|
{
|
||||||
|
return $this->builder->where('module', '=', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function action($value)
|
||||||
|
{
|
||||||
|
return $this->builder->where('action', '=', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function targetType($value)
|
||||||
|
{
|
||||||
|
return $this->builder->where('target_type', '=', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function targetId($value)
|
||||||
|
{
|
||||||
|
return $this->builder->where('target_id', '=', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function targetField($value)
|
||||||
|
{
|
||||||
|
return $this->builder->where('target_field', '=', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function userId($value)
|
||||||
|
{
|
||||||
|
return $this->builder->where('user_id', '=', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function startTime($value)
|
||||||
|
{
|
||||||
|
return $this->builder->where('created_at', '>=', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function endTime($value)
|
||||||
|
{
|
||||||
|
return $this->builder->where('created_at', '<=', $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,6 +4,8 @@ namespace App\Http\Controllers\Auth;
|
|||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Providers\RouteServiceProvider;
|
use App\Providers\RouteServiceProvider;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||||
|
|
||||||
class LoginController extends Controller
|
class LoginController extends Controller
|
||||||
@ -37,4 +39,21 @@ class LoginController extends Controller
|
|||||||
{
|
{
|
||||||
$this->middleware('guest')->except('logout');
|
$this->middleware('guest')->except('logout');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function username()
|
||||||
|
{
|
||||||
|
return 'name';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function login(Request $request)
|
||||||
|
{
|
||||||
|
$credentials = $request->only('name', 'password');
|
||||||
|
|
||||||
|
if (Auth::attempt($credentials)) {
|
||||||
|
// 通过认证..
|
||||||
|
return response()->json(['token' => $request->user()->api_token]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json(['error' => 'auth login fail']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,11 +3,13 @@
|
|||||||
namespace App\Http\Controllers\Auth;
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\User;
|
||||||
use App\Providers\RouteServiceProvider;
|
use App\Providers\RouteServiceProvider;
|
||||||
use App\User;
|
|
||||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Faker\Generator as Faker;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class RegisterController extends Controller
|
class RegisterController extends Controller
|
||||||
{
|
{
|
||||||
@ -50,9 +52,10 @@ class RegisterController extends Controller
|
|||||||
protected function validator(array $data)
|
protected function validator(array $data)
|
||||||
{
|
{
|
||||||
return Validator::make($data, [
|
return Validator::make($data, [
|
||||||
'name' => ['required', 'string', 'max:255'],
|
'name' => ['required', 'string', 'unique:users', 'max:255'],
|
||||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
'email' => ['string', 'email', 'max:255', 'unique:users'],
|
||||||
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
||||||
|
'role_id' => ['required', 'numeric', 'exists:roles,id'],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,14 +63,17 @@ class RegisterController extends Controller
|
|||||||
* Create a new user instance after a valid registration.
|
* Create a new user instance after a valid registration.
|
||||||
*
|
*
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @return \App\User
|
* @return User
|
||||||
*/
|
*/
|
||||||
protected function create(array $data)
|
protected function create(array $data)
|
||||||
{
|
{
|
||||||
|
$faker = new Faker();
|
||||||
|
|
||||||
return User::create([
|
return User::create([
|
||||||
'name' => $data['name'],
|
'name' => $data['name'],
|
||||||
'email' => $data['email'],
|
'email' => $data['email'] ?? $faker->unique()->safeEmail,
|
||||||
'password' => Hash::make($data['password']),
|
'password' => Hash::make($data['password']),
|
||||||
|
'api_token' => Str::random(60),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,4 +10,40 @@ use Illuminate\Routing\Controller as BaseController;
|
|||||||
class Controller extends BaseController
|
class Controller extends BaseController
|
||||||
{
|
{
|
||||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||||
|
|
||||||
|
protected $res = [
|
||||||
|
'httpCode' => 200,
|
||||||
|
'errorCode' => 0,
|
||||||
|
'errorMessage' => '',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $log;
|
||||||
|
|
||||||
|
protected function setValidatorFailResponse($errorMessage)
|
||||||
|
{
|
||||||
|
return $this->res = [
|
||||||
|
'httpCode' => 400,
|
||||||
|
'errorCode' => 400416,
|
||||||
|
'errorMessage' => $errorMessage,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setBeforeUpdate($data)
|
||||||
|
{
|
||||||
|
$this->log->before_update = is_array($data) ? json_encode($data, 256) : $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setAfterUpdate($data)
|
||||||
|
{
|
||||||
|
$this->log->after_update = is_array($data) ? json_encode($data, 256) : $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function addLog($targetId = 0, $targetField = '', $targetType = '')
|
||||||
|
{
|
||||||
|
if ($targetType) {
|
||||||
|
$this->log->target_type = $targetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->log->add($targetId, $targetField);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
106
app/Http/Controllers/Goods/GoodsBrandsController.php
Normal file
106
app/Http/Controllers/Goods/GoodsBrandsController.php
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Goods;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Resources\GoodsBrandResource;
|
||||||
|
use App\Models\GoodsBrand;
|
||||||
|
use App\Models\Log as LogModel;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
|
class GoodsBrandsController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct(Request $request)
|
||||||
|
{
|
||||||
|
$this->log = new LogModel([
|
||||||
|
'module' => 'goods',
|
||||||
|
'action' => $request->getMethod(),
|
||||||
|
'target_type' => 'goods_brand',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$goodsBrands = GoodsBrand::query()->paginate();
|
||||||
|
|
||||||
|
return GoodsBrandResource::collection($goodsBrands);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'names' => 'required|array',
|
||||||
|
'names.*' => 'required|string|max:255|unique:goods_brands,name',
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$goodsBrands = [];
|
||||||
|
foreach ($request->names as $name) {
|
||||||
|
$goodsBrands[] = ['name' => $name];
|
||||||
|
}
|
||||||
|
$goodsBrand = new GoodsBrand();
|
||||||
|
if (!$goodsBrand->batchInsert($goodsBrands)) {
|
||||||
|
$this->res = [
|
||||||
|
'httpCode' => 500,
|
||||||
|
'errorCode' => 500500,
|
||||||
|
'errorMessage' => '批量添加失败',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$this->setAfterUpdate($goodsBrands);
|
||||||
|
$this->addLog(0, 'add');
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
return new GoodsBrandResource(GoodsBrand::query()->find($id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update($id, Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'name' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'max:255',
|
||||||
|
Rule::unique('goods_brands')->ignore($id),
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$goodsBrand = GoodsBrand::query()->find($id);
|
||||||
|
$this->setBeforeUpdate($goodsBrand->name);
|
||||||
|
$goodsBrand->name = request('name');
|
||||||
|
$goodsBrand->save();
|
||||||
|
$this->setAfterUpdate($goodsBrand->name);
|
||||||
|
$this->addLog($id, 'name');
|
||||||
|
|
||||||
|
return new GoodsBrandResource($goodsBrand);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
$goodsBrand = GoodsBrand::query()->find($id);
|
||||||
|
try {
|
||||||
|
$goodsBrand->delete();
|
||||||
|
$this->addLog($id, 'status');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->res = [
|
||||||
|
'httpCode' => 500,
|
||||||
|
'errorCode' => 500416,
|
||||||
|
'errorMessage' => $e->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
94
app/Http/Controllers/Goods/GoodsController.php
Normal file
94
app/Http/Controllers/Goods/GoodsController.php
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Goods;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\GoodsSkuRequest;
|
||||||
|
use App\Http\Resources\GoodsResource;
|
||||||
|
use App\Models\Log as LogModel;
|
||||||
|
use App\Utils\FormatUtils;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use App\Models\Goods;
|
||||||
|
use App\Http\Requests\GoodsRequest;
|
||||||
|
use App\Models\DailyStockRecord;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
class GoodsController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct(Request $request)
|
||||||
|
{
|
||||||
|
$this->log = new LogModel([
|
||||||
|
'module' => 'goods',
|
||||||
|
'action' => $request->getMethod(),
|
||||||
|
'target_type' => 'goods_sku',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$goods = Goods::query()->get(['id', 'title', 'img_url', 'type_id', 'brand_id', 'goods_code']);
|
||||||
|
|
||||||
|
return GoodsResource::collection($goods);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$goodsRules = (new GoodsRequest())->rules();
|
||||||
|
$skuRules = (new GoodsSkuRequest())->arrayRules('skus.*.');
|
||||||
|
$validator = Validator::make($request->all(), array_merge($goodsRules, ['skus' => ['required', 'array']], $skuRules));
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
DB::beginTransaction();
|
||||||
|
try {
|
||||||
|
if (!empty($request->goods_id)) {
|
||||||
|
$goods = Goods::query()->find($request->goods_id);
|
||||||
|
} else {
|
||||||
|
$goods = new Goods();
|
||||||
|
$goods->title = $request->title;
|
||||||
|
$goods->img_url = $request->img_url;
|
||||||
|
$goods->type_id = $request->type_id;
|
||||||
|
$goods->brand_id = $request->brand_id;
|
||||||
|
$goods->goods_code = $request->goods_code;
|
||||||
|
$goods->save();
|
||||||
|
}
|
||||||
|
$goodsSkus = [];
|
||||||
|
foreach ($request->skus as $item) {
|
||||||
|
$item['goods_id'] = $goods->id;
|
||||||
|
$item['reference_price'] = $item['cost'] * 1.5;
|
||||||
|
$goodsSkus[] = $item;
|
||||||
|
}
|
||||||
|
$collection = $goods->skus()->createMany($goodsSkus)->toArray();
|
||||||
|
$this->setAfterUpdate($collection);
|
||||||
|
$this->addLog(0, 'add');
|
||||||
|
$newRecords = [];
|
||||||
|
foreach ($collection as $sku) {
|
||||||
|
$newRecords[] = [
|
||||||
|
'sku_id' => $sku['id'],
|
||||||
|
'day' => FormatUtils::date(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$record = new DailyStockRecord();
|
||||||
|
$record->batchInsert($newRecords);
|
||||||
|
DB::commit();
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
DB::rollBack();
|
||||||
|
$this->res = [
|
||||||
|
'httpCode' => 400,
|
||||||
|
'errorCode' => 400416,
|
||||||
|
'errorMessage' => $exception->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function download()
|
||||||
|
{
|
||||||
|
return Storage::download(resource_path('templates/goods_skus_import.xlsx'));
|
||||||
|
}
|
||||||
|
}
|
||||||
350
app/Http/Controllers/Goods/GoodsSkusController.php
Normal file
350
app/Http/Controllers/Goods/GoodsSkusController.php
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Goods;
|
||||||
|
|
||||||
|
use App\Exports\GoodsSkusExport;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\GoodsRequest;
|
||||||
|
use App\Http\Requests\GoodsSkuRequest;
|
||||||
|
use App\Models\Goods;
|
||||||
|
use App\Models\Log;
|
||||||
|
use App\Models\Log as LogModel;
|
||||||
|
use App\Utils\FormatUtils;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\GoodsSku;
|
||||||
|
use App\Http\Resources\GoodsSkuResource;
|
||||||
|
use App\Imports\GoodsSkusImport;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
use App\Models\DailyStockRecord;
|
||||||
|
|
||||||
|
class GoodsSkusController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct(Request $request)
|
||||||
|
{
|
||||||
|
$this->log = new LogModel([
|
||||||
|
'module' => 'goods',
|
||||||
|
'action' => $request->getMethod(),
|
||||||
|
'target_type' => 'goods_sku',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$goods = Goods::query()->filter()->get()->toArray();
|
||||||
|
$goodsIds = array_column($goods, 'id');
|
||||||
|
// 状态变更时间查询,日志
|
||||||
|
$ids = [];
|
||||||
|
if ($request->get('keyword_type', '') && $request->get('keyword_value', '')) {
|
||||||
|
$ids = Log::query()->where('target_type', 'sku')
|
||||||
|
->where('target_field', $request->keyword_type)
|
||||||
|
->whereBetween('created_at', explode(' - ', $request->keyword_value))
|
||||||
|
->pluck('sku_id')
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
$day = FormatUtils::date();
|
||||||
|
$goodsSkus = GoodsSku::query()
|
||||||
|
->whereIn('goods_id', $goodsIds)
|
||||||
|
->when($ids, function ($query, $ids) {
|
||||||
|
return $query->whereIn('id', $ids);
|
||||||
|
})
|
||||||
|
->filter()
|
||||||
|
->with(['goods' => function ($query) {
|
||||||
|
$query->with(['type:id,name', 'brand:id,name']);
|
||||||
|
}])
|
||||||
|
->with(['daily' => function ($query) use ($day) {
|
||||||
|
return $query->where('day', $day)->first(['id', 'sku_id', 'day', 'arrived_today_num', 'loss_num', 'inventory']);
|
||||||
|
}])
|
||||||
|
->paginate();
|
||||||
|
|
||||||
|
return GoodsSkuResource::collection($goodsSkus);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
return new GoodsSkuResource(GoodsSku::query()
|
||||||
|
->with(['goods' => function ($query) {
|
||||||
|
$query->with(['type:id,name', 'brand:id,name']);
|
||||||
|
}])
|
||||||
|
->find($id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update($id, Request $request)
|
||||||
|
{
|
||||||
|
$goodsRules = (new GoodsRequest())->arrayRules('goods.');
|
||||||
|
$skuRules = (new GoodsSkuRequest())->arrayRules('sku.');
|
||||||
|
$validator = Validator::make($request->all(), array_merge($goodsRules, $skuRules));
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
DB::beginTransaction();
|
||||||
|
try {
|
||||||
|
// 商品规格更新
|
||||||
|
$sku = GoodsSku::query()->find($id);
|
||||||
|
$this->setBeforeUpdate($sku->toArray());
|
||||||
|
$sku->update($request->sku);
|
||||||
|
$this->setAfterUpdate($sku->toArray());
|
||||||
|
$this->addLog($id, 'update');
|
||||||
|
// 商品更新
|
||||||
|
$goods = Goods::query()->find($sku->goods_id);
|
||||||
|
$this->setBeforeUpdate($goods->toArray());
|
||||||
|
$goods->update($request->goods);
|
||||||
|
$this->setAfterUpdate($goods->toArray());
|
||||||
|
$this->addLog($sku->goods_id, 'update', 'goods');
|
||||||
|
DB::commit();
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
DB::rollBack();
|
||||||
|
$this->res = [
|
||||||
|
'httpCode' => 400,
|
||||||
|
'errorCode' => 400416,
|
||||||
|
'errorMessage' => $exception->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function batchUpdate(Request $request)
|
||||||
|
{
|
||||||
|
$appendRules = [
|
||||||
|
'updateType' => ['required', 'string', Rule::in(['newest', 'inventory', 'stock'])],
|
||||||
|
'skus' => ['required', 'array'],
|
||||||
|
'skus.*.id' => [
|
||||||
|
'required',
|
||||||
|
Rule::exists('goods_skus', 'id'),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$validator = $this->validateUpdate($request->all(), $appendRules);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$function = $request->updateType;
|
||||||
|
|
||||||
|
return $this->$function($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function newest($request)
|
||||||
|
{
|
||||||
|
DB::beginTransaction();
|
||||||
|
try {
|
||||||
|
$logs = [];
|
||||||
|
foreach ($request->skus as $sku) {
|
||||||
|
$costLog = $arrivedLog = [
|
||||||
|
'module' => 'goods',
|
||||||
|
'action' => $request->getMethod(),
|
||||||
|
'target_type' => 'goods_sku',
|
||||||
|
'target_id' => $sku['id'],
|
||||||
|
'user_id' => $request->user()->id
|
||||||
|
];
|
||||||
|
// 成本
|
||||||
|
$goodsSku = GoodsSku::query()->where('id', $sku['id'])->first(['id', 'cost', 'stock', 'num']);
|
||||||
|
$costLog['target_field'] = 'cost';
|
||||||
|
$costLog['before_update'] = $goodsSku->cost;
|
||||||
|
$goodsSku->cost = $sku['cost'];
|
||||||
|
$goodsSku->reference_price = $sku['cost'] * 1.5;
|
||||||
|
$goodsSku->stock += $sku['arrived_today_num'];
|
||||||
|
$goodsSku->num += $sku['arrived_today_num'];
|
||||||
|
$goodsSku->save();
|
||||||
|
$costLog['after_update'] = $goodsSku->cost;
|
||||||
|
$logs[] = $costLog;
|
||||||
|
// 今日到货
|
||||||
|
$record = DailyStockRecord::query()->where('sku_id', $sku['id'])->where('day', FormatUtils::date())->first(['id', 'arrived_today_num']);
|
||||||
|
$arrivedLog['target_field'] = 'arrived_today_num';
|
||||||
|
$arrivedLog['before_update'] = $record->arrived_today_num;
|
||||||
|
$record->arrived_today_num += $sku['arrived_today_num'];
|
||||||
|
$record->save();
|
||||||
|
$arrivedLog['after_update'] = $record->arrived_today_num;
|
||||||
|
$logs[] = $arrivedLog;
|
||||||
|
}
|
||||||
|
$log = new LogModel();
|
||||||
|
$log->batchInsert($logs);
|
||||||
|
DB::commit();
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
DB::rollBack();
|
||||||
|
$this->res = [
|
||||||
|
'httpCode' => 400,
|
||||||
|
'errorCode' => 400500,
|
||||||
|
'errorMessage' => $exception->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function inventory($request)
|
||||||
|
{
|
||||||
|
DB::beginTransaction();
|
||||||
|
try {
|
||||||
|
$logs = [];
|
||||||
|
foreach ($request->skus as $sku) {
|
||||||
|
$inventoryLog = [
|
||||||
|
'module' => 'goods',
|
||||||
|
'action' => $request->getMethod(),
|
||||||
|
'target_type' => 'goods_sku',
|
||||||
|
'target_id' => $sku['id'],
|
||||||
|
'user_id' => $request->user()->id
|
||||||
|
];
|
||||||
|
// 今日到货
|
||||||
|
$record = DailyStockRecord::query()->where('sku_id', $sku['id'])->where('day', FormatUtils::date())->first(['id', 'inventory']);
|
||||||
|
$inventoryLog['target_field'] = 'inventory';
|
||||||
|
$inventoryLog['before_update'] = $record->inventory;
|
||||||
|
$record->inventory = $sku['inventory'];
|
||||||
|
$record->save();
|
||||||
|
$inventoryLog['after_update'] = $record->inventory;
|
||||||
|
$logs[] = $inventoryLog;
|
||||||
|
}
|
||||||
|
$log = new LogModel();
|
||||||
|
$log->batchInsert($logs);
|
||||||
|
DB::commit();
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
DB::rollBack();
|
||||||
|
$this->res = [
|
||||||
|
'httpCode' => 400,
|
||||||
|
'errorCode' => 400500,
|
||||||
|
'errorMessage' => $exception->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function stock($skus)
|
||||||
|
{
|
||||||
|
$update = reset($skus);
|
||||||
|
DB::beginTransaction();
|
||||||
|
try {
|
||||||
|
$sku = GoodsSku::query()->where('id', $update['id'])->get(['id', 'two_days_ago_num', 'yesterday_num', 'num', 'stock']);
|
||||||
|
$record = DailyStockRecord::query()
|
||||||
|
->where('sku_id', $sku->id)
|
||||||
|
->where('day', FormatUtils::date())
|
||||||
|
->first();
|
||||||
|
$this->setBeforeUpdate([
|
||||||
|
'two_days_ago_num' => $sku->two_days_ago_num,
|
||||||
|
'yesterday_num' => $sku->yesterday_num,
|
||||||
|
'num' => $sku->num,
|
||||||
|
'arrived_today_num' => $record->arrived_today_num,
|
||||||
|
]);
|
||||||
|
$sku->two_days_ago_num = $update['two_days_ago_num'];
|
||||||
|
$sku->yesterday_num = $update['yesterday_num'];
|
||||||
|
$sku->num = $update['two_days_ago_num'] + $update['yesterday_num'] + $sku->stock;
|
||||||
|
$sku->save();
|
||||||
|
$record->arrived_today_num = $update['arrived_today_num'];
|
||||||
|
$record->save();
|
||||||
|
$this->setAfterUpdate([
|
||||||
|
'two_days_ago_num' => $sku->two_days_ago_num,
|
||||||
|
'yesterday_num' => $sku->yesterday_num,
|
||||||
|
'arrived_today_num' => $record->arrived_today_num,
|
||||||
|
]);
|
||||||
|
$this->addLog($sku->id, 'stock');
|
||||||
|
DB::commit();
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
DB::rollBack();
|
||||||
|
$this->res = [
|
||||||
|
'httpCode' => 400,
|
||||||
|
'errorCode' => 400416,
|
||||||
|
'errorMessage' => $exception->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateField($id, Request $request)
|
||||||
|
{
|
||||||
|
$rules = [
|
||||||
|
'updateField' => [
|
||||||
|
'required',
|
||||||
|
Rule::in(['reference_price', 'reserve', 'loss_num', 'status'])
|
||||||
|
],
|
||||||
|
'reference_price' => [
|
||||||
|
'sometimes',
|
||||||
|
'numeric',
|
||||||
|
'gt:0'
|
||||||
|
],
|
||||||
|
'reserve' => [
|
||||||
|
'sometimes',
|
||||||
|
'integer',
|
||||||
|
],
|
||||||
|
'loss_num' => [
|
||||||
|
'sometimes',
|
||||||
|
'integer',
|
||||||
|
],
|
||||||
|
'reason' => [
|
||||||
|
'sometimes',
|
||||||
|
'required',
|
||||||
|
'string'
|
||||||
|
],
|
||||||
|
'status' => [
|
||||||
|
'sometimes',
|
||||||
|
'required',
|
||||||
|
'integer',
|
||||||
|
Rule::in([0, 1, 2])],
|
||||||
|
];
|
||||||
|
$validator = Validator::make($request->all(), $rules);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$updateField = \request('updateField');
|
||||||
|
if ('loss_num' === $updateField) {
|
||||||
|
$model = DailyStockRecord::query()
|
||||||
|
->where('sku_id', $id)
|
||||||
|
->where('day', FormatUtils::date())
|
||||||
|
->first(['id', 'loss_num']);
|
||||||
|
$this->log->message = $request->get('reason');
|
||||||
|
$this->setBeforeUpdate($model->loss_num);
|
||||||
|
$model->loss_num += $request->loss_num;
|
||||||
|
} else {
|
||||||
|
$model = GoodsSku::query()->find($id);
|
||||||
|
$this->setBeforeUpdate($model->$updateField);
|
||||||
|
if ('reserve' === $updateField) {
|
||||||
|
$changeNum = $model->reserve - $request->reserve;
|
||||||
|
$model->stock += $changeNum;
|
||||||
|
$model->reserve = $request->reserve;
|
||||||
|
$model->num += $changeNum;
|
||||||
|
} else {
|
||||||
|
$model->$updateField = $request->$updateField;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$model->save();
|
||||||
|
$this->setAfterUpdate($model->$updateField);
|
||||||
|
$this->addLog($id, $updateField);
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
if (!$request->hasFile('goodsSkus')) {
|
||||||
|
$this->res = [
|
||||||
|
'httpCode' => 404,
|
||||||
|
'errorCode' => 404404,
|
||||||
|
'errorMessage' => 'not found goodsSkus file',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$collection = Excel::import(new GoodsSkusImport(), $request->file('goodsSkus'));
|
||||||
|
$this->setAfterUpdate($collection->toArray());
|
||||||
|
$this->addLog(0, 'import');
|
||||||
|
} catch (ValidationException $exception) {
|
||||||
|
$this->setValidatorFailResponse($exception->validator->getMessageBag()->getMessages());
|
||||||
|
}
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function export(Request $request)
|
||||||
|
{
|
||||||
|
$type = $request->get('exportType');
|
||||||
|
ob_end_clean();
|
||||||
|
return Excel::download(new GoodsSkusExport($type), $type, '.xlsx');
|
||||||
|
}
|
||||||
|
}
|
||||||
98
app/Http/Controllers/Goods/GoodsTypesController.php
Normal file
98
app/Http/Controllers/Goods/GoodsTypesController.php
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Goods;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Resources\GoodsTypeResource;
|
||||||
|
use App\Models\GoodsType;
|
||||||
|
use App\Models\Log as LogModel;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
|
class GoodsTypesController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct(Request $request)
|
||||||
|
{
|
||||||
|
$this->log = new LogModel([
|
||||||
|
'module' => 'goods',
|
||||||
|
'action' => $request->getMethod(),
|
||||||
|
'target_type' => 'goods_type',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$goodsTypes = GoodsType::query()->paginate();
|
||||||
|
|
||||||
|
return GoodsTypeResource::collection($goodsTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'names' => 'required|array',
|
||||||
|
'names.*' => 'required|string|max:255|unique:goods_types,name',
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$goodsTypes = [];
|
||||||
|
foreach ($request->names as $name) {
|
||||||
|
$goodsTypes[] = ['name' => $name];
|
||||||
|
}
|
||||||
|
$goodsType = new GoodsType();
|
||||||
|
if (!$goodsType->batchInsert($goodsTypes)) {
|
||||||
|
$this->res = [
|
||||||
|
'httpCode' => 500,
|
||||||
|
'errorCode' => 500500,
|
||||||
|
'errorMessage' => '批量添加失败',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$this->setAfterUpdate($goodsTypes);
|
||||||
|
$this->addLog(0, 'add');
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
return new GoodsTypeResource(GoodsType::query()->find($id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update($id, Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'name' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'max:255',
|
||||||
|
Rule::unique('goods_types')->ignore($id),
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$goodsType = GoodsType::query()->find($id);
|
||||||
|
$this->setBeforeUpdate($goodsType->name);
|
||||||
|
$goodsType->name = request('name');
|
||||||
|
$goodsType->save();
|
||||||
|
$this->setAfterUpdate($goodsType->name);
|
||||||
|
$this->addLog($id, 'name');
|
||||||
|
|
||||||
|
return new GoodsTypeResource($goodsType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
$goodsType = GoodsType::query()->find($id);
|
||||||
|
$goodsType->delete();
|
||||||
|
$this->addLog($id, 'status');
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
21
app/Http/Controllers/Log/LogsController.php
Normal file
21
app/Http/Controllers/Log/LogsController.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Log;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\Log;
|
||||||
|
use App\Http\Resources\LogsResource;
|
||||||
|
|
||||||
|
class LogsController extends Controller
|
||||||
|
{
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$res = Log::query()
|
||||||
|
->with(['user:id,name'])
|
||||||
|
->filter()
|
||||||
|
->paginate();
|
||||||
|
|
||||||
|
return LogsResource::collection($res);
|
||||||
|
}
|
||||||
|
}
|
||||||
114
app/Http/Controllers/Menu/MenusController.php
Normal file
114
app/Http/Controllers/Menu/MenusController.php
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Menu;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Log as LogModel;
|
||||||
|
use App\Models\Menu;
|
||||||
|
use App\Http\Resources\MenusResource;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Utils\ArrayUtils;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
use App\Utils\FormatUtils;
|
||||||
|
|
||||||
|
class MenusController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct(Request $request)
|
||||||
|
{
|
||||||
|
$this->log = new LogModel([
|
||||||
|
'module' => 'menu',
|
||||||
|
'action' => $request->getMethod(),
|
||||||
|
'target_type' => 'menu',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$permissions = $request->user()->getPermissionsViaRoles()->toArray();
|
||||||
|
$permissions = array_column($permissions, 'name');
|
||||||
|
$menus = Menu::query()->get()->toArray();
|
||||||
|
$hasPermissionMenus = [];
|
||||||
|
foreach ($menus as $menu) {
|
||||||
|
if (in_array($menu['code'], $permissions, true)) {
|
||||||
|
$hasPermissionMenus[] = $menu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$menus = FormatUtils::formatTreeData($hasPermissionMenus, 0);
|
||||||
|
|
||||||
|
return MenusResource::collection($menus);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'name' => 'required|string|max:32',
|
||||||
|
'code' => 'required|string|max:32|unique:menus,code',
|
||||||
|
'parent_id' => 'required|integer',
|
||||||
|
'seq' => 'required|integer',
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$menu = new Menu();
|
||||||
|
$menu->name = $request->name;
|
||||||
|
$menu->code = $request->code;
|
||||||
|
$menu->parent_id = $request->parent_id;
|
||||||
|
$menu->seq = $request->seq;
|
||||||
|
$menu->save();
|
||||||
|
$this->setAfterUpdate($menu->toArray());
|
||||||
|
$this->addLog($menu->id, 'add');
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
return new MenusResource(Menu::query()->find($id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update($id, Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'name' => ['required', 'string', 'max:32',],
|
||||||
|
'code' => ['required', 'string', 'max:32', Rule::unique('menus')->ignore($id),],
|
||||||
|
'parent_id' => ['required', 'integer',],
|
||||||
|
'seq' => ['required', 'integer',],
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$menu = Menu::query()->find($id);
|
||||||
|
$this->setBeforeUpdate($menu->toArray());
|
||||||
|
$menu->name = $request->name;
|
||||||
|
$menu->code = $request->code;
|
||||||
|
$menu->parent_id = $request->parent_id;
|
||||||
|
$menu->seq = $request->seq;
|
||||||
|
$menu->save();
|
||||||
|
$this->setAfterUpdate($menu->toArray());
|
||||||
|
$this->addLog($id, 'update');
|
||||||
|
|
||||||
|
return new MenusResource($menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
$menu = Menu::query()->find($id);
|
||||||
|
try {
|
||||||
|
$menu->delete();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->res = [
|
||||||
|
'httpCode' => 500,
|
||||||
|
'errorCode' => 500416,
|
||||||
|
'errorMessage' => $e->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
82
app/Http/Controllers/Permission/PermissionsController.php
Normal file
82
app/Http/Controllers/Permission/PermissionsController.php
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Permission;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Log as LogModel;
|
||||||
|
use App\Utils\ArrayUtils;
|
||||||
|
use App\Utils\FormatUtils;
|
||||||
|
use Spatie\Permission\Models\Permission;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
use App\Http\Resources\PermissionsResource;
|
||||||
|
|
||||||
|
class PermissionsController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct(Request $request)
|
||||||
|
{
|
||||||
|
$this->log = new LogModel([
|
||||||
|
'module' => 'permission',
|
||||||
|
'action' => $request->getMethod(),
|
||||||
|
'target_type' => 'permission',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$permissions = Permission::query()->get()->toArray();
|
||||||
|
$permissions = ArrayUtils::index($permissions, 'name');
|
||||||
|
$routes = include(resource_path('lang/zh-CN/permission.php'));
|
||||||
|
foreach ($routes as $key => &$route) {
|
||||||
|
$route['id'] = $permissions[$key]['id'];
|
||||||
|
}
|
||||||
|
$routes = FormatUtils::formatTreeData($routes, 0);
|
||||||
|
|
||||||
|
return PermissionsResource::collection($routes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'name' => 'required|string|max:255|unique:permissions,name',
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$permission = new Permission();
|
||||||
|
$permission->name = $request->name;
|
||||||
|
$permission->save();
|
||||||
|
$this->setAfterUpdate($permission->name);
|
||||||
|
$this->addLog($permission->id, 'add');
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
return new PermissionsResource(Permission::query()->find($id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update($id, Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'name' => ['required', 'string', 'max:255', Rule::unique('permissions')->ignore($id),]
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$permission = Permission::query()->find($id);
|
||||||
|
$this->setBeforeUpdate($permission->name);
|
||||||
|
$permission->name = $request->name;
|
||||||
|
$permission->save();
|
||||||
|
$this->setAfterUpdate($permission->name);
|
||||||
|
$this->addLog($id, 'name');
|
||||||
|
|
||||||
|
return new PermissionsResource($permission);
|
||||||
|
}
|
||||||
|
}
|
||||||
94
app/Http/Controllers/Role/RolesController.php
Normal file
94
app/Http/Controllers/Role/RolesController.php
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Role;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Log as LogModel;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
use Spatie\Permission\Models\Permission;
|
||||||
|
use Spatie\Permission\Models\Role;
|
||||||
|
use App\Http\Resources\RolesResource;
|
||||||
|
|
||||||
|
class RolesController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct(Request $request)
|
||||||
|
{
|
||||||
|
$this->log = new LogModel([
|
||||||
|
'module' => 'role',
|
||||||
|
'action' => $request->getMethod(),
|
||||||
|
'target_type' => 'role',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$roles = Role::query()->with('permissions')->get()->toArray();
|
||||||
|
$routes = include(resource_path('lang/zh-CN/permission.php'));
|
||||||
|
foreach ($roles as &$role) {
|
||||||
|
$permissions = [];
|
||||||
|
foreach ($role['permissions'] as $item) {
|
||||||
|
$permissions[] = $routes[$item['name']]['name'];
|
||||||
|
}
|
||||||
|
$role['permissions'] = $permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RolesResource::collection($roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'name' => 'required|string|max:255|unique:roles,name',
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$role = new Role();
|
||||||
|
$role->name = $request->name;
|
||||||
|
$role->save();
|
||||||
|
$this->setAfterUpdate($role->name);
|
||||||
|
$this->addLog($role->id, 'add');
|
||||||
|
|
||||||
|
return new RolesResource($role);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addPermissions($id, Request $request)
|
||||||
|
{
|
||||||
|
$role = Role::query()->findOrFail($id);
|
||||||
|
$permissions = Permission::query()->findOrFail($request->permissionIds);
|
||||||
|
$role->syncPermissions($permissions);
|
||||||
|
$this->setAfterUpdate($permissions->toArray());
|
||||||
|
$this->addLog($id, 'set', 'permission');
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
return new RolesResource(Role::query()->find($id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update($id, Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'name' => ['required', 'string', 'max:255', Rule::unique('roles')->ignore($id),]
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$role = Role::query()->find($id);
|
||||||
|
$this->setBeforeUpdate($role->name);
|
||||||
|
$role->name = $request->name;
|
||||||
|
$role->save();
|
||||||
|
$this->setAfterUpdate($role->name);
|
||||||
|
$this->addLog($id, 'name');
|
||||||
|
|
||||||
|
return new RolesResource($role);
|
||||||
|
}
|
||||||
|
}
|
||||||
99
app/Http/Controllers/Shop/ShopsController.php
Normal file
99
app/Http/Controllers/Shop/ShopsController.php
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Shop;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Listeners\BindBusinessGoods;
|
||||||
|
use App\Listeners\UpdateBusinessGoodsStock;
|
||||||
|
use App\Models\Shop;
|
||||||
|
use App\Http\Resources\ShopsResource;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use App\Services\Business\BusinessFactory;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
|
class ShopsController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$shops = Shop::query()->paginate();
|
||||||
|
foreach ($shops as $shop) {
|
||||||
|
$shop->authUrl = '';
|
||||||
|
if ('妙选' !== $shop->plat_id && '未授权' === $shop->status) {
|
||||||
|
$shop->authUrl = BusinessFactory::init()->make($shop->plat_id)->getAuthUrl($shop->id, $shop->getOriginal('plat_id'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ShopsResource::collection($shops);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPlatList()
|
||||||
|
{
|
||||||
|
$shop = new Shop();
|
||||||
|
|
||||||
|
return new ShopsResource($shop->getPlatList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'name' => 'required|string|max:255|unique:shops,name',
|
||||||
|
'plat_id' => 'required|integer',
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$shop = new Shop();
|
||||||
|
$shop->name = $request->name;
|
||||||
|
$shop->plat_id = $request->plat_id;
|
||||||
|
$shop->save();
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function authBind(Request $request)
|
||||||
|
{
|
||||||
|
[$shopId, $platId] = explode('_', $request->get('state'));
|
||||||
|
$shop = new Shop();
|
||||||
|
$platList = $shop->getPlatList();
|
||||||
|
$shop = $shop->find($shopId);
|
||||||
|
if ($platList[$platId] === $shop->plat_id) {
|
||||||
|
BusinessFactory::init()->make($shop->plat_id)->authCallback($request->get('code'), $shop->id);
|
||||||
|
} else {
|
||||||
|
$this->res = [
|
||||||
|
'httpCode' => 403,
|
||||||
|
'errorCode' => 403400,
|
||||||
|
'errorMessage' => '信息不匹配',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function business(Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'type' => ['required', 'string', Rule::in(['goods', 'orders'])],
|
||||||
|
'erp_shop_id' => ['required', 'integer', 'exists:shops,id'],
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$shop = new Shop();
|
||||||
|
$shop = $shop->find($request->get('erp_shop_id'));
|
||||||
|
$business = BusinessFactory::init()->make($shop->plat_id);
|
||||||
|
$business->setShop($shop);
|
||||||
|
if ('goods' === $request->get('type')) {
|
||||||
|
$business->bindGoods($request->get('data'));
|
||||||
|
event(new BindBusinessGoods($shop));
|
||||||
|
}
|
||||||
|
if ('orders' === $request->get('type')) {
|
||||||
|
$business->saveOrders();
|
||||||
|
event(new UpdateBusinessGoodsStock($shop));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
34
app/Http/Controllers/UploadController.php
Normal file
34
app/Http/Controllers/UploadController.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Log as LogModel;
|
||||||
|
use App\Utils\UploadUtils;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class UploadController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct(Request $request)
|
||||||
|
{
|
||||||
|
$this->log = new LogModel([
|
||||||
|
'module' => 'file',
|
||||||
|
'action' => $request->getMethod(),
|
||||||
|
'target_type' => 'upload',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
if (!$request->hasFile('uploadFile')) {
|
||||||
|
$this->res = [
|
||||||
|
'httpCode' => 404,
|
||||||
|
'errorCode' => 404404,
|
||||||
|
'errorMessage' => 'not found file',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$this->addLog(0, 'add');
|
||||||
|
$this->res['resource'] = UploadUtils::putForUploadedFile('image', $request->uploadFile);
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
108
app/Http/Controllers/User/UsersController.php
Normal file
108
app/Http/Controllers/User/UsersController.php
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\User;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Log as LogModel;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Faker\Generator as Faker;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use App\Http\Resources\UsersResource;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
|
class UsersController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct(Request $request)
|
||||||
|
{
|
||||||
|
$this->log = new LogModel([
|
||||||
|
'module' => 'user',
|
||||||
|
'action' => $request->getMethod(),
|
||||||
|
'target_type' => 'user',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$users = User::query()->where('id', '<>', 1)->with('roles:id,name,guard_name')->paginate();
|
||||||
|
|
||||||
|
return UsersResource::collection($users);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request, Faker $faker)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'name' => 'required|string|max:255|unique:users,name',
|
||||||
|
'password' => 'required|string|min:8|confirmed',
|
||||||
|
'email' => 'email',
|
||||||
|
'role_name' => 'required|string|exists:roles,name'
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$user = new User();
|
||||||
|
$user->name = $request->name;
|
||||||
|
$user->email = \request('email', $faker->unique()->safeEmail);
|
||||||
|
$user->password = $request->password;
|
||||||
|
$user->api_token = Str::random(60);
|
||||||
|
$user->save();
|
||||||
|
$this->setAfterUpdate($user->toArray());
|
||||||
|
$this->addLog($user->id, 'add');
|
||||||
|
$user->assignRole($request->role_name);
|
||||||
|
|
||||||
|
return new UsersResource($user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
return new UsersResource(User::query()->with('roles:id,name,guard_name')->find($id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update($id, Request $request)
|
||||||
|
{
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'name' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'max:255',
|
||||||
|
Rule::unique('users')->ignore($id),
|
||||||
|
],
|
||||||
|
// 'old_password' => 'sometimes|required|string|min:8',
|
||||||
|
'password' => 'sometimes|string|min:8|confirmed',
|
||||||
|
'email' => 'sometimes|email',
|
||||||
|
'role_name' => 'sometimes|required|string|exists:roles,name'
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
$user = User::query()->find($id);
|
||||||
|
$user->update($request->toArray());
|
||||||
|
if ($request->has('role_name')) {
|
||||||
|
$user->syncRoles($request->role_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UsersResource($user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destory($id)
|
||||||
|
{
|
||||||
|
$user = User::query()->find($id);
|
||||||
|
try {
|
||||||
|
$user->delete();
|
||||||
|
$this->addLog($id, 'status');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->res = [
|
||||||
|
'httpCode' => 500,
|
||||||
|
'errorCode' => 500416,
|
||||||
|
'errorMessage' => $e->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return response($this->res, $this->res['httpCode']);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -61,6 +61,9 @@ class Kernel extends HttpKernel
|
|||||||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||||
|
'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
|
||||||
|
'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
|
||||||
|
'check.permissions' => \App\Http\Middleware\CheckPermissions::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
38
app/Http/Middleware/CheckPermissions.php
Normal file
38
app/Http/Middleware/CheckPermissions.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
|
class CheckPermissions
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \Closure $next
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle($request, Closure $next)
|
||||||
|
{
|
||||||
|
// 获取当前路由名称
|
||||||
|
$currentRouteName = Route::currentRouteName();
|
||||||
|
// 引入当前守卫的权限文件
|
||||||
|
$routes = include(resource_path('lang/zh-CN/permission.php'));
|
||||||
|
if (is_array($routes) && array_key_exists($currentRouteName, $routes)) {
|
||||||
|
$permissions = $request->user()->getPermissionsViaRoles()->toArray();
|
||||||
|
$permissions = array_column($permissions, 'name');
|
||||||
|
if (in_array($currentRouteName, $permissions, true)) {
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$res = [
|
||||||
|
'httpCode' => 403,
|
||||||
|
'errorCode' => 403403,
|
||||||
|
'errorMessage' => '您没有使用此功能的权限' . $currentRouteName,
|
||||||
|
];
|
||||||
|
return response($res, 403);
|
||||||
|
}
|
||||||
|
}
|
||||||
47
app/Http/Requests/GoodsRequest.php
Normal file
47
app/Http/Requests/GoodsRequest.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
|
class GoodsRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => ['sometimes', 'required', 'integer', 'exists:goods,id'],
|
||||||
|
'title' => ['required', 'string', 'max:255'],
|
||||||
|
'img_url' => ['required', 'string', 'max:255'],
|
||||||
|
'type_id' => ['required', 'integer', 'exists:goods_types,id'],
|
||||||
|
'brand_id' => ['integer', 'exists:goods_brands,id'],
|
||||||
|
'goods_code' => ['required', 'alpha_dash', 'max:32', Rule::unique('goods')->ignore(request('goods_id'))],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function arrayRules($arrayName)
|
||||||
|
{
|
||||||
|
$arrayRules = [];
|
||||||
|
$rules = $this->rules();
|
||||||
|
foreach ($rules as $key => $val) {
|
||||||
|
$arrayRules[$arrayName . $key] = $val;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $arrayRules;
|
||||||
|
}
|
||||||
|
}
|
||||||
65
app/Http/Requests/GoodsSkuRequest.php
Normal file
65
app/Http/Requests/GoodsSkuRequest.php
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
|
class GoodsSkuRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => ['sometimes', 'required', 'integer', 'exists:goods_skus,id'],
|
||||||
|
'goods_id' => ['sometimes', 'required', 'integer', 'exists:goods,id'],
|
||||||
|
'title' => ['required', 'string', 'max:255'],
|
||||||
|
'sku_code' => ['required', 'distinct', 'alpha_dash', 'max:32'],
|
||||||
|
'status' => ['required', 'integer', Rule::in([0, 1, 2])],
|
||||||
|
'num' => ['required', 'integer'],
|
||||||
|
'cost' => ['required', 'numeric'],
|
||||||
|
'reference_price' => [
|
||||||
|
'sometimes',
|
||||||
|
'numeric',
|
||||||
|
'gt:0'
|
||||||
|
],
|
||||||
|
'reserve' => [
|
||||||
|
'sometimes',
|
||||||
|
'integer',
|
||||||
|
],
|
||||||
|
'loss_num' => [
|
||||||
|
'sometimes',
|
||||||
|
'integer',
|
||||||
|
],
|
||||||
|
'inventory' => [
|
||||||
|
'sometimes',
|
||||||
|
'integer',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function arrayRules($arrayName)
|
||||||
|
{
|
||||||
|
$arrayRules = [];
|
||||||
|
$rules = $this->rules();
|
||||||
|
foreach ($rules as $key => $val) {
|
||||||
|
$arrayRules[$arrayName . $key] = $val;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $arrayRules;
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/Http/Resources/GoodsBrandResource.php
Normal file
19
app/Http/Resources/GoodsBrandResource.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class GoodsBrandResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return parent::toArray($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/Http/Resources/GoodsResource.php
Normal file
19
app/Http/Resources/GoodsResource.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class GoodsResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return parent::toArray($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/Http/Resources/GoodsSkuResource.php
Normal file
19
app/Http/Resources/GoodsSkuResource.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class GoodsSkuResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return parent::toArray($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/Http/Resources/GoodsTypeResource.php
Normal file
19
app/Http/Resources/GoodsTypeResource.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class GoodsTypeResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return parent::toArray($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/Http/Resources/LogsResource.php
Normal file
19
app/Http/Resources/LogsResource.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class LogsResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return parent::toArray($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/Http/Resources/MenusResource.php
Normal file
19
app/Http/Resources/MenusResource.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class MenusResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return parent::toArray($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/Http/Resources/PermissionsResource.php
Normal file
19
app/Http/Resources/PermissionsResource.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class PermissionsResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return parent::toArray($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/Http/Resources/RolesResource.php
Normal file
19
app/Http/Resources/RolesResource.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class RolesResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return parent::toArray($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/Http/Resources/ShopsResource.php
Normal file
19
app/Http/Resources/ShopsResource.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class ShopsResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return parent::toArray($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/Http/Resources/UsersResource.php
Normal file
19
app/Http/Resources/UsersResource.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class UsersResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return parent::toArray($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
91
app/Imports/GoodsSkusImport.php
Normal file
91
app/Imports/GoodsSkusImport.php
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Imports;
|
||||||
|
|
||||||
|
use App\Models\Goods;
|
||||||
|
use App\Models\GoodsBrand;
|
||||||
|
use App\Models\GoodsSku;
|
||||||
|
use App\Models\GoodsType;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
|
||||||
|
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use App\Utils\ArrayUtils;
|
||||||
|
|
||||||
|
class GoodsSkusImport implements ToCollection, SkipsEmptyRows
|
||||||
|
{
|
||||||
|
private $statusMap = [
|
||||||
|
'下架' => 0,
|
||||||
|
'在售' => 1,
|
||||||
|
'预警' => 2,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ValidationException
|
||||||
|
*/
|
||||||
|
public function collection(Collection $collection)
|
||||||
|
{
|
||||||
|
unset($collection[0], $collection[1]);
|
||||||
|
$arr = $collection->toArray();
|
||||||
|
$validator = Validator::make($arr, [
|
||||||
|
'*.0' => ['required', 'string', 'max:255'],
|
||||||
|
'*.1' => ['required', 'string', 'max:255', 'exists:goods_types,name'],
|
||||||
|
'*.2' => ['string', 'max:255', 'exists:goods_brands,name'],
|
||||||
|
'*.3' => ['required', 'alpha_dash', 'max:32', 'unique:goods,goods_code'],
|
||||||
|
'*.4' => ['required', 'string', 'max:255'],
|
||||||
|
'*.5' => ['required', 'distinct', 'alpha_dash', 'max:32'],
|
||||||
|
'*.6' => ['required', 'string', Rule::in(['下架', '在售', '预警'])],
|
||||||
|
'*.7' => ['required', 'max:10'],
|
||||||
|
'*.8' => ['required', 'max:10'],
|
||||||
|
]);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
throw new ValidationException($validator);
|
||||||
|
}
|
||||||
|
$types = array_column($arr, 1);
|
||||||
|
$types = GoodsType::query()->whereIn('name', $types)->get(['id', 'name'])->toArray();
|
||||||
|
$types = ArrayUtils::index($types, 'name');
|
||||||
|
$brands = array_column($arr, 2);
|
||||||
|
$brands = GoodsBrand::query()->whereIn('name', $brands)->get(['id', 'name'])->toArray();
|
||||||
|
$brands = ArrayUtils::index($brands, 'name');
|
||||||
|
$goodsCodes = array_column($arr, 3);
|
||||||
|
$hasGoods = Goods::query()->whereIn('goods_code', $goodsCodes)->get(['id', 'goods_code'])->toArray();
|
||||||
|
$hasGoods = ArrayUtils::index($hasGoods, 'goods_code');
|
||||||
|
$newGoods = $skus = [];
|
||||||
|
foreach ($arr as $item) {
|
||||||
|
$sku = [
|
||||||
|
'goods_id' => $item[3],
|
||||||
|
'title' => $item[4],
|
||||||
|
'sku_code' => $item[5],
|
||||||
|
'status' => $this->statusMap[$item[6]],
|
||||||
|
'num' => $item[7],
|
||||||
|
'cost' => $item[8],
|
||||||
|
];
|
||||||
|
// 主商品已存在
|
||||||
|
if (isset($hasGoods[$item[3]])) {
|
||||||
|
$sku['goods_id'] = $hasGoods[$item[3]]['id'];
|
||||||
|
} else {
|
||||||
|
// 新商品
|
||||||
|
$newGoods[$item[3]] = [
|
||||||
|
'title' => $item[0],
|
||||||
|
'type_id' => $types[$item[1]]['id'],
|
||||||
|
'brand_id' => $brands[$item[2]]['id'],
|
||||||
|
'goods_code' => $item[3],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$skus[] = $sku;
|
||||||
|
}
|
||||||
|
if ($newGoods) {
|
||||||
|
$goods = new Goods();
|
||||||
|
$goods->batchInsert(array_values($newGoods));
|
||||||
|
$hasGoods = Goods::query()->whereIn('goods_code', array_column($newGoods, 'goods_code'))->get(['id', 'goods_code'])->toArray();
|
||||||
|
$hasGoods = ArrayUtils::index($hasGoods, 'goods_code');
|
||||||
|
foreach ($skus as &$sku) {
|
||||||
|
$sku['goods_id'] = isset($hasGoods[$sku['goods_id']]) ? $hasGoods[$sku['goods_id']]['id'] : $sku['goods_id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$goodsSku = new GoodsSku();
|
||||||
|
$goodsSku->batchInsert(array_values($skus));
|
||||||
|
}
|
||||||
|
}
|
||||||
34
app/Listeners/BindBusinessGoods.php
Normal file
34
app/Listeners/BindBusinessGoods.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Listeners;
|
||||||
|
|
||||||
|
use App\Models\Shop;
|
||||||
|
use Illuminate\Auth\Events\Registered;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
|
||||||
|
class BindBusinessGoods
|
||||||
|
{
|
||||||
|
protected $shop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the event listener.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(Shop $shop)
|
||||||
|
{
|
||||||
|
$this->shop = $shop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the event.
|
||||||
|
*
|
||||||
|
* @param Registered $event
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle(Registered $event)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
31
app/Listeners/SendDatabaseNotification.php
Normal file
31
app/Listeners/SendDatabaseNotification.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Listeners;
|
||||||
|
|
||||||
|
use Illuminate\Auth\Events\Registered;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
|
||||||
|
class SendDatabaseNotification
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create the event listener.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the event.
|
||||||
|
*
|
||||||
|
* @param Registered $event
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle(Registered $event)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
34
app/Listeners/UpdateBusinessGoodsStock.php
Normal file
34
app/Listeners/UpdateBusinessGoodsStock.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Listeners;
|
||||||
|
|
||||||
|
use App\Models\Shop;
|
||||||
|
use Illuminate\Auth\Events\Registered;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
|
||||||
|
class UpdateBusinessGoodsStock
|
||||||
|
{
|
||||||
|
protected $shop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the event listener.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(Shop $shop)
|
||||||
|
{
|
||||||
|
$this->shop = $shop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the event.
|
||||||
|
*
|
||||||
|
* @param Registered $event
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle(Registered $event)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
13
app/Models/BusinessGoodsSku.php
Normal file
13
app/Models/BusinessGoodsSku.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
class BusinessGoodsSku extends Model
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 不可批量赋值的属性。为空则所有熟悉都可以批量赋值
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $guarded = [];
|
||||||
|
}
|
||||||
13
app/Models/BusinessOrder.php
Normal file
13
app/Models/BusinessOrder.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
class BusinessOrder extends Model
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 不可批量赋值的属性。为空则所有熟悉都可以批量赋值
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $guarded = [];
|
||||||
|
}
|
||||||
18
app/Models/BusinessOrderItem.php
Normal file
18
app/Models/BusinessOrderItem.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
class BusinessOrderItem extends Model
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 不可批量赋值的属性。为空则所有熟悉都可以批量赋值
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $guarded = [];
|
||||||
|
|
||||||
|
public function order()
|
||||||
|
{
|
||||||
|
return $this->hasOne(BusinessOrder::class, 'id', 'business_order_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
8
app/Models/DailyStockRecord.php
Normal file
8
app/Models/DailyStockRecord.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
class DailyStockRecord extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
8
app/Models/FailedJob.php
Normal file
8
app/Models/FailedJob.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
class FailedJob extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
37
app/Models/Goods.php
Normal file
37
app/Models/Goods.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Models\traits\Filter;
|
||||||
|
|
||||||
|
class Goods extends Model
|
||||||
|
{
|
||||||
|
use Filter;
|
||||||
|
|
||||||
|
//查询字段
|
||||||
|
public $fieldSearchable = [
|
||||||
|
'goods_title',
|
||||||
|
'type_id',
|
||||||
|
'brand_id',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $guarded = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多规格
|
||||||
|
*/
|
||||||
|
public function skus()
|
||||||
|
{
|
||||||
|
return $this->hasMany(GoodsSku::class, 'goods_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function brand()
|
||||||
|
{
|
||||||
|
return $this->hasOne(GoodsBrand::class, 'id', 'brand_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function type()
|
||||||
|
{
|
||||||
|
return $this->hasOne(GoodsType::class, 'id', 'type_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
13
app/Models/GoodsBrand.php
Normal file
13
app/Models/GoodsBrand.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
class GoodsBrand extends Model
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 数组中的属性会被隐藏。
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $hidden = ['deleted_at'];
|
||||||
|
}
|
||||||
62
app/Models/GoodsSku.php
Normal file
62
app/Models/GoodsSku.php
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Models\traits\Filter;
|
||||||
|
|
||||||
|
class GoodsSku extends Model
|
||||||
|
{
|
||||||
|
use Filter;
|
||||||
|
|
||||||
|
//查询字段
|
||||||
|
public $fieldSearchable = [
|
||||||
|
'sku_title',
|
||||||
|
'status',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不可批量赋值的属性。为空则所有熟悉都可以批量赋值
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $guarded = [];
|
||||||
|
|
||||||
|
protected $hidden = ['created_at'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取状态
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getStatusAttribute($value)
|
||||||
|
{
|
||||||
|
$map = [
|
||||||
|
0 => '下架',
|
||||||
|
1 => '在售',
|
||||||
|
2 => '预警',
|
||||||
|
];
|
||||||
|
return $map[$value];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 此规格从属于一个商品
|
||||||
|
*/
|
||||||
|
public function goods()
|
||||||
|
{
|
||||||
|
return $this->hasOne(Goods::class, 'id', 'goods_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 此规格每日记录
|
||||||
|
*/
|
||||||
|
public function daily()
|
||||||
|
{
|
||||||
|
return $this->hasOne(DailyStockRecord::class, 'sku_id', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function order()
|
||||||
|
{
|
||||||
|
return $this->hasOne(BusinessOrderItem::class, 'external_sku_id', 'id');
|
||||||
|
}
|
||||||
|
}
|
||||||
13
app/Models/GoodsType.php
Normal file
13
app/Models/GoodsType.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
class GoodsType extends Model
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 数组中的属性会被隐藏。
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $hidden = ['deleted_at'];
|
||||||
|
}
|
||||||
114
app/Models/Log.php
Normal file
114
app/Models/Log.php
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Models\traits\Filter;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class Log extends Model
|
||||||
|
{
|
||||||
|
use Filter;
|
||||||
|
|
||||||
|
//查询字段
|
||||||
|
public $fieldSearchable = [
|
||||||
|
'module',
|
||||||
|
'action',
|
||||||
|
'target_type',
|
||||||
|
'target_id',
|
||||||
|
'target_field',
|
||||||
|
'user_id',
|
||||||
|
'created_at',
|
||||||
|
];
|
||||||
|
|
||||||
|
public $fillable = [
|
||||||
|
'module',
|
||||||
|
'action',
|
||||||
|
'target_type',
|
||||||
|
'target_id',
|
||||||
|
'target_field',
|
||||||
|
'before_update',
|
||||||
|
'after_update',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function getModuleAttribute($value)
|
||||||
|
{
|
||||||
|
$map = [
|
||||||
|
'goods' => '商品',
|
||||||
|
'menu' => '菜单',
|
||||||
|
'permission' => '权限',
|
||||||
|
'role' => '角色',
|
||||||
|
'user' => '用户',
|
||||||
|
'plat' => '平台',
|
||||||
|
'file' => '文件',
|
||||||
|
];
|
||||||
|
|
||||||
|
return $map[$value];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getActionAttribute($value)
|
||||||
|
{
|
||||||
|
$map = [
|
||||||
|
'GET' => '查看',
|
||||||
|
'POST' => '新增',
|
||||||
|
'PATCH' => '更新',
|
||||||
|
'DELETE' => '删除',
|
||||||
|
];
|
||||||
|
|
||||||
|
return $map[$value];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTargetTypeAttribute($value)
|
||||||
|
{
|
||||||
|
$map = [
|
||||||
|
'goods_sku' => '商品&规格',
|
||||||
|
'goods_type' => '商品种类',
|
||||||
|
'goods_brand' => '商品品牌',
|
||||||
|
'permission' => '权限',
|
||||||
|
'role' => '角色',
|
||||||
|
'menu' => '菜单',
|
||||||
|
'user' => '用户',
|
||||||
|
'upload' => '上传',
|
||||||
|
'kuaituantuan' => '快团团',
|
||||||
|
'miaoxuan' => '妙选',
|
||||||
|
];
|
||||||
|
|
||||||
|
return $map[$value];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTargetFieldAttribute($value)
|
||||||
|
{
|
||||||
|
$map = [
|
||||||
|
'add' => '创建',
|
||||||
|
'status' => '状态',
|
||||||
|
'name' => '名称',
|
||||||
|
'title' => '名称',
|
||||||
|
'import' => '导入',
|
||||||
|
'export' => '导出',
|
||||||
|
'set' => '设置',
|
||||||
|
'cost' => '成本',
|
||||||
|
'stock' => '库存',
|
||||||
|
'inventory' => '库存盘点',
|
||||||
|
];
|
||||||
|
|
||||||
|
return $map[$value];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUserIdAttribute($value)
|
||||||
|
{
|
||||||
|
$this->attributes['user_id'] = Auth::id() ?: $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add($targetId = 0, $targetField = '')
|
||||||
|
{
|
||||||
|
$this->attributes['user_id'] = Auth::id();
|
||||||
|
$this->attributes['target_id'] = $targetId;
|
||||||
|
$this->attributes['target_field'] = $targetField;
|
||||||
|
|
||||||
|
return $this->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->hasOne(User::class, 'id', 'user_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
8
app/Models/Menu.php
Normal file
8
app/Models/Menu.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
class Menu extends Model
|
||||||
|
{
|
||||||
|
protected $hidden = ['created_at', 'updated_at'];
|
||||||
|
}
|
||||||
35
app/Models/Model.php
Normal file
35
app/Models/Model.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model as EloquentModel;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class Model extends EloquentModel
|
||||||
|
{
|
||||||
|
public function scopeRecent($query)
|
||||||
|
{
|
||||||
|
return $query->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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function batchInsert(array $data)
|
||||||
|
{
|
||||||
|
$time = date('Y-m-d H:i:s');
|
||||||
|
foreach ($data as &$val) {
|
||||||
|
$val['created_at'] = $val['created_at'] ?? $time;
|
||||||
|
$val['updated_at'] = $val['updated_at'] ?? $time;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Db::table($this->getTable())->insert($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
8
app/Models/PasswordReset.php
Normal file
8
app/Models/PasswordReset.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
class PasswordReset extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
44
app/Models/Shop.php
Normal file
44
app/Models/Shop.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Shop extends Model
|
||||||
|
{
|
||||||
|
protected $hidden = [
|
||||||
|
'access_token',
|
||||||
|
'expires_at',
|
||||||
|
'expires_in',
|
||||||
|
'refresh_token',
|
||||||
|
'refresh_token_expires_at',
|
||||||
|
'refresh_token_expires_in',
|
||||||
|
'pop_auth_token_create_response',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $guarded = [];
|
||||||
|
|
||||||
|
public function getStatusAttribute($value)
|
||||||
|
{
|
||||||
|
$map = [
|
||||||
|
0 => '未授权',
|
||||||
|
1 => '已授权',
|
||||||
|
2 => '无需授权',
|
||||||
|
3 => '停用',
|
||||||
|
];
|
||||||
|
|
||||||
|
return $map[$value];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPlatList()
|
||||||
|
{
|
||||||
|
return ['妙选', '快团团'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPlatIdAttribute($value)
|
||||||
|
{
|
||||||
|
$map = $this->getPlatList();
|
||||||
|
|
||||||
|
return $map[$value];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,14 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Spatie\Permission\Traits\HasRoles;
|
||||||
|
|
||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
use Notifiable;
|
use Notifiable;
|
||||||
|
use HasRoles;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
@ -25,7 +27,7 @@ class User extends Authenticatable
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
'password', 'remember_token',
|
'password', 'remember_token', 'api_token', 'email_verified_at',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,4 +38,14 @@ class User extends Authenticatable
|
|||||||
protected $casts = [
|
protected $casts = [
|
||||||
'email_verified_at' => 'datetime',
|
'email_verified_at' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function setPasswordAttribute($value)
|
||||||
|
{
|
||||||
|
$this->attributes['password'] = Hash::make($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isRoot()
|
||||||
|
{
|
||||||
|
return $this->name === 'erpAdmin';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
52
app/Models/traits/Filter.php
Normal file
52
app/Models/traits/Filter.php
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models\traits;
|
||||||
|
|
||||||
|
trait Filter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 过滤
|
||||||
|
*/
|
||||||
|
public function scopeFilter($query)
|
||||||
|
{
|
||||||
|
$filters = $this->getFilterClass($query);
|
||||||
|
if ($filters) {
|
||||||
|
|
||||||
|
return $filters->apply($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
//自动获取过滤的类
|
||||||
|
private function getFilterClass($query)
|
||||||
|
{
|
||||||
|
$prefix = 'App\Filters\\';
|
||||||
|
$filterClass = $this->getModelFilterClass($query);
|
||||||
|
if (!$filterClass) {
|
||||||
|
$currentClass = get_class($this);
|
||||||
|
$className = substr(strrchr($currentClass, '\\'), 1). 'Filter';
|
||||||
|
}
|
||||||
|
$filterClass = $prefix.$className;
|
||||||
|
if (class_exists($filterClass)) {
|
||||||
|
|
||||||
|
return new $filterClass();
|
||||||
|
}
|
||||||
|
$filterClass = $prefix.'Filters';
|
||||||
|
|
||||||
|
return new $filterClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
//查看 model是否有 getModelClassName 方法
|
||||||
|
private function getModelFilterClass($query)
|
||||||
|
{
|
||||||
|
$model = $query->getModel();
|
||||||
|
$className = '';
|
||||||
|
if (method_exists($model, 'getFilterClassName')) {
|
||||||
|
$className = $model->getFilterClassName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $className;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -6,6 +6,9 @@ use Illuminate\Auth\Events\Registered;
|
|||||||
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
|
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
|
||||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
|
use App\Listeners\SendDatabaseNotification;
|
||||||
|
use App\Listeners\BindBusinessGoods;
|
||||||
|
use App\Listeners\UpdateBusinessGoodsStock;
|
||||||
|
|
||||||
class EventServiceProvider extends ServiceProvider
|
class EventServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
@ -17,6 +20,9 @@ class EventServiceProvider extends ServiceProvider
|
|||||||
protected $listen = [
|
protected $listen = [
|
||||||
Registered::class => [
|
Registered::class => [
|
||||||
SendEmailVerificationNotification::class,
|
SendEmailVerificationNotification::class,
|
||||||
|
SendDatabaseNotification::class,
|
||||||
|
BindBusinessGoods::class,
|
||||||
|
UpdateBusinessGoodsStock::class,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
90
app/Services/Business/BusinessClient.php
Normal file
90
app/Services/Business/BusinessClient.php
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Business;
|
||||||
|
use App\Models\Log;
|
||||||
|
use App\Models\Shop;
|
||||||
|
use Facade\FlareClient\Http\Client;
|
||||||
|
|
||||||
|
abstract class BusinessClient
|
||||||
|
{
|
||||||
|
protected $redirectUri = 'http://erp.chutang66.com/callback';
|
||||||
|
protected $code;
|
||||||
|
protected $shop;
|
||||||
|
|
||||||
|
abstract public function auth();
|
||||||
|
|
||||||
|
abstract public function downloadGoods();
|
||||||
|
|
||||||
|
abstract public function bindGoods($goods);
|
||||||
|
|
||||||
|
abstract public function incrQuantity($skuId);
|
||||||
|
|
||||||
|
abstract public function downloadOrders($beginTime, $endTime, $activityNo, $downloadType = 'default');
|
||||||
|
|
||||||
|
abstract public function saveOrders($orders);
|
||||||
|
|
||||||
|
public function authCallback($code, $shopId)
|
||||||
|
{
|
||||||
|
$this->setCode($code);
|
||||||
|
$this->setShop($shopId);
|
||||||
|
$this->auth();
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setShopWithId($shopId)
|
||||||
|
{
|
||||||
|
$this->shop = Shop::query()->find($shopId);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setShop(Shop $shop)
|
||||||
|
{
|
||||||
|
$this->shop = $shop;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getShop()
|
||||||
|
{
|
||||||
|
return $this->shop;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setCode($code)
|
||||||
|
{
|
||||||
|
$this->code = $code;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCode()
|
||||||
|
{
|
||||||
|
return $this->code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function formDataPostRequest($url, $params)
|
||||||
|
{
|
||||||
|
$headers = [
|
||||||
|
'headers' => ['Content-type' => 'multipart/form-data;charset=UTF-8'],
|
||||||
|
'form_params' => $params
|
||||||
|
];
|
||||||
|
$res = (new Client())->makeCurlRequest('POST', $url, $headers);
|
||||||
|
$res = json_decode($res->getBody()->getContents(), true);
|
||||||
|
if (isset($res['error_response'])) {
|
||||||
|
$log = new Log();
|
||||||
|
$log->module = 'plat';
|
||||||
|
$log->action = 'POST';
|
||||||
|
$log->target_type = 'kuaituantuan';
|
||||||
|
$log->target_id = 0;
|
||||||
|
$log->target_field = '更新库存';
|
||||||
|
$log->user_id = 1;
|
||||||
|
$log->message = json_encode($res, 256);
|
||||||
|
$log->save();
|
||||||
|
|
||||||
|
throw new \Exception($res['error_response']['error_msg'], $res['error_response']['error_code']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
app/Services/Business/BusinessFactory.php
Normal file
25
app/Services/Business/BusinessFactory.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Business;
|
||||||
|
|
||||||
|
use App\Services\Business\KuaiTuanTuan\KuaiTuanTuan;
|
||||||
|
|
||||||
|
class BusinessFactory
|
||||||
|
{
|
||||||
|
private $platList;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->platList['快团团'] = KuaiTuanTuan::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function make($platName)
|
||||||
|
{
|
||||||
|
return new $this->platList[$platName];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function init()
|
||||||
|
{
|
||||||
|
return new self();
|
||||||
|
}
|
||||||
|
}
|
||||||
63
app/Services/Business/KuaiTuanTuan/Goods.php
Normal file
63
app/Services/Business/KuaiTuanTuan/Goods.php
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Business\KuaiTuanTuan;
|
||||||
|
|
||||||
|
use App\Models\BusinessGoodsSku;
|
||||||
|
|
||||||
|
class Goods
|
||||||
|
{
|
||||||
|
public static function downloadGoods($activityNo, $page = 1, $size = 100)
|
||||||
|
{
|
||||||
|
$type = 'pdd.ktt.goods.query.list';
|
||||||
|
$appendParams = [
|
||||||
|
'activity_no' => $activityNo, // 非必填,团号(团号和创建时间只能传一个)
|
||||||
|
'page' => $page,
|
||||||
|
'size' => $size,
|
||||||
|
// 'update_time_end' => '', // 非必填,结束最后更新时间(毫秒级时间戳)
|
||||||
|
// 'update_time_start' => '', // 非必填,起始最后更新时间(毫秒级时间戳)
|
||||||
|
// 'create_time_end' => '', // 非必填,开始时间结束(毫秒级时间戳)
|
||||||
|
// 'create_time_start' => '' // 非必填, 开始时间起始(毫秒级时间戳)
|
||||||
|
];
|
||||||
|
|
||||||
|
return [$type, $appendParams];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function bindGoods(array $goodsList, $shopId)
|
||||||
|
{
|
||||||
|
foreach ($goodsList as $businessGood) {
|
||||||
|
$skuList = $businessGood['sku_list'];
|
||||||
|
unset($businessGood['sku_list']);
|
||||||
|
foreach ($skuList as $sku) {
|
||||||
|
$sku['spec_list'] = json_encode($sku['spec_list'], 256);
|
||||||
|
$data = array_merge($businessGood, $sku);
|
||||||
|
BusinessGoodsSku::updateOrCreate(
|
||||||
|
['shop_id' => $shopId, 'activity_no' => $businessGood['activity_no'], 'goods_id' => $businessGood['goods_id'], 'sku_id' => $sku['sku_id']],
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function downloadSingle($goodsId)
|
||||||
|
{
|
||||||
|
$type = 'pdd.ktt.goods.query.single';
|
||||||
|
$appendParams = [
|
||||||
|
'goods_id' => $goodsId
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function incrQuantity($goodsId, $quantity, $skuId, $modifyType = 2)
|
||||||
|
{
|
||||||
|
$type = 'pdd.ktt.goods.incr.quantity';
|
||||||
|
$appendParams = [
|
||||||
|
'goods_id' => $goodsId,
|
||||||
|
'quantity_delta' => $quantity,
|
||||||
|
'sku_id' => $skuId,
|
||||||
|
// 非必填
|
||||||
|
'modify_quantity_type' => $modifyType, // 修改库存的类型,不传或1代表增量修改,2代表全量修改
|
||||||
|
];
|
||||||
|
|
||||||
|
return [$type, $appendParams];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
135
app/Services/Business/KuaiTuanTuan/KuaiTuanTuan.php
Normal file
135
app/Services/Business/KuaiTuanTuan/KuaiTuanTuan.php
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Business\KuaiTuanTuan;
|
||||||
|
|
||||||
|
use App\Listeners\BindBusinessGoods;
|
||||||
|
use App\Models\BusinessGoodsSku;
|
||||||
|
use App\Models\GoodsSku;
|
||||||
|
use App\Services\Business\BusinessClient;
|
||||||
|
use App\Models\Log;
|
||||||
|
|
||||||
|
class KuaiTuanTuan extends BusinessClient
|
||||||
|
{
|
||||||
|
// 所有的请求和响应数据编码皆为utf-8格式,url里的所有参数值请做urlencode编码。
|
||||||
|
// 如果请求的content-type是 application/x-www-form-urlencoded,所有参数值也做urlencode编码;
|
||||||
|
// 如果是multipart/form-data格式,每个表单字段的参数值无需编码,但每个表单字段的charset需要指定为utf-8
|
||||||
|
// 如果指定接口返回数据格式为JSON,请指明header头content-type: application/json
|
||||||
|
protected $clientId = '';
|
||||||
|
|
||||||
|
protected $clientSecret = '';
|
||||||
|
|
||||||
|
protected $publicParams = [
|
||||||
|
'type' => '',
|
||||||
|
'client_id' => '',
|
||||||
|
'access_token' => '', // 非必填,通过code获取的access_token
|
||||||
|
'timestamp' => '',
|
||||||
|
'data_type' => '', // 非必填,响应格式,即返回数据的格式,JSON或者XML(二选一),默认JSON,注意是大写
|
||||||
|
'version' => '', // 非必填, API协议版本号,默认为V1,可不填
|
||||||
|
'sign' => ''
|
||||||
|
];
|
||||||
|
|
||||||
|
public function auth()
|
||||||
|
{
|
||||||
|
$accessToken = $this->getAccessTokenWithCode();
|
||||||
|
$accessToken['pop_auth_token_create_response'] = json_encode($accessToken, 256);
|
||||||
|
$this->shop->update($accessToken);
|
||||||
|
|
||||||
|
return $this->shop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function downloadGoods($page = 1)
|
||||||
|
{
|
||||||
|
[$type, $appendParams] = Goods::downloadGoods($this->shop->owner_name, $page);
|
||||||
|
$res = $this->formDataPostRequest($type, $appendParams);
|
||||||
|
$goods = $res['ktt_goods_query_list_response']['goods_list'];
|
||||||
|
$this->bindGoods($goods);
|
||||||
|
$pageNum = ceil($res['total'] / $appendParams['size']);
|
||||||
|
if ($pageNum > $page && 10 >= $page) {
|
||||||
|
$this->downloadGoods($page + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function bindGoods($goods)
|
||||||
|
{
|
||||||
|
Goods::bindGoods($goods, $this->shop->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function incrQuantity($skuId)
|
||||||
|
{
|
||||||
|
$goodsSku = GoodsSku::query()->find($skuId);
|
||||||
|
$business = BusinessGoodsSku::query()->where('shop_id', $this->shop->id)->where('self_sku_id', $skuId)->first(['goods_id', 'sku_id']);
|
||||||
|
[$type, $appendParams] = Goods::incrQuantity($business->goodsId, $goodsSku->stock, $business->sku_id);
|
||||||
|
$this->formDataPostRequest($type, $appendParams);
|
||||||
|
$log = new Log();
|
||||||
|
$log->module = 'plat';
|
||||||
|
$log->action = 'POST';
|
||||||
|
$log->target_type = 'kuaituantuan';
|
||||||
|
$log->target_id = 0;
|
||||||
|
$log->target_field = $type;
|
||||||
|
$log->user_id = 1;
|
||||||
|
$log->message = 'success';
|
||||||
|
$log->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function downloadOrders($beginTime, $endTime, $activityNo, $downloadType = 'default')
|
||||||
|
{
|
||||||
|
if ('increment' === $downloadType) {
|
||||||
|
[$type, $appendParams] = Order::downloadIncrementOrders($beginTime, $endTime, $activityNo);
|
||||||
|
} else {
|
||||||
|
[$type, $appendParams] = Order::downloadOrders($beginTime, $endTime, $activityNo);
|
||||||
|
}
|
||||||
|
$res = $this->formDataPostRequest($type, $appendParams);
|
||||||
|
|
||||||
|
|
||||||
|
return $res['ktt_order_list_response']['order_list'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveOrders($orders)
|
||||||
|
{
|
||||||
|
Order::saveOrders($orders, $this->shop->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getAccessTokenWithCode()
|
||||||
|
{
|
||||||
|
$type = 'pdd.pop.auth.token.create';
|
||||||
|
$res = $this->doRequest($type, ['code' => $this->code]);
|
||||||
|
|
||||||
|
return $res['pop_auth_token_create_response'];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getSign($params)
|
||||||
|
{
|
||||||
|
$params = ksort($params);
|
||||||
|
$str = '';
|
||||||
|
foreach ($params as $key => $val) {
|
||||||
|
$str .= $key . $val;
|
||||||
|
}
|
||||||
|
$str = $this->clientSecret . $str . $this->clientSecret;
|
||||||
|
|
||||||
|
return strtoupper(md5($str));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function doRequest($type, $appendParams = [], $url = 'http://gw-api.pinduoduo.com/api/router')
|
||||||
|
{
|
||||||
|
$publicParams = [
|
||||||
|
'type' => $type,
|
||||||
|
'client_id' => $this->clientId,
|
||||||
|
'timestamp' => time()
|
||||||
|
];
|
||||||
|
if ('pdd.pop.auth.token.create' !== $type) {
|
||||||
|
$publicParams['access_token'] = $this->getAccessToken();
|
||||||
|
}
|
||||||
|
$publicParams = array_merge($publicParams, $appendParams);
|
||||||
|
$publicParams['sign'] = $this->getSign($publicParams);
|
||||||
|
|
||||||
|
return $this->formDataPostRequest($url, $publicParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getAuthUrl($shopId, $platId)
|
||||||
|
{
|
||||||
|
$state = $shopId . '_' . $platId;
|
||||||
|
|
||||||
|
return "https://oauth.pinduoduo.com/authorize/ktt?client_id={$this->clientId}&redirect_uri={$this->redirectUri}&state={$state}";
|
||||||
|
}
|
||||||
|
}
|
||||||
70
app/Services/Business/KuaiTuanTuan/Order.php
Normal file
70
app/Services/Business/KuaiTuanTuan/Order.php
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Business\KuaiTuanTuan;
|
||||||
|
|
||||||
|
use App\Models\BusinessOrder;
|
||||||
|
|
||||||
|
class Order
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 根据成交时间拉取订单列表
|
||||||
|
*/
|
||||||
|
public static function downloadOrders($beginTime, $endTime, $activityNo)
|
||||||
|
{
|
||||||
|
$type = 'pdd.ktt.order.list';
|
||||||
|
$appendParams = [
|
||||||
|
'confirm_at_begin' => $beginTime, // 成交启始时间, 必填,毫秒时间戳
|
||||||
|
'confirm_at_end' => $endTime, // 成交结束时间,必填, 毫秒时间戳,成交结束时间 - 成交启始时间 <= 24h
|
||||||
|
'page_number' => 1, // 页码, 必填
|
||||||
|
'page_size' => 100, // 数量, 必填, 1~100
|
||||||
|
// 非必填
|
||||||
|
'activity_no' => $activityNo, // 团号
|
||||||
|
'after_sales_status' => 0, // 售后状态, 可选 0-未发起售后 1-退款中 2-退款成功 3-待处理 4-拒绝退款 6-待(顾客)退货 7-待(团长)确认退货 8-(顾客)撤销 9-(系统)关闭
|
||||||
|
'cancel_status' => 0, // 取消状态, 可选 0-未取消 1-已取消
|
||||||
|
// 'shipping_status' => '', // 发货状态 0-未发货 1-已发货 2-部分发货 3-已收货
|
||||||
|
// 'verification_status' => '', // 核销状态, 可选 0-未核销 1-已核销 2-部分核销
|
||||||
|
];
|
||||||
|
|
||||||
|
return [$type, $appendParams];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 快团团增量查订单
|
||||||
|
*/
|
||||||
|
public static function downloadIncrementOrders($beginTime, $endTime, $activityNo)
|
||||||
|
{
|
||||||
|
$type = 'pdd.ktt.increment.order.query';
|
||||||
|
$appendParams = [
|
||||||
|
'start_updated_at' => $beginTime, // 更新起始时间
|
||||||
|
'end_updated_at' => $endTime, // 更新结束时间
|
||||||
|
'page_number' => 1, // 页码
|
||||||
|
'page_size' => 100, // 数量
|
||||||
|
// 非必填
|
||||||
|
'activity_no' => $activityNo, // 团号
|
||||||
|
'after_sales_status' => 0, // 售后状态, 可选 0-未发起售后 1-退款中 2-退款成功 3-待处理 4-拒绝退款 6-待(顾客)退货 7-待(团长)确认退货 8-(顾客)撤销 9-(系统)关闭
|
||||||
|
'cancel_status' => 0, // 取消状态, 可选 0-未取消 1-已取消
|
||||||
|
// 'shipping_status' => '', // 发货状态 0-未发货 1-已发货 2-部分发货 3-已收货
|
||||||
|
// 'verification_status' => '', // 核销状态, 可选 0-未核销 1-已核销 2-部分核销
|
||||||
|
];
|
||||||
|
|
||||||
|
return [$type, $appendParams];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载订单事件之后去统计 然后更新库存
|
||||||
|
public static function saveOrders(array $orders, $shopId)
|
||||||
|
{
|
||||||
|
foreach ($orders as $order) {
|
||||||
|
$orderRecord = BusinessOrder::updateOrCreate(
|
||||||
|
['shop_id' => $shopId, 'order_sn' => $order['order_sn']],
|
||||||
|
$order
|
||||||
|
);
|
||||||
|
foreach ($order['sub_order_list'] as $item) {
|
||||||
|
$orderRecord = BusinessOrder::updateOrCreate(
|
||||||
|
['shop_id' => $shopId, 'business_order_id' => $orderRecord->id, 'goods_id' => $item['goods_id'], 'sku_id' => $item['sku_id']],
|
||||||
|
$item
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
30
app/Services/Business/MiaoXuan/Goods.php
Normal file
30
app/Services/Business/MiaoXuan/Goods.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Business\MiaoXuan;
|
||||||
|
|
||||||
|
use App\Models\BusinessGoodsSku;
|
||||||
|
|
||||||
|
class Goods
|
||||||
|
{
|
||||||
|
public static function bindGoods(array $goods, $shopId)
|
||||||
|
{
|
||||||
|
foreach ($goods as $item) {
|
||||||
|
BusinessGoodsSku::updateOrCreate(
|
||||||
|
['shop_id' => $shopId, 'goods_id' => $item['goods_id'], 'sku_id' => $item['sku_id']],
|
||||||
|
$item
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function incrQuantity($shopId, $quantity, $businessGoods)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'stock' => $quantity,
|
||||||
|
'business_sku_id' => $businessGoods['sku_id'],
|
||||||
|
'business_goods_id' => $businessGoods['goods_id'],
|
||||||
|
'erp_shop_id' => $shopId,
|
||||||
|
'erp_sku_id' => $businessGoods['external_sku_id']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
53
app/Services/Business/MiaoXuan/MiaoXuan.php
Normal file
53
app/Services/Business/MiaoXuan/MiaoXuan.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Business\MiaoXuan;
|
||||||
|
|
||||||
|
use App\Models\BusinessGoodsSku;
|
||||||
|
use App\Models\GoodsSku;
|
||||||
|
use App\Models\Log;
|
||||||
|
use App\Services\Business\BusinessClient;
|
||||||
|
|
||||||
|
class MiaoXuan extends BusinessClient
|
||||||
|
{
|
||||||
|
|
||||||
|
public function auth()
|
||||||
|
{
|
||||||
|
// TODO: Implement auth() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
public function downloadGoods()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function bindGoods($goods)
|
||||||
|
{
|
||||||
|
Goods::bindGoods($goods, $this->shop->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function incrQuantity($skuId)
|
||||||
|
{
|
||||||
|
$goodsSku = GoodsSku::query()->find($skuId);
|
||||||
|
$business = BusinessGoodsSku::query()->where('shop_id', $this->shop->id)->where('self_sku_id', $skuId)->first(['goods_id', 'sku_id', 'external_sku_id'])->toArray();
|
||||||
|
$appendParams = Goods::incrQuantity($this->shop->id, $goodsSku->stock, $business);
|
||||||
|
$url = ''; // http://shop.chutang66.com/miaoxuan/stock
|
||||||
|
$this->formDataPostRequest($url, $appendParams);
|
||||||
|
$log = new Log();
|
||||||
|
$log->module = 'plat';
|
||||||
|
$log->action = 'POST';
|
||||||
|
$log->target_type = 'miaoxuan';
|
||||||
|
$log->target_id = 0;
|
||||||
|
$log->target_field = '更新库存';
|
||||||
|
$log->user_id = 1;
|
||||||
|
$log->message = 'success';
|
||||||
|
$log->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function downloadOrders($beginTime, $endTime, $activityNo, $downloadType = 'default')
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveOrders($orders)
|
||||||
|
{
|
||||||
|
Order::saveOrders($orders, $this->shop->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
26
app/Services/Business/MiaoXuan/Order.php
Normal file
26
app/Services/Business/MiaoXuan/Order.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Business\MiaoXuan;
|
||||||
|
|
||||||
|
use App\Models\BusinessOrder;
|
||||||
|
|
||||||
|
class Order
|
||||||
|
{
|
||||||
|
// 下载订单事件之后去统计 然后更新库存
|
||||||
|
public static function saveOrders(array $orders, $shopId)
|
||||||
|
{
|
||||||
|
foreach ($orders as $order) {
|
||||||
|
$orderRecord = BusinessOrder::updateOrCreate(
|
||||||
|
['shop_id' => $shopId, 'order_sn' => $order['order_sn']],
|
||||||
|
$order
|
||||||
|
);
|
||||||
|
foreach ($order['sub_order_list'] as $item) {
|
||||||
|
$orderRecord = BusinessOrder::updateOrCreate(
|
||||||
|
['shop_id' => $shopId, 'business_order_id' => $orderRecord->id, 'goods_id' => $item['goods_id'], 'sku_id' => $item['sku_id']],
|
||||||
|
$item
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
23
app/Utils/ArrayUtils.php
Normal file
23
app/Utils/ArrayUtils.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Utils;
|
||||||
|
|
||||||
|
class ArrayUtils
|
||||||
|
{
|
||||||
|
public static function index(array $array, $name)
|
||||||
|
{
|
||||||
|
$indexedArray = [];
|
||||||
|
if (empty($array)) {
|
||||||
|
|
||||||
|
return $indexedArray;
|
||||||
|
}
|
||||||
|
foreach ($array as $item) {
|
||||||
|
if (isset($item[$name])) {
|
||||||
|
$indexedArray[$item[$name]] = $item;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $indexedArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
50
app/Utils/FormatUtils.php
Normal file
50
app/Utils/FormatUtils.php
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Utils;
|
||||||
|
|
||||||
|
class FormatUtils
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 格式化为树形结构
|
||||||
|
* @param $menus
|
||||||
|
* @param $parentValue
|
||||||
|
* @param string $juniorTitle //下级标题
|
||||||
|
* @param string $parentKey
|
||||||
|
* @param string $subKey
|
||||||
|
* @param string $useKey
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function formatTreeData($menus, $parentValue, $juniorTitle = 'children', $parentKey = 'parent_id', $subKey = 'id', $useKey = '')
|
||||||
|
{
|
||||||
|
$data = [];
|
||||||
|
foreach ($menus as $menu) {
|
||||||
|
if ($menu[$parentKey] == $parentValue) {
|
||||||
|
$res = self::formatTreeData($menus, $menu[$subKey], $juniorTitle, $parentKey, $subKey, $useKey);
|
||||||
|
if (!empty($res)) {
|
||||||
|
$menu[$juniorTitle] = $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($useKey) {
|
||||||
|
$data[$menu[$useKey]] = $menu;
|
||||||
|
} else {
|
||||||
|
$data[] = $menu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 今天7点到明天7点算作今天
|
||||||
|
*/
|
||||||
|
public static function date()
|
||||||
|
{
|
||||||
|
$time = time();
|
||||||
|
$inventoryTime = strtotime(date('Y-m-d 07:00:00'));
|
||||||
|
if ($time < $inventoryTime) {
|
||||||
|
$time = strtotime('-1 day');
|
||||||
|
}
|
||||||
|
|
||||||
|
return date('Y-m-d', $time);
|
||||||
|
}
|
||||||
|
}
|
||||||
123
app/Utils/UploadUtils.php
Normal file
123
app/Utils/UploadUtils.php
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Utils;
|
||||||
|
|
||||||
|
use Illuminate\Http\UploadedFile;
|
||||||
|
use Intervention\Image\Facades\Image;
|
||||||
|
use OSS\Core\OssException;
|
||||||
|
use OSS\OssClient;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class UploadUtils
|
||||||
|
{
|
||||||
|
private static $ossClient;
|
||||||
|
private static $bucket = 'ct-upimg';
|
||||||
|
private static $prefix = 'ju8hn6/erp/shop/';
|
||||||
|
|
||||||
|
|
||||||
|
public static function init()
|
||||||
|
{
|
||||||
|
if (static::$ossClient === null) {
|
||||||
|
static::$ossClient = new OssClient(config('filesystems.disks.aliyun.access_id'), config('filesystems.disks.aliyun.access_key'), config('filesystems.disks.aliyun.endpoint'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (static::$bucket === null) {
|
||||||
|
static::$bucket = config('filesystems.disks.aliyun.bucket');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function putForUploadedResizeImage($bucketPath, UploadedFile $upload, $width = 800, $extension = null)
|
||||||
|
{
|
||||||
|
if ($upload->extension() != 'gif') {
|
||||||
|
// 压缩图片
|
||||||
|
$originalName = static::randomFileName($extension ?: $upload->getClientOriginalExtension());
|
||||||
|
$storagePath = storage_path('app/public/file/') . $originalName;
|
||||||
|
$img = Image::make($upload->getRealPath());
|
||||||
|
|
||||||
|
// 未传宽度 大于800压缩至800 否则按照原宽度
|
||||||
|
$width = $img->width() >= 800 ? 800 : $img->width();
|
||||||
|
// 高度自适应
|
||||||
|
$img->resize($width, null, function ($constraint) {
|
||||||
|
$constraint->aspectRatio();
|
||||||
|
});
|
||||||
|
$img->save($storagePath);
|
||||||
|
$upload = new UploadedFile($storagePath, $originalName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传并删除压缩图片
|
||||||
|
try {
|
||||||
|
$filePath = static::put($bucketPath, $upload->getRealPath(), $upload->getClientOriginalExtension());
|
||||||
|
} catch (OssException $e) {
|
||||||
|
throw $e;
|
||||||
|
} finally {
|
||||||
|
if (isset($storagePath)) {
|
||||||
|
unlink($storagePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
//上传图片
|
||||||
|
public static function putForUploadedFile($bucketPath, UploadedFile $upload)
|
||||||
|
{
|
||||||
|
return static::put($bucketPath, $upload->getRealPath(), $upload->getClientOriginalExtension());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function put($bucketPath, $filepath, $ext)
|
||||||
|
{
|
||||||
|
static::init();
|
||||||
|
try {
|
||||||
|
$filePath = static::$prefix . $bucketPath . '/' . static::randomFileName($ext);
|
||||||
|
static::$ossClient->uploadFile(static::$bucket, $filePath, $filepath);
|
||||||
|
} catch (OssException $e) {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
return $filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function buildFilePath()
|
||||||
|
{
|
||||||
|
return date('Y') . '/' . date('m') . '/' . date('d');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function randomFileName($ext, $len = 40)
|
||||||
|
{
|
||||||
|
return Str::random($len) . '.' . $ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除修改前,上传修改后图片
|
||||||
|
public static function delAndUploadImage($file, $filePath, UploadedFile $upload)
|
||||||
|
{
|
||||||
|
static::delFile($file);
|
||||||
|
return static::putForUploadedFile($filePath, $upload);
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除修改前,上传修改后视频
|
||||||
|
public static function delAndUploadVideo($file, $filePath, UploadedFile $upload)
|
||||||
|
{
|
||||||
|
static::delFile($file);
|
||||||
|
return static::putForUploadedFile($filePath, $upload);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function delFile($file)
|
||||||
|
{
|
||||||
|
static::init();
|
||||||
|
if (static::exist($file)) {
|
||||||
|
return static::$ossClient->deleteObject(static::$bucket, $file);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function exist($file)
|
||||||
|
{
|
||||||
|
static::init();
|
||||||
|
return static::$ossClient->doesObjectExist(static::$bucket, $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getFullImgUrl($filePath)
|
||||||
|
{
|
||||||
|
return config('filesystems.disks.aliyun.url') . $filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -9,9 +9,13 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.2.5|^8.0",
|
"php": "^7.2.5|^8.0",
|
||||||
|
"aliyuncs/oss-sdk-php": "^2.5",
|
||||||
"fideloper/proxy": "^4.4",
|
"fideloper/proxy": "^4.4",
|
||||||
|
"intervention/image": "^2.7",
|
||||||
"laravel/framework": "^6.20.26",
|
"laravel/framework": "^6.20.26",
|
||||||
"laravel/tinker": "^2.5"
|
"laravel/tinker": "^2.5",
|
||||||
|
"maatwebsite/excel": "^3.1",
|
||||||
|
"spatie/laravel-permission": "*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"facade/ignition": "^1.16.15",
|
"facade/ignition": "^1.16.15",
|
||||||
|
|||||||
1003
composer.lock
generated
1003
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,7 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'name' => 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),
|
'asset_url' => env('ASSET_URL', null),
|
||||||
|
|
||||||
|
|||||||
@ -68,7 +68,7 @@ return [
|
|||||||
'providers' => [
|
'providers' => [
|
||||||
'users' => [
|
'users' => [
|
||||||
'driver' => 'eloquent',
|
'driver' => 'eloquent',
|
||||||
'model' => App\User::class,
|
'model' => \App\Models\User::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
// 'users' => [
|
// 'users' => [
|
||||||
|
|||||||
@ -48,12 +48,12 @@ return [
|
|||||||
'url' => env('DATABASE_URL'),
|
'url' => env('DATABASE_URL'),
|
||||||
'host' => env('DB_HOST', '127.0.0.1'),
|
'host' => env('DB_HOST', '127.0.0.1'),
|
||||||
'port' => env('DB_PORT', '3306'),
|
'port' => env('DB_PORT', '3306'),
|
||||||
'database' => env('DB_DATABASE', 'forge'),
|
'database' => env('DB_DATABASE', 'erp'),
|
||||||
'username' => env('DB_USERNAME', 'forge'),
|
'username' => env('DB_USERNAME', ''),
|
||||||
'password' => env('DB_PASSWORD', ''),
|
'password' => env('DB_PASSWORD', ''),
|
||||||
'unix_socket' => env('DB_SOCKET', ''),
|
'unix_socket' => env('DB_SOCKET', ''),
|
||||||
'charset' => 'utf8mb4',
|
'charset' => 'utf8',
|
||||||
'collation' => 'utf8mb4_unicode_ci',
|
'collation' => 'utf8_general_ci',
|
||||||
'prefix' => '',
|
'prefix' => '',
|
||||||
'prefix_indexes' => true,
|
'prefix_indexes' => true,
|
||||||
'strict' => true,
|
'strict' => true,
|
||||||
|
|||||||
@ -64,7 +64,22 @@ return [
|
|||||||
'url' => env('AWS_URL'),
|
'url' => env('AWS_URL'),
|
||||||
'endpoint' => env('AWS_ENDPOINT'),
|
'endpoint' => env('AWS_ENDPOINT'),
|
||||||
],
|
],
|
||||||
|
'aliyun' => [
|
||||||
|
'driver' => 'oss',
|
||||||
|
'access_id' => 'LTAI6do39W9jINpe',
|
||||||
|
'access_key' => 'XLhp5w4WnRcqji204GYOm7hZsoXSB6',
|
||||||
|
'bucket' => 'ct-upimg',
|
||||||
|
'endpoint' => 'oss-cn-hangzhou.aliyuncs.com', // OSS 外网节点或自定义外部域名
|
||||||
|
// 'cdnDomain' => 'cdn-xiangma.yx090.com', // 如果isCName为true, getUrl会判断cdnDomain是否设定来决定返回的url,如果cdnDomain未设置,则使用endpoint来生成url,否则使用cdn
|
||||||
|
'url' => 'https://ct-upimg.yx090.com/',
|
||||||
|
'ssl' => true,
|
||||||
|
'isCName' => false, // 是否使用自定义域名,true: 则Storage.url()会使用自定义的cdn或域名生成文件url, false: 则使用外部节点生成url
|
||||||
|
'debug' => true
|
||||||
|
],
|
||||||
|
'root' => [
|
||||||
|
'driver' => 'local',
|
||||||
|
'root' => '/'
|
||||||
|
]
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
161
config/permission.php
Normal file
161
config/permission.php
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
'models' => [
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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',
|
||||||
|
],
|
||||||
|
];
|
||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/** @var \Illuminate\Database\Eloquent\Factory $factory */
|
/** @var \Illuminate\Database\Eloquent\Factory $factory */
|
||||||
|
|
||||||
use App\User;
|
use App\Models\User;
|
||||||
use Faker\Generator as Faker;
|
use Faker\Generator as Faker;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
@ -19,10 +19,11 @@ use Illuminate\Support\Str;
|
|||||||
|
|
||||||
$factory->define(User::class, function (Faker $faker) {
|
$factory->define(User::class, function (Faker $faker) {
|
||||||
return [
|
return [
|
||||||
'name' => $faker->name,
|
'name' => 'erpAdmin',
|
||||||
'email' => $faker->unique()->safeEmail,
|
'email' => $faker->unique()->safeEmail,
|
||||||
'email_verified_at' => now(),
|
'email_verified_at' => now(),
|
||||||
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
|
'password' => 'password', // password
|
||||||
|
'api_token' => Str::random(60),
|
||||||
'remember_token' => Str::random(10),
|
'remember_token' => Str::random(10),
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|||||||
@ -19,6 +19,8 @@ class CreateUsersTable extends Migration
|
|||||||
$table->string('email')->unique();
|
$table->string('email')->unique();
|
||||||
$table->timestamp('email_verified_at')->nullable();
|
$table->timestamp('email_verified_at')->nullable();
|
||||||
$table->string('password');
|
$table->string('password');
|
||||||
|
$table->string('api_token', 80)->unique()->nullable(false);
|
||||||
|
$table->softDeletes();
|
||||||
$table->rememberToken();
|
$table->rememberToken();
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -0,0 +1,141 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Spatie\Permission\PermissionRegistrar;
|
||||||
|
|
||||||
|
class CreatePermissionTables extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$tableNames = config('permission.table_names');
|
||||||
|
$columnNames = config('permission.column_names');
|
||||||
|
$teams = config('permission.teams');
|
||||||
|
|
||||||
|
if (empty($tableNames)) {
|
||||||
|
throw new \Exception('Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.');
|
||||||
|
}
|
||||||
|
if ($teams && empty($columnNames['team_foreign_key'] ?? null)) {
|
||||||
|
throw new \Exception('Error: team_foreign_key on config/permission.php not loaded. Run [php artisan config:clear] and try again.');
|
||||||
|
}
|
||||||
|
|
||||||
|
Schema::create($tableNames['permissions'], function (Blueprint $table) {
|
||||||
|
$table->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']);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateGoodsTypesTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('goods_types', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->string('name')->nullable(false);
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->timestamps();
|
||||||
|
// 索引
|
||||||
|
$table->unique('name');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('goods_types');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateGoodsBrandsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('goods_brands', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->string('name')->nullable(false);
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->timestamps();
|
||||||
|
// 索引
|
||||||
|
$table->unique('name');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('goods_brands');
|
||||||
|
}
|
||||||
|
}
|
||||||
38
database/migrations/2022_07_26_090143_create_goods_table.php
Normal file
38
database/migrations/2022_07_26_090143_create_goods_table.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateGoodsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('goods', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->string('title')->nullable(false);
|
||||||
|
$table->string('img_url')->nullable()->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');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateGoodsSkusTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('goods_skus', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->unsignedBigInteger('goods_id')->nullable(false)->comment('商品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();
|
||||||
|
// 索引
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('goods_skus');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateDailyStockRecordsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('daily_stock_records', function (Blueprint $table) {
|
||||||
|
$table->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->unique('sku_id', 'day');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('daily_stock_records');
|
||||||
|
}
|
||||||
|
}
|
||||||
41
database/migrations/2022_07_26_105818_create_logs_table.php
Normal file
41
database/migrations/2022_07_26_105818_create_logs_table.php
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateLogsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('logs', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->string('module')->comment('模块');
|
||||||
|
$table->string('action')->comment('操作');
|
||||||
|
$table->string('target_type')->nullable()->comment('目标类型');
|
||||||
|
$table->bigInteger('target_id')->nullable()->default(0)->comment('目标id');
|
||||||
|
$table->string('target_field')->nullable()->comment('目标字段');
|
||||||
|
$table->text('before_update')->nullable()->comment('更新前数据');
|
||||||
|
$table->text('after_update')->nullable()->comment('更新后数据');
|
||||||
|
$table->text('message')->nullable()->comment('备注信息');
|
||||||
|
$table->bigInteger('user_id')->comment('操作人id');
|
||||||
|
$table->index(['target_type', 'target_id', 'target_field']);
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('logs');
|
||||||
|
}
|
||||||
|
}
|
||||||
38
database/migrations/2022_07_28_095523_create_menus_table.php
Normal file
38
database/migrations/2022_07_28_095523_create_menus_table.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateMenusTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('menus', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->string('code', 32)->nullable(false)->comment('菜单编码');
|
||||||
|
$table->string('name', 32)->nullable(false)->comment('菜单名称');
|
||||||
|
$table->unsignedBigInteger('parent_id')->default(0);
|
||||||
|
$table->unsignedInteger('seq')->default(0)->comment('排序序号');
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->timestamps();
|
||||||
|
// 索引
|
||||||
|
$table->unique('code');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('menus');
|
||||||
|
}
|
||||||
|
}
|
||||||
45
database/migrations/2022_08_02_022448_create_shops_table.php
Normal file
45
database/migrations/2022_08_02_022448_create_shops_table.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateShopsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('shops', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->string('name')->unique();
|
||||||
|
$table->unsignedTinyInteger('plat_id')->comment('平台id');
|
||||||
|
$table->string('access_token')->nullable();
|
||||||
|
$table->unsignedMediumInteger('expires_at')->nullable()->comment('access_token过期时间点');
|
||||||
|
$table->unsignedInteger('expires_in')->nullable()->comment('access_token过期时间段,10(表示10秒后过期)');
|
||||||
|
$table->string('owner_id')->nullable()->comment('商家店铺id');
|
||||||
|
$table->string('owner_name')->nullable()->comment('商家账号名称');
|
||||||
|
$table->string('refresh_token')->nullable()->comment('refresh token,可用来刷新access_token');
|
||||||
|
$table->unsignedMediumInteger('refresh_token_expires_at')->nullable()->comment('Refresh token过期时间点');
|
||||||
|
$table->unsignedInteger('refresh_token_expires_in')->nullable()->comment('refresh_token过期时间段,10表示10秒后过期');
|
||||||
|
$table->text('scope')->nullable()->comment('接口列表');
|
||||||
|
$table->text('pop_auth_token_create_response')->nullable()->comment('授权认证信息');
|
||||||
|
$table->string('status')->default(0)->comment('状态');
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('shops');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateBusinessGoodsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('business_goods_skus', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->bigInteger('shop_id');
|
||||||
|
$table->bigInteger('self_sku_id')->nullable();
|
||||||
|
$table->string('activity_no')->nullable();
|
||||||
|
$table->string('category_name')->nullable();
|
||||||
|
$table->mediumInteger('create_time')->nullable();
|
||||||
|
$table->text('goods_desc')->nullable();
|
||||||
|
$table->string('goods_id')->nullable();
|
||||||
|
$table->text('goods_image_list')->nullable();
|
||||||
|
$table->string('goods_name')->nullable();
|
||||||
|
$table->integer('is_activity_delete')->nullable();
|
||||||
|
$table->integer('limit_buy')->nullable();
|
||||||
|
$table->mediumInteger('market_price')->nullable();
|
||||||
|
$table->mediumInteger('update_time')->nullable();
|
||||||
|
$table->string('external_sku_id')->nullable();
|
||||||
|
$table->mediumInteger('goods_purchase_price')->nullable();
|
||||||
|
$table->mediumInteger('price_in_fen')->nullable();
|
||||||
|
$table->mediumInteger('quantity')->nullable();
|
||||||
|
$table->integer('quantity_type')->nullable();
|
||||||
|
$table->mediumInteger('reserve_quantity')->nullable();
|
||||||
|
$table->mediumInteger('sku_id')->nullable();
|
||||||
|
$table->mediumInteger('sold_quantity')->nullable();
|
||||||
|
$table->text('spec_list')->nullable();
|
||||||
|
$table->string('spec_name')->nullable();
|
||||||
|
$table->string('thumb_url')->nullable();
|
||||||
|
$table->mediumInteger('total_quantity')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('business_goods');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateBusinessOrdersTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('business_orders', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->integer('shop_id');
|
||||||
|
$table->bigInteger('activity_no')->nullable();
|
||||||
|
$table->string('activity_title')->nullable();
|
||||||
|
$table->mediumInteger('after_sales_status')->nullable();
|
||||||
|
$table->string('business_note')->nullable();
|
||||||
|
$table->string('buyer_memo')->nullable();
|
||||||
|
$table->integer('cancel_status')->nullable();
|
||||||
|
$table->mediumInteger('confirm_at')->nullable();
|
||||||
|
$table->mediumInteger('discount_amount')->nullable();
|
||||||
|
$table->string('help_sell_nickname')->nullable();
|
||||||
|
$table->string('inner_transaction_id')->nullable();
|
||||||
|
$table->boolean('is_supplier')->nullable();
|
||||||
|
$table->integer('logistics_type')->nullable();
|
||||||
|
$table->integer('mall_activity_type')->nullable();
|
||||||
|
$table->string('nick_name')->nullable();
|
||||||
|
$table->mediumInteger('order_amount')->nullable();
|
||||||
|
$table->string('order_sn')->nullable();
|
||||||
|
$table->integer('participate_no')->nullable();
|
||||||
|
$table->mediumInteger('platform_discount_amount')->nullable();
|
||||||
|
$table->string('receiver_address_city')->nullable();
|
||||||
|
$table->string('receiver_address_detail')->nullable();
|
||||||
|
$table->string('receiver_address_district')->nullable();
|
||||||
|
$table->string('receiver_address_province')->nullable();
|
||||||
|
$table->string('receiver_mobile')->nullable();
|
||||||
|
$table->string('receiver_name')->nullable();
|
||||||
|
$table->string('secret_remark')->nullable();
|
||||||
|
$table->string('self_pick_site_no')->nullable();
|
||||||
|
$table->string('self_pick_up_address')->nullable();
|
||||||
|
$table->string('self_pick_up_contact_mobile')->nullable();
|
||||||
|
$table->string('self_pick_up_contact_name')->nullable();
|
||||||
|
$table->string('self_pick_up_site_name')->nullable();
|
||||||
|
$table->mediumInteger('service_amount')->nullable();
|
||||||
|
$table->mediumInteger('shipping_amount')->nullable();
|
||||||
|
$table->integer('shipping_status')->nullable();
|
||||||
|
$table->string('supply_activity_no')->nullable();
|
||||||
|
$table->integer('supply_participate_no')->nullable();
|
||||||
|
$table->mediumInteger('theoretical_refund_amount')->nullable();
|
||||||
|
$table->string('transaction_id')->nullable();
|
||||||
|
$table->mediumInteger('updated_at')->nullable();
|
||||||
|
$table->integer('verification_status')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('business_orders');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateBusinessOrderItemsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('business_order_items', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->bigInteger('shop_id');
|
||||||
|
$table->bigInteger('business_order_id');
|
||||||
|
$table->integer('already_cancel_number')->nullable();
|
||||||
|
$table->integer('cancel_status')->nullable();
|
||||||
|
$table->string('category_name')->nullable();
|
||||||
|
$table->string('external_sku_id')->nullable();
|
||||||
|
$table->mediumInteger('goods_amount')->nullable();
|
||||||
|
$table->mediumInteger('goods_cost_price')->nullable();
|
||||||
|
$table->mediumInteger('goods_id')->nullable();
|
||||||
|
$table->string('goods_name')->nullable();
|
||||||
|
$table->integer('goods_number')->nullable();
|
||||||
|
$table->mediumInteger('goods_price')->nullable();
|
||||||
|
$table->mediumInteger('goods_purchase_price')->nullable();
|
||||||
|
$table->string('goods_specification')->nullable();
|
||||||
|
$table->mediumInteger('help_sell_amount')->nullable();
|
||||||
|
$table->boolean('is_supplier')->nullable();
|
||||||
|
$table->integer('need_verification_number')->nullable();
|
||||||
|
$table->integer('shipping_status')->nullable();
|
||||||
|
$table->mediumInteger('sku_id')->nullable();
|
||||||
|
$table->string('sub_order_sn')->nullable();
|
||||||
|
$table->mediumInteger('theoretically_refund_amount')->nullable();
|
||||||
|
$table->string('thumb_url')->nullable();
|
||||||
|
$table->integer('verification_number')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('business_order_items');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,5 +12,11 @@ class DatabaseSeeder extends Seeder
|
|||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
// $this->call(UsersTableSeeder::class);
|
// $this->call(UsersTableSeeder::class);
|
||||||
|
factory(\App\Models\User::class)->create();
|
||||||
|
$this->call([
|
||||||
|
MenusTableSeeder::class,
|
||||||
|
PermissionsTableSeeder::class,
|
||||||
|
RolesTableSeeder::class,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
35
database/seeds/MenusTableSeeder.php
Normal file
35
database/seeds/MenusTableSeeder.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class MenusTableSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
// 商品管理-(商品列表,商品种类,商品品牌)
|
||||||
|
$id = DB::table('menus')->insertGetId(['parent_id' => 0,'code' => 'GOODS_MANAGE', 'name' => '商品管理', 'seq' => 0]);
|
||||||
|
DB::table('menus')->insert([
|
||||||
|
['parent_id' => $id,'code' => 'GOODS_LIST', 'name' => '商品列表', 'seq' => 0],
|
||||||
|
['parent_id' => $id,'code' => 'GOODS_TYPE', 'name' => '商品种类', 'seq' => 1],
|
||||||
|
['parent_id' => $id,'code' => 'GOODS_BRAND', 'name' => '商品品牌', 'seq' => 2],
|
||||||
|
]);
|
||||||
|
// 店铺管理
|
||||||
|
DB::table('menus')->insertGetId(['parent_id' => 0,'code' => 'SHOP_MANAGE', 'name' => '店铺管理', 'seq' => 1]);
|
||||||
|
// 用户管理
|
||||||
|
DB::table('menus')->insertGetId(['parent_id' => 0,'code' => 'USER_MANAGE', 'name' => '用户管理', 'seq' => 2]);
|
||||||
|
// 系统管理-(角色管理,权限管理)
|
||||||
|
$id = DB::table('menus')->insertGetId(['parent_id' => 0,'code' => 'SYSTEM_MANAGE', 'name' => '系统管理', 'seq' => 3]);
|
||||||
|
DB::table('menus')->insert([
|
||||||
|
['parent_id' => $id,'code' => 'ROLE_MANAGE', 'name' => '角色管理', 'seq' => 0],
|
||||||
|
['parent_id' => $id,'code' => 'PERMISSION_MANAGE', 'name' => '权限管理', 'seq' => 1],
|
||||||
|
]);
|
||||||
|
// 系统日志
|
||||||
|
DB::table('menus')->insertGetId(['parent_id' => 0,'code' => 'SYSTEM_LOG', 'name' => '系统日志', 'seq' => 4]);
|
||||||
|
}
|
||||||
|
}
|
||||||
22
database/seeds/PermissionsTableSeeder.php
Normal file
22
database/seeds/PermissionsTableSeeder.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class PermissionsTableSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$routes = include(resource_path('lang/zh-CN/permission.php'));
|
||||||
|
$data = [];
|
||||||
|
foreach ($routes as $key => $route) {
|
||||||
|
$data[] = ['name' => $key, 'guard_name' => 'api'];
|
||||||
|
}
|
||||||
|
DB::table('permissions')->insert($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
database/seeds/RolesTableSeeder.php
Normal file
19
database/seeds/RolesTableSeeder.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class RolesTableSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
DB::table('roles')->insert([
|
||||||
|
['name' => '超级管理员', 'guard_name' => 'api'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
3
resources/frontend/.browserslistrc
Normal file
3
resources/frontend/.browserslistrc
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
> 1%
|
||||||
|
last 2 versions
|
||||||
|
not dead
|
||||||
17
resources/frontend/.eslintrc.js
vendored
Normal file
17
resources/frontend/.eslintrc.js
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
env: {
|
||||||
|
node: true
|
||||||
|
},
|
||||||
|
extends: [
|
||||||
|
'plugin:vue/essential',
|
||||||
|
'@vue/standard'
|
||||||
|
],
|
||||||
|
parserOptions: {
|
||||||
|
parser: 'babel-eslint'
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||||
|
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
|
||||||
|
}
|
||||||
|
}
|
||||||
23
resources/frontend/.gitignore
vendored
Normal file
23
resources/frontend/.gitignore
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/dist
|
||||||
|
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
24
resources/frontend/README.md
Normal file
24
resources/frontend/README.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# hello-world
|
||||||
|
|
||||||
|
## Project setup
|
||||||
|
```
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and hot-reloads for development
|
||||||
|
```
|
||||||
|
npm run serve
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and minifies for production
|
||||||
|
```
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lints and fixes files
|
||||||
|
```
|
||||||
|
npm run lint
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customize configuration
|
||||||
|
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||||
5
resources/frontend/babel.config.js
vendored
Normal file
5
resources/frontend/babel.config.js
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
'@vue/cli-plugin-babel/preset'
|
||||||
|
]
|
||||||
|
}
|
||||||
13478
resources/frontend/package-lock.json
generated
Normal file
13478
resources/frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user