mirror of
https://gitee.com/hzchunfen/erp.git
synced 2025-12-01 14:40:44 +00:00
鲜花2.0-gmv接口开发完成+ sku和spu维度的报表接口开发完成
This commit is contained in:
parent
f9bc1fc65a
commit
dd6f9427c7
@ -32,6 +32,7 @@ class BusinessOrdersUpdate
|
||||
*/
|
||||
public function __construct($businessGoodSku, $num)
|
||||
{
|
||||
try {
|
||||
$this->businessGoodSku = $businessGoodSku->toArray();
|
||||
$this->num = $num;
|
||||
$updateResult = false;
|
||||
@ -45,9 +46,14 @@ class BusinessOrdersUpdate
|
||||
if (!$updateResult) {
|
||||
Log::error("sku 业务更新失败", (array)$this->businessGoodSku);
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
Log::error("库存告警发生异常", ["error" => $exception->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
private function updateStock()
|
||||
|
||||
private
|
||||
function updateStock()
|
||||
{
|
||||
$this->goodsSku = GoodsSku::query()
|
||||
->where('external_sku_id', $this->businessGoodSku['external_sku_id'])
|
||||
@ -76,7 +82,8 @@ class BusinessOrdersUpdate
|
||||
*
|
||||
* @return \Illuminate\Broadcasting\Channel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
public
|
||||
function broadcastOn()
|
||||
{
|
||||
return new PrivateChannel('channel-name');
|
||||
}
|
||||
|
||||
@ -47,4 +47,23 @@ class Controller extends BaseController
|
||||
|
||||
return $this->log->add($targetId, $targetField);
|
||||
}
|
||||
|
||||
public function success($data, $msg = "")
|
||||
{
|
||||
return [
|
||||
"success" => true,
|
||||
"msg" => $msg,
|
||||
"data" => $data
|
||||
];
|
||||
}
|
||||
|
||||
public function error($errorCode, $msg = "")
|
||||
{
|
||||
return [
|
||||
"success" => false,
|
||||
"msg" => $msg,
|
||||
"errorCode" => $errorCode,
|
||||
"data"=>[]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,8 +57,8 @@ class DataCenterController extends Controller
|
||||
//进行校验验证
|
||||
$validator = Validator::make($allParams, [
|
||||
'type' => 'required|integer', //1表示今日
|
||||
'start_day' => 'sometimes|string',
|
||||
'end_day' => 'sometimes|string'
|
||||
'start_day' => 'sometimes|date_format:Y-m-d',
|
||||
'end_day' => 'sometimes|date_format:Y-m-d'
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
@ -66,7 +66,7 @@ class DataCenterController extends Controller
|
||||
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||
return response($this->res, $this->res['httpCode']);
|
||||
}
|
||||
return SaleDataService::saleStatistics($request);
|
||||
return $this->success(SaleDataService::saleStatistics($request));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,7 +74,8 @@ class DataCenterController extends Controller
|
||||
* @param Request $request
|
||||
* @return array|\Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|mixed
|
||||
*/
|
||||
public function spuSaleStatistics(Request $request){
|
||||
public function spuSaleStatistics(Request $request)
|
||||
{
|
||||
//进行校验验证
|
||||
$validator = Validator::make($request->all(), [
|
||||
'type' => 'required|integer', //1表示今日
|
||||
@ -86,21 +87,23 @@ class DataCenterController extends Controller
|
||||
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||
return response($this->res, $this->res['httpCode']);
|
||||
}
|
||||
return SaleDataService::spuSaleStatistics($request);
|
||||
return $this->success(SaleDataService::spuSaleStatistics($request));
|
||||
}
|
||||
|
||||
public function gmvStatistics(Request $request){
|
||||
public function gmvStatistics(Request $request)
|
||||
{
|
||||
//进行校验验证
|
||||
$validator = Validator::make($request->all(), [
|
||||
'type' => 'required|integer', //1表示今日
|
||||
'start_day' => 'sometimes|date_format:Y-m-d',
|
||||
'end_day' => 'sometimes|date_format:Y-m-d'
|
||||
'start_day' => 'required_unless:type,1|date_format:Y-m-d',
|
||||
'end_day' => 'required_unless:type,1|date_format:Y-m-d',
|
||||
"interval" => 'sometimes|integer|max:120|min:1'
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
//校验失败返回异常
|
||||
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
||||
return response($this->res, $this->res['httpCode']);
|
||||
}
|
||||
return SaleDataService::gmvStatistics($request);
|
||||
return $this->success(SaleDataService::gmvStatistics($request));
|
||||
}
|
||||
}
|
||||
@ -30,7 +30,7 @@ class DailyStockRecordController extends Controller
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$build = DailyStockRecord::query()->filter()->with("goodsSku:id,name");
|
||||
$build = DailyStockRecord::query()->filter()->with("goodsSku:id,name,title");
|
||||
if (!empty($request->title)) {
|
||||
$build->whereHas('goodsSku', function ($query) use ($request) {
|
||||
$query->where('name', 'like', '%' . $request->title . '%');
|
||||
|
||||
@ -22,10 +22,18 @@ use Maatwebsite\Excel\Facades\Excel;
|
||||
|
||||
class LossRecordController extends Controller
|
||||
{
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->log = new LogModel([
|
||||
'module' => 'supplier',
|
||||
'action' => $request->getMethod(),
|
||||
'target_type' => 'loss_record',
|
||||
]);
|
||||
}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$builder = LossRecords::query()->filter()->with("goodsSku:name,external_sku_id");
|
||||
$builder = LossRecords::query()->filter()->with("goodsSku:name,external_sku_id,title");
|
||||
if (!empty($request->start_time) && !empty($request->end_time)) {
|
||||
$builder->whereBetween('created_at', [$request->start_time, $request->end_time]);
|
||||
}
|
||||
|
||||
@ -11,7 +11,6 @@ use App\Imports\PurchaseImport;
|
||||
use App\Models\GoodsSku;
|
||||
use App\Models\Log;
|
||||
use App\Models\Log as LogModel;
|
||||
use App\Models\LossRecords;
|
||||
use App\Models\PurchaseRecords;
|
||||
use App\Models\Suppliers;
|
||||
use App\Services\DeveloperConfig\DeveloperConfigService;
|
||||
@ -26,10 +25,17 @@ use Maatwebsite\Excel\Facades\Excel;
|
||||
|
||||
class PurchaseRecordController extends Controller
|
||||
{
|
||||
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->log = new LogModel([
|
||||
'module' => 'supplier',
|
||||
'action' => $request->getMethod(),
|
||||
'target_type' => 'purchase_record',
|
||||
]);
|
||||
}
|
||||
public function index(Request $request)
|
||||
{
|
||||
$builder = PurchaseRecords::query()->filter()->with("goodsSku:id,name,external_sku_id");
|
||||
$builder = PurchaseRecords::query()->filter()->with("goodsSku:id,name,external_sku_id,title");
|
||||
if (!empty($request->start_time) && !empty($request->end_time)) {
|
||||
$builder->whereBetween('created_at', [$request->start_time, $request->end_time]);
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ class InventoryImport implements ToArray, SkipsEmptyRows
|
||||
*/
|
||||
public function array(array $collection)
|
||||
{
|
||||
if (!empty($collection)) {
|
||||
unset($collection[0]);
|
||||
$externalSkuIds = [];
|
||||
$inventoryKeyByExternalSkuIdMap = [];
|
||||
@ -46,3 +47,4 @@ class InventoryImport implements ToArray, SkipsEmptyRows
|
||||
$goodSkuService->inventory($goodsSkus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ class LossImport implements ToArray, SkipsEmptyRows
|
||||
*/
|
||||
public function array(array $collection)
|
||||
{
|
||||
if(!empty($collection)){
|
||||
unset($collection[0]);
|
||||
$externalSkuIds = [];
|
||||
foreach ($collection as &$row) {
|
||||
@ -35,9 +36,10 @@ class LossImport implements ToArray, SkipsEmptyRows
|
||||
$updateIds = [];
|
||||
$hasGoodsSkus = GoodsSku::query()
|
||||
->whereIn('external_sku_id', $externalSkuIds)
|
||||
->get(['id', 'status', 'external_sku_id', 'stock'])
|
||||
->get(['id', 'status', 'external_sku_id', 'stock', "sale_stock", "cost"])
|
||||
->toArray();
|
||||
$hasGoodsSkus = ArrayUtils::index($hasGoodsSkus, 'external_sku_id');
|
||||
|
||||
//excel字段排序 編碼 商品名稱 报损數量 成本价 采购人名称 报损原因
|
||||
foreach ($collection as $row) {
|
||||
if (!isset($hasGoodsSkus[$row[0]])) {
|
||||
@ -61,4 +63,7 @@ class LossImport implements ToArray, SkipsEmptyRows
|
||||
// 批量更新
|
||||
event(new BatchStockUpdateEvent($updateIds));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ class PurchaseImport implements ToArray, SkipsEmptyRows
|
||||
*/
|
||||
public function array(array $collection)
|
||||
{
|
||||
if (!empty($collection)) {
|
||||
unset($collection[0]);
|
||||
$externalSkuIds = [];
|
||||
foreach ($collection as &$row) {
|
||||
@ -65,3 +66,4 @@ class PurchaseImport implements ToArray, SkipsEmptyRows
|
||||
event(new BatchStockUpdateEvent($updateIds));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +16,8 @@ use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use App\Services\Business\BusinessFactory;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class BusinessOrderUpdateListener implements ShouldQueue
|
||||
{
|
||||
@ -39,6 +41,7 @@ class BusinessOrderUpdateListener implements ShouldQueue
|
||||
*/
|
||||
public function handle(BusinessOrdersUpdate $event)
|
||||
{
|
||||
try {
|
||||
//查询库存是否满足告警规则
|
||||
$skuId = $event->goodsSku->id;
|
||||
$nowTime = Carbon::now()->toDateTimeString();
|
||||
@ -56,5 +59,8 @@ class BusinessOrderUpdateListener implements ShouldQueue
|
||||
$messageService = new MessageService();
|
||||
$messageService->createLowerStockNoticeMessage($inventory, $event->goodsSku->toArray());
|
||||
}
|
||||
}catch(\Exception $exception) {
|
||||
Log::error("库存告警发生异常",["error"=>$exception->getMessage()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,8 +74,8 @@ class GoodSkuService
|
||||
public function handleSkusWithCombinationGoods(array $skusWithCombinationGoods){
|
||||
//查询sku当前未发货的数量 需要扣减
|
||||
$externalSkuIds = collect($skusWithCombinationGoods)->pluck("external_sku_id")->toArray();
|
||||
//默认只查7天内未发货的数据
|
||||
$startTime = Carbon::now()->subDays(7)->startOfDay()->toDateTimeString();
|
||||
//默认只查15天内未发货的数据
|
||||
$startTime = Carbon::now()->subDays(15)->startOfDay()->toDateTimeString();
|
||||
$unshippedDataCollect = BusinessOrderItem::query()
|
||||
->leftJoin("business_orders as b", "business_order_id", "=", "b.id")
|
||||
->select("external_sku_id", DB::raw("sum(goods_number) as goods_total"), DB::raw("sum(already_cancel_number) as cancel_total"))
|
||||
@ -107,7 +107,8 @@ class GoodSkuService
|
||||
'cost' => number_format(($goodsSkuItem['stock'] * $goodsSkuItem['cost'] + $v['cost'] * $v['num'])
|
||||
/ ($goodsSkuItem['stock'] + $v['num']), 2),
|
||||
];
|
||||
GoodsSku::query()->where('external_sku_id', $goodsSkuItem['external_sku_id'])->update($updateParams);
|
||||
GoodsSku::query()->where('external_sku_id',"=", $goodsSkuItem['external_sku_id'])
|
||||
->update($updateParam);
|
||||
$updateIds[] = $goodsSkuItem['id'];
|
||||
$updateParams[] = $updateParam;
|
||||
} else {
|
||||
|
||||
@ -40,7 +40,7 @@ class SaleDataService
|
||||
, DB::raw("sum(CASE WHEN b.shipping_status=0 THEN goods_number-already_cancel_number ELSE 0 END) as unshipping_num")
|
||||
, DB::raw("sum(goods_number-already_cancel_number) as goods_total")
|
||||
, DB::raw("ROUND(sum(goods_amount) / 100,2) as goods_total_amount"))
|
||||
->where("business_order_items.created_at", ">", Carbon::now()->startOfDay()->toDateTimeString())
|
||||
->where("business_order_items.created_at", ">", Carbon::now()->subDays(3)->startOfDay()->toDateTimeString())
|
||||
->where("business_order_items.cancel_status", "=", 0)
|
||||
->groupBy('external_sku_id')
|
||||
->orderBy("goods_total", "DESC")
|
||||
@ -62,7 +62,7 @@ class SaleDataService
|
||||
$endTime = Carbon::parse($request->input("end_day"))->endOfDay()->toDateTimeString();
|
||||
$dailyRecord = DailyStockRecord::query()
|
||||
->select("sku_id", DB::raw("sum(order_goods_num) as goods_total")
|
||||
, DB::raw("ROUND(sum(order_total_amount) / 100,2) as goods_total_amount"))
|
||||
, DB::raw("sum(order_total_amount) as goods_total_amount"))
|
||||
->whereBetween("created_at", [$startTime, $endTime])
|
||||
->groupBy("sku_id")
|
||||
->having(DB::raw("sum(order_goods_num)"), ">", 0)
|
||||
@ -136,14 +136,14 @@ class SaleDataService
|
||||
{
|
||||
//spu 基本就是全统计了
|
||||
if (StaticTypeEnum::TODAY == $request->type) {
|
||||
return static::spuSaleStatisticsByToday($request);
|
||||
return static::spuSaleStatisticsByToday();
|
||||
} else {
|
||||
//统计历史数据 这里走缓存
|
||||
return static::spuSaleStatisticsByHistoryCache($request);
|
||||
}
|
||||
}
|
||||
|
||||
public static function spuSaleStatisticsByToday(Request $request)
|
||||
public static function spuSaleStatisticsByToday()
|
||||
{
|
||||
//实时统计 sku维度
|
||||
$orderItems = BusinessOrderItem::query()
|
||||
@ -153,7 +153,7 @@ class SaleDataService
|
||||
, DB::raw("sum(CASE WHEN b.shipping_status=0 THEN goods_number-already_cancel_number ELSE 0 END) as unshipping_num")
|
||||
, DB::raw("sum(goods_number-already_cancel_number) as goods_total")
|
||||
, DB::raw("ROUND(sum(goods_amount) / 100,2) as goods_total_amount"))
|
||||
->where("business_order_items.created_at", ">", Carbon::now()->startOfDay()->toDateTimeString())
|
||||
->where("business_order_items.created_at", ">", Carbon::now()->subDays(3)->startOfDay()->toDateTimeString())
|
||||
->where("business_order_items.cancel_status", "=", 0)
|
||||
->groupBy('external_sku_id')->get()->toArray();
|
||||
$externalSkuIds = collect($orderItems)->pluck("external_sku_id")->toArray();
|
||||
@ -183,6 +183,11 @@ class SaleDataService
|
||||
})->values()->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过历史报表统计spu数据-缓存
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public static function spuSaleStatisticsByHistoryCache(Request $request)
|
||||
{
|
||||
$startTime = Carbon::parse($request->input("start_day"))->toDateTimeString();
|
||||
@ -194,11 +199,17 @@ class SaleDataService
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过历史报表统计spu数据
|
||||
* @param $startTime
|
||||
* @param $endTime
|
||||
* @return array
|
||||
*/
|
||||
public static function spuSaleStatisticsByHistory($startTime, $endTime)
|
||||
{
|
||||
$dailyAllRecord = DailyStockRecord::query()
|
||||
->select("sku_id", DB::raw("sum(order_goods_num) as goods_total")
|
||||
, DB::raw("ROUND(sum(order_total_amount) / 100,2) as goods_total_amount"))
|
||||
, DB::raw("sum(order_total_amount) as goods_total_amount"))
|
||||
->whereBetween("created_at", [$startTime, $endTime])
|
||||
->groupBy("sku_id")
|
||||
->having(DB::raw("sum(order_goods_num)"), ">", 0)
|
||||
@ -226,18 +237,46 @@ class SaleDataService
|
||||
];
|
||||
})->values()->toArray();
|
||||
}
|
||||
public static function gmvStatistics(Request $request){
|
||||
|
||||
public static function gmvStatistics(Request $request)
|
||||
{
|
||||
//gmv
|
||||
if (StaticTypeEnum::TODAY == $request->type) {
|
||||
|
||||
//以半小时为间隔统计数据
|
||||
$todayStartTime = Carbon::now()->subDays(3)->startOfDay()->toDateTimeString();
|
||||
$orderItems = BusinessOrderItem::query()
|
||||
->select("business_order_items.external_sku_id", "goods_number", "already_cancel_number", "goods_amount", "created_at")
|
||||
->where("business_order_items.created_at", ">", $todayStartTime)
|
||||
->where("business_order_items.cancel_status", "=", 0)
|
||||
->get()->toArray();
|
||||
$interval = $request->input("interval", 30);
|
||||
return collect($orderItems)->groupBy(function ($v) use ($todayStartTime, $interval) {
|
||||
$diff = Carbon::parse($v['created_at'])->diffInMinutes(Carbon::parse($todayStartTime));
|
||||
return (int)floor($diff / $interval);
|
||||
})->map(function ($v, $key) use ($todayStartTime, $interval) {
|
||||
return [
|
||||
"sort_key" => $key,
|
||||
"interval" => $interval,
|
||||
"time_start" => Carbon::parse($todayStartTime)->addMinutes($key * $interval)->toTimeString(),
|
||||
"time_end" => Carbon::parse($todayStartTime)->addMinutes(($key + 1) * $interval)->toTimeString(),
|
||||
"goods_total" => $v->sum("goods_number") - $v->sum("already_cancel_number"),
|
||||
"goods_total_amount" => $v->sum("goods_amount"),
|
||||
];
|
||||
})->sort()->values()->toArray();
|
||||
} else {
|
||||
//统计历史数据 这里走缓存
|
||||
//统计历史数据
|
||||
$startTime = Carbon::parse($request->input("start_day"))->toDateTimeString();
|
||||
$endTime = Carbon::parse($request->input("end_day"))->endOfDay()->toDateTimeString();
|
||||
|
||||
}
|
||||
return DailyStockRecord::query()
|
||||
->select("day", DB::raw("sum(order_total_amount) as goods_total_amount")
|
||||
, DB::raw("sum(order_goods_num) as goods_total"))
|
||||
->whereBetween("created_at", [$startTime, $endTime])
|
||||
->groupBy("day")->orderBy("day")
|
||||
->get()->toArray();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ class CreateSuppliersTable extends Migration
|
||||
$table->string('address')->nullable()->comment('地址');
|
||||
$table->string('link_tel',100)->nullable()->comment('联系方式');
|
||||
$table->string('payment_account',100)->nullable()->comment('支付方式');
|
||||
$table->string('supply_type')->nullable()->comment('供应类型');
|
||||
$table->string('agent_name')->nullable()->comment('代理人名称');
|
||||
$table->Integer('agent_id')->nullable()->comment('代理人id');
|
||||
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddOrderTotalAmountToDailyStockRecord extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
if (Schema::hasColumn('daily_stock_records', 'order_total_amount')) {
|
||||
return;
|
||||
}
|
||||
Schema::table('daily_stock_records', function (Blueprint $table) {
|
||||
$table->decimal('order_total_amount')->default(0)->comment('订单总金额');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('daily_stock_record', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -600,18 +600,35 @@ return [
|
||||
],
|
||||
'sale_statistics' => [
|
||||
'id' => 181,
|
||||
'name' => '销售统计',
|
||||
'name' => 'sku销售统计',
|
||||
'parent_id' => 18,
|
||||
'show' => 1,
|
||||
],
|
||||
'data_center.sale_statistics' => [
|
||||
'id' => 1811,
|
||||
'name' => '销售统计',
|
||||
'name' => 'sku统计接口',
|
||||
'parent_id' => 18
|
||||
],
|
||||
'spu_sale_statistics' => [
|
||||
'id' => 182,
|
||||
'name' => 'spu销售统计',
|
||||
'parent_id' => 18,
|
||||
'show' => 1,
|
||||
],
|
||||
'data_center.spu_sale_statistics' => [
|
||||
'id' => 1812,
|
||||
'name' => 'spu销售统计',
|
||||
'id' => 1820,
|
||||
'name' => 'spu销售统计接口',
|
||||
'parent_id' => 18
|
||||
],
|
||||
'gmv_statistics' => [
|
||||
'id' => 183,
|
||||
'name' => '交易趋势',
|
||||
'parent_id' => 18,
|
||||
'show' => 1,
|
||||
],
|
||||
'data_center.gmv_statistics' => [
|
||||
'id' => 1830,
|
||||
'name' => 'gmv统计',
|
||||
'parent_id' => 18,
|
||||
],
|
||||
];
|
||||
|
||||
@ -89,7 +89,7 @@ Route::middleware(['auth:api', 'check.permissions'])->group(function () {
|
||||
// 数据中心 销售报表
|
||||
Route::get('data_center/sale_statistics', [DataCenterController::class, 'saleStatistics'])->name('data_center.sale_statistics');
|
||||
Route::get('data_center/spu_sale_statistics', [DataCenterController::class, 'spuSaleStatistics'])->name('data_center.spu_sale_statistics');
|
||||
|
||||
Route::get('data_center/gmv_statistics', [DataCenterController::class, 'gmvStatistics'])->name('data_center.gmv_statistics');
|
||||
});
|
||||
Route::get('stock/goods_skus', [GoodsSkusController::class, 'stockNum'])->middleware('auth:api');
|
||||
Route::get('goods/filter/{title}', [GoodsCombinationController::class, 'goodsSkus'])->middleware('auth:api');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user