log = new LogModel([ 'module' => 'goods', 'action' => $request->getMethod(), 'target_type' => 'goods_sku', ]); } public function index(Request $request) { $goods = Goods::query()->filter()->get()->toArray(); $goodsIds = array_column($goods, 'id'); // 状态变更时间查询,日志 $ids = []; if ($request->get('keyword_type', '') && $request->get('keyword_value', '')) { $ids = Log::query()->where('target_type', 'sku') ->where('target_field', $request->keyword_type) ->whereBetween('created_at', explode(' - ', $request->keyword_value)) ->pluck('sku_id') ->toArray(); } $day = DateTimeUtils::getToday(); $goodsSkus = GoodsSku::query() ->whereIn('goods_id', $goodsIds) ->when($ids, function ($query, $ids) { return $query->whereIn('id', $ids); }) ->filter() ->with(['goods' => function ($query) { $query->with(['type:id,name', 'brand:id,name']); }]) ->with(['daily' => function ($query) use ($day) { $query->where('day', $day); }]) ->orderBy('updated_at', 'desc') ->paginate(); return GoodsSkuResource::collection($goodsSkus); } public function show($id) { return new GoodsSkuResource(GoodsSku::query() ->with(['goods' => function ($query) { $query->with(['type:id,name', 'brand:id,name']); }]) ->find($id)); } public function update($id, Request $request) { $goodsRules = (new GoodsRequest())->arrayRules('goods.'); $skuRules = (new GoodsSkuRequest())->arrayRules('sku.'); $validator = Validator::make($request->all(), array_merge($goodsRules, $skuRules)); if ($validator->fails()) { $this->setValidatorFailResponse($validator->getMessageBag()->getMessages()); return response($this->res, $this->res['httpCode']); } DB::beginTransaction(); try { // 商品规格更新 $sku = GoodsSku::query()->find($id); $this->setBeforeUpdate($sku->toArray()); $sku->update($request->sku); $this->setAfterUpdate($sku->toArray()); $this->addLog($id, 'update'); // 商品更新 $goods = Goods::query()->find($sku->goods_id); $this->log = new LogModel([ 'module' => 'goods', 'action' => $request->getMethod(), 'target_type' => 'goods', ]); $this->setBeforeUpdate($goods->toArray()); $goods->update($request->goods); $this->setAfterUpdate($goods->toArray()); $this->addLog($sku->goods_id, 'update'); DB::commit(); } catch (\Exception $exception) { DB::rollBack(); $this->res = [ 'httpCode' => 400, 'errorCode' => 400416, 'errorMessage' => $exception->getMessage(), ]; } return response($this->res, $this->res['httpCode']); } public function batchUpdate(Request $request) { $appendRules = [ 'updateType' => ['required', 'string', Rule::in(['newest', 'inventory', 'stock'])], 'skus' => ['required', 'array'], 'skus.*.id' => [ 'required', Rule::exists('goods_skus', 'id'), ], ]; $skuRules = (new GoodsSkuRequest())->arrayRules('skus.*.'); $validator = Validator::make($request->all(), array_merge($appendRules, $skuRules)); if ($validator->fails()) { $this->setValidatorFailResponse($validator->getMessageBag()->getMessages()); return response($this->res, $this->res['httpCode']); } $function = $request->updateType; return $this->$function($request); } private function newest($request) { DB::beginTransaction(); try { $logs = []; foreach ($request->skus as $sku) { $costLog = $arrivedLog = [ 'module' => 'goods', 'action' => $request->getMethod(), 'target_type' => 'goods_sku', 'target_id' => $sku['id'], 'user_id' => $request->user()->id ]; // 成本 $goodsSku = GoodsSku::query()->where('id', $sku['id'])->first(['id', 'cost', 'stock', 'num']); $costLog['target_field'] = 'cost'; $costLog['before_update'] = $goodsSku->cost; $goodsSku->cost = $sku['cost']; $goodsSku->reference_price = $sku['cost'] * 1.5; $goodsSku->stock += $sku['arrived_today_num']; $goodsSku->num += $sku['arrived_today_num']; $goodsSku->save(); $costLog['after_update'] = $goodsSku->cost; $logs[] = $costLog; // 今日到货 $record = DailyStockRecord::query()->where('sku_id', $sku['id'])->where('day', DateTimeUtils::getToday())->first(['id', 'arrived_today_num']); $arrivedLog['target_field'] = 'arrived_today_num'; $arrivedLog['before_update'] = $record->arrived_today_num; $record->arrived_today_num += $sku['arrived_today_num']; $record->save(); $arrivedLog['after_update'] = $record->arrived_today_num; $logs[] = $arrivedLog; } $log = new LogModel(); $log->batchInsert($logs); DB::commit(); event(new StockUpdateEvent(array_column($request->skus, 'id'))); } catch (\Exception $exception) { DB::rollBack(); $this->res = [ 'httpCode' => 400, 'errorCode' => 400500, 'errorMessage' => $exception->getMessage(), ]; } return response($this->res, $this->res['httpCode']); } private function inventory($request) { DB::beginTransaction(); try { $logs = []; foreach ($request->skus as $sku) { $inventoryLog = [ 'module' => 'goods', 'action' => $request->getMethod(), 'target_type' => 'goods_sku', 'target_id' => $sku['id'], 'user_id' => $request->user()->id ]; $record = DailyStockRecord::query()->where('sku_id', $sku['id'])->where('day', DateTimeUtils::getToday())->first(['id', 'inventory']); $inventoryLog['target_field'] = 'inventory'; $inventoryLog['before_update'] = $record->inventory; $record->inventory = $sku['inventory']; $record->save(); $inventoryLog['after_update'] = $record->inventory; $logs[] = $inventoryLog; } $log = new LogModel(); $log->batchInsert($logs); DB::commit(); } catch (\Exception $exception) { DB::rollBack(); $this->res = [ 'httpCode' => 400, 'errorCode' => 400500, 'errorMessage' => $exception->getMessage(), ]; } return response($this->res, $this->res['httpCode']); } private function stock($request) { $skus = $request->skus; $update = reset($skus); DB::beginTransaction(); try { $sku = GoodsSku::query()->where('id', $update['id'])->first(['id', 'two_days_ago_num', 'yesterday_num', 'num', 'stock', 'reserve']); $record = DailyStockRecord::query() ->where('sku_id', $sku->id) ->where('day', DateTimeUtils::getToday()) ->first(); $this->setBeforeUpdate([ 'two_days_ago_num' => $sku->two_days_ago_num, 'yesterday_num' => $sku->yesterday_num, 'arrived_today_num' => $record->arrived_today_num, 'num' => $sku->num, 'stock' => $sku->stock, ]); $sku->two_days_ago_num = $update['two_days_ago_num']; $sku->yesterday_num = $update['yesterday_num']; $sku->num = $update['two_days_ago_num'] + $update['yesterday_num'] + $update['arrived_today_num']; $sku->stock += ($update['two_days_ago_num'] + $update['yesterday_num'] + $update['arrived_today_num'] - $record->arrived_today_num - $sku->two_days_ago_num - $sku->yesterday_num); $sku->save(); $record->arrived_today_num = $update['arrived_today_num']; $record->save(); $this->setAfterUpdate([ 'two_days_ago_num' => $sku->two_days_ago_num, 'yesterday_num' => $sku->yesterday_num, 'arrived_today_num' => $record->arrived_today_num, 'num' => $sku->num, 'stock' => $sku->stock, ]); $this->addLog($sku->id, 'stock'); DB::commit(); event(new StockUpdateEvent($sku)); } catch (\Exception $exception) { DB::rollBack(); $this->res = [ 'httpCode' => 400, 'errorCode' => 400416, 'errorMessage' => $exception->getMessage(), ]; } return response($this->res, $this->res['httpCode']); } public function updateField($id, Request $request) { $rules = [ 'updateField' => [ 'required', Rule::in(['reference_price', 'reserve', 'loss_num', 'status']) ], 'reference_price' => [ 'sometimes', 'numeric', 'gt:0' ], 'reserve' => [ 'sometimes', 'integer', ], 'loss_num' => [ 'sometimes', 'integer', ], 'reason' => [ 'sometimes', 'required', 'string' ], 'status' => [ 'sometimes', 'required', 'integer', Rule::in([0, 1, 2])], ]; $validator = Validator::make($request->all(), $rules); if ($validator->fails()) { $this->setValidatorFailResponse($validator->getMessageBag()->getMessages()); goto end; } $updateField = \request('updateField'); $sku = GoodsSku::query()->find($id); if ('loss_num' === $updateField) { $record = DailyStockRecord::query() ->where('sku_id', $id) ->where('day', DateTimeUtils::getToday()) ->first(['id', 'loss_num']); $this->log->message = $request->get('reason'); $this->setBeforeUpdate($record->loss_num); $record->loss_num += $request->loss_num; $record->save(); $this->setAfterUpdate($record->loss_num); $sku->stock -= $request->loss_num; } else { $sku->$updateField = $request->$updateField; } $this->setBeforeUpdate($sku->$updateField); if ('reserve' === $updateField) { $changeNum = $sku->reserve - $request->reserve; if (0 > $changeNum + $sku->stock) { $this->setValidatorFailResponse('预留量超过库存数量'); goto end; } $sku->stock += $changeNum; } $sku->save(); if (in_array($updateField, ['reserve', 'loss_num'])) { event(new StockUpdateEvent($sku)); } $this->setAfterUpdate($sku->$updateField); $this->addLog($id, $updateField); end: return response($this->res, $this->res['httpCode']); } public function store(Request $request) { if (!$request->hasFile('goodsSkus')) { $this->res = [ 'httpCode' => 404, 'errorCode' => 404404, 'errorMessage' => 'not found goodsSkus file', ]; } try { $import = new GoodsSkusImport(); $path = $request->file('goodsSkus'); Excel::import($import, $path); $this->addLog(0, 'import'); } catch (ValidationException $exception) { $this->setValidatorFailResponse($exception->validator->getMessageBag()->getMessages()); } return response($this->res, $this->res['httpCode']); } public function export(Request $request) { $type = $request->get('exportType'); ob_end_clean(); return Excel::download(new GoodsSkusExport($type), $type, '.xlsx'); } }