diff --git a/app/Console/Commands/DeleteGoodsSku.php b/app/Console/Commands/DeleteGoodsSku.php new file mode 100644 index 0000000..2595273 --- /dev/null +++ b/app/Console/Commands/DeleteGoodsSku.php @@ -0,0 +1,68 @@ +argument('code'); + if (empty($code)) { + reutrn; + } + [$goodsCode, $skuCode] = explode('_', $code); + DB::beginTransaction(); + try { + $goods = Goods::query()->where('goods_code', $goodsCode)->first(); + $countSkus = GoodsSku::query()->where('goods_id', $goods->id)->count(); + $sku = GoodsSku::query()->where('goods_id', $goods->id)->where('sku_code', $skuCode)->first(); + DailyStockRecord::where('sku_id', $sku->id)->delete(); + Log::where('module', 'goods')->where('target_type', 'goods_sku')->where('target_id', $sku->id)->delete(); + $sku->delete(); + if (1 === $countSkus) { + $goods->delete(); + } + DB::commit(); + $this->info('删除成功'); + } catch (\Exception $exception) { + DB::rollBack(); + $this->info('删除失败' . $exception->getMessage()); + } + } +} diff --git a/app/Console/Commands/Test.php b/app/Console/Commands/Test.php index 49ef95a..cc41613 100644 --- a/app/Console/Commands/Test.php +++ b/app/Console/Commands/Test.php @@ -7,6 +7,7 @@ use App\Models\Shop; use App\Services\Business\BusinessFactory; use App\Utils\DateTimeUtils; use Illuminate\Console\Command; +use Illuminate\Support\Facades\DB; class Test extends Command { diff --git a/app/Http/Controllers/Business/BusinessGoodsSkusController.php b/app/Http/Controllers/Business/BusinessGoodsSkusController.php index 75418fb..f7d5b95 100644 --- a/app/Http/Controllers/Business/BusinessGoodsSkusController.php +++ b/app/Http/Controllers/Business/BusinessGoodsSkusController.php @@ -2,15 +2,29 @@ namespace App\Http\Controllers\Business; +use App\Events\StockUpdateEvent; use App\Http\Controllers\Controller; use App\Http\Resources\BusinessGoodsSkuResource; use App\Models\BusinessGoodsSku; +use App\Models\BusinessOrderItem; +use App\Models\GoodsSku; +use App\Models\Log as LogModel; use Illuminate\Http\Request; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rule; class BusinessGoodsSkusController extends Controller { + public function __construct(Request $request) + { + $this->log = new LogModel([ + 'module' => 'plat', + 'action' => $request->getMethod(), + 'target_type' => 'goods', + ]); + } + public function index(Request $request) { $businessGoodsSkus = BusinessGoodsSku::query() @@ -32,9 +46,50 @@ class BusinessGoodsSkusController extends Controller return response($this->res, $this->res['httpCode']); } $sku = BusinessGoodsSku::find($id); + $this->setBeforeUpdate($sku->is_sync); $sku->is_sync = $request->input('is_sync'); $sku->save(); + $this->setAfterUpdate($sku->is_sync); + $this->addLog($id, 'status'); return response($this->res, $this->res['httpCode']); } + + public function destroy(Request $request, $id) + { + DB::beginTransaction(); + try { + $sku = BusinessGoodsSku::find($id); + $this->setBeforeUpdate($sku->toArray()); + BusinessOrderItem::where('goods_id', $sku->goods_id)->where('sku_id', $sku->sku_id)->delete(); + $sku->delete(); + $this->setAfterUpdate(''); + $this->addLog($id, ''); + DB::commit(); + } catch (Exception $exception) { + DB::rollBack(); + // 返回错误 + $this->setValidatorFailResponse($exception->getMessages()); + } + + return response($this->res, $this->res['httpCode']); + } + + public function syncStock(Request $request, $id) + { + $businessGoodsSku = BusinessGoodsSku::find($id); + [$goodsCode, $skuCode] = explode('_', $businessGoodsSku->external_sku_id); + $sku = GoodsSku::query()->where('sku_code', $skuCode) + ->whereHas('goods', function ($query) use ($goodsCode) { + $query->where('goods_code', $goodsCode); + }) + ->first(); + if (empty($sku)) { + $this->setValidatorFailResponse('未找到对应的商品,请核实后再次同步或删除此平台商品'); + } else { + event(new StockUpdateEvent($sku)); + $this->res['message'] = '库存同步请求发送成功,具体结果查看日志'; + } + return response($this->res, $this->res['httpCode']); + } } diff --git a/app/Http/Controllers/Goods/GoodsSkusController.php b/app/Http/Controllers/Goods/GoodsSkusController.php index 2b59401..73b3f02 100644 --- a/app/Http/Controllers/Goods/GoodsSkusController.php +++ b/app/Http/Controllers/Goods/GoodsSkusController.php @@ -7,6 +7,7 @@ use App\Exports\GoodsSkusExport; use App\Http\Controllers\Controller; use App\Http\Requests\GoodsRequest; use App\Http\Requests\GoodsSkuRequest; +use App\Imports\InventoryImport; use App\Models\BusinessOrderItem; use App\Models\Goods; use App\Models\Log; @@ -37,7 +38,13 @@ class GoodsSkusController extends Controller public function index(Request $request) { - $goods = Goods::query()->filter()->get()->toArray(); + $goodsCode = $skuCode = ''; + if ($externalSkuId = $request->get('external_sku_id')) { + [$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 = []; @@ -54,6 +61,9 @@ class GoodsSkusController extends Controller ->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) { $query->with(['type:id,name', 'brand:id,name']); @@ -460,4 +470,26 @@ class GoodsSkusController extends Controller ob_end_clean(); return Excel::download(new GoodsSkusExport($type), $type . '.xlsx'); } + + public function inventoryImport(Request $request) + { + if (!$request->hasFile('inventoryFile')) { + $this->res = [ + 'httpCode' => 404, + 'errorCode' => 404404, + 'errorMessage' => 'not found inventory file', + ]; + } + + try { + $import = new InventoryImport(); + $path = $request->file('inventoryFile'); + Excel::import($import, $path); + $this->addLog(0, 'import', 'inventory'); + } catch (ValidationException $exception) { + $this->setValidatorFailResponse($exception->validator->getMessageBag()->getMessages()); + } + + return response($this->res, $this->res['httpCode']); + } } diff --git a/app/Imports/GoodsSkusImport.php b/app/Imports/GoodsSkusImport.php index 9fb7f88..4db9e8c 100644 --- a/app/Imports/GoodsSkusImport.php +++ b/app/Imports/GoodsSkusImport.php @@ -30,12 +30,12 @@ class GoodsSkusImport implements ToCollection, SkipsEmptyRows * @throws ValidationException * @throws Exception */ - public function collection(Collection $rows) + public function collection(Collection $collection) { - unset($rows[0], $rows[1]); - $rows = $rows->toArray(); + unset($collection[0], $collection[1]); + $collection = $collection->toArray(); $types = $brands = $goodsCodes = []; - foreach ($rows as &$row) { + foreach ($collection as &$row) { $row = array_map(static function ($v) { return trim($v); }, $row); @@ -43,7 +43,7 @@ class GoodsSkusImport implements ToCollection, SkipsEmptyRows $brands[] = $row[2]; $goodsCodes[] = $row[3]; } - $validator = Validator::make($rows, [ + $validator = Validator::make($collection, [ '*.0' => ['required', 'string', 'max:191'], '*.1' => ['required', 'string', 'max:191', 'exists:goods_types,name'], '*.2' => ['string', 'max:191', 'exists:goods_brands,name'], @@ -64,7 +64,7 @@ class GoodsSkusImport implements ToCollection, SkipsEmptyRows $hasGoods = Goods::query()->whereIn('goods_code', $goodsCodes)->get(['id', 'goods_code'])->toArray(); $hasGoods = ArrayUtils::index($hasGoods, 'goods_code'); $newGoods = $skus = []; - foreach ($rows as $row) { + foreach ($collection as $row) { $sku = [ 'goods_id' => $row[3], 'title' => $row[4], diff --git a/app/Imports/InventoryImport.php b/app/Imports/InventoryImport.php new file mode 100644 index 0000000..aaf425e --- /dev/null +++ b/app/Imports/InventoryImport.php @@ -0,0 +1,75 @@ +toArray(); + $goodsCodes = []; + foreach ($collection as &$row) { + $row = array_map(static function ($v) { + return trim($v); + }, $row); + $goodsCodes[] = $row[0]; + } + unset($row); + $hasGoods = Goods::query()->whereIn('goods_code', $goodsCodes)->get(['id', 'goods_code'])->toArray(); + $hasGoods = ArrayUtils::index($hasGoods, 'goods_code'); + $updateIds = []; + $day = DateTimeUtils::getToday(); + $dateTime = date('Y-m-d H:i:s'); + DB::beginTransaction(); + try { + foreach ($collection as $row) { + if (!isset($hasGoods[$row[0]])) { + continue; + } + $goodsSku = GoodsSku::query() + ->where('goods_id', $hasGoods[$row[0]]['id']) + ->where('sku_code', $row[4]) + ->first(['id']); + if (empty($goodsSku)) { + Log::warning(json_encode($row, 256) . '=====库存导入未找到'); + continue; + } + $updateIds[] = $goodsSku->id; + DailyStockRecord::where('sku_id', $goodsSku->id)->where('day', $day)->update([ + 'inventory' => $row[6], + 'inventory_time' => $dateTime + ]); + } + DB::commit(); + } catch (Exception $exception) { + DB::rollBack(); + // 返回错误 + throw $exception; + } + $onSkuIds = GoodsSku::query() + ->where('stock', '>', 0) + ->where('status', '<>', 0) + ->pluck('id') + ->toArray(); + if ($downSkuIds = array_diff($onSkuIds, $updateIds)) { + event(new StockUpdateEvent($downSkuIds)); + } + } +} diff --git a/app/Models/BusinessGoodsSku.php b/app/Models/BusinessGoodsSku.php index 6ebad84..d584cf9 100644 --- a/app/Models/BusinessGoodsSku.php +++ b/app/Models/BusinessGoodsSku.php @@ -19,14 +19,43 @@ class BusinessGoodsSku extends Model * @var mixed */ public $goods_id; + /** * @var mixed */ public $sku_id; + /** * @var mixed */ public $external_sku_id; + + protected $hidden = [ + 'self_sku_id', + 'activity_no', + 'goods_desc', + 'goods_image_list', + 'is_activity_delete', + 'limit_buy', + 'market_price', + 'update_time', + 'goods_purchase_price', + 'price_in_fen', + 'quantity', + 'goods_purchase_price', + 'price_in_fen', + 'quantity', + 'quantity_type', + 'reserve_quantity', + 'sold_quantity', + 'spec_list', + 'spec_name', + 'thumb_url', + 'total_quantity', + 'updated_at', + 'create_time' + ]; + /** * 不可批量赋值的属性。为空则所有熟悉都可以批量赋值 * diff --git a/database/seeds/MenusTableSeeder.php b/database/seeds/MenusTableSeeder.php index 6c864eb..5ba89b9 100644 --- a/database/seeds/MenusTableSeeder.php +++ b/database/seeds/MenusTableSeeder.php @@ -31,6 +31,9 @@ class MenusTableSeeder extends Seeder ['parent_id' => $id, 'code' => 'SYSTEM_LOG', 'name' => '系统日志', 'seq' => 2], ]); // 平台 - DB::table('menus')->insertGetId(['parent_id' => 0, 'code' => 'PLAT', 'name' => '平台', 'seq' => 4]); + $id = DB::table('menus')->insertGetId(['parent_id' => 0, 'code' => 'PLAT', 'name' => '平台', 'seq' => 4]); + DB::table('menus')->insert([ + ['parent_id' => $id, 'code' => 'PLAT_GOODS_LIST', 'name' => '货品列表', 'seq' => 0], + ]); } } diff --git a/resources/frontend/src/api/plat.js b/resources/frontend/src/api/plat.js new file mode 100644 index 0000000..85de7ab --- /dev/null +++ b/resources/frontend/src/api/plat.js @@ -0,0 +1,34 @@ +import http from "@/util/http.js"; + +// 平台页面请求 + +// 平台商品列表 +export function platGoodsList(params) { + return http({ + url: "/api/plat_goods", + method: "get", + params, + }); +} + +export function updateSyncStatus(id, params) { + return http({ + url: "/api/plat_goods/" + id, + method: "patch", + params, + }); +} + +export function deletePlatGoods(id) { + return http({ + url: "/api/plat_goods/" + id, + method: "delete", + }); +} + +export function syncStock(id) { + return http({ + url: "/api/plat/sync/" + id + "/stock/", + method: "post", + }); +} diff --git a/resources/frontend/src/main.js b/resources/frontend/src/main.js index 45acd6c..dcbde24 100644 --- a/resources/frontend/src/main.js +++ b/resources/frontend/src/main.js @@ -7,12 +7,6 @@ import "element-ui/lib/theme-chalk/index.css"; import "@/css/style.css"; import "./router/index2"; -// import Router from 'vue-router' -// const routerPush = Router.prototype.push -// Router.prototype.push = function push(location) { -// return routerPush.call(this, location).catch(error=> error) -// } - Vue.use(ElementUI); Vue.config.productionTip = false; diff --git a/resources/frontend/src/router/index1.js b/resources/frontend/src/router/index1.js index 46ff141..9bfe814 100644 --- a/resources/frontend/src/router/index1.js +++ b/resources/frontend/src/router/index1.js @@ -60,6 +60,11 @@ const list = [ path: "/", redirect: "GOODS_LIST", }, + { + path: "PLAT_GOODS_LIST", + name: "货品列表", + component: () => import("../views/plat/goodsList.vue"), + }, ], }, ]; diff --git a/resources/frontend/src/views/brand/brand.vue b/resources/frontend/src/views/brand/brand.vue index ca3a99f..4f1814b 100644 --- a/resources/frontend/src/views/brand/brand.vue +++ b/resources/frontend/src/views/brand/brand.vue @@ -4,7 +4,7 @@ 新增 -
+
diff --git a/resources/frontend/src/views/goods/goods.vue b/resources/frontend/src/views/goods/goods.vue index cfb36a9..60fe464 100644 --- a/resources/frontend/src/views/goods/goods.vue +++ b/resources/frontend/src/views/goods/goods.vue @@ -5,6 +5,10 @@
+ + + + @@ -51,17 +55,22 @@
- +
全部商品(共{{ total }}条)
- 新建商品 上新 - 库存盘点 + + 盘点导入 + + 新建商品 导入商品 表格导出 + 库存盘点
@@ -69,7 +78,7 @@ - + - +