diff --git a/app/Console/Commands/Inventory.php b/app/Console/Commands/Inventory.php index 265f63c..61b12fb 100644 --- a/app/Console/Commands/Inventory.php +++ b/app/Console/Commands/Inventory.php @@ -53,7 +53,7 @@ class Inventory extends Command // 数据库存储过程,7点定时执行 $data = []; $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) { $data[] = [ 'sku_id' => $sku->id, diff --git a/app/Console/Commands/Test.php b/app/Console/Commands/Test.php index ddaae9a..a332fe4 100644 --- a/app/Console/Commands/Test.php +++ b/app/Console/Commands/Test.php @@ -52,104 +52,5 @@ class Test extends Command */ public function handle() { - $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('今日价格数据未找到,请先上传'); - } - $todayGoodsPrice = []; - foreach ($todayPrice as $item) { - $todayGoodsPrice[$item['external_sku_id']] = [ - 'today_price' => $item['price'], - 'goods_name' => $item['goodsSku']['goods']['title'] . $item['goodsSku']['title'], - 'external_sku_id' => $item['external_sku_id'], - ]; - } - $shops = Shop::query() - ->where('plat_id', Shop::$PLAT_KTT) - ->where('expires_at', '>', time()) - ->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); - } - foreach ($data as $shopName => $activity) { - foreach ($activity as $activityNo => $item) { - foreach ($item as $k => $v) { - foreach ($v as $i) { - if ('diff_price' === $k) { - $s[] = [$shopName, $i['title'], $i['goods_name'], $i['price_in_fen'], $i['today_price'], $i['external_sku_id']]; - } - if ('not_in_group' === $k) { - $s[] = [$shopName, $i['title'], $i['goods_name'], '团购无此商品', $i['today_price'], $i['external_sku_id']]; - } - } - } - } - } - dd($s); - - ob_end_clean(); - return Excel::download(new DiffTodayPriceGoodsExport($data), date('Y-m-d') . '今日差价商品.xlsx'); - } - - private function diffTodayPrice($businessGoodsSkus, $todayPrice,$activities) - { - $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']]['today_price']) { - $item['today_price'] = $todayPrice[$item['external_sku_id']]['today_price']; - $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; } } diff --git a/app/Console/Commands/UpdateExternalSkuId.php b/app/Console/Commands/UpdateExternalSkuId.php index f6a8786..9715df4 100644 --- a/app/Console/Commands/UpdateExternalSkuId.php +++ b/app/Console/Commands/UpdateExternalSkuId.php @@ -38,7 +38,13 @@ class UpdateExternalSkuId extends Command */ public function handle() { - GoodsSku::chunk(500, static function ($skus) { + 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(); diff --git a/app/Events/BusinessOrdersUpdate.php b/app/Events/BusinessOrdersUpdate.php index b44823c..8ddb52d 100644 --- a/app/Events/BusinessOrdersUpdate.php +++ b/app/Events/BusinessOrdersUpdate.php @@ -28,7 +28,11 @@ class BusinessOrdersUpdate */ public function __construct($item, $num) { - $this->businessGoods = $item->toArray(); + if (is_array($item)) { + $this->businessGoods = $item; + } else { + $this->businessGoods = $item->toArray(); + } $this->num = $num; $this->updateStock(); } @@ -37,6 +41,10 @@ class BusinessOrdersUpdate { try { $this->goodsSku = GoodsSku::query() + ->with([ + 'combinationGoods', + 'combinationGoods.goodsSkuItem:id,external_sku_id', + ]) ->where('external_sku_id', $this->businessGoods['external_sku_id']) ->first(); } catch (\Exception $e) { @@ -46,6 +54,10 @@ class BusinessOrdersUpdate if ($this->goodsSku) { $this->goodsSku->stock += $this->num; $this->goodsSku->save(); + foreach ($this->goodsSku->combinationGoods as $item) { + $this->businessGoods['external_sku_id'] = $item['goodsSkuItem']['external_sku_id']; + event(new BusinessOrdersUpdate($this->businessGoods, 0 - $item['item_num'])); + } } } diff --git a/app/Exports/DiffTodayPriceGoodsExport.php b/app/Exports/DiffTodayPriceGoodsExport.php index d4595d1..caa133d 100644 --- a/app/Exports/DiffTodayPriceGoodsExport.php +++ b/app/Exports/DiffTodayPriceGoodsExport.php @@ -47,7 +47,7 @@ class DiffTodayPriceGoodsExport implements FromCollection, ShouldAutoSize $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['today_price'], $i['external_sku_id']]; + $bodyData[] = [$shopName, $i['title'], $i['goods_name'], '团购无此商品', $i['shop_price'][$shopName], $i['external_sku_id']]; } } } diff --git a/app/Http/Controllers/Business/BusinessGoodsSkusController.php b/app/Http/Controllers/Business/BusinessGoodsSkusController.php index 204b8ed..264bca9 100644 --- a/app/Http/Controllers/Business/BusinessGoodsSkusController.php +++ b/app/Http/Controllers/Business/BusinessGoodsSkusController.php @@ -137,6 +137,7 @@ class BusinessGoodsSkusController extends Controller 'today_price' => $item['price'], 'goods_name' => $item['goodsSku']['goods']['title'] . $item['goodsSku']['title'], 'external_sku_id' => $item['external_sku_id'], + 'shop_price' => json_decode($item['shop_price'], true), ]; } $shops = Shop::query() @@ -166,14 +167,14 @@ class BusinessGoodsSkusController extends Controller if ($businessGoodsSkus->isEmpty()) { continue; } - $data[$shop->name] = $this->diffTodayPrice($businessGoodsSkus, $todayGoodsPrice, $activities); + $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) + private function diffTodayPrice($businessGoodsSkus, $todayPrice, $activities, $shopName) { $data = []; foreach ($businessGoodsSkus as $item) { @@ -184,8 +185,8 @@ class BusinessGoodsSkusController extends Controller // $data[$item['activity_no']]['in_group'][] = $item->toArray(); // } // 价格不一样 - if (isset($todayPrice[$item['external_sku_id']]) && $item['price_in_fen'] != $todayPrice[$item['external_sku_id']]['today_price']) { - $item['today_price'] = $todayPrice[$item['external_sku_id']]['today_price']; + 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(); } } diff --git a/app/Http/Controllers/Goods/GoodsCombinationController.php b/app/Http/Controllers/Goods/GoodsCombinationController.php index 9608e47..0cd3ae3 100644 --- a/app/Http/Controllers/Goods/GoodsCombinationController.php +++ b/app/Http/Controllers/Goods/GoodsCombinationController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Goods; +use App\Events\StockUpdateEvent; use App\Http\Controllers\Controller; use App\Http\Resources\GoodsSkuResource; use App\Models\CombinationGood; @@ -66,24 +67,43 @@ class GoodsCombinationController extends Controller } 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->title = $request->input('title'); - $sku->sku_code = $request->input('external_sku_id'); - $sku->external_sku_id = $request->input('external_sku_id'); $sku->is_combination = 1; - $sku->save(); } + $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 ($request->input('combination_goods') as $item) { - CombinationGood::query()->create(['goods_sku_id' => $sku->id, 'item_id' => $item['item_id'],'item_num' => $item['item_num']]); + 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)); } catch (\Exception $exception) { DB::rollBack(); $this->res = [ diff --git a/app/Http/Controllers/Goods/GoodsSkusController.php b/app/Http/Controllers/Goods/GoodsSkusController.php index 393666a..0911db1 100644 --- a/app/Http/Controllers/Goods/GoodsSkusController.php +++ b/app/Http/Controllers/Goods/GoodsSkusController.php @@ -52,7 +52,7 @@ class GoodsSkusController extends Controller $query->where('day', $day); }]) ->where('is_combination', 0) - ->orderByDesc('updated_at') + ->orderByDesc('stock') ->paginate(10); $fields = implode(',', [ 'shop_id', @@ -508,23 +508,36 @@ class GoodsSkusController extends Controller public function stockNum() { - $roseTypeId = GoodsType::query()->where('name', '玫瑰')->value('id'); - $totalNum = GoodsSku::query() + $skus = GoodsSku::query() ->where('is_combination', 0) ->where('status', '>', 0) - ->sum('stock'); - $roseNum = GoodsSku::query() - ->where('is_combination', 0) - ->whereHas('goods', function (Builder $query) use ($roseTypeId) { - $query->where('type_id', $roseTypeId); - }) - ->where('status', '>', 0) - ->sum('stock'); + ->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([ - 'total_num' => $totalNum, 'rose_num' => $roseNum, - 'other_num' => $totalNum - $roseNum, + 'other_num' => $otherNum, ]); } } diff --git a/app/Http/Controllers/Shop/ShopsController.php b/app/Http/Controllers/Shop/ShopsController.php index 2b93ed7..858f3b2 100644 --- a/app/Http/Controllers/Shop/ShopsController.php +++ b/app/Http/Controllers/Shop/ShopsController.php @@ -191,7 +191,6 @@ class ShopsController extends Controller { $shopId = $request->get('shop_id'); $skus = GoodsSku::query() - ->where('is_combination', 0) ->where('status', '>', 0) ->whereNotNull('external_sku_id') ->pluck('stock', 'external_sku_id') diff --git a/app/Imports/GoodsSkuLocationImport.php b/app/Imports/GoodsSkuLocationImport.php index 89019a2..b10a070 100644 --- a/app/Imports/GoodsSkuLocationImport.php +++ b/app/Imports/GoodsSkuLocationImport.php @@ -2,7 +2,7 @@ namespace App\Imports; -use App\Models\Goods; +use App\Models\GoodsSku; use App\Models\GoodsSkuLocation; use Maatwebsite\Excel\Concerns\SkipsEmptyRows; use Maatwebsite\Excel\Concerns\ToArray; @@ -17,37 +17,36 @@ class GoodsSkuLocationImport implements ToArray, SkipsEmptyRows, WithStartRow public function array(array $array) { - $goodsCode = $deleteLocation = []; + $externalSkuIds = $deleteLocation = []; foreach ($array as &$row) { $row = array_map(function ($value) { return trim($value); }, $row); - $goodsCode[] = $row[2]; - $deleteLocation[] = $row[5]; + $externalSkuIds[] = $row[2]; + $deleteLocation[] = $row[3]; } GoodsSkuLocation::query()->whereIn('location', $deleteLocation)->delete(); unset($row); - $goods = Goods::query() - ->whereIn('goods_code', $goodsCode) - ->get(['id', 'goods_code', 'title']); + $skus = GoodsSku::query() + ->with('goods:id,title') + ->whereIn('external_sku_id', $externalSkuIds) + ->get(['id', 'goods_id', 'title', 'external_sku_id']); $goodsSkus = []; - foreach ($goods as $goodsItem) { - foreach ($goodsItem->skus as $sku){ - $goodsSkus[$goodsItem['goods_code']][$sku->sku_code] = [ - 'goods_id' => $goodsItem->id, - 'goods_sku_id' => $sku->id, - 'external_sku_id' => $goodsItem['goods_code'] . '_' . $sku->sku_code, - 'goods_name' => $goodsItem['title'] . '_' . $sku->title, - ]; - } + foreach ($skus as $sku) { + $goodsSkus[$sku['external_sku_id']] = [ + 'goods_id' => $sku['goods_id'], + 'goods_sku_id' => $sku['id'], + 'external_sku_id' => $sku['external_sku_id'], + 'goods_name' => $sku['goods']['title'] . $sku['title'], + ]; } $data = []; foreach ($array as $row) { - if (isset($goodsSkus[$row[2]][$row[4]])) { - $data[] = array_merge($goodsSkus[$row[2]][$row[4]], [ + if (isset($goodsSkus[$row[2]])) { + $data[] = array_merge($goodsSkus[$row[2]], [ 'date' => date('Y-m-d'), 'today_init_num' => $row[1], - 'location' => $row[5], + 'location' => $row[3], ]); } } diff --git a/app/Imports/InventoryImport.php b/app/Imports/InventoryImport.php index 29d97bb..2532ff8 100644 --- a/app/Imports/InventoryImport.php +++ b/app/Imports/InventoryImport.php @@ -3,78 +3,80 @@ namespace App\Imports; use App\Models\DailyStockRecord; -use App\Models\Goods; use App\Models\GoodsSku; +use App\Models\TodayPrice; use App\Utils\DateTimeUtils; use Exception; -use Illuminate\Support\Collection; -use Illuminate\Support\Facades\Log; use Maatwebsite\Excel\Concerns\SkipsEmptyRows; -use Maatwebsite\Excel\Concerns\ToCollection; +use Maatwebsite\Excel\Concerns\ToArray; use App\Utils\ArrayUtils; use App\Events\StockUpdateEvent; -class InventoryImport implements ToCollection, SkipsEmptyRows +class InventoryImport implements ToArray, SkipsEmptyRows { /** * @throws Exception */ - public function collection(Collection $collection) + public function array(array $collection) { + $header = $collection[0]; unset($collection[0]); - $collection = $collection->toArray(); - $goodsCodes = []; + $externalSkuId = []; foreach ($collection as &$row) { $row = array_map(static function ($v) { return trim($v); }, $row); - $goodsCodes[] = $row[0]; + $externalSkuId[] = $row[0]; } unset($row); - $hasGoods = Goods::query()->whereIn('goods_code', $goodsCodes)->get(['id', 'goods_code'])->toArray(); - $hasGoodsIds = array_column($hasGoods, 'id'); - $hasGoods = ArrayUtils::index($hasGoods, 'goods_code'); - $updateIds = []; + $updateIds = $todayPrice = []; $day = DateTimeUtils::getToday(); $dateTime = date('Y-m-d H:i:s'); $hasGoodsSkus = GoodsSku::query() - ->whereIn('goods_id', $hasGoodsIds) - ->get(['id', 'status', 'stock', 'cost', 'sku_code', 'goods_id']) + ->whereIn('external_sku_id', $externalSkuId) + ->get(['id', 'status', 'external_sku_id']) ->toArray(); + $hasGoodsSkus = ArrayUtils::index($hasGoodsSkus, 'external_sku_id'); foreach ($collection as $row) { - if (!isset($hasGoods[$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) . '=====库存导入未找到'); + if (!isset($hasGoodsSkus[$row[0]])) { continue; } + $goodsSku = $hasGoodsSkus[$row[0]]; if ('下架' === $goodsSku['status']) { GoodsSku::query()->where('id', $goodsSku['id'])->update([ - 'stock' => $row[6] + $row[7], - 'cost' => $row[8], + 'stock' => $row[2] + $row[3], + 'cost' => $row[4], 'status' => 1, ]); } else { GoodsSku::query()->where('id', $goodsSku['id'])->update([ - 'stock' => $row[6] + $row[7], - 'cost' => $row[8], + 'stock' => $row[2] + $row[3], + 'cost' => $row[4], ]); } $updateIds[] = $goodsSku['id']; DailyStockRecord::query()->where('sku_id', $goodsSku['id'])->where('day', $day)->update([ - 'arrived_today_num' => $row[7], - 'inventory' => $row[6], + 'arrived_today_num' => $row[3], + 'inventory' => $row[2], '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); $onSkuIds = GoodsSku::query() diff --git a/app/Imports/TodayPriceImport.php b/app/Imports/TodayPriceImport.php index e05e9cd..7438845 100644 --- a/app/Imports/TodayPriceImport.php +++ b/app/Imports/TodayPriceImport.php @@ -5,27 +5,30 @@ namespace App\Imports; use App\Models\TodayPrice; use Maatwebsite\Excel\Concerns\SkipsEmptyRows; use Maatwebsite\Excel\Concerns\ToArray; -use Maatwebsite\Excel\Concerns\WithStartRow; -class TodayPriceImport implements ToArray, SkipsEmptyRows, WithStartRow +class TodayPriceImport implements ToArray, SkipsEmptyRows { - public function startRow(): int - { - return 2; - } - 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 > 2) { + $shopPrice[$header[$i]] = $v; + } + } $data[] = [ 'day' => $day, - 'external_sku_id' => $row[0], - 'price' => $row[1], + 'external_sku_id' => $row[1], + 'price' => $row[2], + 'shop_price' => json_encode($shopPrice, 256) ]; } TodayPrice::query()->delete(); diff --git a/database/migrations/2023_04_20_091631_create_today_prices_table.php b/database/migrations/2023_04_20_091631_create_today_prices_table.php index 0c7794e..2713516 100644 --- a/database/migrations/2023_04_20_091631_create_today_prices_table.php +++ b/database/migrations/2023_04_20_091631_create_today_prices_table.php @@ -22,7 +22,9 @@ class CreateTodayPricesTable extends Migration $table->date('day'); $table->string('external_sku_id'); $table->float('price'); + $table->text('shop_price'); $table->index(['external_sku_id', 'day']); + $table->timestamps(); }); } diff --git a/resources/frontend/src/views/goods/combination.vue b/resources/frontend/src/views/goods/combination.vue index 2050e66..83ff1f4 100644 --- a/resources/frontend/src/views/goods/combination.vue +++ b/resources/frontend/src/views/goods/combination.vue @@ -38,7 +38,7 @@ - + @@ -186,8 +186,8 @@ export default { type: 'success' }); this.dialogVisible = false; + this.handleCurrentChange(1); }) - this.getList(); } else { return false; }