Merge pull request !156 from 赵世界/develop
This commit is contained in:
赵世界 2023-04-22 08:08:18 +00:00 committed by Gitee
commit 6b7acd365c
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
126 changed files with 1727 additions and 296 deletions

View File

@ -46,18 +46,17 @@ class DeleteGoodsSku extends Command
if (empty($code)) { if (empty($code)) {
reutrn; reutrn;
} }
[$goodsCode, $skuCode] = explode('_', $code);
DB::beginTransaction(); DB::beginTransaction();
try { try {
$goods = Goods::query()->where('goods_code', $goodsCode)->first(); $sku = GoodsSku::query()->where('external_sku_id', $code)->first();
$goods = Goods::query()->find($sku->goods_id);
$countSkus = GoodsSku::query()->where('goods_id', $goods->id)->count(); $countSkus = GoodsSku::query()->where('goods_id', $goods->id)->count();
$sku = GoodsSku::query()->where('goods_id', $goods->id)->where('sku_code', $skuCode)->first();
DailyStockRecord::query()->where('sku_id', $sku->id)->delete(); DailyStockRecord::query()->where('sku_id', $sku->id)->delete();
Log::query()->where('module', 'goods')->where('target_type', 'goods_sku')->where('target_id', $sku->id)->delete(); Log::query()->where('module', 'goods')->where('target_type', 'goods_sku')->where('target_id', $sku->id)->delete();
$sku->delete();
if (1 === $countSkus) { if (1 === $countSkus) {
$goods->delete(); $goods->delete();
} }
$sku->delete();
DB::commit(); DB::commit();
$this->info('删除成功'); $this->info('删除成功');
} catch (\Exception $exception) { } catch (\Exception $exception) {

View File

@ -53,7 +53,7 @@ class Inventory extends Command
// 数据库存储过程,7点定时执行 // 数据库存储过程,7点定时执行
$data = []; $data = [];
$date = date('Y-m-d'); $date = date('Y-m-d');
GoodsSku::chunk(500, static function ($skus) use (&$data, $date) { GoodsSku::query()->chunk(500, static function ($skus) use (&$data, $date) {
foreach ($skus as $sku) { foreach ($skus as $sku) {
$data[] = [ $data[] = [
'sku_id' => $sku->id, 'sku_id' => $sku->id,

View File

@ -6,7 +6,6 @@ use App\Services\Business\BusinessFactory;
use App\Utils\DateTimeUtils; use App\Utils\DateTimeUtils;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use App\Models\Shop; use App\Models\Shop;
use Illuminate\Support\Facades\Log;
use Swoole\Timer; use Swoole\Timer;
use Swoole\Event; use Swoole\Event;
@ -50,7 +49,6 @@ class Swoole extends Command
$endTime = DateTimeUtils::getMicroTime(); $endTime = DateTimeUtils::getMicroTime();
$beginTime = $endTime - 3000; $beginTime = $endTime - 3000;
$endTime += 3000; $endTime += 3000;
Log::info($beginTime . '--' . $endTime);
foreach ($shops as $shop) { foreach ($shops as $shop) {
BusinessFactory::init()->make($shop->plat_id)->setShop($shop)->downloadOrdersAndSave($beginTime, $endTime, 'increment'); BusinessFactory::init()->make($shop->plat_id)->setShop($shop)->downloadOrdersAndSave($beginTime, $endTime, 'increment');
} }

View File

@ -3,16 +3,21 @@
namespace App\Console\Commands; namespace App\Console\Commands;
use App\Events\StockUpdateEvent; use App\Events\StockUpdateEvent;
use App\Exports\DiffTodayPriceGoodsExport;
use App\Models\BusinessGoodsSku; use App\Models\BusinessGoodsSku;
use App\Models\BusinessOrder; use App\Models\BusinessOrder;
use App\Models\GoodsSku; use App\Models\GoodsSku;
use App\Models\GoodsType;
use App\Models\Log; use App\Models\Log;
use App\Models\Shop; use App\Models\Shop;
use App\Models\TodayPrice;
use App\Services\Business\BusinessFactory; use App\Services\Business\BusinessFactory;
use App\Utils\DateTimeUtils; use App\Utils\DateTimeUtils;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use App\Jobs\BusinessGoodsSkuIncrQuantity; use App\Jobs\BusinessGoodsSkuIncrQuantity;
use Illuminate\Database\Eloquent\Builder;
use Maatwebsite\Excel\Facades\Excel;
class Test extends Command class Test extends Command
{ {

View File

@ -0,0 +1,54 @@
<?php
namespace App\Console\Commands;
use App\Models\GoodsSku;
use Illuminate\Console\Command;
class UpdateExternalSkuId extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'update:goods_skus:external_sku_id';
/**
* The console command description.
*
* @var string
*/
protected $description = '更新goods_sku的external_sku_id';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
GoodsSku::query()->whereNull('external_sku_id')->chunk(500, static function ($skus) {
foreach ($skus as $sku) {
$sku->external_sku_id = $sku->goods->goods_code . '_' . $sku->sku_code;
$sku->save();
}
});
GoodsSku::query()->where('external_sku_id', '')->chunk(500, static function ($skus) {
foreach ($skus as $sku) {
$sku->external_sku_id = $sku->goods->goods_code . '_' . $sku->sku_code;
$sku->save();
}
});
}
}

View File

@ -35,11 +35,8 @@ class BusinessOrdersUpdate
private function updateStock() private function updateStock()
{ {
try { try {
[$goodsCode, $skuCode] = explode('_', $this->businessGoods['external_sku_id']); $this->goodsSku = GoodsSku::query()
$this->goodsSku = GoodsSku::query()->where('sku_code', $skuCode) ->where('external_sku_id', $this->businessGoods['external_sku_id'])
->whereHas('goods', function ($query) use ($goodsCode) {
$query->where('goods_code', $goodsCode);
})
->first(); ->first();
} catch (\Exception $e) { } catch (\Exception $e) {
Log::error('事件库存更新失败: ' . $e->getMessage()); Log::error('事件库存更新失败: ' . $e->getMessage());

View File

@ -18,6 +18,7 @@ class StockUpdateEvent
public $goodsSku; public $goodsSku;
public $goodsSkus; public $goodsSkus;
public $isBatch; public $isBatch;
public $combinationGoodsUpdate;
/** /**
* Create a new event instance. * Create a new event instance.
@ -26,12 +27,13 @@ class StockUpdateEvent
* *
* @return void * @return void
*/ */
public function __construct($data, $isBatch = 0) public function __construct($data, $isBatch = 0, $combinationGoodsUpdate = false)
{ {
$this->isBatch = $isBatch; $this->isBatch = $isBatch;
$this->combinationGoodsUpdate = $combinationGoodsUpdate;
if (is_array($data)) { if (is_array($data)) {
// ids集合 // ids集合
$this->goodsSkus = GoodsSku::query()->whereIn('id', $data)->with(['goods:id,goods_code'])->get(); $this->goodsSkus = GoodsSku::query()->whereIn('id', $data)->get();
} else { } else {
// GoodsSku Elo模型对象 // GoodsSku Elo模型对象
$this->goodsSku = $data; $this->goodsSku = $data;

View File

@ -0,0 +1,59 @@
<?php
namespace App\Exports;
use App\Models\DailyStockRecord;
use App\Models\Log;
use App\Utils\ArrayUtils;
use App\Utils\DateTimeUtils;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use App\Models\GoodsSku;
use Illuminate\Support\Collection;
class DiffTodayPriceGoodsExport implements FromCollection, ShouldAutoSize
{
private $data;
public function __construct($data)
{
$this->data = $this->createData($data);
}
/**
* @return \Illuminate\Support\Collection
*/
public function collection()
{
return new Collection($this->data);
}
private function createData($data)
{
$headTitle = [
'店铺',
'团购标题',
'商品名称',
'快团团价格',
'今日价格',
'编码',
];
$bodyData = [];
foreach ($data as $shopName => $activity) {
foreach ($activity as $activityNo => $item) {
foreach ($item as $k => $v) {
foreach ($v as $i) {
if ('diff_price' === $k) {
$bodyData[] = [$shopName, $i['title'], $i['goods_name'], $i['price_in_fen'], $i['today_price'], $i['external_sku_id']];
}
if ('not_in_group' === $k) {
$bodyData[] = [$shopName, $i['title'], $i['goods_name'], '团购无此商品', $i['shop_price'][$shopName], $i['external_sku_id']];
}
}
}
}
}
return [$headTitle, $bodyData];
}
}

View File

@ -6,16 +6,16 @@ class BusinessGoodsSkuFilter extends Filters
{ {
protected function externalSkuId($value) protected function externalSkuId($value)
{ {
return $this->builder->where('external_sku_id', '=', trim($value)); return $this->builder->where('external_sku_id', trim($value));
} }
protected function goodsName($value) protected function goodsName($value)
{ {
return $this->builder->where('goods_name', '=', trim($value)); return $this->builder->where('goods_name', trim($value));
} }
protected function shopId($value) protected function shopId($value)
{ {
return $this->builder->where('shop_id', '=', trim($value)); return $this->builder->where('shop_id', trim($value));
} }
} }

View File

@ -6,36 +6,36 @@ class BusinessOrderFilter extends Filters
{ {
protected function participateNo($value) protected function participateNo($value)
{ {
return $this->builder->where('participate_no', '=', trim($value)); return $this->builder->where('participate_no', trim($value));
} }
protected function shopId($value) protected function shopId($value)
{ {
return $this->builder->where('shop_id', '=', $value); return $this->builder->where('shop_id', $value);
} }
protected function activityNo($value) protected function activityNo($value)
{ {
return $this->builder->where('activity_no', '=', $value); return $this->builder->where('activity_no', $value);
} }
protected function shippingStatus($value) protected function shippingStatus($value)
{ {
return $this->builder->where('shipping_status', '=', $value); return $this->builder->where('shipping_status', $value);
} }
protected function isSupplier($value) protected function isSupplier($value)
{ {
return $this->builder->where('is_supplier', '=', $value); return $this->builder->where('is_supplier', $value);
} }
protected function cancelStatus($value) protected function cancelStatus($value)
{ {
return $this->builder->where('cancel_status', '=', $value); return $this->builder->where('cancel_status', $value);
} }
protected function afterSalesStatus($value) protected function afterSalesStatus($value)
{ {
return $this->builder->where('after_sales_status', '=', $value); return $this->builder->where('after_sales_status', $value);
} }
} }

View File

@ -12,14 +12,14 @@ class GoodsFilter extends Filters
protected function typeId($value) protected function typeId($value)
{ {
if($value){ if($value){
return $this->builder->where('type_id', '=', $value); return $this->builder->where('type_id', $value);
} }
} }
protected function brandId($value) protected function brandId($value)
{ {
if($value){ if($value){
return $this->builder->where('brand_id', '=', $value); return $this->builder->where('brand_id', $value);
} }
} }
} }

View File

@ -6,16 +6,21 @@ class GoodsSkuFilter extends Filters
{ {
protected function skuTitle($value) protected function skuTitle($value)
{ {
return $this->builder->where('title', '=', $value); return $this->builder->where('title', $value);
} }
protected function status($value) protected function status($value)
{ {
return $this->builder->where('status', '=', $value); return $this->builder->where('status', $value);
} }
protected function excludeIds($value) protected function excludeIds($value)
{ {
return $this->builder->whereNotIn('id', $value); return $this->builder->whereNotIn('id', $value);
} }
protected function externalSkuId($value)
{
return $this->builder->where('external_sku_id', $value);
}
} }

View File

@ -9,39 +9,35 @@ class GoodsSkuLocationFilter extends Filters
{ {
public function date($value) public function date($value)
{ {
return $this->builder->where('date', '=', $value); return $this->builder->where('date', $value);
} }
public function goodsTitle($value) public function goodsTitle($value)
{ {
$goodsId = Goods::query()->where('title', $value)->value('id'); $goodsId = Goods::query()->where('title', $value)->value('id');
return $this->builder->where('goods_id', '=', $goodsId); return $this->builder->where('goods_id', $goodsId);
} }
public function goodsCode($value) public function goodsCode($value)
{ {
$goodsId = Goods::query()->where('goods_code', $value)->value('id'); $goodsId = Goods::query()->where('goods_code', $value)->value('id');
return $this->builder->where('goods_id', '=', $goodsId); return $this->builder->where('goods_id', $goodsId);
} }
public function externalSkuId($value) public function externalSkuId($value)
{ {
[$goodsCode, $skuCode] = explode('_', $value); return $this->builder->where('external_sku_id', $value);
$goodsId = Goods::query()->where('goods_code', $goodsCode)->value('id');
$skuId = GoodsSku::query()->where('sku_code', $skuCode)->value('id');
return $this->builder->where('goods_sku_id', '=', $skuId)->where('goods_id', '=', $goodsId);
} }
public function location($value) public function location($value)
{ {
return $this->builder->where('location', '=', $value); return $this->builder->where('location', $value);
} }
public function status($value) public function status($value)
{ {
return $this->builder->where('status', '=', $value); return $this->builder->where('status', $value);
} }
} }

View File

@ -11,11 +11,11 @@ class GroupGoodsFilter extends Filters
protected function groupId($value) protected function groupId($value)
{ {
return $this->builder->where('group_id', '=', $value); return $this->builder->where('group_id', $value);
} }
protected function externalSkuId($value) protected function externalSkuId($value)
{ {
return $this->builder->where('external_sku_id', '=', $value); return $this->builder->where('external_sku_id', $value);
} }
} }

View File

@ -12,12 +12,12 @@ class GroupsFilter extends Filters
protected function shopId($value) protected function shopId($value)
{ {
if ($value) { if ($value) {
return $this->builder->where('shop_id', '=', $value); return $this->builder->where('shop_id', $value);
} }
} }
protected function status($value) protected function status($value)
{ {
return $this->builder->where('status', '=', $value); return $this->builder->where('status', $value);
} }
} }

View File

@ -6,32 +6,32 @@ class LogFilter extends Filters
{ {
protected function module($value) protected function module($value)
{ {
return $this->builder->where('module', '=', $value); return $this->builder->where('module', $value);
} }
protected function action($value) protected function action($value)
{ {
return $this->builder->where('action', '=', $value); return $this->builder->where('action', $value);
} }
protected function targetType($value) protected function targetType($value)
{ {
return $this->builder->where('target_type', '=', $value); return $this->builder->where('target_type', $value);
} }
protected function targetId($value) protected function targetId($value)
{ {
return $this->builder->where('target_id', '=', $value); return $this->builder->where('target_id', $value);
} }
protected function targetField($value) protected function targetField($value)
{ {
return $this->builder->where('target_field', '=', $value); return $this->builder->where('target_field', $value);
} }
protected function userId($value) protected function userId($value)
{ {
return $this->builder->where('user_id', '=', $value); return $this->builder->where('user_id', $value);
} }
protected function startTime($value) protected function startTime($value)

View File

@ -6,6 +6,6 @@ class ShopFilter extends Filters
{ {
protected function platId($value) protected function platId($value)
{ {
return $this->builder->where('plat_id', '=', $value)->where('expires_at', '>', time()); return $this->builder->where('plat_id', $value)->where('expires_at', '>', time());
} }
} }

View File

@ -5,14 +5,22 @@ namespace App\Http\Controllers\Business;
use App\Events\BusinessOrdersUpdate; use App\Events\BusinessOrdersUpdate;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Http\Resources\BusinessGoodsSkuResource; use App\Http\Resources\BusinessGoodsSkuResource;
use App\Imports\TodayPriceImport;
use App\Models\BusinessGoodsSku; use App\Models\BusinessGoodsSku;
use App\Models\BusinessOrderItem; use App\Models\BusinessOrderItem;
use App\Models\Goods;
use App\Models\GoodsSku; use App\Models\GoodsSku;
use App\Models\Log as LogModel; use App\Models\Log as LogModel;
use App\Models\Shop;
use App\Models\TodayPrice;
use App\Services\Business\BusinessFactory;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
use Maatwebsite\Excel\Facades\Excel;
use App\Exports\DiffTodayPriceGoodsExport;
class BusinessGoodsSkusController extends Controller class BusinessGoodsSkusController extends Controller
{ {
@ -47,10 +55,10 @@ class BusinessGoodsSkusController extends Controller
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
} }
$sku = BusinessGoodsSku::query()->find($id); $sku = BusinessGoodsSku::query()->find($id);
$this->setBeforeUpdate($sku->is_sync); $this->setBeforeUpdateForLog($sku->is_sync);
$sku->is_sync = $request->input('is_sync'); $sku->is_sync = $request->input('is_sync');
$sku->save(); $sku->save();
$this->setAfterUpdate($sku->is_sync); $this->setAfterUpdateForLog($sku->is_sync);
$this->addLog($id, 'status'); $this->addLog($id, 'status');
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
@ -61,10 +69,10 @@ class BusinessGoodsSkusController extends Controller
DB::beginTransaction(); DB::beginTransaction();
try { try {
$sku = BusinessGoodsSku::query()->find($id); $sku = BusinessGoodsSku::query()->find($id);
$this->setBeforeUpdate($sku->toArray()); $this->setBeforeUpdateForLog($sku->toArray());
BusinessOrderItem::query()->where('goods_id', $sku->goods_id)->where('sku_id', $sku->sku_id)->delete(); BusinessOrderItem::query()->where('goods_id', $sku->goods_id)->where('sku_id', $sku->sku_id)->delete();
$sku->delete(); $sku->delete();
$this->setAfterUpdate(''); $this->setAfterUpdateForLog('');
$this->addLog($id, ''); $this->addLog($id, '');
DB::commit(); DB::commit();
} catch (Exception $exception) { } catch (Exception $exception) {
@ -79,11 +87,8 @@ class BusinessGoodsSkusController extends Controller
public function syncStock($id, Request $request) public function syncStock($id, Request $request)
{ {
$businessGoodsSku = BusinessGoodsSku::query()->where('is_sync', 1)->find($id); $businessGoodsSku = BusinessGoodsSku::query()->where('is_sync', 1)->find($id);
[$goodsCode, $skuCode] = explode('_', $businessGoodsSku->external_sku_id); $sku = GoodsSku::query()
$sku = GoodsSku::query()->where('sku_code', $skuCode) ->where('external_sku_id', $businessGoodsSku->external_sku_id)
->whereHas('goods', function ($query) use ($goodsCode) {
$query->where('goods_code', $goodsCode);
})
->first(); ->first();
if (empty($sku)) { if (empty($sku)) {
$this->setValidatorFailResponse('未找到对应的商品,请核实后再次同步或删除此平台商品'); $this->setValidatorFailResponse('未找到对应的商品,请核实后再次同步或删除此平台商品');
@ -93,4 +98,115 @@ class BusinessGoodsSkusController extends Controller
} }
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
} }
public function todayPriceImport(Request $request)
{
if (!$request->hasFile('today_price')) {
$this->res = [
'httpCode' => 404,
'errorCode' => 404404,
'errorMessage' => 'not found file',
];
}
try {
$import = new TodayPriceImport();
$path = $request->file('today_price');
Excel::import($import, $path);
} catch (ValidationException $exception) {
$this->setValidatorFailResponse($exception->validator->getMessageBag()->getMessages());
}
return response($this->res, $this->res['httpCode']);
}
public function exportTodayPrice(Request $request)
{
$todayPrice = TodayPrice::query()
->with([
'goodsSku:id,goods_id,title,external_sku_id',
'goodsSku.goods:id,title',
])
->where('day', date('Y-m-d'))
->get();
if ($todayPrice->isEmpty()) {
exit('今日价格数据未找到,请先上传');
}
$shopNames = $todayGoodsPrice = [];
foreach ($todayPrice as $item) {
$shopPrice = json_decode($item['shop_price'], true);
$todayGoodsPrice[$item['external_sku_id']] = [
'goods_name' => $item['goodsSku']['goods']['title'] . $item['goodsSku']['title'],
'external_sku_id' => $item['external_sku_id'],
'shop_price' => $shopPrice,
];
$shopNames = $shopNames ?: array_keys($shopNames);
}
$shops = Shop::query()
->where('plat_id', Shop::$PLAT_KTT)
->where('expires_at', '>', time())
->whereIn('name', $shopNames)
->get();
$data = [];
foreach ($shops as $shop) {
$business = BusinessFactory::init()->make($shop->plat_id);
$business->setShop($shop);
$res = $business->queryGroup();
if (!isset($res['ktt_group_query_list_response'])) {
continue;
}
$activityNos = $activities = [];
foreach ($res['ktt_group_query_list_response']['activity_list'] as $activity) {
if (0 === $activity['is_help_sell'] && '补款勿拍' !== $activity['title']) {
$activityNos[] = $activity['activity_no'];
$activities[$activity['activity_no']] = $activity['title'];
}
}
$businessGoodsSkus = BusinessGoodsSku::query()
->where('shop_id', $shop->id)
->whereIn('activity_no', $activityNos)
->orderBy('activity_no')
->get(['shop_id', 'title', 'activity_no', 'goods_name', 'price_in_fen', 'external_sku_id']);
if ($businessGoodsSkus->isEmpty()) {
continue;
}
$data[$shop->name] = $this->diffTodayPrice($businessGoodsSkus, $todayGoodsPrice, $activities, $shop->name);
}
ob_end_clean();
return Excel::download(new DiffTodayPriceGoodsExport($data), date('Y-m-d') . '今日差价商品.xlsx');
}
private function diffTodayPrice($businessGoodsSkus, $todayPrice, $activities, $shopName)
{
$data = [];
foreach ($businessGoodsSkus as $item) {
// 记录团购下商品id
$data[$item['activity_no']]['ids'][] = $item['external_sku_id'];
// 团购中有,表格没有
// if (!isset($todayPrice[$item['external_sku_id']])) {
// $data[$item['activity_no']]['in_group'][] = $item->toArray();
// }
// 价格不一样
if (isset($todayPrice[$item['external_sku_id']]) && $item['price_in_fen'] != $todayPrice[$item['external_sku_id']]['shop_price'][$shopName]) {
$item['today_price'] = $todayPrice[$item['external_sku_id']]['shop_price'][$shopName];
$data[$item['activity_no']]['diff_price'][] = $item->toArray();
}
}
$todayIds = array_keys($todayPrice);
foreach ($data as $no => &$arr) {
foreach ($arr as $key => $value) {
if ('ids' === $key) {
$ids = array_unique($value);
$ids = array_diff($todayIds, $ids);
foreach ($ids as $id) {
$todayPrice[$id]['title'] = $activities[$no];
$arr['not_in_group'][] = $todayPrice[$id];
}
}
}
unset($arr['ids']);
}
return $data;
}
} }

View File

@ -29,12 +29,12 @@ class Controller extends BaseController
]; ];
} }
protected function setBeforeUpdate($data) protected function setBeforeUpdateForLog($data)
{ {
$this->log->before_update = is_array($data) ? json_encode($data, 256) : $data; $this->log->before_update = is_array($data) ? json_encode($data, 256) : $data;
} }
protected function setAfterUpdate($data) protected function setAfterUpdateForLog($data)
{ {
$this->log->after_update = is_array($data) ? json_encode($data, 256) : $data; $this->log->after_update = is_array($data) ? json_encode($data, 256) : $data;
} }

View File

@ -51,7 +51,7 @@ class GoodsBrandsController extends Controller
'errorMessage' => '批量添加失败', 'errorMessage' => '批量添加失败',
]; ];
} }
$this->setAfterUpdate($goodsBrands); $this->setAfterUpdateForLog($goodsBrands);
$this->addLog(0, 'add'); $this->addLog(0, 'add');
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
@ -78,10 +78,10 @@ class GoodsBrandsController extends Controller
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
} }
$goodsBrand = GoodsBrand::query()->find($id); $goodsBrand = GoodsBrand::query()->find($id);
$this->setBeforeUpdate($goodsBrand->name); $this->setBeforeUpdateForLog($goodsBrand->name);
$goodsBrand->name = request('name'); $goodsBrand->name = request('name');
$goodsBrand->save(); $goodsBrand->save();
$this->setAfterUpdate($goodsBrand->name); $this->setAfterUpdateForLog($goodsBrand->name);
$this->addLog($id, 'name'); $this->addLog($id, 'name');
return new GoodsBrandResource($goodsBrand); return new GoodsBrandResource($goodsBrand);

View File

@ -0,0 +1,187 @@
<?php
namespace App\Http\Controllers\Goods;
use App\Events\StockUpdateEvent;
use App\Http\Controllers\Controller;
use App\Http\Resources\GoodsSkuResource;
use App\Imports\CombinationGoodsImport;
use App\Models\CombinationGood;
use App\Models\Goods;
use App\Models\GoodsSku;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
use Maatwebsite\Excel\Facades\Excel;
class GoodsCombinationController extends Controller
{
public function index(Request $request)
{
// ToDo
// 可通过子商城查找主商品
$skus = GoodsSku::query()
->with([
'combinationGoods:id,goods_sku_id,item_id,item_num',
'combinationGoods.goodsSkuItem:id,goods_id,title,stock,external_sku_id,updated_at,yesterday_num,reference_price,status',
'combinationGoods.goodsSkuItem.goods:id,title,img_url',
])
->where('is_combination', 1)
->filter()
->paginate($request->get('per_page'));
foreach ($skus as &$item) {
$items = [];
foreach ($item['combinationGoods'] as $combinationItem) {
$items[] = [
'cost' => 0,
'external_sku_id' => $combinationItem['goodsSkuItem']['external_sku_id'],
'goods_id' => $combinationItem['goodsSkuItem']['goods_id'],
'id' => $combinationItem['item_id'],
'is_combination' => 0,
'num' => $combinationItem['item_num'],
'reference_price' => $combinationItem['goodsSkuItem']['reference_price'],
'status' => $combinationItem['goodsSkuItem']['status'],
'stock' => $combinationItem['goodsSkuItem']['stock'],
'thumb_url' => $combinationItem['goodsSkuItem']['goods']['img_url'],
'img_url' => $combinationItem['goodsSkuItem']['goods']['img_url'],
'title' => $combinationItem['goodsSkuItem']['goods']['title'] . $combinationItem['goodsSkuItem']['title'],
'updated_at' => $combinationItem['goodsSkuItem']['updated_at'],
'yesterday_num' => $combinationItem['goodsSkuItem']['yesterday_num'],
];
}
$item['children'] = $items;
unset($item['combinationGoods']);
}
return GoodsSkuResource::collection($skus);
}
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required',
'external_sku_id' => 'required',
'combination_goods.*' => 'required',
'combination_goods.*.item_id' => 'required',
'combination_goods.*.item_num' => 'required|gt:0',
]);
if ($validator->fails()) {
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
return response($this->res, $this->res['httpCode']);
}
DB::beginTransaction();
try {
$combinationGoods = $request->input('combination_goods');
$itemIds = array_column($combinationGoods, 'item_id');
$skus = GoodsSku::query()
->whereIn('id', $itemIds)
->pluck('stock', 'id')
->toArray();
$stock = 0;
foreach ($combinationGoods as $item) {
$num = (int)($skus[$item['item_id']] / $item['item_num']);
if (0 === $stock) {
$stock = $num;
continue;
}
if ($num < $stock) {
$stock = $num;
}
}
if ($id = $request->input('id')) {
$sku = GoodsSku::query()->findOrFail($id);
} else {
$sku = new GoodsSku();
$sku->goods_id = 0;
$sku->is_combination = 1;
}
$sku->title = $request->input('title');
$sku->sku_code = $request->input('external_sku_id');
$sku->external_sku_id = $request->input('external_sku_id');
$sku->stock = $stock;
$sku->save();
CombinationGood::query()
->where('goods_sku_id', $sku->id)
->delete();
foreach ($combinationGoods as $item) {
CombinationGood::query()->create(['goods_sku_id' => $sku->id, 'item_id' => $item['item_id'], 'item_num' => $item['item_num']]);
}
DB::commit();
// event(new StockUpdateEvent($sku, 0, true));
} catch (\Exception $exception) {
DB::rollBack();
$this->res = [
'httpCode' => 400,
'errorCode' => 400500,
'errorMessage' => $exception->getMessage(),
];
}
return response($this->res, $this->res['httpCode']);
}
public function show(Request $request, $id)
{
$sku = GoodsSku::query()
->with([
'combinationGoods:id,goods_sku_id,item_id,item_num',
'combinationGoods.goodsSkuItem:id,title,goods_id',
'combinationGoods.goodsSkuItem.goods:id,title',
])
->findOrFail($id);
$items = [];
foreach ($sku['combinationGoods'] as $item) {
$items[] = [
'id' => $item['goodsSkuItem']['id'],
'title' => $item['goodsSkuItem']['goods']['title'] . $item['goodsSkuItem']['title'],
];
}
$sku['skus'] = $items;
return new GoodsSkuResource($sku);
}
public function destroy(Request $request, $id)
{
}
public function goodsSkus(Request $request, $title)
{
$goodsIds = Goods::query()
->where('title', 'like', '%' . $title . '%')
->pluck('id');
$skus = GoodsSku::query()
->whereIn('goods_id', $goodsIds)
->where('is_combination', 0)
->with('goods:id,title')
->get(['id', 'title', 'goods_id']);
foreach ($skus as &$sku) {
$sku['title'] = $sku['goods']['title'] . $sku['title'];
}
return GoodsSkuResource::collection($skus);
}
public function import(Request $request)
{
if (!$request->hasFile('combinationGoods')) {
$this->res = [
'httpCode' => 404,
'errorCode' => 404404,
'errorMessage' => 'not found file',
];
}
try {
$import = new CombinationGoodsImport();
$path = $request->file('combinationGoods');
Excel::import($import, $path);
} catch (ValidationException $exception) {
$this->setValidatorFailResponse($exception->validator->getMessageBag()->getMessages());
}
return response($this->res, $this->res['httpCode']);
}
}

View File

@ -60,10 +60,11 @@ class GoodsController extends Controller
$item['goods_id'] = $goods->id; $item['goods_id'] = $goods->id;
$item['stock'] = $item['num']; $item['stock'] = $item['num'];
$item['reference_price'] = $item['cost'] * 1.5; $item['reference_price'] = $item['cost'] * 1.5;
$item['external_sku_id'] = $goods->goods_code . '_' . $item['sku_code'];
$goodsSkus[] = $item; $goodsSkus[] = $item;
} }
$collection = $goods->skus()->createMany($goodsSkus)->toArray(); $collection = $goods->skus()->createMany($goodsSkus)->toArray();
$this->setAfterUpdate($collection); $this->setAfterUpdateForLog($collection);
$this->addLog(0, 'add'); $this->addLog(0, 'add');
$newRecords = []; $newRecords = [];
foreach ($collection as $sku) { foreach ($collection as $sku) {

View File

@ -10,10 +10,12 @@ use App\Http\Requests\GoodsSkuRequest;
use App\Imports\InventoryImport; use App\Imports\InventoryImport;
use App\Models\BusinessOrderItem; use App\Models\BusinessOrderItem;
use App\Models\Goods; use App\Models\Goods;
use App\Models\GoodsType;
use App\Models\Log; use App\Models\Log;
use App\Models\Log as LogModel; use App\Models\Log as LogModel;
use App\Utils\ArrayUtils; use App\Utils\ArrayUtils;
use App\Utils\DateTimeUtils; use App\Utils\DateTimeUtils;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Models\GoodsSku; use App\Models\GoodsSku;
use App\Http\Resources\GoodsSkuResource; use App\Http\Resources\GoodsSkuResource;
@ -39,39 +41,17 @@ class GoodsSkusController extends Controller
public function index(Request $request) public function index(Request $request)
{ {
$goodsCode = $skuCode = ''; $builder = GoodsSku::query();
if ($externalSkuId = $request->get('external_sku_id')) { $this->preparQueryGoodsSkus($request, $builder);
[$goodsCode, $skuCode] = explode('_', $externalSkuId);
}
$goods = Goods::query()->filter()->when($goodsCode, function ($query, $goodsCode) {
return $query->where('goods_code', $goodsCode);
})->get()->toArray();
$goodsIds = array_column($goods, 'id');
// 状态变更时间查询,日志
$ids = [];
if ($request->get('keyword_type', '') && $request->get('keyword_value', '')) {
$ids = Log::query()->where('target_type', 'goods_sku')
->where('target_field', $request->keyword_type)
->whereBetween('created_at', explode(' - ', $request->keyword_value))
->pluck('target_id')
->toArray();
}
$day = DateTimeUtils::getToday(); $day = DateTimeUtils::getToday();
$goodsSkus = GoodsSku::query() $goodsSkus = $builder->filter()
->whereIn('goods_id', $goodsIds)
->when($ids, function ($query, $ids) {
return $query->whereIn('id', $ids);
})
->when($skuCode, function ($query, $skuCode) {
return $query->where('sku_code', $skuCode);
})
->filter()
->with(['goods' => function ($query) { ->with(['goods' => function ($query) {
$query->with(['type:id,name', 'brand:id,name']); $query->with(['type:id,name', 'brand:id,name']);
}]) }])
->with(['daily' => function ($query) use ($day) { ->with(['daily' => function ($query) use ($day) {
$query->where('day', $day); $query->where('day', $day);
}]) }])
->where('is_combination', 0)
->orderBy('updated_at', 'desc') ->orderBy('updated_at', 'desc')
->paginate($request->get('per_page')); ->paginate($request->get('per_page'));
$fields = implode(',', [ $fields = implode(',', [
@ -82,20 +62,19 @@ class GoodsSkusController extends Controller
]); ]);
$rolesName = $request->user()->getRoleNames()->toArray(); $rolesName = $request->user()->getRoleNames()->toArray();
foreach ($goodsSkus as &$sku) { foreach ($goodsSkus as &$sku) {
$externalSkuId = $sku['goods']['goods_code'] . '_' . $sku['sku_code'];
$lastInventoryTime = $sku['daily']['inventory_time']; $lastInventoryTime = $sku['daily']['inventory_time'];
$orderDetail = BusinessOrderItem::query() $orderDetail = BusinessOrderItem::query()
->select(DB::raw($fields)) ->select(DB::raw($fields))
->where('external_sku_id', $externalSkuId) ->with(['shop:id,name'])
->where('external_sku_id', $sku['external_sku_id'])
->when($lastInventoryTime, function ($query) use ($lastInventoryTime) { ->when($lastInventoryTime, function ($query) use ($lastInventoryTime) {
$query->where('created_at', '>', $lastInventoryTime); $query->where('created_at', '>', $lastInventoryTime);
}) })
->groupBy(['shop_id', 'external_sku_id']) ->groupBy(['shop_id', 'external_sku_id'])
->with(['shop:id,name']) ->get()
->get(); ->toArray();
$addOrderGoodsNum = $reduceOrderGoodsNum = 0; $addOrderGoodsNum = $reduceOrderGoodsNum = 0;
if ($orderDetail) { if ($orderDetail) {
$orderDetail = $orderDetail->toArray();
$addOrderGoodsNum = array_sum(array_column($orderDetail, 'number')); $addOrderGoodsNum = array_sum(array_column($orderDetail, 'number'));
$reduceOrderGoodsNum = array_sum(array_column($orderDetail, 'cancel_number')); $reduceOrderGoodsNum = array_sum(array_column($orderDetail, 'cancel_number'));
} }
@ -110,6 +89,22 @@ class GoodsSkusController extends Controller
return GoodsSkuResource::collection($goodsSkus); return GoodsSkuResource::collection($goodsSkus);
} }
private function preparQueryGoodsSkus(Request $request, &$builder)
{
if ($request->get('keyword_type') && $request->get('keyword_value')) {
$skuIds = Log::query()->where('target_type', 'goods_sku')
->where('target_field', $request->keyword_type)
->whereBetween('created_at', explode(' - ', $request->keyword_value))
->pluck('target_id')
->toArray();
$builder->whereIn('id', $skuIds);
}
if ($request->get('goods_title') || $request->get('type_id') || $request->get('brand_id')) {
$goodsIds = Goods::query()->filter()->pluck('id')->toArray();
$builder->whereIn('goods_id', $goodsIds);
}
}
public function show($id) public function show($id)
{ {
$sku = GoodsSku::query() $sku = GoodsSku::query()
@ -146,9 +141,10 @@ class GoodsSkusController extends Controller
try { try {
// 商品规格更新 // 商品规格更新
$sku = GoodsSku::query()->find($id); $sku = GoodsSku::query()->find($id);
$this->setBeforeUpdate($sku->toArray()); $this->setBeforeUpdateForLog($sku->toArray());
$request->sku['external_sku_id'] = $request->goods['goods_code'] . '_' . $request->sku['sku_code'];
$sku->update($request->sku); $sku->update($request->sku);
$this->setAfterUpdate($sku->toArray()); $this->setAfterUpdateForLog($sku->toArray());
$this->addLog($id, 'update'); $this->addLog($id, 'update');
// 商品更新 // 商品更新
$goods = Goods::query()->find($sku->goods_id); $goods = Goods::query()->find($sku->goods_id);
@ -157,9 +153,9 @@ class GoodsSkusController extends Controller
'action' => $request->getMethod(), 'action' => $request->getMethod(),
'target_type' => 'goods', 'target_type' => 'goods',
]); ]);
$this->setBeforeUpdate($goods->toArray()); $this->setBeforeUpdateForLog($goods->toArray());
$goods->update($request->goods); $goods->update($request->goods);
$this->setAfterUpdate($goods->toArray()); $this->setAfterUpdateForLog($goods->toArray());
$this->addLog($sku->goods_id, 'update'); $this->addLog($sku->goods_id, 'update');
DB::commit(); DB::commit();
} catch (\Exception $exception) { } catch (\Exception $exception) {
@ -351,7 +347,7 @@ class GoodsSkusController extends Controller
->where('sku_id', $sku->id) ->where('sku_id', $sku->id)
->where('day', DateTimeUtils::getToday()) ->where('day', DateTimeUtils::getToday())
->first(); ->first();
$this->setBeforeUpdate([ $this->setBeforeUpdateForLog([
'two_days_ago_num' => $sku->two_days_ago_num, 'two_days_ago_num' => $sku->two_days_ago_num,
'yesterday_num' => $sku->yesterday_num, 'yesterday_num' => $sku->yesterday_num,
'arrived_today_num' => $record->arrived_today_num, 'arrived_today_num' => $record->arrived_today_num,
@ -366,7 +362,7 @@ class GoodsSkusController extends Controller
$sku->save(); $sku->save();
$record->arrived_today_num = $update['arrived_today_num']; $record->arrived_today_num = $update['arrived_today_num'];
$record->save(); $record->save();
$this->setAfterUpdate([ $this->setAfterUpdateForLog([
'two_days_ago_num' => $sku->two_days_ago_num, 'two_days_ago_num' => $sku->two_days_ago_num,
'yesterday_num' => $sku->yesterday_num, 'yesterday_num' => $sku->yesterday_num,
'arrived_today_num' => $record->arrived_today_num, 'arrived_today_num' => $record->arrived_today_num,
@ -432,14 +428,14 @@ class GoodsSkusController extends Controller
->where('day', DateTimeUtils::getToday()) ->where('day', DateTimeUtils::getToday())
->first(['id', 'loss_num']); ->first(['id', 'loss_num']);
$this->log->message = $request->get('reason'); $this->log->message = $request->get('reason');
$this->setBeforeUpdate($record->loss_num); $this->setBeforeUpdateForLog($record->loss_num);
$record->loss_num += $request->loss_num; $record->loss_num += $request->loss_num;
$record->save(); $record->save();
$this->setAfterUpdate($record->loss_num); $this->setAfterUpdateForLog($record->loss_num);
$sku->stock -= $request->loss_num; $sku->stock -= $request->loss_num;
$sku->save(); $sku->save();
} else { } else {
$this->setBeforeUpdate($sku->$updateField); $this->setBeforeUpdateForLog($sku->$updateField);
if ('reserve' === $updateField) { if ('reserve' === $updateField) {
$changeNum = $sku->reserve - $request->reserve; $changeNum = $sku->reserve - $request->reserve;
if (0 > $changeNum + $sku->stock) { if (0 > $changeNum + $sku->stock) {
@ -450,7 +446,7 @@ class GoodsSkusController extends Controller
} }
$sku->$updateField = $request->$updateField; $sku->$updateField = $request->$updateField;
$sku->save(); $sku->save();
$this->setAfterUpdate($sku->$updateField); $this->setAfterUpdateForLog($sku->$updateField);
} }
if (in_array($updateField, ['reserve', 'loss_num'])) { if (in_array($updateField, ['reserve', 'loss_num'])) {
event(new StockUpdateEvent($sku)); event(new StockUpdateEvent($sku));
@ -509,4 +505,39 @@ class GoodsSkusController extends Controller
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
} }
public function stockNum()
{
$skus = GoodsSku::query()
->where('is_combination', 0)
->where('status', '>', 0)
->pluck('stock', 'external_sku_id')
->toArray();
$roseNum = $otherNum = 0;
foreach ($skus as $externalSkuId => $stock) {
// 玫瑰
if (false !== strpos($externalSkuId, 'M')) {
$roseNum += $stock;
continue;
}
// 草花剔除A开头
if (false !== strpos($externalSkuId, 'A')) {
continue;
}
// 剔除Z开头组合
if (false !== strpos($externalSkuId, 'Z')) {
continue;
}
// 剔除N开头年宵花
if (false !== strpos($externalSkuId, 'N')) {
continue;
}
$otherNum += $stock;
}
return response()->json([
'rose_num' => $roseNum,
'other_num' => $otherNum,
]);
}
} }

View File

@ -51,7 +51,7 @@ class GoodsTypesController extends Controller
'errorMessage' => '批量添加失败', 'errorMessage' => '批量添加失败',
]; ];
} }
$this->setAfterUpdate($goodsTypes); $this->setAfterUpdateForLog($goodsTypes);
$this->addLog(0, 'add'); $this->addLog(0, 'add');
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
@ -78,10 +78,10 @@ class GoodsTypesController extends Controller
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
} }
$goodsType = GoodsType::query()->find($id); $goodsType = GoodsType::query()->find($id);
$this->setBeforeUpdate($goodsType->name); $this->setBeforeUpdateForLog($goodsType->name);
$goodsType->name = request('name'); $goodsType->name = request('name');
$goodsType->save(); $goodsType->save();
$this->setAfterUpdate($goodsType->name); $this->setAfterUpdateForLog($goodsType->name);
$this->addLog($id, 'name'); $this->addLog($id, 'name');
return new GoodsTypeResource($goodsType); return new GoodsTypeResource($goodsType);

View File

@ -45,7 +45,7 @@ class MenusController extends Controller
} }
} }
$permissionCodes = array_unique($permissionCodes); $permissionCodes = array_unique($permissionCodes);
$menus = Menu::query()->orderBy('parent_id')->orderBy('seq')->get()->toArray(); $menus = Menu::query()->where('show', 1)->orderBy('parent_id')->orderBy('seq')->get()->toArray();
$hasPermissionMenus = []; $hasPermissionMenus = [];
foreach ($menus as $menu) { foreach ($menus as $menu) {
if (in_array($menu['code'], $permissionCodes, true)) { if (in_array($menu['code'], $permissionCodes, true)) {
@ -76,7 +76,7 @@ class MenusController extends Controller
$menu->parent_id = $request->parent_id; $menu->parent_id = $request->parent_id;
$menu->seq = $request->seq; $menu->seq = $request->seq;
$menu->save(); $menu->save();
$this->setAfterUpdate($menu->toArray()); $this->setAfterUpdateForLog($menu->toArray());
$this->addLog($menu->id, 'add'); $this->addLog($menu->id, 'add');
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
@ -101,13 +101,13 @@ class MenusController extends Controller
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
} }
$menu = Menu::query()->find($id); $menu = Menu::query()->find($id);
$this->setBeforeUpdate($menu->toArray()); $this->setBeforeUpdateForLog($menu->toArray());
$menu->name = $request->name; $menu->name = $request->name;
$menu->code = $request->code; $menu->code = $request->code;
$menu->parent_id = $request->parent_id; $menu->parent_id = $request->parent_id;
$menu->seq = $request->seq; $menu->seq = $request->seq;
$menu->save(); $menu->save();
$this->setAfterUpdate($menu->toArray()); $this->setAfterUpdateForLog($menu->toArray());
$this->addLog($id, 'update'); $this->addLog($id, 'update');
return new MenusResource($menu); return new MenusResource($menu);

View File

@ -53,7 +53,7 @@ class PermissionsController extends Controller
$permission = new Permission(); $permission = new Permission();
$permission->name = $request->name; $permission->name = $request->name;
$permission->save(); $permission->save();
$this->setAfterUpdate($permission->name); $this->setAfterUpdateForLog($permission->name);
$this->addLog($permission->id, 'add'); $this->addLog($permission->id, 'add');
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
@ -75,10 +75,10 @@ class PermissionsController extends Controller
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
} }
$permission = Permission::query()->find($id); $permission = Permission::query()->find($id);
$this->setBeforeUpdate($permission->name); $this->setBeforeUpdateForLog($permission->name);
$permission->name = $request->name; $permission->name = $request->name;
$permission->save(); $permission->save();
$this->setAfterUpdate($permission->name); $this->setAfterUpdateForLog($permission->name);
$this->addLog($id, 'name'); $this->addLog($id, 'name');
return new PermissionsResource($permission); return new PermissionsResource($permission);

