feat: #20220801 代码优化,商品导入

This commit is contained in:
赵世界 2022-08-01 04:18:07 +08:00
parent 85311a2308
commit d700f50caa
27 changed files with 1334 additions and 40 deletions

View File

@ -4,5 +4,43 @@ namespace App\Filters;
class LogFilter extends Filters
{
protected function moudule($value)
{
return $this->builder->where('moudule', '=', $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);
}
}

View File

@ -16,4 +16,13 @@ class Controller extends BaseController
'errorCode' => 0,
'errorMessage' => '',
];
protected function setValidatorFailResponse($errorMessage)
{
return $this->res = [
'httpCode' => 400,
'errorCode' => 400416,
'errorMessage' => $errorMessage,
];
}
}

View File

@ -25,12 +25,9 @@ class GoodsBrandsController extends Controller
'names.*' => 'required|string|max:255|unique:goods_brands,name',
]);
if ($validator->fails()) {
$this->res = [
'httpCode' => 400,
'errorCode' => 400416,
'errorMessage' => $validator->getMessageBag()->getMessages(),
];
goto end;
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
return response($this->res, $this->res['httpCode']);
}
$goodsBrands = [];
foreach ($request->names as $name) {
@ -44,7 +41,6 @@ class GoodsBrandsController extends Controller
'errorMessage' => '批量添加失败',
];
}
end:
return response($this->res, $this->res['httpCode']);
}
@ -65,11 +61,8 @@ class GoodsBrandsController extends Controller
]
]);
if ($validator->fails()) {
$this->res = [
'httpCode' => 400,
'errorCode' => 400416,
'errorMessage' => $validator->getMessageBag()->getMessages(),
];
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
return response($this->res, $this->res['httpCode']);
}
$goodsBrand = GoodsBrand::query()->find($id);

View File

@ -49,12 +49,9 @@ class GoodsController extends Controller
'skus.*.cost' => ['required', 'numeric', 'max:10'],
]);
if ($validator->fails()) {
$this->res = [
'httpCode' => 400,
'errorCode' => 400416,
'errorMessage' => $validator->getMessageBag()->getMessages(),
];
goto end;
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
return response($this->res, $this->res['httpCode']);
}
DB::beginTransaction();
try {
@ -80,7 +77,6 @@ class GoodsController extends Controller
'errorMessage' => $exception->getMessage(),
];
}
end:
return response($this->res, $this->res['httpCode']);
}

View File

@ -6,12 +6,15 @@ use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\GoodsSku;
use App\Http\Resources\GoodsSkuResource;
use App\Imports\GoodsSkusImport;
use Illuminate\Validation\ValidationException;
use Maatwebsite\Excel\Facades\Excel;
class GoodsSkusController extends Controller
{
public function index(Request $request)
{
return GoodsSku::query()->get(['id', 'title'])->toArray();
return new GoodsSkuResource(GoodsSku::query()->get(['id', 'title']));
}
public function show($id)
@ -23,4 +26,22 @@ class GoodsSkusController extends Controller
{
}
public function store(Request $request)
{
if (!$request->hasFile('goodsSkus')) {
$this->res = [
'httpCode' => 404,
'errorCode' => 404404,
'errorMessage' => 'not found goodsSkus file',
];
}
try {
Excel::import(new GoodsSkusImport(), $request->file('goodsSkus'));
} catch (ValidationException $exception) {
$this->setValidatorFailResponse($exception->validator->getMessageBag()->getMessages());
}
return response($this->res, $this->res['httpCode']);
}
}

View File

@ -25,12 +25,9 @@ class GoodsTypesController extends Controller
'names.*' => 'required|string|max:255|unique:goods_types,name',
]);
if ($validator->fails()) {
$this->res = [
'httpCode' => 400,
'errorCode' => 400416,
'errorMessage' => $validator->getMessageBag()->getMessages(),
];
goto end;
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
return response($this->res, $this->res['httpCode']);
}
$goodsTypes = [];
foreach ($request->names as $name) {
@ -44,7 +41,6 @@ class GoodsTypesController extends Controller
'errorMessage' => '批量添加失败',
];
}
end:
return response($this->res, $this->res['httpCode']);
}
@ -61,15 +57,12 @@ class GoodsTypesController extends Controller
'required',
'string',
'max:255',
Rule::unique('goods_brands')->ignore($id),
Rule::unique('goods_types')->ignore($id),
]
]);
if ($validator->fails()) {
$this->res = [
'httpCode' => 400,
'errorCode' => 400416,
'errorMessage' => $validator->getMessageBag()->getMessages(),
];
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
return response($this->res, $this->res['httpCode']);
}
$goodsType = GoodsType::query()->find($id);

