commit
83901c8fcf
@ -1,15 +1,15 @@
|
||||
APP_NAME=Laravel
|
||||
APP_NAME=ERP
|
||||
APP_ENV=local
|
||||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
APP_URL=http://erp.test
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=laravel
|
||||
DB_DATABASE=erp
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
|
||||
|
||||
16
README.md
16
README.md
@ -2,21 +2,27 @@
|
||||
|
||||
#### 介绍
|
||||
|
||||
主要为鲜花售卖提供一个统一的商品管理平台,支持对接第三方平台,包括商品管理,库存同步,订单管理,发货等
|
||||
|
||||
#### 软件架构
|
||||
|
||||
- laravel 6.*
|
||||
- vue2.*
|
||||
- element-ui
|
||||
|
||||
#### 安装教程
|
||||
#### 本地开发安装教程
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
1. `composer install`
|
||||
2. `cp .env.example .env`
|
||||
3. 修改 .env 配置项为本地配置
|
||||
4. 创建数据库 `CREATE DATABASE IF NOT EXISTS `erp` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci;`
|
||||
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
|
||||
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);
|
||||
}
|
||||
}
|
||||
56
app/Console/Commands/Swoole.php
Normal file
56
app/Console/Commands/Swoole.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Services\Business\BusinessFactory;
|
||||
use App\Utils\DateTimeUtils;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Shop;
|
||||
|
||||
use Swoole\Timer;
|
||||
use Swoole\Event;
|
||||
|
||||
class Swoole extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'swoole:timer';
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
Timer::tick(1000, function () {
|
||||
$shops = Shop::query()->where('plat_id', 1)->where('status', 1)->get();
|
||||
$endTime = DateTimeUtils::getMicroTime();
|
||||
$beginTime = $endTime - 10000;
|
||||
foreach ($shops as $shop) {
|
||||
BusinessFactory::init()->make($shop->plat_id)->setShop($shop)->downloadOrdersAndSave($beginTime, $endTime, 'increment', 1);
|
||||
}
|
||||
});
|
||||
Event::wait();
|
||||
}
|
||||
}
|
||||
62
app/Console/Commands/Test.php
Normal file
62
app/Console/Commands/Test.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Shop;
|
||||
use App\Services\Business\BusinessFactory;
|
||||
use App\Utils\DateTimeUtils;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class Test extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'test';
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
$shop = Shop::query()->find(1);
|
||||
$business = BusinessFactory::init()->make($shop->plat_id);
|
||||
$business->setShop($shop);
|
||||
// 下载商品列表
|
||||
// $business->downloadGoodsListAndBind();
|
||||
|
||||
// 下载单个商品
|
||||
// $business->downloadGoods(1);
|
||||
|
||||
// 库存修改
|
||||
// $business->incrQuantity(1);
|
||||
|
||||
// 订单下载
|
||||
// $beginTime = DateTimeUtils::getMicroTime('2022-08-08');
|
||||
// $endTime = DateTimeUtils::getMicroTime('2022-08-09');
|
||||
// $business->downloadOrdersAndSave($beginTime, $endTime);
|
||||
|
||||
$this->info('执行测试成功');
|
||||
}
|
||||
}
|
||||
51
app/Console/Commands/UpdateSuperAdminPermissions.php
Normal file
51
app/Console/Commands/UpdateSuperAdminPermissions.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 UpdateSuperAdminPermissions 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('更新成功');
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use App\Console\Commands\Inventory;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
@ -24,8 +25,9 @@ class Kernel extends ConsoleKernel
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
// $schedule->command('inspire')
|
||||
// ->hourly();
|
||||
// 服务器添加cron入口
|
||||
// * * * * * cd /home/wwwroot/erp.staging.chutang66.com && php artisan schedule:run >> /dev/null 2>&1
|
||||
$schedule->command(Inventory::class)->dailyAt('07:00');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
58
app/Events/BusinessOrdersUpdate.php
Normal file
58
app/Events/BusinessOrdersUpdate.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Models\BusinessOrderItem;
|
||||
use App\Models\GoodsSku;
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class BusinessOrdersUpdate
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
public $num;
|
||||
public $businessOrderItem;
|
||||
public $goodsSku;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(BusinessOrderItem $item, $num)
|
||||
{
|
||||
$this->businessOrderItem = $item;
|
||||
$this->num = $num;
|
||||
$this->updateStock();
|
||||
}
|
||||
|
||||
private function updateStock()
|
||||
{
|
||||
[$goodsCode, $skuCode] = explode('_', $this->businessOrderItem->external_sku_id);
|
||||
$this->goodsSku = GoodsSku::query()->where('sku_code', $skuCode)
|
||||
->with(['goods' => function ($query) use ($goodsCode) {
|
||||
$query->where('goods_code', $goodsCode);
|
||||
}])
|
||||
->first();
|
||||
if ($this->goodsSku) {
|
||||
$this->goodsSku->stock += $this->num;
|
||||
$this->goodsSku->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return \Illuminate\Broadcasting\Channel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
return new PrivateChannel('channel-name');
|
||||
}
|
||||
}
|
||||
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\Providers\RouteServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
|
||||
class LoginController extends Controller
|
||||
@ -37,4 +39,21 @@ class LoginController extends Controller
|
||||
{
|
||||
$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;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use App\User;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Faker\Generator as Faker;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
@ -50,9 +52,10 @@ class RegisterController extends Controller
|
||||
protected function validator(array $data)
|
||||
{
|
||||
return Validator::make($data, [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
||||
'name' => ['required', 'string', 'unique:users', 'max:191'],
|
||||
'email' => ['string', 'email', 'max:191', 'unique:users'],
|
||||
'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.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \App\User
|
||||
* @return User
|
||||
*/
|
||||
protected function create(array $data)
|
||||
{
|
||||
$faker = new Faker();
|
||||
|
||||
return User::create([
|
||||
'name' => $data['name'],
|
||||
'email' => $data['email'],
|
||||
'email' => $data['email'] ?? $faker->unique()->safeEmail,
|
||||
'password' => Hash::make($data['password']),
|
||||
'api_token' => Str::random(60),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,4 +10,40 @@ use Illuminate\Routing\Controller as BaseController;
|
||||
class Controller extends BaseController
|
||||
{
|
||||
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:191|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:191',
|
||||
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']);
|
||||
}
|
||||
}
|
||||
100
app/Http/Controllers/Goods/GoodsController.php
Normal file
100
app/Http/Controllers/Goods/GoodsController.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?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\DateTimeUtils;
|
||||
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['stock'] = $item['num'];
|
||||
$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' => DateTimeUtils::getToday(),
|
||||
];
|
||||
}
|
||||
$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()
|
||||
{
|
||||
$file = resource_path('templates/goods_skus_import.xlsx');
|
||||
$headers = [
|
||||
'Content-Type: application/xlsx',
|
||||
];
|
||||
|
||||
return response()->download($file, 'goods_skus_import.xlsx', $headers);
|
||||
}
|
||||
}
|
||||
367
app/Http/Controllers/Goods/GoodsSkusController.php
Normal file
367
app/Http/Controllers/Goods/GoodsSkusController.php
Normal file
@ -0,0 +1,367 @@
|
||||
<?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\DateTimeUtils;
|
||||
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 = DateTimeUtils::getToday();
|
||||
$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) {
|
||||
$query->where('day', $day);
|
||||
}])
|
||||
->orderBy('updated_at', 'desc')
|
||||
->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->log = new LogModel([
|
||||
'module' => 'goods',
|
||||
'action' => $request->getMethod(),
|
||||
'target_type' => 'goods',
|
||||
]);
|
||||
$this->setBeforeUpdate($goods->toArray());
|
||||
$goods->update($request->goods);
|
||||
$this->setAfterUpdate($goods->toArray());
|
||||
$this->addLog($sku->goods_id, 'update');
|
||||
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'),
|
||||
],
|
||||
];
|
||||
$skuRules = (new GoodsSkuRequest())->arrayRules('skus.*.');
|
||||
$validator = Validator::make($request->all(), array_merge($appendRules, $skuRules));
|
||||
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', DateTimeUtils::getToday())->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', DateTimeUtils::getToday())->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($request)
|
||||
{
|
||||
$skus = $request->skus;
|
||||
$update = reset($skus);
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$sku = GoodsSku::query()->where('id', $update['id'])->first(['id', 'two_days_ago_num', 'yesterday_num', 'num', 'stock', 'reserve']);
|
||||
$record = DailyStockRecord::query()
|
||||
->where('sku_id', $sku->id)
|
||||
->where('day', DateTimeUtils::getToday())
|
||||
->first();
|
||||
$this->setBeforeUpdate([
|
||||
'two_days_ago_num' => $sku->two_days_ago_num,
|
||||
'yesterday_num' => $sku->yesterday_num,
|
||||
'arrived_today_num' => $record->arrived_today_num,
|
||||
'num' => $sku->num,
|
||||
'stock' => $sku->stock,
|
||||
]);
|
||||
$sku->two_days_ago_num = $update['two_days_ago_num'];
|
||||
$sku->yesterday_num = $update['yesterday_num'];
|
||||
$stock = $update['two_days_ago_num'] + $update['yesterday_num'] + $update['arrived_today_num'] - $sku->reserve - $record->loss_num;
|
||||
$sku->stock = $stock;
|
||||
$sku->num = $stock + $sku->reserve + $record->loss_num;
|
||||
$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,
|
||||
'num' => $sku->num,
|
||||
'stock' => $sku->stock,
|
||||
]);
|
||||
$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());
|
||||
goto end;
|
||||
}
|
||||
$updateField = \request('updateField');
|
||||
$sku = GoodsSku::query()->find($id);
|
||||
if ('loss_num' === $updateField) {
|
||||
$record = DailyStockRecord::query()
|
||||
->where('sku_id', $id)
|
||||
->where('day', DateTimeUtils::getToday())
|
||||
->first(['id', 'loss_num']);
|
||||
$this->log->message = $request->get('reason');
|
||||
$this->setBeforeUpdate($record->loss_num);
|
||||
$record->loss_num += $request->loss_num;
|
||||
$record->save();
|
||||
$this->setAfterUpdate($record->loss_num);
|
||||
$sku->stock -= $request->loss_num;
|
||||
} else {
|
||||
$sku->$updateField = $request->$updateField;
|
||||
}
|
||||
$this->setBeforeUpdate($sku->$updateField);
|
||||
if ('reserve' === $updateField) {
|
||||
$changeNum = $sku->reserve - $request->reserve;
|
||||
if (0 > $changeNum + $sku->stock) {
|
||||
$this->setValidatorFailResponse('预留量超过库存数量');
|
||||
goto end;
|
||||
}
|
||||
$sku->stock += $changeNum;
|
||||
}
|
||||
$sku->save();
|
||||
$this->setAfterUpdate($sku->$updateField);
|
||||
$this->addLog($id, $updateField);
|
||||
end:
|
||||
|
||||
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 {
|
||||
$import = new GoodsSkusImport();
|
||||
$path = $request->file('goodsSkus');
|
||||
Excel::import($import, $path);
|
||||
$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:191|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:191',
|
||||
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']);
|
||||
}
|
||||
}
|
||||
22
app/Http/Controllers/Log/LogsController.php
Normal file
22
app/Http/Controllers/Log/LogsController.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?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()
|
||||
->orderBy('id', 'desc')
|
||||
->with(['user:id,name'])
|
||||
->filter()
|
||||
->paginate();
|
||||
|
||||
return LogsResource::collection($res);
|
||||
}
|
||||
}
|
||||
112
app/Http/Controllers/Menu/MenusController.php
Normal file
112
app/Http/Controllers/Menu/MenusController.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?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 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:191|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:191', 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')->where('id', '<>', 1)->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:191|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:191', 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);
|
||||
}
|
||||
}
|
||||
134
app/Http/Controllers/Shop/ShopsController.php
Normal file
134
app/Http/Controllers/Shop/ShopsController.php
Normal file
@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Shop;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Shop;
|
||||
use App\Http\Resources\ShopsResource;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\Services\Business\BusinessFactory;
|
||||
use Illuminate\Validation\Rule;
|
||||
use App\Models\BusinessOrderItem;
|
||||
|
||||
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:191|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;
|
||||
if (0 == $request->plat_id) {
|
||||
$shop->status = 2;
|
||||
}
|
||||
$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);
|
||||
} 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'));
|
||||
}
|
||||
if ('orders' === $request->get('type')) {
|
||||
$business->saveOrders($request->get('data'));
|
||||
}
|
||||
|
||||
return response(['Code' => 10000, 'Message' => 'SUCCESS']);
|
||||
}
|
||||
|
||||
public function countOrdersNumWithSkuCode(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'sku_code' => ['required', 'array'],
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||
|
||||
return response($this->res, $this->res['httpCode']);
|
||||
}
|
||||
$fields = implode(',', [
|
||||
'shop_id',
|
||||
'external_sku_id',
|
||||
'count(id) as count',
|
||||
]);
|
||||
$res = BusinessOrderItem::query()
|
||||
->select(DB::raw($fields))
|
||||
->whereIn('external_sku_id', $request->get('sku_code'))
|
||||
->groupBy(['shop_id', 'external_sku_id'])
|
||||
->with(['shop:id,name'])
|
||||
->get();
|
||||
$data = [];
|
||||
foreach ($res as $item) {
|
||||
$data[$item->external_sku_id][] = [
|
||||
'shop_name' => $item->shop->name,
|
||||
'count' => $item->count,
|
||||
];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
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:191|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:191',
|
||||
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,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::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:191'],
|
||||
'img_url' => ['required', 'string', 'max:191'],
|
||||
'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;
|
||||
}
|
||||
}
|
||||
77
app/Http/Requests/GoodsSkuRequest.php
Normal file
77
app/Http/Requests/GoodsSkuRequest.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?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' => ['sometimes', 'required', 'string', 'max:191'],
|
||||
'sku_code' => ['sometimes', 'required', 'distinct', 'alpha_dash', 'max:32'],
|
||||
'status' => ['sometimes', 'required', 'integer', Rule::in([0, 1, 2])],
|
||||
'num' => ['sometimes', 'required', 'integer'],
|
||||
'cost' => ['sometimes', 'required', 'numeric', 'gt:0'],
|
||||
'reference_price' => [
|
||||
'sometimes',
|
||||
'numeric',
|
||||
'gt:0'
|
||||
],
|
||||
'reserve' => [
|
||||
'sometimes',
|
||||
'integer',
|
||||
],
|
||||
'loss_num' => [
|
||||
'sometimes',
|
||||
'integer',
|
||||
],
|
||||
'arrived_today_num' => [
|
||||
'sometimes',
|
||||
'integer',
|
||||
],
|
||||
'yesterday_num' => [
|
||||
'sometimes',
|
||||
'integer',
|
||||
],
|
||||
'two_days_ago_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);
|
||||
}
|
||||
}
|
||||
111
app/Imports/GoodsSkusImport.php
Normal file
111
app/Imports/GoodsSkusImport.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace App\Imports;
|
||||
|
||||
use App\Models\DailyStockRecord;
|
||||
use App\Models\Goods;
|
||||
use App\Models\GoodsBrand;
|
||||
use App\Models\GoodsSku;
|
||||
use App\Models\GoodsType;
|
||||
use App\Utils\DateTimeUtils;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
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:191'],
|
||||
'*.1' => ['required', 'string', 'max:191', 'exists:goods_types,name'],
|
||||
'*.2' => ['string', 'max:191', 'exists:goods_brands,name'],
|
||||
'*.3' => ['required', 'alpha_dash', 'max:32'],
|
||||
'*.4' => ['required', 'string', 'max:191'],
|
||||
'*.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;
|
||||
}
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
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 &$newGoodsSku) {
|
||||
$newGoodsSku['goods_id'] = isset($hasGoods[$newGoodsSku['goods_id']]) ? $hasGoods[$newGoodsSku['goods_id']]['id'] : $newGoodsSku['goods_id'];
|
||||
}
|
||||
unset($newGoodsSku);
|
||||
}
|
||||
$goodsSku = new GoodsSku();
|
||||
$goodsSku->batchInsert(array_values($skus));
|
||||
$collection = GoodsSku::query()->whereIn('sku_code', array_column($skus, 'sku_code'))->get(['id', 'sku_code'])->toArray();
|
||||
$newRecords = [];
|
||||
foreach ($collection as $sku) {
|
||||
$newRecords[] = [
|
||||
'sku_id' => $sku['id'],
|
||||
'day' => DateTimeUtils::getToday(),
|
||||
];
|
||||
}
|
||||
$record = new DailyStockRecord();
|
||||
$record->batchInsert($newRecords);
|
||||
DB::commit();
|
||||
} catch (\Exception $exception) {
|
||||
DB::rollBack();
|
||||
}
|
||||
}
|
||||
}
|
||||
45
app/Jobs/BusinessGoodsSkuIncrQuantity.php
Normal file
45
app/Jobs/BusinessGoodsSkuIncrQuantity.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\BusinessOrderItem;
|
||||
use App\Models\GoodsSku;
|
||||
use App\Services\Business\BusinessFactory;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class BusinessGoodsSkuIncrQuantity implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $shop;
|
||||
public $businessOrderItem;
|
||||
public $num;
|
||||
public $goodsSku;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($shop, BusinessOrderItem $businessOrderItem, $num, GoodsSku $goodsSku)
|
||||
{
|
||||
$this->shop = $shop;
|
||||
$this->businessOrderItem = $businessOrderItem;
|
||||
$this->num = $num;
|
||||
$this->goodsSku = $goodsSku;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
BusinessFactory::init()->make($this->shop['plat_id'])->setShopWithId($this->shop['id'])->incrQuantity($this->businessOrderItem, $this->num, true, $this->goodsSku);
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
35
app/Listeners/SendDatabaseNotification.php
Normal file
35
app/Listeners/SendDatabaseNotification.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use App\Events\BusinessOrdersUpdate;
|
||||
|
||||
class SendDatabaseNotification implements ShouldQueue
|
||||
{
|
||||
use InteractsWithQueue;
|
||||
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param BusinessOrdersUpdate $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(BusinessOrdersUpdate $event)
|
||||
{
|
||||
if (5 >= $event->goodsSku->stock) {
|
||||
// 发送通知给管理员
|
||||
}
|
||||
}
|
||||
}
|
||||
56
app/Listeners/UpdateBusinessGoodsStock.php
Normal file
56
app/Listeners/UpdateBusinessGoodsStock.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use App\Models\Log;
|
||||
use App\Models\Shop;
|
||||
use App\Services\Business\BusinessFactory;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use App\Events\BusinessOrdersUpdate;
|
||||
use App\Jobs\BusinessGoodsSkuIncrQuantity;
|
||||
|
||||
class UpdateBusinessGoodsStock implements ShouldQueue
|
||||
{
|
||||
use InteractsWithQueue;
|
||||
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param BusinessOrdersUpdate $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(BusinessOrdersUpdate $event)
|
||||
{
|
||||
if (empty($event->goodsSku)) {
|
||||
$log = new Log();
|
||||
$log->module = 'goods';
|
||||
$log->action = 'PATCH';
|
||||
$log->target_type = 'goods_sku';
|
||||
$log->target_id = $event->goodsSku->id;
|
||||
$log->target_field = 'stock';
|
||||
$log->user_id = $event->businessOrderItem->shop_id;
|
||||
$log->message = ($event->businessOrderItem->external_sku_id ?: '商品') . '未找到';
|
||||
$log->save();
|
||||
return;
|
||||
}
|
||||
$shops = Shop::query()->where('id', '<>', $event->businessOrderItem->shop_id)->where('status', 1)->get(['id', 'plat_id']);
|
||||
if (empty($shops)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($shops as $shop) {
|
||||
BusinessGoodsSkuIncrQuantity::dispatch($shop, $event->businessOrderItem, $event->num, $event->goodsSku);
|
||||
}
|
||||
}
|
||||
}
|
||||
37
app/Models/BusinessGoodsSku.php
Normal file
37
app/Models/BusinessGoodsSku.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
class BusinessGoodsSku extends Model
|
||||
{
|
||||
/**
|
||||
* 不可批量赋值的属性。为空则所有熟悉都可以批量赋值
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'shop_id',
|
||||
'business_order_id',
|
||||
'already_cancel_number',
|
||||
'cancel_status',
|
||||
'category_name',
|
||||
'external_sku_id',
|
||||
'goods_amount',
|
||||
'goods_cost_price',
|
||||
'goods_id',
|
||||
'goods_name',
|
||||
'goods_number',
|
||||
'goods_price',
|
||||
'goods_purchase_price',
|
||||
'goods_specification',
|
||||
'help_sell_amount',
|
||||
'is_supplier',
|
||||
'need_verification_number',
|
||||
'shipping_status',
|
||||
'sku_id',
|
||||
'sub_order_sn',
|
||||
'theoretically_refund_amount',
|
||||
'thumb_url',
|
||||
'verification_number',
|
||||
];
|
||||
}
|
||||
53
app/Models/BusinessOrder.php
Normal file
53
app/Models/BusinessOrder.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
class BusinessOrder extends Model
|
||||
{
|
||||
/**
|
||||
* 不可批量赋值的属性。为空则所有熟悉都可以批量赋值
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'shop_id',
|
||||
'receiver_address_detail',
|
||||
'receiver_address_province',
|
||||
'self_pick_site_no',
|
||||
'discount_amount',
|
||||
'theoretical_refund_amount',
|
||||
'receiver_address_district',
|
||||
'verification_status',
|
||||
'inner_transaction_id',
|
||||
'is_supplier',
|
||||
'service_amount',
|
||||
'supply_participate_no',
|
||||
'updated_at',
|
||||
'order_amount',
|
||||
'receiver_address_city',
|
||||
'receiver_name',
|
||||
'business_note',
|
||||
'buyer_memo',
|
||||
'logistics_type',
|
||||
'help_sell_nickname',
|
||||
'activity_title',
|
||||
'after_sales_status',
|
||||
'mall_activity_type',
|
||||
'transaction_id',
|
||||
'activity_no',
|
||||
'confirm_at',
|
||||
'platform_discount_amount',
|
||||
'participate_no',
|
||||
'receiver_mobile',
|
||||
'shipping_status',
|
||||
'shipping_amount',
|
||||
'cancel_status',
|
||||
'nick_name',
|
||||
'order_sn',
|
||||
];
|
||||
|
||||
public function items()
|
||||
{
|
||||
return $this->hasMany(BusinessOrderItem::class, 'business_order_id');
|
||||
}
|
||||
}
|
||||
47
app/Models/BusinessOrderItem.php
Normal file
47
app/Models/BusinessOrderItem.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
class BusinessOrderItem extends Model
|
||||
{
|
||||
/**
|
||||
* 不可批量赋值的属性。为空则所有熟悉都可以批量赋值
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'shop_id',
|
||||
'business_order_id',
|
||||
'already_cancel_number',
|
||||
'cancel_status',
|
||||
'category_name',
|
||||
'external_sku_id',
|
||||
'goods_amount',
|
||||
'goods_cost_price',
|
||||
'goods_id',
|
||||
'goods_name',
|
||||
'goods_number',
|
||||
'goods_price',
|
||||
'goods_purchase_price',
|
||||
'goods_specification',
|
||||
'help_sell_amount',
|
||||
'is_supplier',
|
||||
'need_verification_number',
|
||||
'shipping_status',
|
||||
'sku_id',
|
||||
'sub_order_sn',
|
||||
'theoretically_refund_amount',
|
||||
'thumb_url',
|
||||
'verification_number',
|
||||
];
|
||||
|
||||
public function order()
|
||||
{
|
||||
return $this->hasOne(BusinessOrder::class, 'id', 'business_order_id');
|
||||
}
|
||||
|
||||
public function shop()
|
||||
{
|
||||
return $this->hasOne(Shop::class, 'id', 'shop_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
|
||||
{
|
||||
protected $hidden = ['created_at', 'updated_at'];
|
||||
}
|
||||
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
|
||||
{
|
||||
|
||||
}
|
||||
43
app/Models/Goods.php
Normal file
43
app/Models/Goods.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\traits\Filter;
|
||||
|
||||
class Goods extends Model
|
||||
{
|
||||
use Filter;
|
||||
|
||||
//查询字段
|
||||
public $fieldSearchable = [
|
||||
'goods_title',
|
||||
'type_id',
|
||||
'brand_id',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'title',
|
||||
'img_url',
|
||||
'type_id',
|
||||
'brand_id',
|
||||
'goods_code',
|
||||
];
|
||||
|
||||
/**
|
||||
* 多规格
|
||||
*/
|
||||
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'];
|
||||
}
|
||||
74
app/Models/GoodsSku.php
Normal file
74
app/Models/GoodsSku.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\traits\Filter;
|
||||
|
||||
class GoodsSku extends Model
|
||||
{
|
||||
use Filter;
|
||||
|
||||
//查询字段
|
||||
public $fieldSearchable = [
|
||||
'sku_title',
|
||||
'status',
|
||||
];
|
||||
|
||||
/**
|
||||
* 不可批量赋值的属性。为空则所有熟悉都可以批量赋值
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'goods_id',
|
||||
'title',
|
||||
'sku_code',
|
||||
'status',
|
||||
'num',
|
||||
'stock',
|
||||
'cost',
|
||||
'two_days_ago_num',
|
||||
'yesterday_num',
|
||||
'reference_price',
|
||||
'reserve',
|
||||
];
|
||||
|
||||
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'];
|
||||
}
|
||||
116
app/Models/Log.php
Normal file
116
app/Models/Log.php
Normal file
@ -0,0 +1,116 @@
|
||||
<?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',
|
||||
'start_time',
|
||||
'end_time',
|
||||
];
|
||||
|
||||
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] ?? $value;
|
||||
}
|
||||
|
||||
public function getActionAttribute($value)
|
||||
{
|
||||
$map = [
|
||||
'GET' => '查看',
|
||||
'POST' => '新增',
|
||||
'PATCH' => '更新',
|
||||
'DELETE' => '删除',
|
||||
];
|
||||
|
||||
return $map[$value] ?? $value;
|
||||
}
|
||||
|
||||
public function getTargetTypeAttribute($value)
|
||||
{
|
||||
$map = [
|
||||
'goods_sku' => '商品&规格',
|
||||
'goods_type' => '商品种类',
|
||||
'goods_brand' => '商品品牌',
|
||||
'permission' => '权限',
|
||||
'role' => '角色',
|
||||
'menu' => '菜单',
|
||||
'user' => '用户',
|
||||
'upload' => '上传',
|
||||
'kuaituantuan' => '快团团',
|
||||
'miaoxuan' => '妙选',
|
||||
'goods' => '商品',
|
||||
];
|
||||
|
||||
return $map[$value] ?? $value;
|
||||
}
|
||||
|
||||
public function getTargetFieldAttribute($value)
|
||||
{
|
||||
$map = [
|
||||
'add' => '创建',
|
||||
'status' => '状态',
|
||||
'name' => '名称',
|
||||
'title' => '名称',
|
||||
'import' => '导入',
|
||||
'export' => '导出',
|
||||
'set' => '设置',
|
||||
'cost' => '成本',
|
||||
'stock' => '库存',
|
||||
'inventory' => '库存盘点',
|
||||
];
|
||||
|
||||
return $map[$value] ?? $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
|
||||
{
|
||||
|
||||
}
|
||||
48
app/Models/Shop.php
Normal file
48
app/Models/Shop.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Shop extends Model
|
||||
{
|
||||
protected $hidden = [
|
||||
'access_token',
|
||||
'expires_in',
|
||||
'refresh_token',
|
||||
'refresh_token_expires_at',
|
||||
'refresh_token_expires_in',
|
||||
'pop_auth_token_create_response',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'access_token', 'expires_at', 'expires_in', 'owner_id', 'owner_name', 'refresh_token', 'refresh_token_expires_at', 'refresh_token_expires_in', 'scope', 'pop_auth_token_create_response', 'status'
|
||||
];
|
||||
|
||||
public function getStatusAttribute($value)
|
||||
{
|
||||
$map = [
|
||||
0 => '未授权',
|
||||
1 => '已授权',
|
||||
2 => '无需授权',
|
||||
3 => '停用',
|
||||
];
|
||||
if (1 === (int)$value && ($this->attributes['expires_at'] - time()) / 3600 <= 72) {
|
||||
return '重新授权';
|
||||
}
|
||||
|
||||
return $map[$value];
|
||||
}
|
||||
|
||||
public function getPlatList()
|
||||
{
|
||||
return ['妙选', '快团团'];
|
||||
}
|
||||
|
||||
public function getPlatIdAttribute($value)
|
||||
{
|
||||
$map = $this->getPlatList();
|
||||
|
||||
return $map[$value];
|
||||
}
|
||||
}
|
||||
@ -1,14 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Spatie\Permission\Traits\HasRoles;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use Notifiable;
|
||||
use HasRoles;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
@ -25,7 +27,7 @@ class User extends Authenticatable
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password', 'remember_token',
|
||||
'password', 'remember_token', 'api_token', 'email_verified_at',
|
||||
];
|
||||
|
||||
/**
|
||||
@ -36,4 +38,14 @@ class User extends Authenticatable
|
||||
protected $casts = [
|
||||
'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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -2,10 +2,10 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
|
||||
use App\Listeners\SendDatabaseNotification;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use App\Listeners\UpdateBusinessGoodsStock;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
@ -15,8 +15,9 @@ class EventServiceProvider extends ServiceProvider
|
||||
* @var array
|
||||
*/
|
||||
protected $listen = [
|
||||
Registered::class => [
|
||||
SendEmailVerificationNotification::class,
|
||||
'App\Events\BusinessOrdersUpdate' => [
|
||||
UpdateBusinessGoodsStock::class,
|
||||
SendDatabaseNotification::class,
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
160
app/Services/Business/BusinessClient.php
Normal file
160
app/Services/Business/BusinessClient.php
Normal file
@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Business;
|
||||
|
||||
use App\Events\BusinessOrdersUpdate;
|
||||
use App\Models\BusinessGoodsSku;
|
||||
use App\Models\BusinessOrder;
|
||||
use App\Models\BusinessOrderItem;
|
||||
use App\Models\GoodsSku;
|
||||
use App\Models\Log;
|
||||
use App\Models\Shop;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
abstract class BusinessClient
|
||||
{
|
||||
protected $redirectUri = 'http://erp.chutang66.com/callback';
|
||||
protected $code;
|
||||
protected $shop;
|
||||
protected $skuId = 0;
|
||||
|
||||
abstract public function auth();
|
||||
|
||||
abstract public function downloadGoodsListAndBind();
|
||||
|
||||
abstract public function downloadGoods($skuId);
|
||||
|
||||
abstract public function bindGoods($goods);
|
||||
|
||||
abstract public function incrQuantity(BusinessGoodsSku $businessGoodsSku, $num, $incremental, GoodsSku $goodsSku);
|
||||
|
||||
abstract public function downloadOrdersAndSave($beginTime, $endTime, $downloadType = 'default', $page = 1);
|
||||
|
||||
public function saveOrders($orders)
|
||||
{
|
||||
$shopId = $this->getShop()->id;
|
||||
foreach ($orders as $order) {
|
||||
unset($order['custom_item_list'], $order['logistics_list'], $order['gift_order_list']);
|
||||
$order['shop_id'] = $shopId;
|
||||
$orderRecord = BusinessOrder::firstOrNew(['shop_id' => $shopId, 'order_sn' => $order['order_sn']], $order);
|
||||
if (empty($orderRecord->id)) {
|
||||
$orderRecord->save();
|
||||
} else {
|
||||
$orderRecord->update($order);
|
||||
}
|
||||
foreach ($order['sub_order_list'] as $item) {
|
||||
$item['shop_id'] = $shopId;
|
||||
$orderItem = BusinessOrderItem::firstOrNew(['shop_id' => $shopId, 'business_order_id' => $orderRecord->id, 'goods_id' => $item['goods_id'], 'sku_id' => $item['sku_id']], $item);
|
||||
$num = 0;
|
||||
if (empty($orderItem->id)) {
|
||||
if ($item['cancel_status']) {
|
||||
if ($num = $item['goods_number'] - $item['already_cancel_number']) {
|
||||
// 扣库存 $reduceNum
|
||||
$num = 0 - $num;
|
||||
}
|
||||
} else {
|
||||
// 扣库存
|
||||
$num = 0 - $item['goods_number'];
|
||||
}
|
||||
$orderItem->save();
|
||||
} else {
|
||||
if ($item['cancel_status'] !== $orderItem->cancel_status) {
|
||||
if ($item['cancel_status']) {
|
||||
// 加库存
|
||||
$num = $item['already_cancel_number'];
|
||||
} else {
|
||||
// 扣库存
|
||||
$num = 0 - $item['goods_number'];
|
||||
}
|
||||
}
|
||||
$orderItem->update($item);
|
||||
}
|
||||
// 增量更新库存
|
||||
if ($num) {
|
||||
event(new BusinessOrdersUpdate($orderItem, $num));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public function setCode($code)
|
||||
{
|
||||
$this->code = $code;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCode()
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
public function setSkuId($skuId)
|
||||
{
|
||||
$this->skuId = $skuId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSkuId()
|
||||
{
|
||||
return $this->skuId;
|
||||
}
|
||||
|
||||
public function formDataPostRequest($url, $params)
|
||||
{
|
||||
$method = 'POST';
|
||||
$headers = [
|
||||
'headers' => ['Content-type' => 'application/x-www-form-urlencoded;charset=UTF-8'],
|
||||
'form_params' => $params
|
||||
];
|
||||
$res = (new Client())->request($method, $url, $headers);
|
||||
$size = $res->getBody()->getSize();
|
||||
$res = json_decode($res->getBody()->getContents(), true);
|
||||
if ('pdd.ktt.increment.order.query' === $params['type']) {
|
||||
$log = Log::query()->where('user_id', $this->getShop()->id)->where('target_field', $params['type'])->first();
|
||||
} else {
|
||||
$log = new Log();
|
||||
}
|
||||
$log->module = 'plat';
|
||||
$log->action = $method;
|
||||
$log->target_type = $this->getShop()->plat_id;
|
||||
$log->target_id = $this->getSkuId();
|
||||
$log->target_field = $params['type'];
|
||||
$log->user_id = $this->getShop()->id;
|
||||
if ($size < 64000) {
|
||||
$log->message = json_encode($res, 256);
|
||||
}
|
||||
$log->save();
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
27
app/Services/Business/BusinessFactory.php
Normal file
27
app/Services/Business/BusinessFactory.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Business;
|
||||
|
||||
use App\Services\Business\KuaiTuanTuan\KuaiTuanTuan;
|
||||
use App\Services\Business\MiaoXuan\MiaoXuan;
|
||||
|
||||
class BusinessFactory
|
||||
{
|
||||
private $platList;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->platList['快团团'] = KuaiTuanTuan::class;
|
||||
$this->platList['妙选'] = MiaoXuan::class;
|
||||
}
|
||||
|
||||
public function make($platName)
|
||||
{
|
||||
return new $this->platList[$platName];
|
||||
}
|
||||
|
||||
public static function init()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
}
|
||||
68
app/Services/Business/KuaiTuanTuan/Goods.php
Normal file
68
app/Services/Business/KuaiTuanTuan/Goods.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?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']);
|
||||
$businessGood['goods_image_list'] = json_encode($businessGood['goods_image_list'], 256);
|
||||
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 static function downloadSingle($goodsId)
|
||||
{
|
||||
$type = 'pdd.ktt.goods.query.single';
|
||||
$appendParams = [
|
||||
'goods_id' => $goodsId,
|
||||
'page' => 1,
|
||||
'size' => 100,
|
||||
];
|
||||
|
||||
return [$type, $appendParams];
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
145
app/Services/Business/KuaiTuanTuan/KuaiTuanTuan.php
Normal file
145
app/Services/Business/KuaiTuanTuan/KuaiTuanTuan.php
Normal file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Business\KuaiTuanTuan;
|
||||
|
||||
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 = '8d7ca13bc27247b6a04e08404b51dfd8';
|
||||
|
||||
protected $clientSecret = '4478bc82dc1e1f68fe06c9f2bc683f1dcb3e6d83';
|
||||
|
||||
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['scope'] = json_encode($accessToken['scope'], 256);
|
||||
$accessToken['pop_auth_token_create_response'] = json_encode($accessToken, 256);
|
||||
$accessToken['status'] = 1;
|
||||
$this->shop->update($accessToken);
|
||||
|
||||
return $this->shop;
|
||||
}
|
||||
|
||||
public function downloadGoodsListAndBind($page = 1)
|
||||
{
|
||||
[$type, $appendParams] = Goods::downloadGoods($this->shop->owner_id, $page);
|
||||
$res = $this->doRequest($type, $appendParams);
|
||||
$goods = $res['ktt_goods_query_list_response']['goods_list'];
|
||||
$this->bindGoods($goods);
|
||||
$pageNum = ceil($res['ktt_goods_query_list_response']['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($businessGoodsSku, $num, $incremental, GoodsSku $goodsSku)
|
||||
{
|
||||
[$type, $appendParams] = Goods::incrQuantity($businessGoodsSku->goods_id, $num, $businessGoodsSku->sku_id, $incremental ? 1 : 2);
|
||||
$this->doRequest($type, $appendParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载没有发起售后,未取消的订单
|
||||
*
|
||||
* @param $beginTime
|
||||
* @param $endTime
|
||||
* @param int $page
|
||||
* @param string $downloadType
|
||||
* @return void
|
||||
*/
|
||||
public function downloadOrdersAndSave($beginTime, $endTime, $downloadType = 'default', $page = 1)
|
||||
{
|
||||
if ('increment' === $downloadType) {
|
||||
[$type, $appendParams] = Order::downloadIncrementOrders($beginTime, $endTime, $page);
|
||||
$responseName = 'ktt_increment_order_query_response';
|
||||
} else {
|
||||
[$type, $appendParams] = Order::downloadOrders($beginTime, $endTime, $page);
|
||||
$responseName = 'ktt_order_list_response';
|
||||
}
|
||||
$res = $this->doRequest($type, $appendParams);
|
||||
$this->saveOrders($res[$responseName]['order_list']);
|
||||
$pageNum = ceil($res[$responseName]['total_count'] / $appendParams['page_size']);
|
||||
if ($pageNum > $page && 10 >= $page) {
|
||||
$this->downloadOrdersAndSave($beginTime, $endTime, $page + 1);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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 = 'https://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->getShop()->access_token;
|
||||
}
|
||||
$publicParams = array_merge($publicParams, $appendParams);
|
||||
$publicParams['sign'] = $this->getSign($publicParams);
|
||||
|
||||
return $this->formDataPostRequest($url, $publicParams);
|
||||
}
|
||||
|
||||
public function downloadGoods($skuId)
|
||||
{
|
||||
$goodsSku = GoodsSku::query()
|
||||
->with(['goods:id,goods_code'])
|
||||
->find($skuId);
|
||||
$code = $goodsSku->goods->goods_code . '_' . $goodsSku->sku_code;
|
||||
$business = BusinessGoodsSku::query()->where('shop_id', $this->shop->id)->where('external_sku_id', $code)->first(['goods_id', 'sku_id']);
|
||||
[$type, $appendParams] = Goods::downloadSingle($business->goods_id);
|
||||
$res = $this->doRequest($type, $appendParams);
|
||||
$goods = $res['response']['result'];
|
||||
$this->bindGoods([$goods]);
|
||||
}
|
||||
|
||||
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}";
|
||||
}
|
||||
}
|
||||
51
app/Services/Business/KuaiTuanTuan/Order.php
Normal file
51
app/Services/Business/KuaiTuanTuan/Order.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Business\KuaiTuanTuan;
|
||||
|
||||
class Order
|
||||
{
|
||||
/**
|
||||
* 根据成交时间拉取订单列表
|
||||
*/
|
||||
public static function downloadOrders($beginTime, $endTime, $page = 1)
|
||||
{
|
||||
$type = 'pdd.ktt.order.list';
|
||||
$appendParams = [
|
||||
'confirm_at_begin' => $beginTime, // 成交启始时间, 必填,毫秒时间戳
|
||||
'confirm_at_end' => $endTime, // 成交结束时间,必填, 毫秒时间戳,成交结束时间 - 成交启始时间 <= 24h
|
||||
'page_number' => $page, // 页码, 必填
|
||||
'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, $page = 1)
|
||||
{
|
||||
$type = 'pdd.ktt.increment.order.query';
|
||||
$appendParams = [
|
||||
'start_updated_at' => $beginTime, // 更新起始时间
|
||||
'end_updated_at' => $endTime, // 更新结束时间
|
||||
'page_number' => $page, // 页码
|
||||
'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];
|
||||
}
|
||||
}
|
||||
|
||||
33
app/Services/Business/MiaoXuan/Goods.php
Normal file
33
app/Services/Business/MiaoXuan/Goods.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?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 [
|
||||
'data' => [
|
||||
'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'],
|
||||
],
|
||||
'type' => '更新库存',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
40
app/Services/Business/MiaoXuan/MiaoXuan.php
Normal file
40
app/Services/Business/MiaoXuan/MiaoXuan.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Business\MiaoXuan;
|
||||
|
||||
use App\Models\GoodsSku;
|
||||
use App\Services\Business\BusinessClient;
|
||||
|
||||
class MiaoXuan extends BusinessClient
|
||||
{
|
||||
|
||||
public function auth()
|
||||
{
|
||||
// TODO: Implement auth() method.
|
||||
}
|
||||
|
||||
public function downloadGoodsListAndBind()
|
||||
{
|
||||
}
|
||||
|
||||
public function bindGoods($goods)
|
||||
{
|
||||
Goods::bindGoods($goods, $this->shop->id);
|
||||
}
|
||||
|
||||
public function incrQuantity($businessGoodsSku, $num, $incremental, GoodsSku $goodsSku)
|
||||
{
|
||||
$appendParams = Goods::incrQuantity($this->shop->id, $goodsSku->stock, $businessGoodsSku);
|
||||
$url = 'http://shop.chutang66.com/miaoxuan/stock';
|
||||
$this->formDataPostRequest($url, $appendParams);
|
||||
}
|
||||
|
||||
public function downloadOrdersAndSave($beginTime, $endTime, $downloadType = 'default', $page = 1)
|
||||
{
|
||||
}
|
||||
|
||||
public function downloadGoods($skuId)
|
||||
{
|
||||
// TODO: Implement downloadGoods() method.
|
||||
}
|
||||
}
|
||||
8
app/Services/Business/MiaoXuan/Order.php
Normal file
8
app/Services/Business/MiaoXuan/Order.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Business\MiaoXuan;
|
||||
|
||||
class Order
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
34
app/Utils/DateTimeUtils.php
Normal file
34
app/Utils/DateTimeUtils.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Utils;
|
||||
|
||||
class DateTimeUtils
|
||||
{
|
||||
/**
|
||||
* 今天7点到明天7点算作今天
|
||||
*/
|
||||
public static function getToday()
|
||||
{
|
||||
$time = time();
|
||||
$inventoryTime = strtotime(date('Y-m-d 07:00:00'));
|
||||
if ($time < $inventoryTime) {
|
||||
$time = strtotime('-1 day');
|
||||
}
|
||||
|
||||
return date('Y-m-d', $time);
|
||||
}
|
||||
|
||||
public static function getMicroTime($dateTime = null)
|
||||
{
|
||||
$time = microtime(true);
|
||||
if ($dateTime && is_string($dateTime)) {
|
||||
$time = strtotime($dateTime);
|
||||
}
|
||||
if ($dateTime && is_int($dateTime)) {
|
||||
$time = $dateTime;
|
||||
}
|
||||
$time *= 1000;
|
||||
|
||||
return ceil($time);
|
||||
}
|
||||
}
|
||||
36
app/Utils/FormatUtils.php
Normal file
36
app/Utils/FormatUtils.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
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,15 @@
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^7.2.5|^8.0",
|
||||
"ext-json": "*",
|
||||
"aliyuncs/oss-sdk-php": "^2.5",
|
||||
"beyondcode/laravel-websockets": "^1.13",
|
||||
"fideloper/proxy": "^4.4",
|
||||
"intervention/image": "^2.7",
|
||||
"laravel/framework": "^6.20.26",
|
||||
"laravel/tinker": "^2.5"
|
||||
"laravel/tinker": "^2.5",
|
||||
"maatwebsite/excel": "^3.1",
|
||||
"spatie/laravel-permission": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"facade/ignition": "^1.16.15",
|
||||
|
||||
3681
composer.lock
generated
3681
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),
|
||||
|
||||
@ -67,7 +67,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'timezone' => 'UTC',
|
||||
'timezone' => 'PRC',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
||||
@ -68,7 +68,7 @@ return [
|
||||
'providers' => [
|
||||
'users' => [
|
||||
'driver' => 'eloquent',
|
||||
'model' => App\User::class,
|
||||
'model' => \App\Models\User::class,
|
||||
],
|
||||
|
||||
// 'users' => [
|
||||
|
||||
@ -48,8 +48,8 @@ return [
|
||||
'url' => env('DATABASE_URL'),
|
||||
'host' => env('DB_HOST', '127.0.0.1'),
|
||||
'port' => env('DB_PORT', '3306'),
|
||||
'database' => env('DB_DATABASE', 'forge'),
|
||||
'username' => env('DB_USERNAME', 'forge'),
|
||||
'database' => env('DB_DATABASE', 'erp'),
|
||||
'username' => env('DB_USERNAME', ''),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'unix_socket' => env('DB_SOCKET', ''),
|
||||
'charset' => 'utf8mb4',
|
||||
@ -71,7 +71,7 @@ return [
|
||||
'database' => env('DB_DATABASE', 'forge'),
|
||||
'username' => env('DB_USERNAME', 'forge'),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'charset' => 'utf8',
|
||||
'charset' => 'utf8mb4',
|
||||
'prefix' => '',
|
||||
'prefix_indexes' => true,
|
||||
'schema' => 'public',
|
||||
@ -86,7 +86,7 @@ return [
|
||||
'database' => env('DB_DATABASE', 'forge'),
|
||||
'username' => env('DB_USERNAME', 'forge'),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'charset' => 'utf8',
|
||||
'charset' => 'utf8mb4',
|
||||
'prefix' => '',
|
||||
'prefix_indexes' => true,
|
||||
],
|
||||
|
||||
@ -64,7 +64,22 @@ return [
|
||||
'url' => env('AWS_URL'),
|
||||
'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 */
|
||||
|
||||
use App\User;
|
||||
use App\Models\User;
|
||||
use Faker\Generator as Faker;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
@ -19,10 +19,11 @@ use Illuminate\Support\Str;
|
||||
|
||||
$factory->define(User::class, function (Faker $faker) {
|
||||
return [
|
||||
'name' => $faker->name,
|
||||
'name' => 'erpAdmin',
|
||||
'email' => $faker->unique()->safeEmail,
|
||||
'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),
|
||||
];
|
||||
});
|
||||
|
||||
@ -13,14 +13,19 @@ class CreateUsersTable extends Migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::defaultStringLength(191);
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->string('name');
|
||||
$table->string('email')->unique();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('password');
|
||||
$table->string('api_token', 80)->unique()->nullable(false);
|
||||
$table->softDeletes();
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
// 索引
|
||||
$table->unique('name');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -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,36 @@
|
||||
<?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::defaultStringLength(191);
|
||||
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,36 @@
|
||||
<?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::defaultStringLength(191);
|
||||
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');
|
||||
}
|
||||
}
|
||||
39
database/migrations/2022_07_26_090143_create_goods_table.php
Normal file
39
database/migrations/2022_07_26_090143_create_goods_table.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?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::defaultStringLength(191);
|
||||
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,45 @@
|
||||
<?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::defaultStringLength(191);
|
||||
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();
|
||||
// 索引
|
||||
$table->unique(['goods_id', 'sku_code']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('goods_skus');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
<?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->timestamps();
|
||||
// 索引
|
||||
$table->unique(['sku_id', 'day']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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');
|
||||
}
|
||||
}
|
||||
39
database/migrations/2022_07_28_095523_create_menus_table.php
Normal file
39
database/migrations/2022_07_28_095523_create_menus_table.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?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::defaultStringLength(191);
|
||||
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');
|
||||
}
|
||||
}
|
||||
46
database/migrations/2022_08_02_022448_create_shops_table.php
Normal file
46
database/migrations/2022_08_02_022448_create_shops_table.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?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::defaultStringLength(191);
|
||||
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->unsignedBigInteger('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->unsignedBigInteger('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->unsignedTinyInteger('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 CreateBusinessGoodsSkusTable 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->bigInteger('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->bigInteger('market_price')->nullable();
|
||||
$table->bigInteger('update_time')->nullable();
|
||||
$table->string('external_sku_id')->nullable();
|
||||
$table->bigInteger('goods_purchase_price')->nullable();
|
||||
$table->bigInteger('price_in_fen')->nullable();
|
||||
$table->bigInteger('quantity')->nullable();
|
||||
$table->integer('quantity_type')->nullable();
|
||||
$table->bigInteger('reserve_quantity')->nullable();
|
||||
$table->bigInteger('sku_id')->nullable();
|
||||
$table->bigInteger('sold_quantity')->nullable();
|
||||
$table->text('spec_list')->nullable();
|
||||
$table->string('spec_name')->nullable();
|
||||
$table->string('thumb_url')->nullable();
|
||||
$table->bigInteger('total_quantity')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('business_goods');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
<?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->string('activity_no')->nullable();
|
||||
$table->string('activity_title')->nullable();
|
||||
$table->bigInteger('after_sales_status')->nullable();
|
||||
$table->string('business_note')->nullable();
|
||||
$table->string('buyer_memo')->nullable();
|
||||
$table->integer('cancel_status')->nullable();
|
||||
$table->bigInteger('confirm_at')->nullable();
|
||||
$table->bigInteger('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->bigInteger('order_amount')->nullable();
|
||||
$table->string('order_sn')->nullable();
|
||||
$table->integer('participate_no')->nullable();
|
||||
$table->bigInteger('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->bigInteger('service_amount')->nullable();
|
||||
$table->bigInteger('shipping_amount')->nullable();
|
||||
$table->integer('shipping_status')->nullable();
|
||||
$table->string('supply_activity_no')->nullable();
|
||||
$table->integer('supply_participate_no')->nullable();
|
||||
$table->bigInteger('theoretical_refund_amount')->nullable();
|
||||
$table->string('transaction_id')->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->bigInteger('goods_amount')->nullable();
|
||||
$table->bigInteger('goods_cost_price')->nullable();
|
||||
$table->bigInteger('goods_id')->nullable();
|
||||
$table->string('goods_name')->nullable();
|
||||
$table->integer('goods_number')->nullable();
|
||||
$table->bigInteger('goods_price')->nullable();
|
||||
$table->bigInteger('goods_purchase_price')->nullable();
|
||||
$table->string('goods_specification')->nullable();
|
||||
$table->bigInteger('help_sell_amount')->nullable();
|
||||
$table->boolean('is_supplier')->nullable();
|
||||
$table->integer('need_verification_number')->nullable();
|
||||
$table->integer('shipping_status')->nullable();
|
||||
$table->bigInteger('sku_id')->nullable();
|
||||
$table->string('sub_order_sn')->nullable();
|
||||
$table->bigInteger('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');
|
||||
}
|
||||
}
|
||||
36
database/migrations/2022_08_10_150657_create_jobs_table.php
Normal file
36
database/migrations/2022_08_10_150657_create_jobs_table.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateJobsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('jobs', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->string('queue')->index();
|
||||
$table->longText('payload');
|
||||
$table->unsignedTinyInteger('attempts');
|
||||
$table->unsignedInteger('reserved_at')->nullable();
|
||||
$table->unsignedInteger('available_at');
|
||||
$table->unsignedInteger('created_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('jobs');
|
||||
}
|
||||
}
|
||||
@ -12,5 +12,11 @@ class DatabaseSeeder extends Seeder
|
||||
public function run()
|
||||
{
|
||||
// $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);
|
||||
}
|
||||
}
|
||||
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