View File

@ -56,7 +56,7 @@ class RolesController extends Controller
$role = new Role(); $role = new Role();
$role->name = $request->name; $role->name = $request->name;
$role->save(); $role->save();
$this->setAfterUpdate($role->name); $this->setAfterUpdateForLog($role->name);
$this->addLog($role->id, 'add'); $this->addLog($role->id, 'add');
return new RolesResource($role); return new RolesResource($role);
@ -67,7 +67,7 @@ class RolesController extends Controller
$role = Role::query()->findOrFail($id); $role = Role::query()->findOrFail($id);
$permissions = Permission::query()->findOrFail($request->permissionIds); $permissions = Permission::query()->findOrFail($request->permissionIds);
$role->syncPermissions($permissions); $role->syncPermissions($permissions);
$this->setAfterUpdate($permissions->toArray()); $this->setAfterUpdateForLog($permissions->toArray());
$this->addLog($id, 'set', 'permission'); $this->addLog($id, 'set', 'permission');
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
@ -89,10 +89,10 @@ class RolesController extends Controller
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
} }
$role = Role::query()->find($id); $role = Role::query()->find($id);
$this->setBeforeUpdate($role->name); $this->setBeforeUpdateForLog($role->name);
$role->name = $request->name; $role->name = $request->name;
$role->save(); $role->save();
$this->setAfterUpdate($role->name); $this->setAfterUpdateForLog($role->name);
$this->addLog($id, 'name'); $this->addLog($id, 'name');
return new RolesResource($role); return new RolesResource($role);