View File

@ -0,0 +1,20 @@
<?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()
->filter()
->paginate();
return LogsResource::collection($res);
}
}

View File

@ -0,0 +1,89 @@
<?php
namespace App\Http\Controllers\Menu;
use App\Http\Controllers\Controller;
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 index()
{
$menus = Menu::query()->get();
$menus = FormatUtils::formatTreeData($menus, 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();
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);
$menu->name = $request->name;
$menu->code = $request->code;
$menu->parent_id = $request->parent_id;
$menu->seq = $request->seq;
$menu->save();
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']);
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Http\Controllers\Permission;
use App\Http\Controllers\Controller;
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 index()
{
$permissions = Permission::query()->get();
return PermissionsResource::collection($permissions);
}
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:255|unique:permissions,name',
]);
if ($validator->fails()) {
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
return response($this->res, $this->res['httpCode']);
}
$permission = new Permission();
$permission->name = $request->name;
$permission->save();
return response($this->res, $this->res['httpCode']);
}
public function show($id)
{
return new PermissionsResource(Permission::query()->find($id));
}
public function update($id, Request $request)
{
$validator = Validator::make($request->all(), [
'name' => ['required', 'string', 'max:255', Rule::unique('permissions')->ignore($id),]
]);
if ($validator->fails()) {
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
return response($this->res, $this->res['httpCode']);
}
$permission = Permission::query()->find($id);
$permission->name = $request->name;
$permission->save();
return new PermissionsResource($permission);
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Http\Controllers\Role;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Spatie\Permission\Models\Role;
use App\Http\Resources\RolesResource;
class RolesController extends Controller
{
public function index()
{
$roles = Role::query()->get();
return RolesResource::collection($roles);
}
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:255|unique:roles,name',
]);
if ($validator->fails()) {
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
return response($this->res, $this->res['httpCode']);
}
$role = new Role();
$role->name = $request->name;
$role->save();
return response($this->res, $this->res['httpCode']);
}
public function show($id)
{
return new RolesResource(Role::query()->find($id));
}
public function update($id, Request $request)
{
$validator = Validator::make($request->all(), [
'name' => ['required', 'string', 'max:255', Rule::unique('roles')->ignore($id),]
]);
if ($validator->fails()) {
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
return response($this->res, $this->res['httpCode']);
}
$role = Role::query()->find($id);
$role->name = $request->name;
$role->save();
return new RolesResource($role);
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class GoodsSkuPost 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 [
//
];
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View File

@ -0,0 +1,91 @@
<?php
namespace App\Imports;
use App\Models\Goods;
use App\Models\GoodsBrand;
use App\Models\GoodsSku;
use App\Models\GoodsType;
use Illuminate\Support\Collection;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
use Maatwebsite\Excel\Concerns\ToCollection;
use Illuminate\Support\Facades\Validator;
use App\Utils\ArrayUtils;
class GoodsSkusImport implements ToCollection
{
private $statusMap = [
'下架' => 0,
'在售' => 1,
'预警' => 2,
];
/**
* @throws ValidationException
*/
public function collection(Collection $collection)
{
unset($collection[0], $collection[1]);
$arr = $collection->toArray();
$validator = Validator::make($arr, [
'*.0' => ['required', 'string', 'max:255'],
'*.1' => ['required', 'string', 'max:255', 'exists:goods_types,name'],
'*.2' => ['string', 'max:255', 'exists:goods_brands,name'],
'*.3' => ['required', 'alpha_dash', 'max:32', 'unique:goods,goods_code'],
'*.4' => ['required', 'string', 'max:255'],
'*.5' => ['required', 'distinct', 'alpha_dash', 'max:32'],
'*.6' => ['required', 'string', Rule::in(['下架', '在售', '预警'])],
'*.7' => ['required', 'max:10'],
'*.8' => ['required', 'max:10'],
]);
if ($validator->fails()) {
throw new ValidationException($validator);
}
$types = array_column($arr, 1);
$types = GoodsType::query()->whereIn('name', $types)->get(['id', 'name'])->toArray();
$types = ArrayUtils::index($types, 'name');
$brands = array_column($arr, 2);
$brands = GoodsBrand::query()->whereIn('name', $brands)->get(['id', 'name'])->toArray();
$brands = ArrayUtils::index($brands, 'name');
$goodsCodes = array_column($arr, 3);
$hasGoods = Goods::query()->whereIn('goods_code', $goodsCodes)->get(['id', 'goods_code'])->toArray();
$hasGoods = ArrayUtils::index($hasGoods, 'goods_code');
$newGoods = $skus = [];
foreach ($arr as $item) {
$sku = [
'goods_id' => $item[3],
'title' => $item[4],
'sku_code' => $item[5],
'status' => $this->statusMap[$item[6]],
'num' => $item[7],
'cost' => $item[8],
];
// 主商品已存在
if (isset($hasGoods[$item[3]])) {
$sku['goods_id'] = $hasGoods[$item[3]]['id'];
} else {
// 新商品
$newGoods[$item[3]] = [
'title' => $item[0],
'type_id' => $types[$item[1]]['id'],
'brand_id' => $brands[$item[2]]['id'],
'goods_code' => $item[3],
];
}
$skus[] = $sku;
}
if ($newGoods) {
$goods = new Goods();
$goods->batchInsert(array_values($newGoods));
$hasGoods = Goods::query()->whereIn('goods_code', array_column($newGoods, 'goods_code'))->get(['id', 'goods_code'])->toArray();
$hasGoods = ArrayUtils::index($hasGoods, 'goods_code');
foreach ($skus as &$sku) {
$sku['goods_id'] = isset($hasGoods[$sku['goods_id']]) ? $hasGoods[$sku['goods_id']]['id'] : $sku['goods_id'];
}
}
$goodsSku = new GoodsSku();
$goodsSku->batchInsert(array_values($skus));
}
}

8
app/Models/Menu.php Normal file
View File

@ -0,0 +1,8 @@
<?php
namespace App\Models;
class Menu extends Model
{
protected $hidden = ['created_at', 'updated_at'];
}

23
app/Utils/ArrayUtils.php Normal file
View 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;
}
}

