From 1b02f90047cc1eaef577d69641145552c2d34298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E4=B8=96=E7=95=8C?= <642747453@qq.com> Date: Thu, 14 Mar 2024 20:50:29 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=94=80=E5=94=AE=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Console/Commands/DailySalesReport.php | 37 +++- .../DataCenter/DataCenterController.php | 38 +++++ .../Resources/DailySalesReportResource.php | 19 +++ app/Models/DailySalesReport.php | 8 + app/Utils/FormatUtils.php | 5 + ...50026_create_daily_sales_reports_table.php | 11 +- database/seeds/MenusTableSeeder.php | 6 +- resources/frontend/src/api/dataCenter.js | 9 + resources/frontend/src/api/goods.js | 2 +- resources/frontend/src/router/list.js | 5 + .../src/views/dataCenter/salesReport.vue | 161 ++++++++++++++++++ resources/lang/zh-CN/permission.php | 18 ++ routes/api.php | 3 + 13 files changed, 313 insertions(+), 9 deletions(-) create mode 100644 app/Http/Controllers/DataCenter/DataCenterController.php create mode 100644 app/Http/Resources/DailySalesReportResource.php create mode 100644 resources/frontend/src/api/dataCenter.js create mode 100644 resources/frontend/src/views/dataCenter/salesReport.vue diff --git a/app/Console/Commands/DailySalesReport.php b/app/Console/Commands/DailySalesReport.php index 0bdeb42..2226550 100644 --- a/app/Console/Commands/DailySalesReport.php +++ b/app/Console/Commands/DailySalesReport.php @@ -9,6 +9,7 @@ use App\Utils\ArrayUtils; use Carbon\Carbon; use Illuminate\Console\Command; use Illuminate\Support\Facades\DB; +use App\Models\DailySalesReport as DailySalesReportModel; class DailySalesReport extends Command { @@ -58,6 +59,7 @@ class DailySalesReport extends Command 'S4' => [ 'startTime' => date('Y-m-d 15:00:00'), 'endTime' => date('Y-m-d 16:00:00'), + ], 'S5' => [ 'startTime' => date('Y-m-d 11:00:00'), @@ -129,8 +131,16 @@ class DailySalesReport extends Command if (!isset($goodsSkus[$externalSkuId])) { continue; } - \App\Models\DailySalesReport::query() - ->updateOrCreate([ + $dailySalesReport = DailySalesReportModel::query() + ->where('date', $date) + ->where('external_sku_id', $externalSkuId) + ->first(); + $sVal = $datum['total_goods_number'] - $datum['total_already_cancel_number']; + $sRate = $s . '_rate'; + $stock = $goodsSkus[$externalSkuId]['daily']['inventory'] + $goodsSkus[$externalSkuId]['daily']['arrived_today_num']; + $sRateVal = $stock ? bcdiv($sVal, $stock, 4) : 0; + if (is_null($dailySalesReport)) { + DailySalesReportModel::query()->updateOrCreate([ 'date' => $date, 'external_sku_id' => $externalSkuId, ], [ @@ -139,10 +149,29 @@ class DailySalesReport extends Command 'name' => $goodsSkus[$externalSkuId]['name'], 'inventory' => $goodsSkus[$externalSkuId]['daily']['inventory'], 'arrived_today_num' => $goodsSkus[$externalSkuId]['daily']['arrived_today_num'], - 'already_cancel_number' => $datum['total_already_cancel_number'], + 'sales_num' => $sVal, 'loss_num' => $goodsSkus[$externalSkuId]['daily']['loss_num'], - $s => $datum['total_goods_number'], + $s => $sVal, + $sRate => $sRateVal, + 'already_cancel_number' => $datum['total_already_cancel_number'], ]); + } else { + $num = 0; + foreach ($map as $key => $val) { + if ($key !== $s) { + $num += $dailySalesReport->$key; + } + } + $dailySalesReport->update([ + 'inventory' => $goodsSkus[$externalSkuId]['daily']['inventory'], + 'arrived_today_num' => $goodsSkus[$externalSkuId]['daily']['arrived_today_num'], + 'sales_num' => $num + $sVal, + 'loss_num' => $goodsSkus[$externalSkuId]['daily']['loss_num'], + $s => $sVal, + $sRate => $sRateVal, + 'already_cancel_number' => $datum['total_already_cancel_number'], + ]); + } } } } diff --git a/app/Http/Controllers/DataCenter/DataCenterController.php b/app/Http/Controllers/DataCenter/DataCenterController.php new file mode 100644 index 0000000..74bc743 --- /dev/null +++ b/app/Http/Controllers/DataCenter/DataCenterController.php @@ -0,0 +1,38 @@ +get('sort', 'sales_num'); + $order = $request->get('sortOrder', 'DESC'); + + + $dailySalesReports = DailySalesReport::query() + ->filter() + ->orderBy($sort, $order) + ->paginate($request->get('per_page')); + + foreach ($dailySalesReports as &$dailySalesReport) { + $dailySalesReport['stock'] = $dailySalesReport['inventory'] + $dailySalesReport['arrived_today_num']; + $dailySalesReport['goal_rate'] = FormatUtils::getPercent($dailySalesReport['goal_rate'], 1); + $dailySalesReport['S1_rate'] = FormatUtils::getPercent($dailySalesReport['S1_rate'], 1); + $dailySalesReport['S2_rate'] = FormatUtils::getPercent($dailySalesReport['S2_rate'], 1); + $dailySalesReport['S3_rate'] = FormatUtils::getPercent($dailySalesReport['S3_rate'], 1); + $dailySalesReport['S4_rate'] = FormatUtils::getPercent($dailySalesReport['S4_rate'], 1); + $dailySalesReport['S5_rate'] = FormatUtils::getPercent($dailySalesReport['S5_rate'], 1); + $dailySalesReport['S6_rate'] = FormatUtils::getPercent($dailySalesReport['S6_rate'], 1); + $dailySalesReport['S7_rate'] = FormatUtils::getPercent($dailySalesReport['S7_rate'], 1); + } + + return DailySalesReportResource::collection($dailySalesReports); + } +} \ No newline at end of file diff --git a/app/Http/Resources/DailySalesReportResource.php b/app/Http/Resources/DailySalesReportResource.php new file mode 100644 index 0000000..a744cc9 --- /dev/null +++ b/app/Http/Resources/DailySalesReportResource.php @@ -0,0 +1,19 @@ + 'like', + ]; } diff --git a/app/Utils/FormatUtils.php b/app/Utils/FormatUtils.php index ab18927..5f56216 100644 --- a/app/Utils/FormatUtils.php +++ b/app/Utils/FormatUtils.php @@ -33,4 +33,9 @@ class FormatUtils } return $data; } + + public static function getPercent($dividend, $divisor, $decimal = 2) + { + return bcdiv($dividend, $divisor, $decimal + 2) * 100 . '%'; + } } diff --git a/database/migrations/2024_03_14_150026_create_daily_sales_reports_table.php b/database/migrations/2024_03_14_150026_create_daily_sales_reports_table.php index a0f19e3..8e94f48 100644 --- a/database/migrations/2024_03_14_150026_create_daily_sales_reports_table.php +++ b/database/migrations/2024_03_14_150026_create_daily_sales_reports_table.php @@ -25,10 +25,10 @@ class CreateDailySalesReportsTable extends Migration $table->string('external_sku_id', 64); $table->integer('inventory')->default(0)->comment('盘点数量'); $table->integer('arrived_today_num')->default(0)->comment('今日到货'); -// $table->integer('sales_num')->default(0)->comment('销量'); + $table->integer('sales_num')->default(0)->comment('销量'); $table->integer('already_cancel_number')->default(0)->comment('已取消数量'); $table->unsignedInteger('loss_num')->default(0)->comment('损耗'); - $table->decimal('goal_rate')->default(0)->comment('目标去化率'); + $table->decimal('goal_rate', 8, 4)->default(0)->comment('目标去化率'); $table->integer('S1')->default(0)->comment('11-12'); $table->integer('S2')->default(0)->comment('11-13:30'); $table->integer('S3')->default(0)->comment('11-15'); @@ -36,6 +36,13 @@ class CreateDailySalesReportsTable extends Migration $table->integer('S5')->default(0)->comment('11-17:30'); $table->integer('S6')->default(0)->comment('11-20'); $table->integer('S7')->default(0)->comment('11-9:30'); + $table->decimal('S1_rate', 8, 4)->default(0); + $table->decimal('S2_rate', 8, 4)->default(0); + $table->decimal('S3_rate', 8, 4)->default(0); + $table->decimal('S4_rate', 8, 4)->default(0); + $table->decimal('S5_rate', 8, 4)->default(0); + $table->decimal('S6_rate', 8, 4)->default(0); + $table->decimal('S7_rate', 8, 4)->default(0); $table->timestamps(); }); diff --git a/database/seeds/MenusTableSeeder.php b/database/seeds/MenusTableSeeder.php index 285c646..cd694f0 100644 --- a/database/seeds/MenusTableSeeder.php +++ b/database/seeds/MenusTableSeeder.php @@ -40,8 +40,10 @@ class MenusTableSeeder extends Seeder ['parent_id' => $id, 'code' => 'PLAT_GOODS_LIST', 'name' => '货品列表', 'seq' => 0], ['parent_id' => $id, 'code' => 'PLAT_ORDER_LIST', 'name' => '订单列表', 'seq' => 1], ]); - // 团购 - 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' => 2]); + // 数据中心 + DB::table('menus')->insertGetId(['parent_id' => 0, 'code' => 'DATA_CENTER', 'name' => '数据中心', 'seq' => 1]); } public function update() diff --git a/resources/frontend/src/api/dataCenter.js b/resources/frontend/src/api/dataCenter.js new file mode 100644 index 0000000..8837f78 --- /dev/null +++ b/resources/frontend/src/api/dataCenter.js @@ -0,0 +1,9 @@ +import http from "@/util/http.js"; + +export function getSalesReportData(params) { + return http({ + url: "/api/data_center/sales_report", + method: "get", + params, + }); +} \ No newline at end of file diff --git a/resources/frontend/src/api/goods.js b/resources/frontend/src/api/goods.js index c91a0de..91d9dba 100644 --- a/resources/frontend/src/api/goods.js +++ b/resources/frontend/src/api/goods.js @@ -186,4 +186,4 @@ export function delGoodsCombination(id) { url: "/api/goods_combination/" + id, method: "delete", }); -} +} \ No newline at end of file diff --git a/resources/frontend/src/router/list.js b/resources/frontend/src/router/list.js index 997fc7c..2e902e0 100644 --- a/resources/frontend/src/router/list.js +++ b/resources/frontend/src/router/list.js @@ -105,6 +105,11 @@ const list = [ name: "电子面单", component: () => import("../views/plat/faceSheet.vue"), }, + { + path: "SALES_REPORT_DATA", + name: "销售数据", + component: () => import("../views/dataCenter/salesReport.vue"), + }, ], }, ]; diff --git a/resources/frontend/src/views/dataCenter/salesReport.vue b/resources/frontend/src/views/dataCenter/salesReport.vue new file mode 100644 index 0000000..d3072e6 --- /dev/null +++ b/resources/frontend/src/views/dataCenter/salesReport.vue @@ -0,0 +1,161 @@ + + + + + diff --git a/resources/lang/zh-CN/permission.php b/resources/lang/zh-CN/permission.php index e454be0..a245aec 100644 --- a/resources/lang/zh-CN/permission.php +++ b/resources/lang/zh-CN/permission.php @@ -459,4 +459,22 @@ return [ 'name' => '收货信息保存', 'parent_id' => 170, ], + // 数据中心 + 'DATA_CENTER' => [ + 'id' => 18, + 'name' => '数据中心', + 'parent_id' => 0, + 'show' => 1, + ], + 'SALES_REPORT_DATA' => [ + 'id' => 180, + 'name' => '销售数据', + 'parent_id' => 18, + 'show' => 1, + ], + 'sales_report.index' => [ + 'id' => 1800, + 'name' => '销售数据列表', + 'parent_id' => 180, + ], ]; diff --git a/routes/api.php b/routes/api.php index d087efd..e804ec4 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,6 +1,7 @@ group(function () { // 发货信息 Route::get('shop/ship/senders', [ShipController::class, 'getSenders'])->name('shop_ship.senders.get'); Route::post('shop/ship/senders', [ShipController::class, 'saveSenders'])->name('shop_ship.senders.save'); + // 数据中心 + Route::get('data_center/sales_report', [DataCenterController::class, 'salesReport'])->name('sales_report.index'); }); Route::get('stock/goods_skus', [GoodsSkusController::class, 'stockNum'])->middleware('auth:api'); Route::get('goods/filter/{title}', [GoodsCombinationController::class, 'goodsSkus'])->middleware('auth:api');