View File

@ -150,11 +150,8 @@ class ShopsController extends Controller
->get(); ->get();
$data = []; $data = [];
foreach ($res as $item) { foreach ($res as $item) {
[$goodsCode, $skuCode] = explode('_', $item['external_sku_id']); $sku = GoodsSku::query()
$sku = GoodsSku::query()->where('sku_code', $skuCode) ->where('external_sku_id', $item['external_sku_id'])
->whereHas('goods', function ($query) use ($goodsCode) {
$query->where('goods_code', $goodsCode);
})
->first(); ->first();
if (empty($sku)) { if (empty($sku)) {
continue; continue;
@ -189,4 +186,36 @@ class ShopsController extends Controller
return response($this->res, $this->res['httpCode']); return response($this->res, $this->res['httpCode']);
} }
public function syncStock(Request $request)
{
$shopId = $request->get('shop_id');
$skus = GoodsSku::query()
->where('status', '>', 0)
->whereNotNull('external_sku_id')
->pluck('stock', 'external_sku_id')
->toArray();
$builder = Shop::query()->where('expires_at', '>', time());
if ('all' === $shopId) {
$shops = $builder->get();
} else {
$shops = $builder->where('id', $shopId)->get();
}
foreach ($shops as $shop) {
$business = BusinessFactory::init()->make($shop->plat_id);
$business->setShop($shop);
foreach ($skus as $externalSkuId => $stock) {
$businessGoodsSkus = BusinessGoodsSku::query()
->select(['goods_id', 'sku_id', 'external_sku_id'])
->where('shop_id', $shop->id)
->where('is_sync', 1)
->where('external_sku_id', $externalSkuId)
->get()
->toArray();
$business->batchIncrQuantity($businessGoodsSkus, $stock, false);
}
}
return response($this->res, $this->res['httpCode']);
}
} }