33
app/Utils/FormatUtils.php Normal file
View File

@ -0,0 +1,33 @@
<?php
namespace App\Utils;
class FormatUtils
{
/**
* 格式化为树形结构
* @param $menus
* @param $parentId
* @param $juniorTitle //下级标题
* @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;
}
}

View File

@ -12,6 +12,7 @@
"fideloper/proxy": "^4.4",
"laravel/framework": "^6.20.26",
"laravel/tinker": "^2.5",
"maatwebsite/excel": "^3.1",
"spatie/laravel-permission": "*"
},
"require-dev": {

633
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "778589ef663266286df2d242bca85f36",
"content-hash": "486f251784470138e7bd835f6ea84ce3",
"packages": [
{
"name": "doctrine/inflector",
@ -305,6 +305,57 @@
],
"time": "2020-12-29T14:50:06+00:00"
},
{
"name": "ezyang/htmlpurifier",
"version": "v4.14.0",
"source": {
"type": "git",
"url": "https://github.com/ezyang/htmlpurifier.git",
"reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/12ab42bd6e742c70c0a52f7b82477fcd44e64b75",
"reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75",
"shasum": ""
},
"require": {
"php": ">=5.2"
},
"type": "library",
"autoload": {
"files": [
"library/HTMLPurifier.composer.php"
],
"psr-0": {
"HTMLPurifier": "library/"
},
"exclude-from-classmap": [
"/library/HTMLPurifier/Language/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1-or-later"
],
"authors": [
{
"name": "Edward Z. Yang",
"email": "admin@htmlpurifier.org",
"homepage": "http://ezyang.com"
}
],
"description": "Standards compliant HTML filter written in PHP",
"homepage": "http://htmlpurifier.org/",
"keywords": [
"html"
],
"support": {
"issues": "https://github.com/ezyang/htmlpurifier/issues",
"source": "https://github.com/ezyang/htmlpurifier/tree/v4.14.0"
},
"time": "2021-12-25T01:21:49+00:00"
},
{
"name": "fideloper/proxy",
"version": "4.4.2",
@ -827,6 +878,262 @@
],
"time": "2022-04-17T13:12:02+00:00"
},
{
"name": "maatwebsite/excel",
"version": "3.1.40",
"source": {
"type": "git",
"url": "https://github.com/SpartnerNL/Laravel-Excel.git",
"reference": "8a54972e3d616c74687c3cbff15765555761885c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/8a54972e3d616c74687c3cbff15765555761885c",
"reference": "8a54972e3d616c74687c3cbff15765555761885c",
"shasum": ""
},
"require": {
"ext-json": "*",
"illuminate/support": "5.8.*|^6.0|^7.0|^8.0|^9.0",
"php": "^7.0|^8.0",
"phpoffice/phpspreadsheet": "^1.18"
},
"require-dev": {
"orchestra/testbench": "^6.0|^7.0",
"predis/predis": "^1.1"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Maatwebsite\\Excel\\ExcelServiceProvider"
],
"aliases": {
"Excel": "Maatwebsite\\Excel\\Facades\\Excel"
}
}
},
"autoload": {
"psr-4": {
"Maatwebsite\\Excel\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Patrick Brouwers",
"email": "patrick@spartner.nl"
}
],
"description": "Supercharged Excel exports and imports in Laravel",
"keywords": [
"PHPExcel",
"batch",
"csv",
"excel",
"export",
"import",
"laravel",
"php",
"phpspreadsheet"
],
"support": {
"issues": "https://github.com/SpartnerNL/Laravel-Excel/issues",
"source": "https://github.com/SpartnerNL/Laravel-Excel/tree/3.1.40"
},
"funding": [
{
"url": "https://laravel-excel.com/commercial-support",
"type": "custom"
},
{
"url": "https://github.com/patrickbrouwers",
"type": "github"
}
],
"time": "2022-05-02T13:50:01+00:00"
},
{
"name": "maennchen/zipstream-php",
"version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/maennchen/ZipStream-PHP.git",
"reference": "c4c5803cc1f93df3d2448478ef79394a5981cc58"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/c4c5803cc1f93df3d2448478ef79394a5981cc58",
"reference": "c4c5803cc1f93df3d2448478ef79394a5981cc58",
"shasum": ""
},
"require": {
"myclabs/php-enum": "^1.5",
"php": ">= 7.1",
"psr/http-message": "^1.0",
"symfony/polyfill-mbstring": "^1.0"
},
"require-dev": {
"ext-zip": "*",
"guzzlehttp/guzzle": ">= 6.3",
"mikey179/vfsstream": "^1.6",
"phpunit/phpunit": ">= 7.5"
},
"type": "library",
"autoload": {
"psr-4": {
"ZipStream\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paul Duncan",
"email": "pabs@pablotron.org"
},
{
"name": "Jonatan Männchen",
"email": "jonatan@maennchen.ch"
},
{
"name": "Jesse Donat",
"email": "donatj@gmail.com"
},
{
"name": "András Kolesár",
"email": "kolesar@kolesar.hu"
}
],
"description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
"keywords": [
"stream",
"zip"
],
"support": {
"issues": "https://github.com/maennchen/ZipStream-PHP/issues",
"source": "https://github.com/maennchen/ZipStream-PHP/tree/master"
},
"funding": [
{
"url": "https://opencollective.com/zipstream",
"type": "open_collective"
}
],
"time": "2020-05-30T13:11:16+00:00"
},
{
"name": "markbaker/complex",
"version": "3.0.1",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPComplex.git",
"reference": "ab8bc271e404909db09ff2d5ffa1e538085c0f22"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/ab8bc271e404909db09ff2d5ffa1e538085c0f22",
"reference": "ab8bc271e404909db09ff2d5ffa1e538085c0f22",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
"phpcompatibility/php-compatibility": "^9.0",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.3",
"squizlabs/php_codesniffer": "^3.4"
},
"type": "library",
"autoload": {
"psr-4": {
"Complex\\": "classes/src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@lange.demon.co.uk"
}
],
"description": "PHP Class for working with complex numbers",
"homepage": "https://github.com/MarkBaker/PHPComplex",
"keywords": [
"complex",
"mathematics"
],
"support": {
"issues": "https://github.com/MarkBaker/PHPComplex/issues",
"source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.1"
},
"time": "2021-06-29T15:32:53+00:00"
},
{
"name": "markbaker/matrix",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPMatrix.git",
"reference": "c66aefcafb4f6c269510e9ac46b82619a904c576"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/c66aefcafb4f6c269510e9ac46b82619a904c576",
"reference": "c66aefcafb4f6c269510e9ac46b82619a904c576",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
"phpcompatibility/php-compatibility": "^9.0",
"phpdocumentor/phpdocumentor": "2.*",
"phploc/phploc": "^4.0",
"phpmd/phpmd": "2.*",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.3",
"sebastian/phpcpd": "^4.0",
"squizlabs/php_codesniffer": "^3.4"
},
"type": "library",
"autoload": {
"psr-4": {
"Matrix\\": "classes/src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@demon-angel.eu"
}
],
"description": "PHP Class for working with matrices",
"homepage": "https://github.com/MarkBaker/PHPMatrix",
"keywords": [
"mathematics",
"matrix",
"vector"
],
"support": {
"issues": "https://github.com/MarkBaker/PHPMatrix/issues",
"source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.0"
},
"time": "2021-07-01T19:01:15+00:00"
},
{
"name": "monolog/monolog",
"version": "2.7.0",
@ -931,6 +1238,66 @@
],
"time": "2022-06-09T08:59:12+00:00"
},
{
"name": "myclabs/php-enum",
"version": "1.8.3",
"source": {
"type": "git",
"url": "https://github.com/myclabs/php-enum.git",
"reference": "b942d263c641ddb5190929ff840c68f78713e937"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/php-enum/zipball/b942d263c641ddb5190929ff840c68f78713e937",
"reference": "b942d263c641ddb5190929ff840c68f78713e937",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": "^7.3 || ^8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"squizlabs/php_codesniffer": "1.*",
"vimeo/psalm": "^4.6.2"
},
"type": "library",
"autoload": {
"psr-4": {
"MyCLabs\\Enum\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP Enum contributors",
"homepage": "https://github.com/myclabs/php-enum/graphs/contributors"
}
],
"description": "PHP Enum implementation",
"homepage": "http://github.com/myclabs/php-enum",
"keywords": [
"enum"
],
"support": {
"issues": "https://github.com/myclabs/php-enum/issues",
"source": "https://github.com/myclabs/php-enum/tree/1.8.3"
},
"funding": [
{
"url": "https://github.com/mnapoli",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum",
"type": "tidelift"
}
],
"time": "2021-07-05T08:18:36+00:00"
},
{
"name": "nesbot/carbon",
"version": "2.59.1",
@ -1204,6 +1571,110 @@
},
"time": "2020-10-15T08:29:30+00:00"
},
{
"name": "phpoffice/phpspreadsheet",
"version": "1.24.1",
"source": {
"type": "git",
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
"reference": "69991111e05fca3ff7398e1e7fca9ebed33efec6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/69991111e05fca3ff7398e1e7fca9ebed33efec6",
"reference": "69991111e05fca3ff7398e1e7fca9ebed33efec6",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-dom": "*",
"ext-fileinfo": "*",
"ext-gd": "*",
"ext-iconv": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-simplexml": "*",
"ext-xml": "*",
"ext-xmlreader": "*",
"ext-xmlwriter": "*",
"ext-zip": "*",
"ext-zlib": "*",
"ezyang/htmlpurifier": "^4.13",
"maennchen/zipstream-php": "^2.1",
"markbaker/complex": "^3.0",
"markbaker/matrix": "^3.0",
"php": "^7.3 || ^8.0",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
"psr/simple-cache": "^1.0 || ^2.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
"dompdf/dompdf": "^1.0 || ^2.0",
"friendsofphp/php-cs-fixer": "^3.2",
"jpgraph/jpgraph": "^4.0",
"mpdf/mpdf": "8.1.1",
"phpcompatibility/php-compatibility": "^9.3",
"phpstan/phpstan": "^1.1",
"phpstan/phpstan-phpunit": "^1.0",
"phpunit/phpunit": "^8.5 || ^9.0",
"squizlabs/php_codesniffer": "^3.7",
"tecnickcom/tcpdf": "^6.4"
},
"suggest": {
"dompdf/dompdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)",
"jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)"
},
"type": "library",
"autoload": {
"psr-4": {
"PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Maarten Balliauw",
"homepage": "https://blog.maartenballiauw.be"
},
{
"name": "Mark Baker",
"homepage": "https://markbakeruk.net"
},
{
"name": "Franck Lefevre",
"homepage": "https://rootslabs.net"
},
{
"name": "Erik Tilt"
},
{
"name": "Adrien Crivelli"
}
],
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
"keywords": [
"OpenXML",
"excel",
"gnumeric",
"ods",
"php",
"spreadsheet",
"xls",
"xlsx"
],
"support": {
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.24.1"
},
"time": "2022-07-18T19:50:48+00:00"
},
{
"name": "phpoption/phpoption",
"version": "1.8.1",
@ -1323,6 +1794,166 @@
},
"time": "2021-03-05T17:36:06+00:00"
},
{
"name": "psr/http-client",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-client.git",
"reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
"reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
"shasum": ""
},
"require": {
"php": "^7.0 || ^8.0",
"psr/http-message": "^1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Client\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP clients",
"homepage": "https://github.com/php-fig/http-client",
"keywords": [
"http",
"http-client",
"psr",
"psr-18"
],
"support": {
"source": "https://github.com/php-fig/http-client/tree/master"
},
"time": "2020-06-29T06:28:15+00:00"
},
{
"name": "psr/http-factory",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-factory.git",
"reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
"reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
"shasum": ""
},
"require": {
"php": ">=7.0.0",
"psr/http-message": "^1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interfaces for PSR-7 HTTP message factories",
"keywords": [
"factory",
"http",
"message",
"psr",
"psr-17",
"psr-7",
"request",
"response"
],
"support": {
"source": "https://github.com/php-fig/http-factory/tree/master"
},
"time": "2019-04-30T12:38:16+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"support": {
"source": "https://github.com/php-fig/http-message/tree/master"
},
"time": "2016-08-06T14:39:51+00:00"
},
{
"name": "psr/log",
"version": "1.1.4",

View File

@ -16,7 +16,7 @@ class CreateGoodsTable extends Migration
Schema::create('goods', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title')->nullable(false);
$table->string('img_url')->nullable(false)->comment('商品图片');
$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('商品编码');

View File

@ -0,0 +1,38 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMenusTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('menus', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('code', 32)->nullable(false)->comment('菜单编码');
$table->string('name', 32)->nullable(false)->comment('菜单名称');
$table->unsignedBigInteger('parent_id')->default(0);
$table->unsignedInteger('seq')->default(0)->comment('排序序号');
$table->softDeletes();
$table->timestamps();
// 索引
$table->unique('code');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('menus');
}
}

View 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]);
}
}

View File

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class PermissionsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
DB::table('permissions')->insert([
['name' => 'GOODS_MANAGE', 'guard_name' => 'api'],
['name' => 'GOODS_LIST', 'guard_name' => 'api'],
['name' => 'GOODS_TYPE', 'guard_name' => 'api'],
['name' => 'GOODS_BRAND', 'guard_name' => 'api'],
['name' => 'SHOP_MANAGE', 'guard_name' => 'api'],
['name' => 'USER_MANAGE', 'guard_name' => 'api'],
['name' => 'SYSTEM_MANAGE', 'guard_name' => 'api'],
['name' => 'ROLE_MANAGE', 'guard_name' => 'api'],
['name' => 'PERMISSION_MANAGE', 'guard_name' => 'api'],
['name' => 'SYSTEM_LOG', 'guard_name' => 'api'],
]);
}
}

View File

@ -0,0 +1,19 @@
<?php
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class RolesTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
DB::table('permissions')->insert([
['name' => '超级管理员', 'guard_name' => 'api'],
]);
}
}

View File

@ -20,17 +20,21 @@ Route::middleware('auth:api')->group(function () {
// 商品品牌
Route::resource('goods_brands', 'Goods\GoodsBrandsController', ['only' => ['index', 'store', 'show', 'update', 'destroy']]);
// 日志
Route::resource('logs', 'Log\LogsController', ['only' => ['index', 'show']]);
Route::resource('logs', 'Log\LogsController', ['only' => ['index']]);
// 商品
Route::resource('goods', 'Goods\GoodsController', ['only' => ['index', 'store']]);
// 商品规格
Route::resource('goods_skus', 'Goods\GoodsSkusController', ['only' => ['index', 'show', 'update']]);
Route::resource('goods_skus', 'Goods\GoodsSkusController', ['only' => ['index', 'show', 'update', 'store']]);
// 店铺
Route::resource('shops', 'Log\LogsController', ['only' => ['index', 'store', 'show', 'update', 'destroy']]);
Route::resource('shops', 'Shop\ShopsController', ['only' => ['index', 'store', 'show', 'update', 'destroy']]);
// 角色
Route::resource('roles', 'Role\RolesController', ['only' => ['index', 'store', 'show', 'update', 'destroy']]);
Route::resource('roles', 'Role\RolesController', ['only' => ['index', 'store', 'show', 'update']]);
// 权限
Route::resource('permissions', 'Permissions\LogsController', ['only' => ['index', 'store', 'show', 'update', 'destroy']]);
Route::resource('permissions', 'Permission\PermissionsController', ['only' => ['index', 'store', 'show', 'update', 'destroy']]);
// 菜单
Route::resource('menus', 'Menu\MenusController', ['only' => ['index',
// 'store', 'show', 'update', 'destroy'
]]);
});
Route::post('/auth/login', [LoginController::class, 'login'])->name('auth.login');