View File

@ -46,7 +46,7 @@ class UsersController extends Controller
$user->password = $request->password; $user->password = $request->password;
$user->api_token = Str::random(60); $user->api_token = Str::random(60);
$user->save(); $user->save();
$this->setAfterUpdate($user->toArray()); $this->setAfterUpdateForLog($user->toArray());
$this->addLog($user->id, 'add'); $this->addLog($user->id, 'add');
$user->assignRole($request->role_name); $user->assignRole($request->role_name);

View File

@ -0,0 +1,86 @@
<?php
namespace App\Imports;
use App\Events\StockUpdateEvent;
use App\Models\CombinationGood;
use App\Models\GoodsSku;
use App\Models\GoodsSkuLocation;
use App\Utils\ArrayUtils;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Concerns\ToArray;
use Maatwebsite\Excel\Concerns\WithStartRow;
class CombinationGoodsImport implements ToArray, SkipsEmptyRows, WithStartRow
{
public function startRow(): int
{
return 2;
}
public function array(array $array)
{
$main = [];
foreach ($array as &$row) {
$row = array_map(function ($value) {
return trim($value);
}, $row);
if (empty($row[0]) || empty($row[1])) {
continue;
}
// 组合商品
if (empty($row[2]) && empty($row[3])) {
$main[$row[1]] = [
'title' => $row[0],
'external_sku_id' => $row[1],
'item' => []
];
} else {
$main[$row[1]]['item'][] = [
'item_code' => $row[2],
'item_num' => $row[3],
];
}
}
foreach ($main as $info) {
if (empty($info['item'])) {
continue;
}
DB::beginTransaction();
try {
$itemCodes = array_column($info['item'], 'item_code');
$skus = GoodsSku::query()
->whereIn('external_sku_id', $itemCodes)
->get(['id', 'external_sku_id', 'stock'])
->toArray();
$skus = ArrayUtils::index($skus, 'external_sku_id');
$stock = 0;
foreach ($info['item'] as $item) {
$num = (int)($skus[$item['item_code']]['stock'] / $item['item_num']);
if (0 === $stock) {
$stock = $num;
continue;
}
if ($num < $stock) {
$stock = $num;
}
}
$sku = GoodsSku::query()->updateOrCreate(
['external_sku_id' => $info['external_sku_id'], 'is_combination' => 1],
['title' => $info['title'], 'goods_id' => 0, 'sku_code' => $info['external_sku_id'], 'stock' => $stock]
);
CombinationGood::query()
->where('goods_sku_id', $sku->id)
->delete();
foreach ($info['item'] as $item) {
CombinationGood::query()->create(['goods_sku_id' => $sku->id, 'item_id' => $skus[$item['item_code']]['id'], 'item_num' => $item['item_num']]);
}
DB::commit();
// event(new StockUpdateEvent($sku, 0, true));
} catch (\Exception $exception) {
DB::rollBack();
}
}
}
}

View File

@ -2,7 +2,7 @@
namespace App\Imports; namespace App\Imports;
use App\Models\Goods; use App\Models\GoodsSku;
use App\Models\GoodsSkuLocation; use App\Models\GoodsSkuLocation;
use Maatwebsite\Excel\Concerns\SkipsEmptyRows; use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Concerns\ToArray; use Maatwebsite\Excel\Concerns\ToArray;
@ -17,37 +17,36 @@ class GoodsSkuLocationImport implements ToArray, SkipsEmptyRows, WithStartRow
public function array(array $array) public function array(array $array)
{ {
$goodsCode = $deleteLocation = []; $externalSkuIds = $deleteLocation = [];
foreach ($array as &$row) { foreach ($array as &$row) {
$row = array_map(function ($value) { $row = array_map(function ($value) {
return trim($value); return trim($value);
}, $row); }, $row);
$goodsCode[] = $row[2]; $externalSkuIds[] = $row[2];
$deleteLocation[] = $row[5]; $deleteLocation[] = $row[3];
} }
GoodsSkuLocation::query()->whereIn('location', $deleteLocation)->delete(); GoodsSkuLocation::query()->whereIn('location', $deleteLocation)->delete();
unset($row); unset($row);
$goods = Goods::query() $skus = GoodsSku::query()
->whereIn('goods_code', $goodsCode) ->with('goods:id,title')
->get(['id', 'goods_code', 'title']); ->whereIn('external_sku_id', $externalSkuIds)
->get(['id', 'goods_id', 'title', 'external_sku_id']);
$goodsSkus = []; $goodsSkus = [];
foreach ($goods as $goodsItem) { foreach ($skus as $sku) {
foreach ($goodsItem->skus as $sku){ $goodsSkus[$sku['external_sku_id']] = [
$goodsSkus[$goodsItem['goods_code']][$sku->sku_code] = [ 'goods_id' => $sku['goods_id'],
'goods_id' => $goodsItem->id, 'goods_sku_id' => $sku['id'],
'goods_sku_id' => $sku->id, 'external_sku_id' => $sku['external_sku_id'],
'external_sku_id' => $goodsItem['goods_code'] . '_' . $sku->sku_code, 'goods_name' => $sku['goods']['title'] . $sku['title'],
'goods_name' => $goodsItem['title'] . '_' . $sku->title,
]; ];
} }
}
$data = []; $data = [];
foreach ($array as $row) { foreach ($array as $row) {
if (isset($goodsSkus[$row[2]][$row[4]])) { if (isset($goodsSkus[$row[2]])) {
$data[] = array_merge($goodsSkus[$row[2]][$row[4]], [ $data[] = array_merge($goodsSkus[$row[2]], [
'date' => date('Y-m-d'), 'date' => date('Y-m-d'),
'today_init_num' => $row[1], 'today_init_num' => $row[1],
'location' => $row[5], 'location' => $row[3],
]); ]);
} }
} }

View File

@ -3,81 +3,84 @@
namespace App\Imports; namespace App\Imports;
use App\Models\DailyStockRecord; use App\Models\DailyStockRecord;
use App\Models\Goods;
use App\Models\GoodsSku; use App\Models\GoodsSku;
use App\Models\TodayPrice;
use App\Utils\DateTimeUtils; use App\Utils\DateTimeUtils;
use Exception; use Exception;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Concerns\SkipsEmptyRows; use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Concerns\ToCollection; use Maatwebsite\Excel\Concerns\ToArray;
use App\Utils\ArrayUtils; use App\Utils\ArrayUtils;
use App\Events\StockUpdateEvent; use App\Events\StockUpdateEvent;
class InventoryImport implements ToCollection, SkipsEmptyRows class InventoryImport implements ToArray, SkipsEmptyRows
{ {
/** /**
* @throws Exception * @throws Exception
*/ */
public function collection(Collection $collection) public function array(array $collection)
{ {
$header = $collection[0];
unset($collection[0]); unset($collection[0]);
$collection = $collection->toArray(); $externalSkuId = [];
$goodsCodes = [];
foreach ($collection as &$row) { foreach ($collection as &$row) {
$row = array_map(static function ($v) { $row = array_map(static function ($v) {
return trim($v); return trim($v);
}, $row); }, $row);
$goodsCodes[] = $row[0]; $externalSkuId[] = $row[0];
} }
unset($row); unset($row);
$hasGoods = Goods::query()->whereIn('goods_code', $goodsCodes)->get(['id', 'goods_code'])->toArray(); $updateIds = $todayPrice = [];
$hasGoodsIds = array_column($hasGoods, 'id');
$hasGoods = ArrayUtils::index($hasGoods, 'goods_code');
$updateIds = [];
$day = DateTimeUtils::getToday(); $day = DateTimeUtils::getToday();
$dateTime = date('Y-m-d H:i:s'); $dateTime = date('Y-m-d H:i:s');
$hasGoodsSkus = GoodsSku::query() $hasGoodsSkus = GoodsSku::query()
->whereIn('goods_id', $hasGoodsIds) ->whereIn('external_sku_id', $externalSkuId)
->get(['id', 'status', 'stock', 'cost', 'sku_code', 'goods_id']) ->get(['id', 'status', 'external_sku_id'])
->toArray(); ->toArray();
$hasGoodsSkus = ArrayUtils::index($hasGoodsSkus, 'external_sku_id');
foreach ($collection as $row) { foreach ($collection as $row) {
if (!isset($hasGoods[$row[0]])) { if (!isset($hasGoodsSkus[$row[0]])) {
continue;
}
$goodsId = $hasGoods[$row[0]]['id'];
$goodsSku = [];
foreach ($hasGoodsSkus as $item) {
if ($item['sku_code'] === $row[4] && $item['goods_id'] === $goodsId) {
$goodsSku = $item;
break;
}
}
if (empty($goodsSku)) {
Log::warning(json_encode($row, 256) . '=====库存导入未找到');
continue; continue;
} }
$goodsSku = $hasGoodsSkus[$row[0]];
if ('下架' === $goodsSku['status']) { if ('下架' === $goodsSku['status']) {
GoodsSku::query()->where('id', $goodsSku['id'])->update([ GoodsSku::query()->where('id', $goodsSku['id'])->update([
'stock' => $row[6] + $row[7], 'stock' => $row[2] + $row[3],
'cost' => $row[8], 'cost' => $row[4],
'status' => 1, 'status' => 1,
]); ]);
} else { } else {
GoodsSku::query()->where('id', $goodsSku['id'])->update([ GoodsSku::query()->where('id', $goodsSku['id'])->update([
'stock' => $row[6] + $row[7], 'stock' => $row[2] + $row[3],
'cost' => $row[8], 'cost' => $row[4],
]); ]);
} }
$updateIds[] = $goodsSku['id']; $updateIds[] = $goodsSku['id'];
DailyStockRecord::query()->where('sku_id', $goodsSku['id'])->where('day', $day)->update([ DailyStockRecord::query()->where('sku_id', $goodsSku['id'])->where('day', $day)->update([
'arrived_today_num' => $row[7], 'arrived_today_num' => $row[3],
'inventory' => $row[6], 'inventory' => $row[2],
'inventory_time' => $dateTime 'inventory_time' => $dateTime
]); ]);
$shopPrice = [];
foreach ($row as $i => $v) {
if ($i > 5) {
$shopPrice[$header[$i]] = $v;
}
}
$todayPrice[] = [
'day' => $day,
'external_sku_id' => $goodsSku['external_sku_id'],
'price' => $row[5],
'shop_price' => json_encode($shopPrice, 256)
];
}
if ($todayPrice) {
TodayPrice::query()->delete();
$model = new TodayPrice();
$model->batchInsert($todayPrice);
} }
sleep(2); sleep(2);
$onSkuIds = GoodsSku::query() $onSkuIds = GoodsSku::query()
->where('is_combination', 0)
->where('status', '>', 0) ->where('status', '>', 0)
->pluck('id') ->pluck('id')
->toArray(); ->toArray();

View File

@ -0,0 +1,37 @@
<?php
namespace App\Imports;
use App\Models\TodayPrice;
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Concerns\ToArray;
class TodayPriceImport implements ToArray, SkipsEmptyRows
{
public function array(array $array)
{
$header = $array[0];
unset($array[0]);
$data = [];
$day = date('Y-m-d');
foreach ($array as $row) {
$row = array_map(function ($value) {
return trim($value);
}, $row);
$shopPrice = [];
foreach ($row as $i => $v) {
if ($i > 1) {
$shopPrice[$header[$i]] = $v;
}
}
$data[] = [
'day' => $day,
'external_sku_id' => $row[1],
'shop_price' => json_encode($shopPrice, 256)
];
}
TodayPrice::query()->delete();
$model = new TodayPrice();
$model->batchInsert($data);
}
}

View File

@ -0,0 +1,95 @@
<?php
namespace App\Listeners;
use App\Models\CombinationGood;
use App\Models\GoodsSku;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use App\Events\StockUpdateEvent;
class CombinationGoodsStockUpdateListener
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param $event
* @return void
*/
public function handle($event)
{
if ($event->combinationGoodsUpdate) {
return false;
}
$updateIds = $combinationGoodsIds = $combinationGoodsItemIds = [];
if ($event->goodsSku) {
if ($event->goodsSku->is_combination) {
$combinationGoodsIds[] = $event->goodsSku->id;
} else {
$combinationGoodsItemIds[$event->goodsSku->id] = $event->goodsSku->stock;
}
}
if ($event->goodsSkus) {
foreach ($event->goodsSkus as $sku) {
if ($sku->is_combination) {
$combinationGoodsIds[] = $sku->id;
} else {
$combinationGoodsItemIds[$sku->id] = $sku->stock;
}
}
}
// 减子商品库存
if ($combinationGoodsIds) {
$combinationGoods = CombinationGood::query()
->with('goodsSku:id,stock')
->whereIn('goods_sku_id', $combinationGoodsIds)
->get();
foreach ($combinationGoods as $item) {
$sku = GoodsSku::query()->find($item['item_id']);
$sku->stock -= $item['item_num'];
$sku->save();
$updateIds[] = $sku->id;
}
}
// 计算主商品库存
if ($combinationGoodsItemIds) {
$itemIds = array_keys($combinationGoodsItemIds);
$goodsSkuIds = CombinationGood::query()
->whereIn('item_id', $itemIds)
->pluck('goods_sku_id')
->toArray();
if (empty($goodsSkuIds)) {
return false;
}
$goodsSkus = GoodsSku::query()
->whereIn('id', $goodsSkuIds)
->pluck('stock', 'id')
->toArray();
foreach ($combinationGoodsItemIds as $itemId => $stock) {
$combinationGoods = CombinationGood::query()
->where('item_id', $itemId)
->get();
foreach ($combinationGoods as $goods) {
$stock = $combinationGoodsItemIds[$goods['item_id']] / $goods['item_num'];
if ($stock < $goodsSkus[$goods['goods_sku_id']]) {
GoodsSku::query()->where('id', $goods['goods_sku_id'])->update(['stock' => $stock]);
$updateIds[] = $goods['goods_sku_id'];
}
}
}
}
if ($updateIds) {
event(new StockUpdateEvent($updateIds, 1, true));
}
}
}

View File

@ -41,7 +41,7 @@ class StockUpdateListener
->select(['goods_id', 'sku_id', 'external_sku_id']) ->select(['goods_id', 'sku_id', 'external_sku_id'])
->where('shop_id', $shop->id) ->where('shop_id', $shop->id)
->where('is_sync', 1) ->where('is_sync', 1)
->where('external_sku_id', $event->goodsSku->goods['goods_code'] . '_' . $event->goodsSku->sku_code) ->where('external_sku_id', $event->goodsSku->external_sku_id)
->get(); ->get();
if ($event->isBatch) { if ($event->isBatch) {
BusinessFactory::init()->make($shop['plat_id'])->setShopWithId($shop['id'])->batchIncrQuantity($businessGoodsSkus->toArray(), $num, false); BusinessFactory::init()->make($shop['plat_id'])->setShopWithId($shop['id'])->batchIncrQuantity($businessGoodsSkus->toArray(), $num, false);
@ -58,7 +58,7 @@ class StockUpdateListener
->select(['goods_id', 'sku_id', 'external_sku_id']) ->select(['goods_id', 'sku_id', 'external_sku_id'])
->where('shop_id', $shop->id) ->where('shop_id', $shop->id)
->where('is_sync', 1) ->where('is_sync', 1)
->where('external_sku_id', $goodsSku->goods['goods_code'] . '_' . $goodsSku->sku_code) ->where('external_sku_id', $goodsSku->external_sku_id)
->get(); ->get();
if ($event->isBatch) { if ($event->isBatch) {
BusinessFactory::init()->make($shop['plat_id'])->setShopWithId($shop['id'])->batchIncrQuantity($businessGoodsSkus->toArray(), $num, false); BusinessFactory::init()->make($shop['plat_id'])->setShopWithId($shop['id'])->batchIncrQuantity($businessGoodsSkus->toArray(), $num, false);

View File

@ -44,7 +44,7 @@ class UpdateBusinessGoodsStock implements ShouldQueue
$log->message = '未找到' . json_encode($event->businessGoods, 256); $log->message = '未找到' . json_encode($event->businessGoods, 256);
$log->save(); $log->save();
return; return false;
} }
$builder = Shop::query()->whereNotIn('status', [Shop::$STATUS_UNAUTHORIZED, Shop::$STATUS_STOP]); $builder = Shop::query()->whereNotIn('status', [Shop::$STATUS_UNAUTHORIZED, Shop::$STATUS_STOP]);
// 非订单影响库存变更,只更新本店铺下商品 // 非订单影响库存变更,只更新本店铺下商品
@ -54,7 +54,7 @@ class UpdateBusinessGoodsStock implements ShouldQueue
$shops = $builder->get(['id', 'plat_id']); $shops = $builder->get(['id', 'plat_id']);
if (empty($shops)) { if (empty($shops)) {
LogFile::info('可操作店铺为空'); LogFile::info('可操作店铺为空');
return; return false;
} }
foreach ($shops as $shop) { foreach ($shops as $shop) {

View File

@ -23,7 +23,6 @@ class BusinessGoodsSku extends Model
'limit_buy', 'limit_buy',
'market_price', 'market_price',
'update_time', 'update_time',
'price_in_fen',
'quantity', 'quantity',
'goods_purchase_price', 'goods_purchase_price',
'quantity_type', 'quantity_type',
@ -66,4 +65,9 @@ class BusinessGoodsSku extends Model
{ {
return $this->belongsTo(Shop::class, 'shop_id', 'id'); return $this->belongsTo(Shop::class, 'shop_id', 'id');
} }
public function getPriceInFenAttribute($val)
{
return $val / 100;
}
} }

View File

@ -0,0 +1,20 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class CombinationGood extends Model
{
protected $guarded = [];
public function goodsSkuItem()
{
return $this->belongsTo(GoodsSku::class, 'item_id', 'id');
}
public function goodsSku()
{
return $this->belongsTo(GoodsSku::class, 'goods_sku_id', 'id');
}
}

View File

@ -12,7 +12,8 @@ class GoodsSku extends Model
public $fieldSearchable = [ public $fieldSearchable = [
'sku_title', 'sku_title',
'status', 'status',
'exclude_ids' 'exclude_ids',
'external_sku_id'
]; ];
protected $fillable = [ protected $fillable = [
@ -27,7 +28,9 @@ class GoodsSku extends Model
'yesterday_num', 'yesterday_num',
'reference_price', 'reference_price',
'reserve', 'reserve',
'thumb_url' 'thumb_url',
'external_sku_id',
'is_combination',
]; ];
protected $hidden = ['created_at']; protected $hidden = ['created_at'];
@ -74,4 +77,19 @@ class GoodsSku extends Model
{ {
return $this->hasOne(DailyStockRecord::class, 'sku_id', 'id'); return $this->hasOne(DailyStockRecord::class, 'sku_id', 'id');
} }
public function combinationItems()
{
return $this->hasMany(CombinationGood::class, 'item_id', 'id');
}
public function combinationGoods()
{
return $this->hasMany(CombinationGood::class, 'goods_sku_id', 'id');
}
public function todayPrice()
{
return $this->hasOne(TodayPrice::class, 'external_sku_id', 'external_sku_id');
}
} }

13
app/Models/TodayPrice.php Normal file
View File

@ -0,0 +1,13 @@
<?php
namespace App\Models;
class TodayPrice extends Model
{
protected $guarded = [];
public function goodsSku()
{
return $this->belongsTo(GoodsSku::class, 'external_sku_id', 'external_sku_id');
}
}

View File

@ -8,6 +8,7 @@ use App\Events\StockUpdateEvent;
use App\Listeners\GroupQueryListener; use App\Listeners\GroupQueryListener;
use App\Listeners\StockUpdateListener; use App\Listeners\StockUpdateListener;
use App\Listeners\StockWarning; use App\Listeners\StockWarning;
use App\Listeners\CombinationGoodsStockUpdateListener;
use App\Listeners\UpdateBusinessGoodsStock; use App\Listeners\UpdateBusinessGoodsStock;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
@ -22,10 +23,12 @@ class EventServiceProvider extends ServiceProvider
BusinessOrdersUpdate::class => [ BusinessOrdersUpdate::class => [
UpdateBusinessGoodsStock::class, UpdateBusinessGoodsStock::class,
StockWarning::class, StockWarning::class,
CombinationGoodsStockUpdateListener::class,
], ],
StockUpdateEvent::class => [ StockUpdateEvent::class => [
StockUpdateListener::class, StockUpdateListener::class,
StockWarning::class, StockWarning::class,
CombinationGoodsStockUpdateListener::class,
], ],
GroupSetEvent::class => [ GroupSetEvent::class => [
GroupQueryListener::class, GroupQueryListener::class,

View File

@ -13,6 +13,9 @@ class CreateUsersTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('users')) {
return;
}
Schema::defaultStringLength(191); Schema::defaultStringLength(191);
Schema::create('users', function (Blueprint $table) { Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');

View File

@ -13,6 +13,9 @@ class CreatePasswordResetsTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('password_resets')) {
return;
}
Schema::create('password_resets', function (Blueprint $table) { Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index(); $table->string('email')->index();
$table->string('token'); $table->string('token');

View File

@ -13,6 +13,9 @@ class CreateFailedJobsTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('failed_jobs')) {
return;
}
Schema::create('failed_jobs', function (Blueprint $table) { Schema::create('failed_jobs', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');
$table->text('connection'); $table->text('connection');

View File

@ -13,6 +13,9 @@ class CreateGoodsTypesTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('goods_types')) {
return;
}
Schema::defaultStringLength(191); Schema::defaultStringLength(191);
Schema::create('goods_types', function (Blueprint $table) { Schema::create('goods_types', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');

View File

@ -13,6 +13,9 @@ class CreateGoodsBrandsTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('goods_brands')) {
return;
}
Schema::defaultStringLength(191); Schema::defaultStringLength(191);
Schema::create('goods_brands', function (Blueprint $table) { Schema::create('goods_brands', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');

View File

@ -13,6 +13,9 @@ class CreateGoodsTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('goods')) {
return;
}
Schema::defaultStringLength(191); Schema::defaultStringLength(191);
Schema::create('goods', function (Blueprint $table) { Schema::create('goods', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');

View File

@ -13,12 +13,15 @@ class CreateGoodsSkusTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('goods_skus')) {
return;
}
Schema::defaultStringLength(191); Schema::defaultStringLength(191);
Schema::create('goods_skus', function (Blueprint $table) { Schema::create('goods_skus', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');
$table->unsignedBigInteger('goods_id')->comment('商品id'); $table->unsignedBigInteger('goods_id')->default(0)->comment('商品id');
$table->string('title')->comment('商品规格'); $table->string('title')->default('')->comment('商品规格');
$table->string('sku_code', 32)->comment('规格编码'); $table->string('sku_code', 32)->default('')->comment('规格编码');
$table->unsignedTinyInteger('status')->default(0)->comment('规格状态(0-下架,1在售,2预警)'); $table->unsignedTinyInteger('status')->default(0)->comment('规格状态(0-下架,1在售,2预警)');
$table->unsignedInteger('num')->default(0)->comment('总量'); $table->unsignedInteger('num')->default(0)->comment('总量');
$table->integer('stock')->default(0)->comment('库存'); $table->integer('stock')->default(0)->comment('库存');

View File

@ -13,6 +13,9 @@ class CreateDailyStockRecordsTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('daily_stock_records')) {
return;
}
Schema::create('daily_stock_records', function (Blueprint $table) { Schema::create('daily_stock_records', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');
$table->bigInteger('sku_id'); $table->bigInteger('sku_id');

View File

@ -13,6 +13,9 @@ class CreateLogsTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('logs')) {
return;
}
Schema::create('logs', function (Blueprint $table) { Schema::create('logs', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');
$table->string('module')->comment('模块'); $table->string('module')->comment('模块');

View File

@ -13,6 +13,9 @@ class CreateMenusTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('menus')) {
return;
}
Schema::defaultStringLength(191); Schema::defaultStringLength(191);
Schema::create('menus', function (Blueprint $table) { Schema::create('menus', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');
@ -20,8 +23,7 @@ class CreateMenusTable extends Migration
$table->string('name', 32)->comment('菜单名称'); $table->string('name', 32)->comment('菜单名称');
$table->unsignedBigInteger('parent_id')->default(0); $table->unsignedBigInteger('parent_id')->default(0);
$table->unsignedInteger('seq')->default(0)->comment('排序序号'); $table->unsignedInteger('seq')->default(0)->comment('排序序号');
$table->softDeletes(); $table->tinyInteger('show')->default(1);
$table->timestamps();
// 索引 // 索引
}); });
} }

View File

@ -13,6 +13,9 @@ class CreateShopsTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('shops')) {
return;
}
Schema::defaultStringLength(191); Schema::defaultStringLength(191);
Schema::create('shops', function (Blueprint $table) { Schema::create('shops', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');

View File

@ -13,6 +13,9 @@ class CreateBusinessGoodsSkusTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('business_goods_skus')) {
return;
}
Schema::create('business_goods_skus', function (Blueprint $table) { Schema::create('business_goods_skus', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');
$table->bigInteger('shop_id'); $table->bigInteger('shop_id');

View File

@ -13,6 +13,9 @@ class CreateBusinessOrdersTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('business_orders')) {
return;
}
Schema::create('business_orders', function (Blueprint $table) { Schema::create('business_orders', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');
$table->integer('shop_id'); $table->integer('shop_id');

View File

@ -13,6 +13,9 @@ class CreateBusinessOrderItemsTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('business_order_items')) {
return;
}
Schema::create('business_order_items', function (Blueprint $table) { Schema::create('business_order_items', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');
$table->bigInteger('shop_id'); $table->bigInteger('shop_id');
@ -40,7 +43,7 @@ class CreateBusinessOrderItemsTable extends Migration
$table->integer('verification_number')->nullable(); $table->integer('verification_number')->nullable();
$table->timestamps(); $table->timestamps();
// 索引 // 索引
$table->index(['shop_id', 'business_order_id', 'goods_id', 'sku_id']); // $table->index(['shop_id', 'business_order_id', 'goods_id', 'sku_id']);
}); });
} }

View File

@ -13,6 +13,9 @@ class CreateJobsTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('jobs')) {
return;
}
Schema::create('jobs', function (Blueprint $table) { Schema::create('jobs', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');
$table->string('queue')->index(); $table->string('queue')->index();

View File

@ -13,6 +13,9 @@ class AddFieldsWithDailyStockRecordsTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasColumns('daily_stock_records', ['order_goods_num', 'inventory_time'])) {
return;
}
Schema::table('daily_stock_records', function (Blueprint $table) { Schema::table('daily_stock_records', function (Blueprint $table) {
$table->integer('order_goods_num')->default(0)->comment('截止盘点时间订单商品数量'); $table->integer('order_goods_num')->default(0)->comment('截止盘点时间订单商品数量');
$table->timestamp('inventory_time')->nullable()->comment('盘点时间'); $table->timestamp('inventory_time')->nullable()->comment('盘点时间');

View File

@ -13,6 +13,9 @@ class AddFieldsWithBusinessGoodsSkusTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasColumn('business_goods_skus', 'is_sync')) {
return;
}
Schema::table('business_goods_skus', function (Blueprint $table) { Schema::table('business_goods_skus', function (Blueprint $table) {
$table->tinyInteger('is_sync')->default(1)->comment('是否同步'); $table->tinyInteger('is_sync')->default(1)->comment('是否同步');
}); });

View File

@ -13,6 +13,9 @@ class CreateGroupsTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('groups')) {
return;
}
Schema::defaultStringLength(191); Schema::defaultStringLength(191);
Schema::create('groups', function (Blueprint $table) { Schema::create('groups', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');

View File

@ -13,6 +13,9 @@ class CreateGroupGoodsTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('group_goods')) {
return;
}
Schema::defaultStringLength(191); Schema::defaultStringLength(191);
Schema::create('group_goods', function (Blueprint $table) { Schema::create('group_goods', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');

View File

@ -13,6 +13,9 @@ class CreateGoodsSkuLocationsTable extends Migration
*/ */
public function up() public function up()
{ {
if (Schema::hasTable('goods_sku_locations')) {
return;
}
Schema::defaultStringLength(191); Schema::defaultStringLength(191);
Schema::create('goods_sku_locations', function (Blueprint $table) { Schema::create('goods_sku_locations', function (Blueprint $table) {
$table->bigIncrements('id'); $table->bigIncrements('id');

View File

@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddExternalSkuIdToGoodsSkusTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if (Schema::hasColumn('goods_skus', 'external_sku_id')) {
return;
}
Schema::defaultStringLength(191);
Schema::table('goods_skus', function (Blueprint $table) {
$table->string('external_sku_id')->default('')->nullable();
$table->tinyInteger('is_combination')->default(0);
$table->index('external_sku_id');
$table->index('is_combination');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('goods_skus', function (Blueprint $table) {
$table->dropColumn('external_sku_id');
$table->dropIndex('external_sku_id');
});
}
}

View File

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCombinationGoodsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if (Schema::hasTable('combination_goods')) {
return;
}
Schema::create('combination_goods', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('goods_sku_id');
$table->unsignedBigInteger('item_id');
$table->unsignedInteger('item_num');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('combination_goods');
}
}

View File

@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateTodayPricesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if (Schema::hasTable('today_prices')) {
return;
}
Schema::defaultStringLength(191);
Schema::create('today_prices', function (Blueprint $table) {
$table->bigIncrements('id');
$table->date('day');
$table->string('external_sku_id');
$table->text('shop_price');
$table->index(['external_sku_id', 'day']);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('today_prices');
}
}

View File

@ -2,6 +2,7 @@
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use App\Models\Menu;
class MenusTableSeeder extends Seeder class MenusTableSeeder extends Seeder
{ {
@ -12,6 +13,7 @@ class MenusTableSeeder extends Seeder
*/ */
public function run() public function run()
{ {
return $this->update();
// 商品管理-(商品列表,商品种类,商品品牌) // 商品管理-(商品列表,商品种类,商品品牌)
$id = DB::table('menus')->insertGetId(['parent_id' => 0, 'code' => 'GOODS_MANAGE', 'name' => '商品管理', 'seq' => 0]); $id = DB::table('menus')->insertGetId(['parent_id' => 0, 'code' => 'GOODS_MANAGE', 'name' => '商品管理', 'seq' => 0]);
DB::table('menus')->insert([ DB::table('menus')->insert([
@ -19,6 +21,7 @@ class MenusTableSeeder extends Seeder
['parent_id' => $id, 'code' => 'GOODS_TYPE', 'name' => '商品种类', 'seq' => 1], ['parent_id' => $id, 'code' => 'GOODS_TYPE', 'name' => '商品种类', 'seq' => 1],
['parent_id' => $id, 'code' => 'GOODS_BRAND', 'name' => '商品品牌', 'seq' => 2], ['parent_id' => $id, 'code' => 'GOODS_BRAND', 'name' => '商品品牌', 'seq' => 2],
['parent_id' => $id, 'code' => 'GOODS_SKU_LOCATION', 'name' => '商品货架', 'seq' => 3], ['parent_id' => $id, 'code' => 'GOODS_SKU_LOCATION', 'name' => '商品货架', 'seq' => 3],
['parent_id' => $id, 'code' => 'GOODS_COMBINATION', 'name' => '组合商品', 'seq' => 4],
]); ]);
// 店铺管理 // 店铺管理
DB::table('menus')->insertGetId(['parent_id' => 0, 'code' => 'SHOP_MANAGE', 'name' => '店铺管理', 'seq' => 10]); DB::table('menus')->insertGetId(['parent_id' => 0, 'code' => 'SHOP_MANAGE', 'name' => '店铺管理', 'seq' => 10]);
@ -40,4 +43,17 @@ class MenusTableSeeder extends Seeder
// 团购 // 团购
DB::table('menus')->insertGetId(['parent_id' => 0, 'code' => 'GROUP_MANAGEMENT', 'name' => '团购管理', 'seq' => 1]); DB::table('menus')->insertGetId(['parent_id' => 0, 'code' => 'GROUP_MANAGEMENT', 'name' => '团购管理', 'seq' => 1]);
} }
public function update()
{
$routes = include(resource_path('lang/zh-CN/permission.php'));
foreach ($routes as $code => $route) {
if (false === strpos($code, '.')) {
DB::table('menus')->updateOrInsert(
['id' => $route['id'], 'parent_id' => $route['parent_id'], 'code' => $code],
['name' => $route['name'], 'show' => $route['show']]
);
}
}
}
} }

View File

@ -14,8 +14,8 @@ class PermissionsTableSeeder extends Seeder
public function run() public function run()
{ {
$routes = include(resource_path('lang/zh-CN/permission.php')); $routes = include(resource_path('lang/zh-CN/permission.php'));
foreach ($routes as $key => $route) { foreach ($routes as $code => $route) {
$data = ['id' => $route['id'], 'name' => $key, 'guard_name' => 'api']; $data = ['id' => $route['id'], 'name' => $code, 'guard_name' => 'api'];
Permission::firstOrCreate($data); Permission::firstOrCreate($data);
} }
} }

View File

@ -0,0 +1 @@
.block[data-v-999e92dc]{margin-top:20px}

View File

@ -1 +0,0 @@
.block[data-v-42e00d18]{margin-top:20px}

View File

@ -0,0 +1 @@
.table[data-v-1ad624b7]{margin-top:20px;position:relative}.btn[data-v-1ad624b7]{float:right}[data-v-1ad624b7] .cell{display:flex;align-items:center}.commodityimg[data-v-1ad624b7]{width:59px;height:59px;background:hsla(0,0%,89%,.39);opacity:1;display:block;margin-right:12px}.Img[data-v-1ad624b7]{width:100%;height:100%}[data-v-1ad624b7] .btn11{padding:0;width:14px;height:14px}[data-v-1ad624b7] .btn11 img{width:100%;height:100%}.page[data-v-1ad624b7]{margin-top:20px}

View File

@ -0,0 +1 @@
.block[data-v-5c3641da]{margin-top:20px}

View File

@ -1 +1 @@
#nprogress{pointer-events:none}#nprogress .bar{background:#29d;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:2px solid transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;-webkit-animation:nprogress-spinner .4s linear infinite;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(1turn)}}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}a[data-v-1cc99200]{text-decoration:none;color:#fff}.block[data-v-1cc99200]{margin-top:20px} #nprogress{pointer-events:none}#nprogress .bar{background:#29d;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:2px solid transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;-webkit-animation:nprogress-spinner .4s linear infinite;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(1turn)}}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}a[data-v-4a281b44]{text-decoration:none;color:#fff}.block[data-v-4a281b44]{margin-top:20px}

View File

@ -1 +0,0 @@
.block[data-v-40c048a6]{margin-top:20px}

View File

@ -1 +0,0 @@
.table[data-v-65f2cb04]{margin-top:20px;position:relative}.btn[data-v-65f2cb04]{float:right}[data-v-65f2cb04] .cell{display:flex;align-items:center}.commodityimg[data-v-65f2cb04]{width:59px;height:59px;background:hsla(0,0%,89%,.39);opacity:1;display:block;margin-right:12px}.Img[data-v-65f2cb04]{width:100%;height:100%}.confirmbtn[data-v-65f2cb04]{width:114px;height:44px;border-radius:3px;margin-top:21px;margin-bottom:8px}.import-right[data-v-65f2cb04]{margin-top:30px}.import-right a[data-v-65f2cb04]{text-decoration:none;color:#000}[data-v-65f2cb04] .btn11{padding:0;width:14px;height:14px}[data-v-65f2cb04] .btn11 img{width:100%;height:100%}.page[data-v-65f2cb04]{margin-top:20px}

View File

@ -0,0 +1 @@
.table[data-v-e8253a8a]{margin-top:20px;position:relative}.btn[data-v-e8253a8a]{float:right}[data-v-e8253a8a] .cell{display:flex;align-items:center}.commodityimg[data-v-e8253a8a]{width:59px;height:59px;background:hsla(0,0%,89%,.39);opacity:1;display:block;margin-right:12px}.Img[data-v-e8253a8a]{width:100%;height:100%}.confirmbtn[data-v-e8253a8a]{width:114px;height:44px;border-radius:3px;margin-top:21px;margin-bottom:8px}.import-right[data-v-e8253a8a]{margin-top:30px}.import-right a[data-v-e8253a8a]{text-decoration:none;color:#000}[data-v-e8253a8a] .btn11{padding:0;width:14px;height:14px}[data-v-e8253a8a] .btn11 img{width:100%;height:100%}.page[data-v-e8253a8a]{margin-top:20px}

View File

@ -1 +1 @@
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>erp</title><link href="css/chunk-088acbde.902ebb66.css" rel="prefetch"><link href="css/chunk-0b2fb3a8.ebe80e03.css" rel="prefetch"><link href="css/chunk-0cbcaa56.e05858e7.css" rel="prefetch"><link href="css/chunk-26daa808.62429343.css" rel="prefetch"><link href="css/chunk-281ed902.b3153d73.css" rel="prefetch"><link href="css/chunk-35db73ce.1f9c10ff.css" rel="prefetch"><link href="css/chunk-4caed774.ad94328f.css" rel="prefetch"><link href="css/chunk-52fcdd7c.51e3ffbd.css" rel="prefetch"><link href="css/chunk-6ae0a0d3.84a02b23.css" rel="prefetch"><link href="css/chunk-743f0316.fb5066fb.css" rel="prefetch"><link href="css/chunk-75426f71.902ebb66.css" rel="prefetch"><link href="css/chunk-7cdb40b2.e7ded070.css" rel="prefetch"><link href="css/chunk-904e5abc.902ebb66.css" rel="prefetch"><link href="css/chunk-a3ddd952.902ebb66.css" rel="prefetch"><link href="css/chunk-ab4d3e40.d941d6ef.css" rel="prefetch"><link href="css/chunk-dae6d032.c998c48a.css" rel="prefetch"><link href="css/chunk-e35186f0.902ebb66.css" rel="prefetch"><link href="css/chunk-f0b6f0d4.a3b83cc4.css" rel="prefetch"><link href="css/chunk-f35dfe36.ea52b615.css" rel="prefetch"><link href="js/chunk-088acbde.e3b91ba7.js" rel="prefetch"><link href="js/chunk-0b2fb3a8.c7277f66.js" rel="prefetch"><link href="js/chunk-0cbcaa56.46e3dd42.js" rel="prefetch"><link href="js/chunk-26daa808.9e326ce2.js" rel="prefetch"><link href="js/chunk-281ed902.01d8bc0c.js" rel="prefetch"><link href="js/chunk-35db73ce.ae2590c3.js" rel="prefetch"><link href="js/chunk-4caed774.d65d1796.js" rel="prefetch"><link href="js/chunk-52fcdd7c.0070e388.js" rel="prefetch"><link href="js/chunk-63c1eac8.59f3df74.js" rel="prefetch"><link href="js/chunk-6ae0a0d3.ee4aa3e0.js" rel="prefetch"><link href="js/chunk-743f0316.cc5e2a5b.js" rel="prefetch"><link href="js/chunk-75426f71.128f599c.js" rel="prefetch"><link href="js/chunk-7cdb40b2.c5de1e6d.js" rel="prefetch"><link href="js/chunk-904e5abc.e6a5edbe.js" rel="prefetch"><link href="js/chunk-a3ddd952.0482ce75.js" rel="prefetch"><link href="js/chunk-ab4d3e40.c28d58b3.js" rel="prefetch"><link href="js/chunk-dae6d032.7fa60b44.js" rel="prefetch"><link href="js/chunk-e35186f0.f1d6b68d.js" rel="prefetch"><link href="js/chunk-f0b6f0d4.b774c023.js" rel="prefetch"><link href="js/chunk-f35dfe36.e7038b09.js" rel="prefetch"><link href="css/app.6c30acd7.css" rel="preload" as="style"><link href="css/chunk-vendors.9181e156.css" rel="preload" as="style"><link href="js/app.0762f328.js" rel="preload" as="script"><link href="js/chunk-vendors.524d6b36.js" rel="preload" as="script"><link href="css/chunk-vendors.9181e156.css" rel="stylesheet"><link href="css/app.6c30acd7.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but erp doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.524d6b36.js"></script><script src="js/app.0762f328.js"></script></body></html> <!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>erp</title><link href="css/chunk-086a167d.daab9de2.css" rel="prefetch"><link href="css/chunk-088acbde.902ebb66.css" rel="prefetch"><link href="css/chunk-0cbcaa56.e05858e7.css" rel="prefetch"><link href="css/chunk-26daa808.62429343.css" rel="prefetch"><link href="css/chunk-300db14a.2653662c.css" rel="prefetch"><link href="css/chunk-32da4b3e.d9ee7431.css" rel="prefetch"><link href="css/chunk-35db73ce.1f9c10ff.css" rel="prefetch"><link href="css/chunk-41cd4e14.4e6d7a5a.css" rel="prefetch"><link href="css/chunk-4caed774.ad94328f.css" rel="prefetch"><link href="css/chunk-52fcdd7c.51e3ffbd.css" rel="prefetch"><link href="css/chunk-6ae0a0d3.84a02b23.css" rel="prefetch"><link href="css/chunk-743f0316.fb5066fb.css" rel="prefetch"><link href="css/chunk-75426f71.902ebb66.css" rel="prefetch"><link href="css/chunk-7cdb40b2.e7ded070.css" rel="prefetch"><link href="css/chunk-904e5abc.902ebb66.css" rel="prefetch"><link href="css/chunk-a3ddd952.902ebb66.css" rel="prefetch"><link href="css/chunk-ab4d3e40.d941d6ef.css" rel="prefetch"><link href="css/chunk-e35186f0.902ebb66.css" rel="prefetch"><link href="css/chunk-f35dfe36.ea52b615.css" rel="prefetch"><link href="css/chunk-fc9299b8.6760bfdb.css" rel="prefetch"><link href="js/chunk-086a167d.0cb8b81f.js" rel="prefetch"><link href="js/chunk-088acbde.4e79f6d0.js" rel="prefetch"><link href="js/chunk-0cbcaa56.46e3dd42.js" rel="prefetch"><link href="js/chunk-26daa808.9e326ce2.js" rel="prefetch"><link href="js/chunk-300db14a.84662a69.js" rel="prefetch"><link href="js/chunk-32da4b3e.0151c647.js" rel="prefetch"><link href="js/chunk-35db73ce.ae2590c3.js" rel="prefetch"><link href="js/chunk-41cd4e14.a0cd0f1b.js" rel="prefetch"><link href="js/chunk-4caed774.d65d1796.js" rel="prefetch"><link href="js/chunk-52fcdd7c.0070e388.js" rel="prefetch"><link href="js/chunk-63c1eac8.59f3df74.js" rel="prefetch"><link href="js/chunk-6ae0a0d3.ee4aa3e0.js" rel="prefetch"><link href="js/chunk-743f0316.d043435c.js" rel="prefetch"><link href="js/chunk-75426f71.128f599c.js" rel="prefetch"><link href="js/chunk-7cdb40b2.3804e4d8.js" rel="prefetch"><link href="js/chunk-904e5abc.e6a5edbe.js" rel="prefetch"><link href="js/chunk-a3ddd952.0482ce75.js" rel="prefetch"><link href="js/chunk-ab4d3e40.0c286099.js" rel="prefetch"><link href="js/chunk-e35186f0.a9d70f92.js" rel="prefetch"><link href="js/chunk-f35dfe36.e7038b09.js" rel="prefetch"><link href="js/chunk-fc9299b8.5fc76239.js" rel="prefetch"><link href="css/app.6c30acd7.css" rel="preload" as="style"><link href="css/chunk-vendors.9181e156.css" rel="preload" as="style"><link href="js/app.7135d5e1.js" rel="preload" as="script"><link href="js/chunk-vendors.524d6b36.js" rel="preload" as="script"><link href="css/chunk-vendors.9181e156.css" rel="stylesheet"><link href="css/app.6c30acd7.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but erp doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.524d6b36.js"></script><script src="js/app.7135d5e1.js"></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
public/dist/js/app.7135d5e1.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/dist/js/app.7135d5e1.js.map vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More